litesoft
@ HEAD
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 |
package org.litesoft.codec; import org.litesoft.commonfoundation.annotations.*; import org.litesoft.commonfoundation.charstreams.*; public class PrimitiveLongCodec { public static final PrimitiveLongCodec SIGNED = new PrimitiveLongCodec( true ); public static final PrimitiveLongCodec NON_NEGATIVE = new PrimitiveLongCodec( false ); private final boolean mSignedValuesOK; private PrimitiveLongCodec( boolean pSignedValuesOK ) { mSignedValuesOK = pSignedValuesOK; } public void encode( @NotNull CharSink pCharSink, long pValue ) { if ( (pValue < 0) && !mSignedValuesOK ) { throw new IllegalArgumentException( "Negative values not supported: " + pValue ); } new Encoder( pCharSink, pValue ).encode(); } public long decode( @NotNull CharSource pCharSource ) { return new Decoder( pCharSource ).decode(); } private static final int NEGATIVE_1ST_CHAR_BIT = 16; private static final int NON_NEGATIVE_1ST_CHAR_BIT = 0; private static final int SIGNED_1ST_CHAR_MASK = 15; private static final int SIGNED_1ST_CHAR_FACTOR = 16; private static final int UNSIGNED_1ST_CHAR_MASK = 31; private static final int UNSIGNED_1ST_CHAR_FACTOR = 32; private static final int MORE_BIT = 32; private static final int MORE_MASK = 31; private static final int MORE_FACTOR = 32; private class Common { protected final int mFirstCharMask; protected final int mFirstCharFactor; protected Common() { if ( mSignedValuesOK ) { mFirstCharMask = SIGNED_1ST_CHAR_MASK; mFirstCharFactor = SIGNED_1ST_CHAR_FACTOR; } else { mFirstCharMask = UNSIGNED_1ST_CHAR_MASK; mFirstCharFactor = UNSIGNED_1ST_CHAR_FACTOR; } } } private class Encoder extends Common { private final CharSink mCharSink; private long mValue; private Encoder( CharSink pCharSink, long pValue ) { mCharSink = pCharSink; mValue = pValue; } public void encode() { if ( mSignedValuesOK && (mValue < 0) ) { if ( Long.MIN_VALUE == mValue ) { mCharSink.add( SixBitCodec.encode( NEGATIVE_1ST_CHAR_BIT ) ); // Record as '-0' } else { mValue = -mValue; encode( NEGATIVE_1ST_CHAR_BIT ); } return; } if ( mValue < mFirstCharFactor ) { mCharSink.add( SixBitCodec.encode( (int) mValue ) ); } else { encode( NON_NEGATIVE_1ST_CHAR_BIT ); } } private void encode( int pNegativeBit ) { int bits = extractBits( mFirstCharMask, mFirstCharFactor ); mCharSink.add( SixBitCodec.encode( bits | pNegativeBit ) ); while ( mValue > 0 ) { bits = extractBits( MORE_MASK, MORE_FACTOR ); mCharSink.add( SixBitCodec.encode( bits ) ); } } private int extractBits( int pBits, int pDivisor ) { int rv = (int) (mValue & pBits); if ( (mValue /= pDivisor) > 0 ) { rv |= MORE_BIT; } return rv; } } private class Decoder extends Common { private final CharSource mValue; private boolean negative; private Decoder( CharSource pValue ) { mValue = pValue; } public long decode() { int bits = SixBitCodec.decode( mValue.getRequired() ); negative = mSignedValuesOK & ((bits & NEGATIVE_1ST_CHAR_BIT) != 0); long result = (bits & mFirstCharMask); for ( long zMultiplier = mFirstCharFactor; (bits & MORE_BIT) != 0; zMultiplier *= MORE_FACTOR ) { bits = SixBitCodec.decode( mValue.getRequired() ); result += (bits & MORE_MASK) * zMultiplier; } if ( !negative ) { return result; } if ( result == 0 ) // '-0' { return Long.MIN_VALUE; } return -result; } } } |
Commits for litesoft/trunk/Java/core/Anywhere/src/org/litesoft/codec/PrimitiveLongCodec.java
Revision | Author | Commited | Message |
---|---|---|---|
948 Diff | GeorgeS | Sat 07 Jun, 2014 23:42:39 +0000 | Jusefuls Formatter Updated to New Code Format |
942 Diff | GeorgeS | Mon 02 Jun, 2014 23:41:46 +0000 | Extracting commonfoundation |
939 Diff | GeorgeS | Mon 02 Jun, 2014 21:30:31 +0000 | Extracting commonfoundation |
831 | GeorgeS | Fri 31 Aug, 2012 22:39:56 +0000 |