22
22
23
23
24
24
import com .igormaznitsa .jbbp .JBBPCustomFieldTypeProcessor ;
25
+ import com .igormaznitsa .jbbp .JBBPExternalValueProvider ;
26
+ import com .igormaznitsa .jbbp .JBBPNamedNumericFieldMap ;
25
27
import com .igormaznitsa .jbbp .JBBPParser ;
28
+ import com .igormaznitsa .jbbp .compiler .JBBPCompiledBlock ;
26
29
import com .igormaznitsa .jbbp .compiler .JBBPNamedFieldInfo ;
27
30
import com .igormaznitsa .jbbp .compiler .tokenizer .JBBPFieldTypeParameterContainer ;
28
31
import com .igormaznitsa .jbbp .io .JBBPBitInputStream ;
@@ -85,13 +88,16 @@ class YearMonthDay {
85
88
@ Bin (type = BinType .BIT , bitNumber = JBBPBitNumber .BITS_5 , order = 3 , bitOrder = JBBPBitOrder .MSB0 )
86
89
byte day ;
87
90
}
88
- final YearMonthDay parsed = JBBPParser .prepare ("bit:6 year; bit:4 month; bit:5 day;" , JBBPBitOrder .MSB0 ).parse (new byte [] {(byte ) 0x3D , (byte ) 0xF8 }).mapTo (new YearMonthDay ());
91
+ final YearMonthDay parsed =
92
+ JBBPParser .prepare ("bit:6 year; bit:4 month; bit:5 day;" , JBBPBitOrder .MSB0 )
93
+ .parse (new byte [] {(byte ) 0x3D , (byte ) 0xF8 }).mapTo (new YearMonthDay ());
89
94
90
95
assertEquals (0x0F , parsed .year );
91
96
assertEquals (0x07 , parsed .month );
92
97
assertEquals (0x1C , parsed .day & 0xFF );
93
98
94
- assertArrayEquals (new byte [] {(byte ) 0x3D , (byte ) 0xF8 }, JBBPOut .BeginBin (JBBPBitOrder .MSB0 ).Bin (parsed ).End ().toByteArray ());
99
+ assertArrayEquals (new byte [] {(byte ) 0x3D , (byte ) 0xF8 },
100
+ JBBPOut .BeginBin (JBBPBitOrder .MSB0 ).Bin (parsed ).End ().toByteArray ());
95
101
}
96
102
97
103
/**
@@ -122,14 +128,17 @@ class TetraTimestamp {
122
128
}
123
129
124
130
125
- TetraTimestamp parsed = JBBPParser .prepare ("bit:2 timezone; bit:2 reserved; bit:4 month; bit:5 day; bit:5 hour; bit:6 minute;" , JBBPBitOrder .MSB0 ).parse (TEST_DATA ).mapTo (new TetraTimestamp ());
131
+ TetraTimestamp parsed = JBBPParser .prepare (
132
+ "bit:2 timezone; bit:2 reserved; bit:4 month; bit:5 day; bit:5 hour; bit:6 minute;" ,
133
+ JBBPBitOrder .MSB0 ).parse (TEST_DATA ).mapTo (new TetraTimestamp ());
126
134
127
135
assertEquals (2 , parsed .month );
128
136
assertEquals (8 , parsed .day );
129
137
assertEquals (10 , parsed .hour );
130
138
assertEquals (1 , parsed .minute );
131
139
132
- assertArrayEquals (TEST_DATA , JBBPOut .BeginBin (JBBPBitOrder .MSB0 ).Bin (parsed ).End ().toByteArray ());
140
+ assertArrayEquals (TEST_DATA ,
141
+ JBBPOut .BeginBin (JBBPBitOrder .MSB0 ).Bin (parsed ).End ().toByteArray ());
133
142
}
134
143
135
144
/**
@@ -200,9 +209,13 @@ public void testMutlithredUsageOfParser() throws Exception {
200
209
for (int i = 0 ; i < ITERATIONS ; i ++) {
201
210
try {
202
211
Thread .sleep (System .nanoTime () & 0xF );
203
- final byte [] ippacket = parserTCP .parse (theData ).findFieldForNameAndType ("Data" , JBBPFieldArrayByte .class ).getArray ();
212
+ final byte [] ippacket =
213
+ parserTCP .parse (theData ).findFieldForNameAndType ("Data" , JBBPFieldArrayByte .class )
214
+ .getArray ();
204
215
assertEquals (119 , ippacket .length );
205
- final byte [] optionsip = parserIP .parse (ippacket ).findFieldForNameAndType ("Options" , JBBPFieldArrayByte .class ).getArray ();
216
+ final byte [] optionsip =
217
+ parserIP .parse (ippacket ).findFieldForNameAndType ("Options" , JBBPFieldArrayByte .class )
218
+ .getArray ();
206
219
assertEquals (4 , optionsip .length );
207
220
parsingCounter .incrementAndGet ();
208
221
} catch (Exception ex ) {
@@ -236,7 +249,8 @@ class Bits {
236
249
byte [] bit ;
237
250
}
238
251
239
- JBBPParser parser = JBBPParser .prepare (JBBPDslBuilder .Begin ().AnnotatedClassFields (Bits .class ).End ());
252
+ JBBPParser parser =
253
+ JBBPParser .prepare (JBBPDslBuilder .Begin ().AnnotatedClassFields (Bits .class ).End ());
240
254
241
255
Bits parsed = parser .parse (new byte [] {73 }).mapTo (new Bits ());
242
256
@@ -253,11 +267,14 @@ class Bits {
253
267
*/
254
268
@ Test
255
269
public void testStringMsb0 () throws Exception {
256
- JBBPOut joparam = JBBPOut .BeginBin (JBBPByteOrder .BIG_ENDIAN , JBBPBitOrder .MSB0 ).String ("zzzz" ).Int (12345 );
270
+ JBBPOut joparam =
271
+ JBBPOut .BeginBin (JBBPByteOrder .BIG_ENDIAN , JBBPBitOrder .MSB0 ).String ("zzzz" ).Int (12345 );
257
272
final byte [] array = joparam .End ().toByteArray ();
258
273
assertArrayEquals (new byte [] {32 , 94 , 94 , 94 , 94 , 0 , 0 , 0x0C , (byte ) 0x9C }, array );
259
- final JBBPFieldStruct bitflds = JBBPParser .prepare ("stringj fin; int i;" , JBBPBitOrder .MSB0 ).parse (array );
260
- assertEquals ("zzzz" , bitflds .findFieldForNameAndType ("fin" , JBBPFieldString .class ).getAsString ());
274
+ final JBBPFieldStruct bitflds =
275
+ JBBPParser .prepare ("stringj fin; int i;" , JBBPBitOrder .MSB0 ).parse (array );
276
+ assertEquals ("zzzz" ,
277
+ bitflds .findFieldForNameAndType ("fin" , JBBPFieldString .class ).getAsString ());
261
278
assertEquals (12345 , bitflds .findFieldForNameAndType ("i" , JBBPFieldInt .class ).getAsInt ());
262
279
}
263
280
@@ -324,15 +341,22 @@ private String readPascalAscIIString(final JBBPBitInputStream in) throws IOExcep
324
341
}
325
342
}
326
343
327
- final JBBPParser parserSingle = JBBPParser .prepare ("asciistr str1; asciistr str2;" , new AscIIPascalString ());
344
+ final JBBPParser parserSingle =
345
+ JBBPParser .prepare ("asciistr str1; asciistr str2;" , new AscIIPascalString ());
328
346
final JBBPFieldStruct parsedSingle = parserSingle .parse (new byte [] {5 , 65 , 66 , 67 , 68 , 69 , 0 });
329
- assertEquals ("ABCDE" , parsedSingle .findFieldForNameAndType ("str1" , JBBPFieldString .class ).getAsString ());
330
- assertEquals ("" , parsedSingle .findFieldForNameAndType ("str2" , JBBPFieldString .class ).getAsString ());
331
-
332
- final JBBPParser parserArray = JBBPParser .prepare ("asciistr [2] str1; asciistr [_] str2;" , new AscIIPascalString ());
333
- final JBBPFieldStruct parsedArrays = parserArray .parse (new byte [] {2 , 65 , 66 , 1 , 67 , 3 , 68 , 69 , 70 , 2 , 71 , 72 , 1 , 73 });
334
- assertArrayEquals (new String [] {"AB" , "C" }, parsedArrays .findFieldForNameAndType ("str1" , JBBPFieldArrayString .class ).getArray ());
335
- assertArrayEquals (new String [] {"DEF" , "GH" , "I" }, parsedArrays .findFieldForNameAndType ("str2" , JBBPFieldArrayString .class ).getArray ());
347
+ assertEquals ("ABCDE" ,
348
+ parsedSingle .findFieldForNameAndType ("str1" , JBBPFieldString .class ).getAsString ());
349
+ assertEquals ("" ,
350
+ parsedSingle .findFieldForNameAndType ("str2" , JBBPFieldString .class ).getAsString ());
351
+
352
+ final JBBPParser parserArray =
353
+ JBBPParser .prepare ("asciistr [2] str1; asciistr [_] str2;" , new AscIIPascalString ());
354
+ final JBBPFieldStruct parsedArrays =
355
+ parserArray .parse (new byte [] {2 , 65 , 66 , 1 , 67 , 3 , 68 , 69 , 70 , 2 , 71 , 72 , 1 , 73 });
356
+ assertArrayEquals (new String [] {"AB" , "C" },
357
+ parsedArrays .findFieldForNameAndType ("str1" , JBBPFieldArrayString .class ).getArray ());
358
+ assertArrayEquals (new String [] {"DEF" , "GH" , "I" },
359
+ parsedArrays .findFieldForNameAndType ("str2" , JBBPFieldArrayString .class ).getArray ());
336
360
}
337
361
338
362
/**
@@ -349,7 +373,8 @@ final class Uint32 implements JBBPCustomFieldTypeProcessor {
349
373
350
374
private final String [] TYPES = new String [] {"uint32" };
351
375
352
- private long uint32_read (final JBBPBitInputStream in , final JBBPByteOrder byteOrder , final JBBPBitOrder bitOrder ) throws IOException {
376
+ private long uint32_read (final JBBPBitInputStream in , final JBBPByteOrder byteOrder ,
377
+ final JBBPBitOrder bitOrder ) throws IOException {
353
378
final int signedInt = in .readInt (byteOrder );
354
379
return signedInt & 0xffffffffL ;
355
380
}
@@ -360,7 +385,8 @@ public String[] getCustomFieldTypes() {
360
385
}
361
386
362
387
@ Override
363
- public boolean isAllowed (final JBBPFieldTypeParameterContainer fieldType , final String fieldName , final int extraData , final boolean isArray ) {
388
+ public boolean isAllowed (final JBBPFieldTypeParameterContainer fieldType ,
389
+ final String fieldName , final int extraData , final boolean isArray ) {
364
390
return extraData == 0 ;
365
391
}
366
392
@@ -374,10 +400,14 @@ private long[] convertLongs(List<Long> longs) {
374
400
}
375
401
376
402
@ Override
377
- public JBBPAbstractField readCustomFieldType (final JBBPBitInputStream in , final JBBPBitOrder bitOrder ,
378
- final int parserFlags , final JBBPFieldTypeParameterContainer customTypeFieldInfo ,
379
- final JBBPNamedFieldInfo fieldName , final int extraData ,
380
- final boolean readWholeStream , final int arrayLength ) throws IOException {
403
+ public JBBPAbstractField readCustomFieldType (final JBBPBitInputStream in ,
404
+ final JBBPBitOrder bitOrder ,
405
+ final int parserFlags ,
406
+ final JBBPFieldTypeParameterContainer customTypeFieldInfo ,
407
+ final JBBPNamedFieldInfo fieldName ,
408
+ final int extraData ,
409
+ final boolean readWholeStream ,
410
+ final int arrayLength ) throws IOException {
381
411
if (arrayLength < 0 ) {
382
412
final long uint32_val = uint32_read (in , customTypeFieldInfo .getByteOrder (), bitOrder );
383
413
return new JBBPFieldLong (fieldName , uint32_val );
@@ -423,6 +453,48 @@ public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in, final
423
453
assertEquals (2 , ((JBBPNumericField ) result .findFieldForName ("keycount" )).getAsInt ());
424
454
}
425
455
456
+ /**
457
+ * Case 09-jun-2020
458
+ * Example how to use external variable value provider.
459
+ *
460
+ * @throws Exception for any error
461
+ */
462
+ @ Test
463
+ public void testByteArrayWhichLengthProvidedExternally () throws Exception {
464
+ class BKlazz {
465
+ @ Bin (order = 1 , type = BinType .BYTE_ARRAY )
466
+ byte [] a ;
467
+ @ Bin (order = 2 , type = BinType .BYTE_ARRAY )
468
+ byte [] b ;
469
+ @ Bin (order = 3 , type = BinType .BYTE_ARRAY )
470
+ byte [] c ;
471
+ }
472
+
473
+ JBBPParser parser = JBBPParser .prepare ("byte [$alen] a; byte [$blen] b; byte [$clen] c;" );
474
+
475
+ BKlazz parsed = parser .parse (new byte [] {1 ,2 ,3 }, null , new JBBPExternalValueProvider () {
476
+ @ Override
477
+ public int provideArraySize (String fieldName ,
478
+ JBBPNamedNumericFieldMap numericFieldMap ,
479
+ JBBPCompiledBlock compiledBlock ) {
480
+ if ("alen" .equals (fieldName )) {
481
+ return 0 ;
482
+ } else if ("blen" .equals (fieldName )) {
483
+ return 3 ;
484
+ } else if ("clen" .equals (fieldName )) {
485
+ return 0 ;
486
+ } else {
487
+ throw new IllegalArgumentException ("Unknown name: " + fieldName );
488
+ }
489
+
490
+ }
491
+ }).mapTo (new BKlazz ());
492
+
493
+ assertArrayEquals (new byte [0 ], parsed .a );
494
+ assertArrayEquals (new byte []{1 ,2 ,3 }, parsed .b );
495
+ assertArrayEquals (new byte [0 ], parsed .c );
496
+ }
497
+
426
498
/**
427
499
* Case 09-jun-2020
428
500
* Example how to write custom field type read-write-mapping processor for nullable byte array.
0 commit comments