litesoft
@ 965
litesoft / trunk / GWT_Sandbox / FormEngine / src / com / temp / foundation / client / pavment / AbstractPlaceTokenCodecCharacterDelta.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
package com.temp.foundation.client.pavment; import com.temp.common.shared.utils.*; /** * Implementation that supports an encoding model of encoded Deltas from one * character to the next. * * @author georgs */ public abstract class AbstractPlaceTokenCodecCharacterDelta implements PlaceTokenCodec { /** * Encode the String (nulls are returned as "") * * @return "" if null passed in, otherwise the Encoded String. */ public final String encode( String unencoded ) { if ( (unencoded == null) || (unencoded.length() == 0) ) { return ""; } char initialCharacter = SixBitCodec.encode( (int) (63 & System.currentTimeMillis()) ); return new Helper( new CharSource( unencoded ), initialCharacter, determinePerCharacterAdjustment( initialCharacter ) ).encode(); } abstract protected int determinePerCharacterAdjustment( char initialCharacter ); /** * Decode the previously "encoded" data, null or bad encoding will return * null. * * @return null indicates that the data was either null or contained * unacceptable characters for decoding. */ public final String decode( String encoded ) { if ( encoded == null ) { return null; } if ( encoded.length() == 0 ) { return ""; } CharSource charSource = new CharSource( encoded ); char initialCharacter = charSource.getRequired(); return new Helper( charSource, initialCharacter, determinePerCharacterAdjustment( initialCharacter ) ).decode(); } private static class Helper { protected StringBuilder mSB = new StringBuilder(); private final CharSource charSource; private final int perCharAdjustment; private int lastClearTextChar; private int deltaRunning = 0; private int charDeltasRemaining = 0; public Helper( CharSource charSource, char firstChar, int perCharAdjustment ) { this.charSource = charSource; this.perCharAdjustment = perCharAdjustment; this.lastClearTextChar = firstChar; } public String encode() { mSB.append( (char) lastClearTextChar ); while ( charSource.anyRemaining() ) { encode( charSource.get() ); } return mSB.toString(); } public String decode() { while ( charSource.anyRemaining() ) { if ( !decode( charSource.get() ) ) { return null; } } // Check for Ran off the End! return (charDeltasRemaining == 0) ? mSB.toString() : null; } private void encode( int chr ) { int delta = (chr - lastClearTextChar) + perCharAdjustment; if ( delta < 0 ) { LLencode( -delta, 'a' ); } else { LLencode( delta, 'A' ); } lastClearTextChar = chr; } private void LLencode( int delta, int base ) { if ( div4 <= delta ) { mSB.append( '4' ); delta = addFactor( delta, base, div4 ); delta = addFactor( delta, base, div3 ); delta = addFactor( delta, base, div2 ); } else if ( div3 <= delta ) { mSB.append( '3' ); delta = addFactor( delta, base, div3 ); delta = addFactor( delta, base, div2 ); } else if ( div2 <= delta ) { mSB.append( '2' ); delta = addFactor( delta, base, div2 ); } LLencodeChar( delta, base ); } private int addFactor( int delta, int base, int divisor ) { int zDelta = 0; while ( delta >= divisor ) { zDelta++; delta -= divisor; } LLencodeChar( zDelta, base ); return delta; } private void LLencodeChar( int delta, int base ) { mSB.append( (delta == 0) ? '0' : (char) (base + (delta - 1)) ); } // 0 = No Change / same letter // A-Z = Delta: +1 to +26 // a-z = Delta: -1 to -26 // 2-4 = Delta: that many letters/'0' follow, witch are in base 27 private static final int div4 = 19683; // 27 * 27 * 27; private static final int div3 = 729; // 27 * 27; private static final int div2 = 27; public boolean decode( int chr ) { if ( charDeltasRemaining > 0 ) { Integer delta = LLdecode( chr ); if ( delta == null ) { return false; } deltaRunning = (deltaRunning * 27) + delta; if ( --charDeltasRemaining == 0 ) { if ( !LLdecodeChar( deltaRunning ) ) { return false; } deltaRunning = 0; } return true; } if ( ('2' <= chr) && (chr <= '4') ) { charDeltasRemaining = chr - '0'; return true; } return LLdecodeChar( LLdecode( chr ) ); } private boolean LLdecodeChar( Integer delta ) { if ( delta == null ) { return false; } lastClearTextChar += delta - perCharAdjustment; mSB.append( (char) lastClearTextChar ); return true; } private Integer LLdecode( int chr ) { if ( chr == '0' ) { return 0; } if ( ('a' <= chr) && (chr <= 'z') ) { return -(1 + (chr - 'a')); } if ( ('A' <= chr) && (chr <= 'Z') ) { return (1 + (chr - 'A')); } return null; // Unacceptable Char } } } |
Commits for litesoft/trunk/GWT_Sandbox/FormEngine/src/com/temp/foundation/client/pavment/AbstractPlaceTokenCodecCharacterDelta.java
Revision | Author | Commited | Message |
---|---|---|---|
965 | GeorgeS | Fri 01 Aug, 2014 03:20:35 +0000 | ! |