public void callback(String word, int level) {
    if (word == null) return;
    int maxidx = word.length();
    int lastStart = -1;
    int i = 0;

    while (i < maxidx) {
      char c = word.charAt(i);
      if (Character.isLetter(c) == true) {
        if (lastStart == -1) {
          lastStart = i;
        }
      } else {
        if (lastStart != -1 && i > lastStart) {
          backend.callback(word.substring(lastStart, i), level);
          lastStart = -1;
        }
      }
      ++i;
    }
  }
Beispiel #2
0
  @Override
  public void getWords(final WordComposer codes, final WordCallback callback) {
    mWordCallback = callback;
    final int codesSize = codes.size();
    // Wont deal with really long words.
    if (codesSize > MAX_WORD_LENGTH - 1) return;

    Arrays.fill(mInputCodes, -1);
    for (int i = 0; i < codesSize; i++) {
      final int[] alternatives = codes.getCodesAt(i);
      System.arraycopy(
          alternatives,
          0,
          mInputCodes,
          i * MAX_ALTERNATIVES,
          Math.min(alternatives.length, MAX_ALTERNATIVES));
    }
    Arrays.fill(mOutputChars, (char) 0);
    Arrays.fill(mFrequencies, 0);

    int count =
        getSuggestionsNative(
            mNativeDict,
            mInputCodes,
            codesSize,
            mOutputChars,
            mFrequencies,
            MAX_WORD_LENGTH,
            MAX_WORDS,
            MAX_ALTERNATIVES,
            -1);

    // If there aren't sufficient suggestions, search for words by allowing
    // wild cards at
    // the different character positions. This feature is not ready for
    // prime-time as we need
    // to figure out the best ranking for such words compared to proximity
    // corrections and
    // completions.
    if (ENABLE_MISSED_CHARACTERS && count < 5) {
      for (int skip = 0; skip < codesSize; skip++) {
        final int tempCount =
            getSuggestionsNative(
                mNativeDict,
                mInputCodes,
                codesSize,
                mOutputChars,
                mFrequencies,
                MAX_WORD_LENGTH,
                MAX_WORDS,
                MAX_ALTERNATIVES,
                skip);
        count = Math.max(count, tempCount);
        if (tempCount > 0) break;
      }
    }

    for (int j = 0; j < count; j++) {
      if (mFrequencies[j] < 1) break;
      final int start = j * MAX_WORD_LENGTH;
      int len = 0;
      while (mOutputChars[start + len] != 0) {
        len++;
      }
      if (len > 0) {
        callback.addWord(mOutputChars, start, len, mFrequencies[j]);
      }
    }
  }
  /**
   * Recursively traverse the tree for words that match the input. Input consists of a list of
   * arrays. Each item in the list is one input character position. An input character is actually
   * an array of multiple possible candidates. This function is not optimized for speed, assuming
   * that the user dictionary will only be a few hundred words in size.
   *
   * @param roots node whose children have to be search for matches
   * @param codes the input character codes
   * @param word the word being composed as a possible match
   * @param depth the depth of traversal - the length of the word being composed thus far
   * @param completion whether the traversal is now in completion mode - meaning that we've
   *     exhausted the input and we're looking for all possible suffixes.
   * @param snr current weight of the word being formed
   * @param inputIndex position in the input characters. This can be off from the depth in case we
   *     skip over some punctuations such as apostrophe in the traversal. That is, if you type
   *     "wouldve", it could be matching "would've", so the depth will be one more than the
   *     inputIndex
   * @param callback the callback class for adding a word
   */
  private void getWordsRec(
      NodeArray roots,
      final WordComposer codes,
      final char[] word,
      final int depth,
      boolean completion,
      float snr,
      int inputIndex,
      WordCallback callback) {
    final int count = roots.length;
    final int codeSize = mInputLength;
    // Optimization: Prune out words that are too long compared to how much was typed.
    if (depth > mMaxDepth) {
      return;
    }
    int[] currentChars = null;
    if (codeSize <= inputIndex) {
      completion = true;
    } else {
      currentChars = codes.getCodesAt(inputIndex);
    }

    for (int i = 0; i < count; i++) {
      final Node node = roots.data[i];
      final char c = node.code;
      final char lowerC = toLowerCase(c);
      boolean terminal = node.terminal;
      NodeArray children = node.children;
      int freq = node.frequency;
      if (completion) {
        word[depth] = c;
        if (terminal) {
          if (!callback.addWord(word, 0, depth + 1, (int) (freq * snr))) {
            return;
          }
        }
        if (children != null) {
          getWordsRec(children, codes, word, depth + 1, completion, snr, inputIndex, callback);
        }
      } else if (c == QUOTE && currentChars[0] != QUOTE) {
        // Skip the ' and continue deeper
        word[depth] = QUOTE;
        if (children != null) {
          getWordsRec(children, codes, word, depth + 1, completion, snr, inputIndex, callback);
        }
      } else {
        for (int j = 0; j < currentChars.length; j++) {
          float addedAttenuation = (j > 0 ? 1f : 3f);
          if (currentChars[j] == -1) {
            break;
          }
          if (currentChars[j] == lowerC || currentChars[j] == c) {
            word[depth] = c;

            if (codes.size() == depth + 1) {
              if (terminal) {
                if (INCLUDE_TYPED_WORD_IF_VALID || !same(word, depth + 1, codes.getTypedWord())) {
                  callback.addWord(
                      word,
                      0,
                      depth + 1,
                      (int) (freq * snr * addedAttenuation * FULL_WORD_FREQ_MULTIPLIER));
                }
              }
              if (children != null) {
                getWordsRec(
                    children,
                    codes,
                    word,
                    depth + 1,
                    true,
                    snr * addedAttenuation,
                    inputIndex + 1,
                    callback);
              }
            } else if (children != null) {
              getWordsRec(
                  children,
                  codes,
                  word,
                  depth + 1,
                  false,
                  snr * addedAttenuation,
                  inputIndex + 1,
                  callback);
            }
          }
        }
      }
    }
  }
 public void pushLevel(int level) {
   backend.pushLevel(level);
 }
 public void popLevel() {
   backend.popLevel();
 }