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.asn1.util.Asn1StringUtils;
24
25
26
27
28
29
30
31 public class TLV
32 {
33
34 private byte tag;
35
36
37 private int length;
38
39
40 private int lengthNbBytes;
41
42
43 private int lengthBytesRead;
44
45
46 private BerValue value;
47
48
49 private int id;
50
51
52
53
54
55
56 private TLV parent;
57
58
59
60
61
62 private int expectedLength;
63
64
65 public static final byte CONSTRUCTED_FLAG = 0x20;
66
67
68 public static final byte TYPE_CLASS_MASK = ( byte ) 0xC0;
69
70
71 public static final byte TYPE_CLASS_UNIVERSAL = 0x00;
72
73
74 public static final int SHORT_MASK = 0x1F;
75
76
77 public static final int LENGTH_LONG_FORM = 0x0080;
78
79
80 public static final int LENGTH_EXTENSION_RESERVED = 0x7F;
81
82
83 public static final int LENGTH_SHORT_MASK = 0x007F;
84
85
86 private static final byte[][] ONE_BYTE = new byte[128][];
87
88
89 static
90 {
91 for ( int i = 0; i < 128; i++ )
92 {
93 ONE_BYTE[i] = new byte[1];
94 ONE_BYTE[i][0] = ( byte ) i;
95 }
96 }
97
98
99
100
101
102
103
104 public TLV( int id )
105 {
106 tag = 0;
107 length = 0;
108 lengthNbBytes = 0;
109 value = new BerValue();
110 this.id = id;
111
112 expectedLength = 0;
113 }
114
115
116
117
118
119
120
121
122 public static boolean isConstructed( byte tag )
123 {
124 return ( tag & CONSTRUCTED_FLAG ) != 0;
125 }
126
127
128
129
130
131
132
133 public boolean isConstructed()
134 {
135 return ( tag & CONSTRUCTED_FLAG ) != 0;
136 }
137
138
139
140
141
142
143
144
145
146 public static boolean isPrimitive( byte tag )
147 {
148 return ( tag & CONSTRUCTED_FLAG ) == 0;
149 }
150
151
152
153
154
155
156
157
158 public static boolean isUniversal( byte tag )
159 {
160 return ( tag & TYPE_CLASS_MASK ) == TYPE_CLASS_UNIVERSAL;
161 }
162
163
164
165
166
167 public void reset()
168 {
169 tag = 0;
170 length = 0;
171 lengthNbBytes = 0;
172 value.reset();
173
174 expectedLength = 0;
175 }
176
177
178
179
180
181 public byte getTag()
182 {
183 return tag;
184 }
185
186
187
188
189
190
191
192 public void setTag( byte tag )
193 {
194 this.tag = tag;
195 }
196
197
198
199
200
201 public BerValue getValue()
202 {
203 return value;
204 }
205
206
207
208
209
210
211
212
213 public int getSize()
214 {
215 return 1 + lengthNbBytes + length;
216 }
217
218
219
220
221
222
223
224
225
226
227 public static int getNbBytes( int length )
228 {
229 if ( length >= 0 )
230 {
231 if ( length < 128 )
232 {
233 return 1;
234 }
235 else if ( length < 256 )
236 {
237 return 2;
238 }
239 else if ( length < 65536 )
240 {
241 return 3;
242 }
243 else if ( length < 16777216 )
244 {
245 return 4;
246 }
247 else
248 {
249 return 5;
250 }
251 }
252 else
253 {
254 return 5;
255 }
256 }
257
258
259
260
261
262
263
264
265 public static byte[] getBytes( int length )
266 {
267 if ( length >= 0 )
268 {
269 if ( length < 128 )
270 {
271 return ONE_BYTE[length];
272 }
273 else
274 {
275 byte[] bytes = new byte[getNbBytes( length )];
276
277 if ( length < 256 )
278 {
279 bytes[0] = ( byte ) 0x81;
280 bytes[1] = ( byte ) length;
281 }
282 else if ( length < 65536 )
283 {
284 bytes[0] = ( byte ) 0x82;
285 bytes[1] = ( byte ) ( length >> 8 );
286 bytes[2] = ( byte ) ( length & 0x00FF );
287 }
288 else if ( length < 16777216 )
289 {
290 bytes[0] = ( byte ) 0x83;
291 bytes[1] = ( byte ) ( length >> 16 );
292 bytes[2] = ( byte ) ( ( length >> 8 ) & 0x00FF );
293 bytes[3] = ( byte ) ( length & 0x00FF );
294 }
295 else
296 {
297 bytes[0] = ( byte ) 0x84;
298 bytes[1] = ( byte ) ( length >> 24 );
299 bytes[2] = ( byte ) ( ( length >> 16 ) & 0x00FF );
300 bytes[3] = ( byte ) ( ( length >> 8 ) & 0x00FF );
301 bytes[4] = ( byte ) ( length & 0x00FF );
302 }
303
304 return bytes;
305 }
306 }
307 else
308 {
309 byte[] bytes = new byte[getNbBytes( length )];
310
311 bytes[0] = ( byte ) 0x84;
312 bytes[1] = ( byte ) ( length >> 24 );
313 bytes[2] = ( byte ) ( ( length >> 16 ) & 0x00FF );
314 bytes[3] = ( byte ) ( ( length >> 8 ) & 0x00FF );
315 bytes[4] = ( byte ) ( length & 0x00FF );
316
317 return bytes;
318 }
319 }
320
321
322
323
324
325 public TLV getParent()
326 {
327 return parent;
328 }
329
330
331
332
333
334 public void setParent( TLV parent )
335 {
336 this.parent = parent;
337 }
338
339
340
341
342
343
344
345 public int getExpectedLength()
346 {
347 return expectedLength;
348 }
349
350
351
352
353
354
355
356 public void setExpectedLength( int expectedLength )
357 {
358 this.expectedLength = expectedLength;
359 }
360
361
362
363
364
365 public int getLengthNbBytes()
366 {
367 return lengthNbBytes;
368 }
369
370
371
372
373
374
375
376 public void setLengthNbBytes( int lengthNbBytes )
377 {
378 this.lengthNbBytes = lengthNbBytes;
379 }
380
381
382
383
384
385 public int getLength()
386 {
387 return length;
388 }
389
390
391
392
393
394
395
396 public void setLength( int length )
397 {
398 this.length = length;
399 }
400
401
402
403
404
405 public int getLengthBytesRead()
406 {
407 return lengthBytesRead;
408 }
409
410
411
412
413
414
415
416 public void setLengthBytesRead( int lengthBytesRead )
417 {
418 this.lengthBytesRead = lengthBytesRead;
419 }
420
421
422
423
424
425
426 public void incLengthBytesRead()
427 {
428 lengthBytesRead++;
429 }
430
431
432
433
434
435 public int getId()
436 {
437 return id;
438 }
439
440
441
442
443
444
445
446 public String toString()
447 {
448
449 StringBuilder sb = new StringBuilder();
450
451 sb.append( "TLV[ " );
452 sb.append( Asn1StringUtils.dumpByte( tag ) ).append( ", " );
453 sb.append( length ).append( ", " );
454 sb.append( value.toString() );
455 sb.append( "]" );
456
457 return sb.toString();
458 }
459 }