private static void updateStateForPair(State state, int index, int pairCode, ICollection<State> result)
 {
    State stateNoBinary = state.endBinaryShift(index);
    // Possibility 1.  Latch to MODE_PUNCT, and then append this code
    result.Add(stateNoBinary.latchAndAppend(MODE_PUNCT, pairCode));
    if (state.Mode != MODE_PUNCT)
    {
       // Possibility 2.  Shift to MODE_PUNCT, and then append this code.
       // Every state except MODE_PUNCT (handled above) can shift
       result.Add(stateNoBinary.shiftAndAppend(MODE_PUNCT, pairCode));
    }
    if (pairCode == 3 || pairCode == 4)
    {
       // both characters are in DIGITS.  Sometimes better to just add two digits
       State digit_state = stateNoBinary
          .latchAndAppend(MODE_DIGIT, 16 - pairCode) // period or comma in DIGIT
          .latchAndAppend(MODE_DIGIT, 1); // space in DIGIT
       result.Add(digit_state);
    }
    if (state.BinaryShiftByteCount > 0)
    {
       // It only makes sense to do the characters as binary if we're already
       // in binary mode.
       State binaryState = state.addBinaryShiftChar(index).addBinaryShiftChar(index + 1);
       result.Add(binaryState);
    }
 }
Exemple #2
0
 /// <summary>
 /// Returns true if "this" state is better (or equal) to be in than "that"
 /// state under all possible circumstances.
 /// </summary>
 public bool isBetterThanOrEqualTo(State other)
 {
    int mySize = this.bitCount + (HighLevelEncoder.LATCH_TABLE[this.mode][other.mode] >> 16);
    if (other.binaryShiftByteCount > 0 &&
        (this.binaryShiftByteCount == 0 || this.binaryShiftByteCount > other.binaryShiftByteCount))
    {
       mySize += 10; // Cost of entering Binary Shift mode.
    }
    return mySize <= other.bitCount;
 }
 // Return a set of states that represent the possible ways of updating this
 // state for the next character.  The resulting set of states are added to
 // the "result" list.
 private void updateStateForChar(State state, int index, ICollection<State> result)
 {
    char ch = (char) (text[index] & 0xFF);
    bool charInCurrentTable = CHAR_MAP[state.Mode][ch] > 0;
    State stateNoBinary = null;
    for (int mode = 0; mode <= MODE_PUNCT; mode++)
    {
       int charInMode = CHAR_MAP[mode][ch];
       if (charInMode > 0)
       {
          if (stateNoBinary == null)
          {
             // Only create stateNoBinary the first time it's required.
             stateNoBinary = state.endBinaryShift(index);
          }
          // Try generating the character by latching to its mode
          if (!charInCurrentTable || mode == state.Mode || mode == MODE_DIGIT)
          {
             // If the character is in the current table, we don't want to latch to
             // any other mode except possibly digit (which uses only 4 bits).  Any
             // other latch would be equally successful *after* this character, and
             // so wouldn't save any bits.
             State latch_state = stateNoBinary.latchAndAppend(mode, charInMode);
             result.Add(latch_state);
          }
          // Try generating the character by switching to its mode.
          if (!charInCurrentTable && SHIFT_TABLE[state.Mode][mode] >= 0)
          {
             // It never makes sense to temporarily shift to another mode if the
             // character exists in the current mode.  That can never save bits.
             State shift_state = stateNoBinary.shiftAndAppend(mode, charInMode);
             result.Add(shift_state);
          }
       }
    }
    if (state.BinaryShiftByteCount > 0 || CHAR_MAP[state.Mode][ch] == 0)
    {
       // It's never worthwhile to go into binary shift mode if you're not already
       // in binary shift mode, and the character exists in your current mode.
       // That can never save bits over just outputting the char in the current mode.
       State binaryState = state.addBinaryShiftChar(index);
       result.Add(binaryState);
    }
 }
Exemple #4
0
 /// <summary>
 /// Create a new state representing this state, but an additional character
 /// output in Binary Shift mode.
 /// </summary>
 public State addBinaryShiftChar(int index)
 {
    Token token = this.token;
    int mode = this.mode;
    int bitCount = this.bitCount;
    if (this.mode == HighLevelEncoder.MODE_PUNCT || this.mode == HighLevelEncoder.MODE_DIGIT)
    {
       //assert binaryShiftByteCount == 0;
       int latch = HighLevelEncoder.LATCH_TABLE[mode][HighLevelEncoder.MODE_UPPER];
       token = token.add(latch & 0xFFFF, latch >> 16);
       bitCount += latch >> 16;
       mode = HighLevelEncoder.MODE_UPPER;
    }
    int deltaBitCount =
       (binaryShiftByteCount == 0 || binaryShiftByteCount == 31) ? 18 :
          (binaryShiftByteCount == 62) ? 9 : 8;
    State result = new State(token, mode, binaryShiftByteCount + 1, bitCount + deltaBitCount);
    if (result.binaryShiftByteCount == 2047 + 31)
    {
       // The string is as long as it's allowed to be.  We should end it.
       result = result.endBinaryShift(index + 1);
    }
    return result;
 }