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
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// This Source Code is in the Public Domain per: http://litesoft.org/License.txt
package org.litesoft.codec;

import org.litesoft.core.annotations.*;
import org.litesoft.core.util.*;

/**
 * Convert Integer value to/from a very tight string representation
 */
public class IntegerCodec
{
    public interface Primitive
    {
        public @NotNull String encode( int pValue );

        public int decode( @NotNull String pValue );

        public int decode( @NotNull CharSource pCharSource );
    }

    public static class SignedPrimitive implements Primitive
    {
        public static final SignedPrimitive INSTANCE = new SignedPrimitive();

        @Override
        public @NotNull String encode( int pValue )
        {
            if ( 0 <= pValue )
            {
                if ( pValue < 16 )
                {
                    return Character.toString( SixBitCodec.encode( pValue ) );
                }
                return new Encoder( pValue ).encode( 0, 16 );
            }

            return new Encoder( Math.abs( (long) pValue ) ).encode( 16, 16 );
        }

        @Override
        public int decode( @NotNull String pValue )
        {
            return decode( new CharSource( pValue ) );
        }

        @Override
        public int decode( @NotNull CharSource pCharSource )
        {
            return toInt( new Decoder( pCharSource ).decode( 16, 16 ) );
        }
    }

    public static class Signed extends AbstractCodec<Integer>
    {
        public static final Signed INSTANCE = new Signed();

        @Override
        protected String encodeNonNull( Integer pValue )
        {
            return SignedPrimitive.INSTANCE.encode( pValue );
        }

        @Override
        protected Integer decodeNonNull( CharSource pCharSource )
        {
            return SignedPrimitive.INSTANCE.decode( pCharSource );
        }
    }

    public static class NonNegativePrimitive implements Primitive
    {
        public static final NonNegativePrimitive INSTANCE = new NonNegativePrimitive();

        @Override
        public @NotNull String encode( int pValue )
        {
            if ( pValue < 0 )
            {
                throw new IllegalArgumentException( "Negative values not supported: " + pValue );
            }
            if ( pValue < 32 )
            {
                return Character.toString( SixBitCodec.encode( pValue ) );
            }
            return new Encoder( pValue ).encode( 0, 32 );
        }

        @Override
        public int decode( @NotNull String pValue )
        {
            return decode( new CharSource( pValue ) );
        }

        @Override
        public int decode( @NotNull CharSource pCharSource )
        {
            return toInt( new Decoder( pCharSource ).decode( 0, 32 ) );
        }
    }

    public static class NonNegative extends AbstractCodec<Integer>
    {
        public static final NonNegative INSTANCE = new NonNegative();

        @Override
        protected String encodeNonNull( Integer pValue )
        {
            return NonNegativePrimitive.INSTANCE.encode( pValue );
        }

        @Override
        protected Integer decodeNonNull( CharSource pCharSource )
        {
            return NonNegativePrimitive.INSTANCE.decode( pCharSource );
        }
    }

    private static int toInt( long pValue )
    {
        if ( (Integer.MIN_VALUE <= pValue) && (pValue <= Integer.MAX_VALUE) )
        {
            return (int) pValue;
        }
        throw new IllegalArgumentException( "Resulting value (" + pValue + ") is outside the acceptable Integer Range" );
    }

    private static class Encoder
    {
        private long mValue;

        Encoder( long pValue )
        {
            mValue = pValue;
        }

        public String encode( int pNegativeBit, int pFirstCharLimit )
        {
            StringBuilder sb = new StringBuilder();
            int bits = extractBits( pFirstCharLimit - 1, pFirstCharLimit );
            sb.append( SixBitCodec.encode( bits | pNegativeBit ) );
            while ( (bits & 32) != 0 )
            {
                bits = extractBits( 31, 32 );
                sb.append( SixBitCodec.encode( bits ) );
            }
            return sb.toString();
        }

        private int extractBits( int pBits, int pDivisor )
        {
            int rv = (int) (mValue & pBits);
            if ( (mValue /= pDivisor) > 0 )
            {
                rv |= 32;
            }
            return rv;
        }
    }

    private static class Decoder
    {
        private CharSource mValue;

        Decoder( CharSource pValue )
        {
            mValue = pValue;
        }

        public long decode( int pNegativeBit, long pMultiplier )
        {
            int bits = SixBitCodec.decode( mValue.getRequired() );
            boolean negative = ((bits & pNegativeBit) != 0);
            if ( negative )
            {
                bits -= pNegativeBit;
            }
            long result = (bits & 31);
            while ( (bits & 32) != 0 )
            {
                bits = SixBitCodec.decode( mValue.getRequired() );
                result += (bits & 31) * pMultiplier;
                pMultiplier *= 32;
            }
            return negative ? -result : result;
        }
    }
}

Commits for litesoft/trunk/Java/core/Anywhere/src/org/litesoft/codec/IntegerCodec.java

Diff revisions: vs.
Revision Author Commited Message
767 Diff Diff GeorgeS picture GeorgeS Sat 14 Jul, 2012 18:19:39 +0000
766 Diff Diff GeorgeS picture GeorgeS Sat 14 Jul, 2012 16:38:04 +0000

!

490 Diff Diff GeorgeS picture GeorgeS Fri 09 Sep, 2011 18:11:40 +0000

Encoding

50 Diff Diff GeorgeS picture GeorgeS Tue 13 Apr, 2010 11:51:38 +0000
49 Diff Diff GeorgeS picture GeorgeS Mon 12 Apr, 2010 02:59:10 +0000

License Text

2 GeorgeS picture GeorgeS Sun 07 Feb, 2010 12:50:58 +0000