Subversion Repository Public Repository

litesoft

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

Diff revisions: vs.
Revision Author Commited Message
948 Diff Diff GeorgeS picture GeorgeS Sat 07 Jun, 2014 23:42:39 +0000

Jusefuls Formatter Updated to New Code Format

942 Diff Diff GeorgeS picture GeorgeS Mon 02 Jun, 2014 23:41:46 +0000

Extracting commonfoundation

939 Diff Diff GeorgeS picture GeorgeS Mon 02 Jun, 2014 21:30:31 +0000

Extracting commonfoundation

831 GeorgeS picture GeorgeS Fri 31 Aug, 2012 22:39:56 +0000