Package com.inet.jortho

Source Code of com.inet.jortho.Dictionary

/*
*  JOrtho
*
*  Copyright (C) 2005-2008 by i-net software
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License as
*  published by the Free Software Foundation; either version 2 of the
*  License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful, but
*  WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
*  General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
*  USA.
*  Created on 02.11.2005
*/
package com.inet.jortho;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;

/**
* A container for a word list.
* @author Volker Berlin
*/
final class Dictionary extends DictionaryBase {
  /**
   * Create an empty Dictionary.
   */
  public Dictionary() {
    tree = new char[10000];
    tree[size++] = LAST_CHAR;
  }

  /**
   * Create an Dictionary from a serialize Dictionary. This is used from the DictionaryFactory.
   * @see #toArray()
   * @see DictionaryFactory
   */
  public Dictionary(final char[] tree) {
    super(tree);
  }

  /**
   * Add a word to the tree. If it already exist then it has no effect.
   * @param word the new word.
   */
  public void add(final String word) {
    idx = 0;
    for (int i = 0; i < word.length(); i++) {
      final char c = word.charAt(i);
      searchCharOrAdd(c);
      if (i == word.length() - 1) {
        tree[idx + 1] |= 0x8000;
        return;
      }
      final int nextIdx = readIndex();
      if (nextIdx == 0) {
        idx = createNewNode();
      }
      else {
        idx = nextIdx;
      }
    }
  }

  /**
   * Check the size of the array and resize it if needed.
   * @param newSize the requied size
   */
  private final void checkSize(final int newSize) {
    if (newSize > tree.length) {
      final char[] puffer = new char[Math.max(newSize, 2 * tree.length)];
      System.arraycopy(tree, 0, puffer, 0, size);
      tree = puffer;
    }
  }

  /**
   * Create a new node at end of the array.
   * On the current idx position is writing the pointer.
   * The pointer on the current idx position must be 0 without some word end flags (0x8000 on idx+1)
   * @return Pointer on new node.
   */
  private final int createNewNode() {
    checkSize(size + 1);
    tree[idx + 1] |= (char) (size >> 16);
    tree[idx + 2] |= (char) (size);
    idx = size;
    tree[idx] = LAST_CHAR;
    size += 1;
    return idx;
  }

  /**
   * Get the size of chars that this dictionary need in memory.
   */
  public int getDataSize() {
    return size;
  }

  private void insertChar(final char c) {
    checkSize(size + 3);
    System.arraycopy(tree, idx, tree, idx + 3, size - idx);
    tree[idx] = c;
    tree[idx + 1] = 0;
    tree[idx + 2] = 0;
    size += 3;
    for (int i = 0; i < size;) {
      if (tree[i] == LAST_CHAR) {
        i++;
      }
      else {
        int index = (tree[i + 1] << 16) + tree[i + 2];
        final int indexValue = index & 0x7fffffff;
        if (indexValue > idx) {
          index += 3;
          tree[i + 1] = (char) (index >> 16);
          tree[i + 2] = (char) (index);
        }
        i += 3;
      }
    }
  }

  /**
   * Load the directory from a compressed stream.
   * @param stream the InputStream
   * @throws IOException if an I/O error occurs.
   */
  public void load(final InputStream stream) throws IOException {
    InputStream zip = new InflaterInputStream(stream);
    zip = new BufferedInputStream(zip);
    size = 0;
    while (zip.available() > 0) {
      final char c = (char) (zip.read() + (zip.read() << 8));
      checkSize(size + 1);
      tree[size++] = c;
    }
    zip.close();
    // Shrinken
    trimToSize();
  }

  /**
   * Load the directory from a compressed file.
   * @param filename the name of the file.
   * @throws IOException if an I/O error occurs.
   */
  public void load(final String filename) throws IOException {
    final FileInputStream fos = new FileInputStream(filename);
    load(fos);
  }

  /**
   * Save this dictionary to the OutputStream. The data will be compressed. After finish the OutputStream is closed.
   * @param stream the OutputStream
   * @throws IOException if an I/O error occurs.
   */
  public void save(final OutputStream stream) throws IOException {
    final Deflater deflater = new Deflater();
    deflater.setLevel(Deflater.BEST_COMPRESSION);
    final DeflaterOutputStream zip = new DeflaterOutputStream(stream, deflater);
    for (int i = 0; i < size; i++) {
      zip.write(tree[i]);
      zip.write(tree[i] >> 8);
    }
    zip.flush();
    zip.close();
  }

  /**
   * Save this dictionary to a compressed file.
   * @param filename the name of the file.
   * @return the size in bytes that was needed.
   * @throws IOException if an I/O error occurs.
   */
  public long save(final String filename) throws IOException {
    // Daten komprimieren und speichern
    final File file = new File(filename);
    final FileOutputStream fos = new FileOutputStream(file);
    save(fos);
    return file.length();
  }

  private void searchCharOrAdd(final char c) {
    if (c == LAST_CHAR) {
      throw new RuntimeException("Invalid Character");
    }
    while (idx < size && tree[idx] < c) {
      idx += 3;
    }
    if (idx >= size) {
      throw new RuntimeException("Internal Error");
    }
    if (tree[idx] == c) {
      return;
    }
    insertChar(c);
    return;
  }

  /**
   * Convert the directory tree to char array.
   * @return a char array that include the data of the dictionary.
   */
  public char[] toArray() {
    final char[] puffer = new char[size];
    System.arraycopy(tree, 0, puffer, 0, size);
    return puffer;
  }

  /**
   * Trims the capacity of this <tt>Dictionary</tt> instance to be the
   * current size.  An application can use this operation to minimize
   * the storage of an <tt>Dictionary</tt> instance.
   * The load methods already call it.
   */
  void trimToSize() {
    final char[] temp = new char[size];
    System.arraycopy(tree, 0, temp, 0, size);
    tree = temp;
  }
}
TOP

Related Classes of com.inet.jortho.Dictionary

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.