1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.asn1.ber.tlv;
21
22
23 import org.apache.directory.api.i18n.I18n;
24 import org.apache.directory.api.util.Strings;
25
26
27
28
29
30
31
32 public final class IntegerDecoder
33 {
34
35 private static final int[] MASK = new int[]
36 { 0x000000FF, 0x0000FFFF, 0x00FFFFFF, 0xFFFFFFFF };
37
38
39
40
41
42
43
44
45
46
47
48
49 public static int parse( BerValue value, int min, int max ) throws IntegerDecoderException
50 {
51 int result = parseInt( value );
52
53 if ( ( result >= min ) && ( result <= max ) )
54 {
55 return result;
56 }
57 else
58 {
59 throw new IntegerDecoderException( I18n.err( I18n.ERR_00038_VALUE_NOT_IN_RANGE, min, max ) );
60 }
61 }
62
63
64
65
66
67
68
69
70
71 public static int parse( BerValue value ) throws IntegerDecoderException
72 {
73 return parseInt( value );
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 private static int parseInt( BerValue value ) throws IntegerDecoderException
101 {
102 int result = 0;
103
104 byte[] bytes = value.getData();
105
106 if ( Strings.isEmpty( bytes ) )
107 {
108 throw new IntegerDecoderException( I18n.err( I18n.ERR_00036_0_BYTES_LONG_INTEGER ) );
109 }
110
111 boolean positive = true;
112
113 switch ( bytes.length )
114 {
115 case 5:
116 if ( bytes[0] == 0x00 )
117 {
118 if ( ( bytes[1] & ( byte ) 0x80 ) != ( byte ) 0x80 )
119 {
120 throw new IntegerDecoderException( I18n.err( I18n.ERR_00036_0_BYTES_LONG_INTEGER ) );
121 }
122
123 result = bytes[1] & 0x00FF;
124 result = ( result << 8 ) | ( bytes[2] & 0x00FF );
125 result = ( result << 8 ) | ( bytes[3] & 0x00FF );
126 result = ( result << 8 ) | ( bytes[4] & 0x00FF );
127 }
128 else
129 {
130 throw new IntegerDecoderException( I18n.err( I18n.ERR_00036_0_BYTES_LONG_INTEGER ) );
131 }
132
133 break;
134
135 case 4:
136 if ( bytes[0] == 0x00 )
137 {
138 result = bytes[1] & 0x00FF;
139 }
140 else
141 {
142 result = bytes[0] & 0x00FF;
143
144 if ( ( bytes[0] & ( byte ) 0x80 ) == ( byte ) 0x80 )
145 {
146 positive = false;
147 }
148
149 result = ( result << 8 ) | ( bytes[1] & 0x00FF );
150 }
151
152 result = ( result << 8 ) | ( bytes[2] & 0x00FF );
153 result = ( result << 8 ) | ( bytes[3] & 0x00FF );
154
155 break;
156
157 case 3:
158 if ( bytes[0] == 0x00 )
159 {
160 result = bytes[1] & 0x00FF;
161 }
162 else
163 {
164 result = bytes[0] & 0x00FF;
165
166 if ( ( bytes[0] & ( byte ) 0x80 ) == ( byte ) 0x80 )
167 {
168 positive = false;
169 }
170
171 result = ( result << 8 ) | ( bytes[1] & 0x00FF );
172 }
173
174 result = ( result << 8 ) | ( bytes[2] & 0x00FF );
175
176 break;
177
178 case 2:
179 if ( bytes[0] == 0x00 )
180 {
181 result = bytes[1] & 0x00FF;
182 }
183 else
184 {
185 result = bytes[0] & 0x00FF;
186
187 if ( ( bytes[0] & ( byte ) 0x80 ) == ( byte ) 0x80 )
188 {
189 positive = false;
190 }
191
192 result = ( result << 8 ) | ( bytes[1] & 0x00FF );
193 }
194
195 break;
196
197 case 1:
198 result = ( result << 8 ) | ( bytes[0] & 0x00FF );
199
200 if ( ( bytes[0] & ( byte ) 0x80 ) == ( byte ) 0x80 )
201 {
202 positive = false;
203 }
204
205 break;
206
207 default:
208 throw new IntegerDecoderException( I18n.err( I18n.ERR_00037_ABOVE_4_BYTES_INTEGER ) );
209 }
210
211 if ( !positive )
212 {
213 result = -( ( ( ~result ) + 1 ) & MASK[bytes.length - 1] );
214 }
215
216 return result;
217 }
218 }