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 var digitState = stateNoBinary .latchAndAppend(MODE_DIGIT, 16 - pairCode) // period or comma in DIGIT .latchAndAppend(MODE_DIGIT, 1); // space in DIGIT result.Add(digitState); } 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); } }
// 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. var latchState = stateNoBinary.latchAndAppend(mode, charInMode); result.Add(latchState); } // 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. var shiftState = stateNoBinary.shiftAndAppend(mode, charInMode); result.Add(shiftState); } } } 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. var binaryState = state.addBinaryShiftChar(index); result.Add(binaryState); } }