com.igormaznitsa.jbbp.mapper.Bin Java Examples

The following examples show how to use com.igormaznitsa.jbbp.mapper.Bin. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ZXEMLSnapshotFormat.java    From zxpoly with GNU General Public License v3.0 6 votes vote down vote up
public byte[] save() throws IOException {
  if (this.pages == null) {
    throw new NullPointerException("Pages must not be null");
  }
  for (final Pages p : this.pages) {
    if (p == null) {
      throw new NullPointerException("Item in Pages contains null");
    }
    for (final Page pp : p.page) {
      if (pp == null) {
        throw new NullPointerException("Detected defined null page");
      }
    }
  }

  return JBBPOut.BeginBin().Bin(this).End().toByteArray();
}
 
Example #2
Source File: JBBPTextWriterTest.java    From java-binary-block-parser with Apache License 2.0 6 votes vote down vote up
@Test
public void testBin_ByteArrayMappedToString() throws Exception {
  class Parsed {
    @Bin(type = BinType.BYTE_ARRAY)
    String str1;
    @Bin(type = BinType.UBYTE_ARRAY)
    String str2;
  }

  final Parsed parsed = JBBPParser.prepare("byte [5] str1; ubyte [4] str2;").parse(new byte[] {49, 50, 51, 52, 53, 54, 55, 56, 57}).mapTo(new Parsed());
  final String text = makeWriter().Bin(parsed).Close().toString();

  System.out.println(text);

  assertFileContent("testwriterbin5.txt", text);
}
 
Example #3
Source File: JBBPDslBuilderTest.java    From java-binary-block-parser with Apache License 2.0 6 votes vote down vote up
@Test
public void testAnotatedClass_AnnottatedButWithoutType() {
  class Test {
    @Bin(order = 1)
    int a;
    @Bin(order = 3)
    int c;
    @Bin(order = 2, byteOrder = JBBPByteOrder.LITTLE_ENDIAN)
    int b;
    @Bin(order = 4, arraySizeExpr = "a+b")
    Internal[] d;

    class Internal {
      @Bin(order = 1)
      short a;
      @Bin(order = 2, arraySizeExpr = "8")
      short[] b;
    }
  }

  assertEquals("Test{int a;<int b;int c;d[a+b]{short a;short[8] b;}}", Begin().AnnotatedClass(Test.class).End());
}
 
Example #4
Source File: JBBPDslBuilderTest.java    From java-binary-block-parser with Apache License 2.0 6 votes vote down vote up
@Test
public void testAnnotatedClass_DefaultBin_InnerClass() {
  @Bin(name = "sometest", type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_5)
  class Test {
    byte a;
    byte b;
    byte c;
    @Bin(name = "dd", type = BinType.BOOL)
    int d;

    @Bin(type = BinType.LONG)
    class Internal {
      int a;
      int b;
      int c;
    }

    @Bin(arraySizeExpr = "_")
    Internal[] array;
  }
  assertEquals("Test{bit:5 a;array[_]{long a;long b;long c;}bit:5 b;bit:5 c;bool dd;}", Begin().AnnotatedClass(Test.class).End(false));
}
 
Example #5
Source File: JBBPTextWriter.java    From java-binary-block-parser with Apache License 2.0 6 votes vote down vote up
@Override
protected void onFieldCustom(final Object obj, final Field field, final Bin annotation, final Object customFieldProcessor, final Object value) {
  try {
    if (extras.isEmpty()) {
      throw new IllegalStateException("There is not any registered extras");
    }

    String str = null;
    for (final Extra e : extras) {
      str = e.doConvertCustomField(JBBPTextWriter.this, obj, field, annotation);
      if (str != null) {
        break;
      }
    }

    if (str != null) {
      ensureValueMode();
      printValueString(str);
      Comment(makeFieldDescription(field, annotation));
    }
  } catch (IOException ex) {
    throw new JBBPIOException("Can't log custom field", ex);
  }
}
 
Example #6
Source File: JBBPTextWriterTest.java    From java-binary-block-parser with Apache License 2.0 6 votes vote down vote up
@Test
public void testBin_ParsedPng_NonMappedRawStruct() throws Exception {
  final InputStream pngStream = getResourceAsInputStream("picture.png");
  try {

    final JBBPParser pngParser = JBBPParser.prepare(
        "long header;"
            + "// chunks\n"
            + "chunks [_]{"
            + "   int length; "
            + "   int type; "
            + "   byte[length] data; "
            + "   int crc;"
            + "}"
    );

    final String text = makeWriter().SetMaxValuesPerLine(16).Bin(pngParser.parse(pngStream)).Close().toString();
    System.out.println(text);
    assertFileContent("testwriterbin2b.txt", text);
  } finally {
    JBBPUtils.closeQuietly(pngStream);
  }
}
 
Example #7
Source File: SNAParsingTest.java    From java-binary-block-parser with Apache License 2.0 6 votes vote down vote up
@Test
public void testParseAndSave_ThroughDslBuilder() throws Exception {
  final JBBPParser parser = JBBPParser.prepare(JBBPDslBuilder.Begin().AnnotatedClass(SNA.class).End());

  final InputStream in = getResourceAsInputStream("zexall.sna");

  JBBPFieldStruct parsed;
  try {
    parsed = parser.parse(in);
  } finally {
    JBBPUtils.closeQuietly(in);
  }

  final SNA mapped = parsed.findFieldForNameAndType("SNA", JBBPFieldStruct.class).mapTo(new SNA());
  assertResource("zexall.sna", JBBPOut.BeginBin().Bin(mapped).End().toByteArray());
}
 
Example #8
Source File: JBBPTextWriter.java    From java-binary-block-parser with Apache License 2.0 6 votes vote down vote up
@Override
protected void onArrayStart(final Object obj, final Field field, final Bin annotation, final int length) {
  try {
    HR();
    if (field.getType() == String.class) {
      Comment("STRING: " + makeFieldDescription(field, annotation));
    } else {
      Comment("START ARRAY : " + makeArrayDescription(field, annotation) + " OF " + field.getType().getComponentType().getSimpleName() + " [" + length + ']');
    }
    HR();
    IndentInc();
  } catch (IOException ex) {
    throw new JBBPIOException("Can't log array field", ex);
  } finally {
    arrayCounter++;
  }
}
 
Example #9
Source File: JBBPTextWriter.java    From java-binary-block-parser with Apache License 2.0 6 votes vote down vote up
/**
 * Print objects which marked by Bin annotation or successors of JBBPAbstractField.
 * <b>NB! Keep in mind that values of fields will be processed for their attributes before printing
 * and for instance a bit field with inversion will be shown as inverted one.</b>
 *
 * @param objs array of object marked by Bin annotation or successors of
 *             JBBPAbstractField
 * @return the context
 * @throws IOException it will be thrown if transport errors
 */
public JBBPTextWriter Bin(final Object... objs) throws IOException {
  if (this.mappedClassObserver == null) {
    this.mappedClassObserver = new MappedObjectLogger();
  }

  ensureNewLineMode();

  for (final Object obj : objs) {
    if (obj == null) {
      write("<NULL>");
    } else {
      if (obj instanceof JBBPAbstractField) {
        printAbstractFieldObject(null, (JBBPAbstractField) obj);
      } else {
        this.mappedClassObserver.init();
        this.mappedClassObserver.processObject(obj);
      }
    }
  }

  return this;
}
 
Example #10
Source File: BasedOnQuestionsAndCasesTest.java    From java-binary-block-parser with Apache License 2.0 6 votes vote down vote up
/**
 * Case 13-aug-2015
 * <p>
 * 3DF8 = 0011 1101 1111 1000 where data are stored from left to right :
 * 6 bits : 0011 11 for year;
 * 4 bits : 01 11 for month
 * 5 bits : 11 100 for day,
 *
 * @throws Exception for any error
 */
@Test
public void testParseDayMonthYearFromBytePairInMSB0AndPackThemBack() throws Exception {
  class YearMonthDay {
    @Bin(type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_6, order = 1, bitOrder = JBBPBitOrder.MSB0)
    byte year;
    @Bin(type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_4, order = 2, bitOrder = JBBPBitOrder.MSB0)
    byte month;
    @Bin(type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_5, order = 3, bitOrder = JBBPBitOrder.MSB0)
    byte day;
  }
  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());

  assertEquals(0x0F, parsed.year);
  assertEquals(0x07, parsed.month);
  assertEquals(0x1C, parsed.day & 0xFF);

  assertArrayEquals(new byte[] {(byte) 0x3D, (byte) 0xF8}, JBBPOut.BeginBin(JBBPBitOrder.MSB0).Bin(parsed).End().toByteArray());
}
 
Example #11
Source File: JBBPTextWriter.java    From java-binary-block-parser with Apache License 2.0 6 votes vote down vote up
@Override
protected void onArrayEnd(final Object obj, final Field field, final Bin annotation) {
  try {
    IndentDec();
    HR();
    if (field.getType() == String.class) {
      Comment("END STRING : " + makeArrayDescription(field, annotation));
    } else {
      Comment("END ARRAY : " + makeArrayDescription(field, annotation));
    }
    HR();
  } catch (IOException ex) {
    throw new JBBPIOException("Can't log array field", ex);
  } finally {
    arrayCounter--;
  }
}
 
Example #12
Source File: JBBPTextWriterTest.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Test
public void testBin_AllEasyTypes_NonMappedRawStruct() throws Exception {
  final JBBPParser parser = JBBPParser.prepare("bit:2 a1; bit:6 a2; byte a; ubyte b; short c; ushort d; int e; long f; bool g;");
  final byte[] testArray = new byte[] {(byte) 0xDE, (byte) 0x12, (byte) 0xFE, (byte) 0x23, (byte) 0x11, (byte) 0x45, (byte) 0xDA, (byte) 0x82, (byte) 0xA0, (byte) 0x33, (byte) 0x7F, (byte) 0x99, (byte) 0x04, (byte) 0x10, (byte) 0x45, (byte) 0xBD, (byte) 0xCA, (byte) 0xFE, (byte) 0x12, (byte) 0x11, (byte) 0xBA, (byte) 0xBE};

  final String text = makeWriter().SetMaxValuesPerLine(16).Bin(parser.parse(testArray)).Close().toString();
  System.out.println(text);
  assertFileContent("txtwrtrjbbpobj1.txt", text);
}
 
Example #13
Source File: JBBPTextWriter.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Override
protected void onFieldFloat(final Object obj, final Field field, final Bin annotation, final float value) {
  try {
    Float(value);
    if (this.arrayCounter == 0) {
      Comment(makeFieldDescription(field, annotation));
    }
  } catch (IOException ex) {
    throw new JBBPIOException("Can't log float field", ex);
  }
}
 
Example #14
Source File: JBBPOut.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Override
protected void onFieldDouble(final Object obj, final Field field, final Bin annotation, final double value) {
  final JBBPByteOrder old = this.byteOrder;
  try {
    this.byteOrder = annotation.byteOrder();
    this.Double(value);
  } catch (IOException ex) {
    throw new JBBPIOException("Can't write double value", ex);
  } finally {
    this.byteOrder = old;
  }
}
 
Example #15
Source File: JBBPOut.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Override
protected void onFieldString(final Object obj, final Field field, final Bin annotation, final String value) {
  final JBBPByteOrder old = this.byteOrder;
  try {
    this.byteOrder = annotation.byteOrder();
    this.String(value);
  } catch (IOException ex) {
    throw new JBBPIOException("Can't write string value", ex);
  } finally {
    this.byteOrder = old;
  }
}
 
Example #16
Source File: AbstractMappedClassFieldObserver.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
/**
 * Process an object. It works only with classes and fields marked by Bin annotations. <b>It doesn't process classes and fields marked by DslBinCustom annotations.</b>
 *
 * @param obj                  an object which is an instance of a mapped class, must not be null
 * @param field                a field where the object has been found, it can be null for first call
 * @param binAnnotationWrapper wrapper to replace Bin annotation values for processing fields, can be null to be ignored
 * @param customFieldProcessor a processor for custom fields, it can be null
 * @see Bin
 * @since 2.0.2
 */
protected void processObject(
    final Object obj,
    final Field field,
    final BinAnnotationWrapper binAnnotationWrapper,
    final Object customFieldProcessor
) {
  JBBPUtils.assertNotNull(obj, "Object must not be null");

  final List<MappedFieldRecord> orderedFields = JBBPMapper.findAffectedFields(obj);

  final Bin clazzAnno = obj.getClass().getAnnotation(Bin.class);
  final Bin fieldAnno = field == null ? null : field.getAnnotation(Bin.class);

  this.onStructStart(obj, field, clazzAnno == null ? fieldAnno : clazzAnno);

  for (final MappedFieldRecord rec : orderedFields) {
    final Bin binAnno = binAnnotationWrapper == null ? rec.binAnnotation : binAnnotationWrapper.setWrapped(rec.binAnnotation);

    if (binAnno.custom() && customFieldProcessor == null) {
      throw new JBBPIllegalArgumentException("Class '" + obj.getClass().getName() + "' contains field '" + rec.mappingField.getName() + "' which is custom one, you must provide JBBPCustomFieldWriter instance to save it.");
    }

    processObjectField(obj, rec, binAnno, customFieldProcessor);
  }

  this.onStructEnd(obj, field, clazzAnno == null ? fieldAnno : clazzAnno);
}
 
Example #17
Source File: JBBPTextWriterTest.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Test
public void testBin_BooleanArray_NonMappedRawStruct() throws Exception {
  final JBBPParser parser = JBBPParser.prepare("bool [_] array;");
  final byte[] testArray = new byte[] {(byte) 0xDE, (byte) 0x00, (byte) 0xFE, (byte) 0x00, (byte) 0x11, (byte) 0x45, (byte) 0xDA, (byte) 0x82, (byte) 0xA0, (byte) 0x33, (byte) 0x7F, (byte) 0x99, (byte) 0x04, (byte) 0x10, (byte) 0x45, (byte) 0xBD, (byte) 0xCA, (byte) 0xFE, (byte) 0x12, (byte) 0x11, (byte) 0x00, (byte) 0xBE};

  final String text = makeWriter().SetMaxValuesPerLine(16).Bin(parser.parse(testArray)).Close().toString();
  System.out.println(text);
  assertFileContent("boolarrayraw.txt", text);
}
 
Example #18
Source File: JBBPTextWriterTest.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Test
public void testBin_StringFieldAndStringArray() throws Exception {
  final JBBPParser parser = JBBPParser.prepare("stringj[2];stringj;");
  final byte[] testArray = new byte[] {
      3, 65, 66, 67,
      3, 68, 69, 70,
      3, 71, 72, 73
  };

  final String text = makeWriter().SetMaxValuesPerLine(16).Bin(parser.parse(testArray)).Close().toString();
  System.out.println(text);
  assertFileContent("txtwrtrjbbpobj3.txt", text);
}
 
Example #19
Source File: JBBPTextWriterTest.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Test
public void testBin_AllEasyTypes_Anonymous_NonMappedRawStruct() throws Exception {
  final JBBPParser parser = JBBPParser.prepare("bit:2; bit:6; byte; ubyte; short; ushort; int; long; bool; stringj;");
  final byte[] testArray = new byte[] {
      (byte) 0xDE, (byte) 0x12, (byte) 0xFE, (byte) 0x23, (byte) 0x11,
      (byte) 0x45, (byte) 0xDA, (byte) 0x82, (byte) 0xA0, (byte) 0x33,
      (byte) 0x7F, (byte) 0x99, (byte) 0x04, (byte) 0x10, (byte) 0x45,
      (byte) 0xBD, (byte) 0xCA, (byte) 0xFE, (byte) 0x12, (byte) 0x11,
      3, 65, 66, 67
  };

  final String text = makeWriter().SetMaxValuesPerLine(16).Bin(parser.parse(testArray)).Close().toString();
  System.out.println(text);
  assertFileContent("txtwrtrjbbpobj2.txt", text);
}
 
Example #20
Source File: JBBPOut.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Override
protected void onFieldFloat(final Object obj, final Field field, final Bin annotation, final float value) {
  final JBBPByteOrder old = this.byteOrder;
  try {
    this.byteOrder = annotation.byteOrder();
    this.Float(value);
  } catch (IOException ex) {
    throw new JBBPIOException("Can't write float value", ex);
  } finally {
    this.byteOrder = old;
  }
}
 
Example #21
Source File: JBBPTextWriterTest.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Test
public void testBin_ValField() throws Exception {
  final JBBPParser parser = JBBPParser.prepare("val:123 a;");
  final String text = makeWriter().SetMaxValuesPerLine(16).Bin(parser.parse(new byte[0])).Close().toString();
  assertEquals("~--------------------------------------------------------------------------------\n" +
      "; Start {} \n" +
      "~--------------------------------------------------------------------------------\n" +
      "    .0x0000007B; int a\n" +
      "~--------------------------------------------------------------------------------\n" +
      "; End {} \n" +
      "~--------------------------------------------------------------------------------\n", text);
}
 
Example #22
Source File: JBBPOut.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Override
protected void onFieldInt(final Object obj, final Field field, final Bin annotation, final int value) {
  final JBBPByteOrder old = this.byteOrder;
  try {
    this.byteOrder = annotation.byteOrder();
    this.Int(value);
  } catch (IOException ex) {
    throw new JBBPIOException("Can't write int value", ex);
  } finally {
    this.byteOrder = old;
  }
}
 
Example #23
Source File: JBBPTextWriterTest.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Test
public void testBin_ParsedDoubleFloat() throws Exception {
  final JBBPTextWriter writer = makeWriter();

  final InputStream pngStream = getResourceAsInputStream("picture.png");
  final JBBPParser parser = JBBPParser.prepare("floatj f; doublej d; floatj [2] fa; doublej [2] da;");

  class Klazz {

    @Bin
    float f;
    @Bin
    float[] fa;
    @Bin
    double d;
    @Bin
    double[] da;
  }

  final byte[] data = new byte[4 + 8 + 4 * 2 + 8 * 2];
  new Random(111222).nextBytes(data);

  final Klazz parsed = parser.parse(data).mapTo(new Klazz());

  final String text = writer.SetMaxValuesPerLine(16).Bin(parsed).Close().toString();

  System.out.println(text);
  assertFileContent("testwriterbinfloatdouble.txt", text);
}
 
Example #24
Source File: JBBPTextWriterTest.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Test
public void testBin_EasyCase() throws Exception {
  @Bin(name = "some class")
  class SomeClass {

    @Bin(order = 1)
    byte a;
    @Bin(order = 2, comment = "Short field")
    short b;
    @Bin(order = 3)
    int c;
    @Bin(order = 4, comment = "Long field")
    long d;
    @Bin(order = 5, comment = "some array")
    byte[] arr = new byte[128];
    @Bin(order = 6, comment = "some string")
    String str = "Hello String";
    @Bin(order = 7, comment = "some string array")
    String[] strs = new String[] {"Hello", null, "World"};
  }

  final SomeClass cl = new SomeClass();
  cl.a = 1;
  cl.b = 2;
  cl.c = 3;
  cl.d = 4;

  final JBBPTextWriter writer = makeWriter();
  writer.SetMaxValuesPerLine(16);

  final String text = writer.SetCommentPrefix("; ").Bin(cl).Close().toString();
  System.out.println(text);
  assertFileContent("testwriterbin1.txt", text);
}
 
Example #25
Source File: JBBPOut.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Override
protected void onFieldCustom(final Object obj, final Field field, final Bin annotation, final Object customFieldProcessor, final Object value) {
  try {
    final JBBPCustomFieldWriter writer = (JBBPCustomFieldWriter) customFieldProcessor;
    writer.writeCustomField(this, this.outStream, obj, field, annotation, value);
  } catch (IOException ex) {
    throw new JBBPIOException("Can't write custom field", ex);
  }
}
 
Example #26
Source File: JBBPOut.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Override
protected void onFieldBits(final Object obj, final Field field, final Bin annotation, final JBBPBitNumber bitNumber, final int value) {
  try {
    this.Bits(bitNumber, value);
  } catch (IOException ex) {
    throw new JBBPIOException("Can't write bit value", ex);
  }
}
 
Example #27
Source File: NetPacketParsingTest.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Test
public void testParseSomePacketGettedOverTCP_ExampleFromStackOverflow() throws Exception {
  final class Parsed {

    @Bin(order = 1)
    byte begin;
    @Bin(order = 2, type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_4)
    int version;
    @Bin(order = 3, type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_4)
    int returnType;
    @Bin(order = 4)
    byte[] productCode;
    @Bin(order = 5, type = BinType.USHORT)
    int dataLength;
  }

  final byte[] testArray = new byte[] {0x23, 0x21, (byte) 0x90, 0x23, 0x21, 0x22, 0x12, 0x00, (byte) 0xAA};

  final Parsed parsed = JBBPParser.prepare("byte begin; bit:4 version; bit:4 returnType; byte [5] productCode; ushort dataLength;")
      .parse(testArray)
      .mapTo(new Parsed());

  assertEquals(0x23, parsed.begin);
  assertEquals(0x01, parsed.version);
  assertEquals(0x02, parsed.returnType);
  assertArrayEquals(new byte[] {(byte) 0x90, 0x23, 0x21, 0x22, 0x12}, parsed.productCode);
  assertEquals(0x00AA, parsed.dataLength);

  assertArrayEquals(testArray, JBBPOut.BeginBin().Bin(parsed).End().toByteArray());
}
 
Example #28
Source File: JBBPOut.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Override
protected void onFieldByte(final Object obj, final Field field, final Bin annotation, final boolean signed, final int value) {
  try {
    this.Byte(value);
  } catch (IOException ex) {
    throw new JBBPIOException("Can't write byte value", ex);
  }
}
 
Example #29
Source File: JBBPOut.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
@Override
protected void onFieldShort(final Object obj, final Field field, final Bin annotation, final boolean signed, final int value) {
  final JBBPByteOrder old = this.byteOrder;
  try {
    this.byteOrder = annotation.byteOrder();
    this.Short(value);
  } catch (IOException ex) {
    throw new JBBPIOException("Can't write short value", ex);
  } finally {
    this.byteOrder = old;
  }
}
 
Example #30
Source File: BasedOnQuestionsAndCasesTest.java    From java-binary-block-parser with Apache License 2.0 5 votes vote down vote up
/**
 * Case 08-feb-2016
 * <p>
 * Incoming data: 0x024281
 * Timestamp format : <a href="http://www.etsi.org/deliver/etsi_en/300300_300399/30039202/02.03.02_60/en_30039202v020302p.pdf">Terrestrial Trunked Radio</a>
 *
 * @throws Exception for any error
 */
@Test
public void testParseTimeStampFromTETRASavedInMSB0() throws Exception {
  final byte[] TEST_DATA = new byte[] {0x2, 0x42, (byte) 0x81};

  class TetraTimestamp {
    @Bin(type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_2, order = 1, bitOrder = JBBPBitOrder.MSB0)
    byte timezone;
    @Bin(type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_2, order = 2, bitOrder = JBBPBitOrder.MSB0)
    byte reserved;
    @Bin(type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_4, order = 3, bitOrder = JBBPBitOrder.MSB0)
    byte month;
    @Bin(type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_5, order = 4, bitOrder = JBBPBitOrder.MSB0)
    byte day;
    @Bin(type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_5, order = 5, bitOrder = JBBPBitOrder.MSB0)
    byte hour;
    @Bin(type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_6, order = 6, bitOrder = JBBPBitOrder.MSB0)
    byte minute;
  }


  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());

  assertEquals(2, parsed.month);
  assertEquals(8, parsed.day);
  assertEquals(10, parsed.hour);
  assertEquals(1, parsed.minute);

  assertArrayEquals(TEST_DATA, JBBPOut.BeginBin(JBBPBitOrder.MSB0).Bin(parsed).End().toByteArray());
}