From e29b271feeb68bb3507780c1abb89207edb0ccb4 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Wed, 5 Feb 2020 21:39:25 +0200 Subject: [PATCH 001/131] started 2.0.2-SNAPSHOT --- jbbp-plugins/jbbp-gradle/pom.xml | 2 +- jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml | 2 +- jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml | 2 +- .../resources/com/igormaznitsa/jbbp/plugin/mvn/mojoConfig.xml | 2 +- jbbp-plugins/jbbp-maven/pom.xml | 2 +- jbbp-plugins/jbbp-plugin-common/pom.xml | 2 +- jbbp-plugins/pom.xml | 2 +- jbbp/pom.xml | 2 +- pom.xml | 4 ++-- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/jbbp-plugins/jbbp-gradle/pom.xml b/jbbp-plugins/jbbp-gradle/pom.xml index 33cf6a55..06c47cd3 100644 --- a/jbbp-plugins/jbbp-gradle/pom.xml +++ b/jbbp-plugins/jbbp-gradle/pom.xml @@ -6,7 +6,7 @@ com.igormaznitsa jbbp-main-plugin-pom - 2.0.1 + 2.0.2-SNAPSHOT jbbp-gradle-plugin diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml index a31fd33c..bf1213be 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-maven-plugin-pom - 2.0.1 + 2.0.2-SNAPSHOT jbbp-maven-plugin-tests diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml index 2f4436d0..82a55537 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-maven-plugin-pom - 2.0.1 + 2.0.2-SNAPSHOT jbbp-maven-plugin diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/resources/com/igormaznitsa/jbbp/plugin/mvn/mojoConfig.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/resources/com/igormaznitsa/jbbp/plugin/mvn/mojoConfig.xml index 1f2ee6b0..32c8b2f2 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/resources/com/igormaznitsa/jbbp/plugin/mvn/mojoConfig.xml +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/resources/com/igormaznitsa/jbbp/plugin/mvn/mojoConfig.xml @@ -14,7 +14,7 @@ com.igormaznitsa jbbp-maven-plugin - 2.0.1 + 2.0.2-SNAPSHOT generate diff --git a/jbbp-plugins/jbbp-maven/pom.xml b/jbbp-plugins/jbbp-maven/pom.xml index 53ee3bcb..ba435949 100644 --- a/jbbp-plugins/jbbp-maven/pom.xml +++ b/jbbp-plugins/jbbp-maven/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-main-plugin-pom - 2.0.1 + 2.0.2-SNAPSHOT jbbp-maven-plugin-pom diff --git a/jbbp-plugins/jbbp-plugin-common/pom.xml b/jbbp-plugins/jbbp-plugin-common/pom.xml index 5157cb73..418443fb 100644 --- a/jbbp-plugins/jbbp-plugin-common/pom.xml +++ b/jbbp-plugins/jbbp-plugin-common/pom.xml @@ -6,7 +6,7 @@ com.igormaznitsa jbbp-main-plugin-pom - 2.0.1 + 2.0.2-SNAPSHOT jbbp-plugin-common diff --git a/jbbp-plugins/pom.xml b/jbbp-plugins/pom.xml index 867b0a49..c02ae88f 100644 --- a/jbbp-plugins/pom.xml +++ b/jbbp-plugins/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-main-pom - 2.0.1 + 2.0.2-SNAPSHOT jbbp-main-plugin-pom diff --git a/jbbp/pom.xml b/jbbp/pom.xml index a7f40c8e..5f1ade2c 100644 --- a/jbbp/pom.xml +++ b/jbbp/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-main-pom - 2.0.1 + 2.0.2-SNAPSHOT jbbp diff --git a/pom.xml b/pom.xml index 43ae0896..8da29226 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.igormaznitsa jbbp-main-pom - 2.0.1 + 2.0.2-SNAPSHOT pom @@ -21,7 +21,7 @@ yyyyMMddHHmm 3.0 1.1.2 - 2.0.1 + 2.0.2-SNAPSHOT ${jbbp.version} 1.8 1.8 From 8442f253e1ebd6e61caa8867c5dc76e5ad65c0f7 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Tue, 18 Feb 2020 22:23:53 +0200 Subject: [PATCH 002/131] #27 added example for custom ASCII string parsing --- .../jbbp/it/BasedOnQuestionsAndCasesTest.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java index 19aafb84..f9faa9dd 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java @@ -34,6 +34,7 @@ import com.igormaznitsa.jbbp.model.JBBPAbstractField; import com.igormaznitsa.jbbp.model.JBBPFieldArrayByte; import com.igormaznitsa.jbbp.model.JBBPFieldArrayLong; +import com.igormaznitsa.jbbp.model.JBBPFieldArrayString; import com.igormaznitsa.jbbp.model.JBBPFieldInt; import com.igormaznitsa.jbbp.model.JBBPFieldLong; import com.igormaznitsa.jbbp.model.JBBPFieldString; @@ -44,6 +45,7 @@ import java.io.EOFException; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -252,6 +254,80 @@ public void testStringMsb0() throws Exception { assertEquals(12345, bitflds.findFieldForNameAndType("i", JBBPFieldInt.class).getAsInt()); } + /** + * Case 18-feb-2020, #27 Strings in other codecs + * Example how to implement custom ASCII string format + * + * @throws Exception for any error + */ + @Test + public void testAscIIPascalString() throws Exception { + final class AscIIPascalString implements JBBPCustomFieldTypeProcessor { + private final String[] TYPES = new String[] {"asciistr"}; + + @Override + public String[] getCustomFieldTypes() { + return TYPES; + } + + @Override + public boolean isAllowed( + final JBBPFieldTypeParameterContainer fieldType, + final String fieldName, + final int extraData, + final boolean isArray + ) { + return extraData == 0; + } + + @Override + public JBBPAbstractField readCustomFieldType( + final JBBPBitInputStream in, + final JBBPBitOrder bitOrder, + final int parserFlags, + final JBBPFieldTypeParameterContainer customTypeFieldInfo, + final JBBPNamedFieldInfo fieldName, + final int extraData, + final boolean readWholeStream, + final int arrayLength + ) throws IOException { + if (arrayLength < 0) { + return new JBBPFieldString(fieldName, readPascalAscIIString(in)); + } else { + final String[] loadedStrings; + if (readWholeStream) { + final List strings = new ArrayList<>(); + while (in.hasAvailableData()) { + strings.add(readPascalAscIIString(in)); + } + loadedStrings = strings.toArray(new String[0]); + } else { + loadedStrings = new String[arrayLength]; + for (int i = 0; i < arrayLength; i++) { + loadedStrings[i] = readPascalAscIIString(in); + } + } + return new JBBPFieldArrayString(fieldName, loadedStrings); + } + } + + private String readPascalAscIIString(final JBBPBitInputStream in) throws IOException { + final byte[] charArray = in.readByteArray(in.readByte()); + return new String(charArray, StandardCharsets.US_ASCII); + } + } + + final JBBPParser parserSingle = JBBPParser.prepare("asciistr str1; asciistr str2;", new AscIIPascalString()); + final JBBPFieldStruct parsedSingle = parserSingle.parse(new byte[] {5, 65, 66, 67, 68, 69, 0}); + assertEquals("ABCDE", parsedSingle.findFieldForNameAndType("str1", JBBPFieldString.class).getAsString()); + assertEquals("", parsedSingle.findFieldForNameAndType("str2", JBBPFieldString.class).getAsString()); + + final JBBPParser parserArray = JBBPParser.prepare("asciistr [2] str1; asciistr [_] str2;", new AscIIPascalString()); + final JBBPFieldStruct parsedArrays = parserArray.parse(new byte[] {2, 65, 66, 1, 67, 3, 68, 69, 70, 2, 71, 72, 1, 73}); + assertArrayEquals(new String[] {"AB", "C"}, parsedArrays.findFieldForNameAndType("str1", JBBPFieldArrayString.class).getArray()); + assertArrayEquals(new String[] {"DEF", "GH", "I"}, parsedArrays.findFieldForNameAndType("str2", JBBPFieldArrayString.class).getArray()); + } + /** * Case 10-aug-2017 * NullPointer exception when referencing a JBBPCustomFieldTypeProcessor parsed field. From ebb1750739c9bb30e872cda18c6064b1925dbc15 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Sun, 19 Apr 2020 20:51:33 +0300 Subject: [PATCH 003/131] #28 added JBBPOut#BinForceByteOrder to override byte order defined in @Bin annotations of written object. --- README.md | 3 + changelog.txt | 3 + .../io/AbstractMappedClassFieldObserver.java | 26 ++- .../com/igormaznitsa/jbbp/io/JBBPOut.java | 33 +++- .../jbbp/utils/BinAnnotationWrapper.java | 158 ++++++++++++++++++ .../jbbp/utils/JBBPTextWriter.java | 2 +- .../com/igormaznitsa/jbbp/io/JBBPOutTest.java | 49 ++++++ pom.xml | 7 +- 8 files changed, 273 insertions(+), 8 deletions(-) create mode 100644 jbbp/src/main/java/com/igormaznitsa/jbbp/utils/BinAnnotationWrapper.java diff --git a/README.md b/README.md index 05b8329b..c30d4467 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,9 @@ Java has some embedded features to parse binary data (for instance ByteBuffer), ![Use cases](https://github.com/raydac/java-binary-block-parser/blob/master/docs/jbbp_mm.png) # Change log +- **2.0.2 (SNAPSHOT)** + - [#28](https://github.com/raydac/java-binary-block-parser/issues/28) added `JBBPOut#BinForceByteOrder` to override byte order defined in `@Bin` annotations of written object. + - **2.0.1 (04-feb-2020)** - [#26](https://github.com/raydac/java-binary-block-parser/issues/26) fixed bug in array write with MSB0 diff --git a/changelog.txt b/changelog.txt index 14a540e9..5606dada 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,6 @@ +2.0.2 (SNAPSHOT) + - [#28](https://github.com/raydac/java-binary-block-parser/issues/28) added `JBBPOut#BinForceByteOrder` to override byte order defined in `@Bin` annotations of written object. + 2.0.1 - [#26](https://github.com/raydac/java-binary-block-parser/issues/26) fixed bug in array write with MSB0 diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/AbstractMappedClassFieldObserver.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/AbstractMappedClassFieldObserver.java index dd47cae7..3ed60797 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/AbstractMappedClassFieldObserver.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/AbstractMappedClassFieldObserver.java @@ -26,6 +26,7 @@ import com.igormaznitsa.jbbp.model.JBBPFieldLong; import com.igormaznitsa.jbbp.model.JBBPFieldShort; import com.igormaznitsa.jbbp.model.JBBPFieldString; +import com.igormaznitsa.jbbp.utils.BinAnnotationWrapper; import com.igormaznitsa.jbbp.utils.JBBPUtils; import java.lang.reflect.Array; import java.lang.reflect.Field; @@ -75,10 +76,12 @@ private static void assertFieldArray(final Field field) { * * @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 forceByteOrder value to replace all byte order values in processing oject, can be null * @param customFieldProcessor a processor for custom fields, it can be null * @see Bin + * @since 2.0.2 */ - protected void processObject(final Object obj, Field field, final Object customFieldProcessor) { + protected void processObject(final Object obj, Field field, final JBBPByteOrder forceByteOrder, final Object customFieldProcessor) { JBBPUtils.assertNotNull(obj, "Object must not be null"); final List orderedFields = JBBPMapper.findAffectedFields(obj); @@ -95,7 +98,7 @@ protected void processObject(final Object obj, Field field, final Object customF 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); + processObjectField(obj, rec, forceByteOrder, binAnno, customFieldProcessor); } this.onStructEnd(obj, field, clazzAnno == null ? fieldAnno : clazzAnno); @@ -106,13 +109,26 @@ protected void processObject(final Object obj, Field field, final Object customF * * @param obj the object which field under processing, must not be null * @param fieldRecord internal record about the field, must not be null + * @param forceByteOrder byte order to replace byte order defined for field, can be null * @param annotation the annotation to be used as data source about the field, * must not be null * @param customFieldProcessor an object which will be provided for processing * of custom fields, must not be null if object contains custom fields + * @since 2.0.2 */ - protected void processObjectField(final Object obj, final MappedFieldRecord fieldRecord, final Bin annotation, final Object customFieldProcessor) { + protected void processObjectField( + final Object obj, + final MappedFieldRecord fieldRecord, + final JBBPByteOrder forceByteOrder, + Bin annotation, + final Object customFieldProcessor + ) { final Field field = fieldRecord.mappingField; + + if (forceByteOrder != null) { + annotation = new BinAnnotationWrapper(annotation).setByteOrder(forceByteOrder); + } + if (annotation.custom()) { this.onFieldCustom(obj, field, annotation, customFieldProcessor, readFieldValue(obj, fieldRecord)); } else { @@ -233,7 +249,7 @@ protected void processObjectField(final Object obj, final MappedFieldRecord fiel } break; case STRUCT: { - processObject(readFieldValue(obj, fieldRecord), field, customFieldProcessor); + processObject(readFieldValue(obj, fieldRecord), field, forceByteOrder, customFieldProcessor); } break; default: { @@ -428,7 +444,7 @@ protected void processObjectField(final Object obj, final MappedFieldRecord fiel final int len = Array.getLength(array); this.onArrayStart(obj, field, annotation, len); for (int i = 0; i < len; i++) { - this.processObject(Array.get(array, i), field, customFieldProcessor); + this.processObject(Array.get(array, i), field, forceByteOrder, customFieldProcessor); } this.onArrayEnd(obj, field, annotation); } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java index 20ed7b1c..b56ff513 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java @@ -1026,9 +1026,40 @@ public JBBPOut Bin(final Object object) throws IOException { */ public JBBPOut Bin(final Object object, final JBBPCustomFieldWriter customFieldWriter) { if (this.processCommands) { - this.processObject(object, null, customFieldWriter); + this.processObject(object, null, null, customFieldWriter); } + return this; + } + /** + * Works like {@link #Bin(Object)} but forcing override of all annotation byte order values by the JBBPOut byte order. + * + * @param object an object to be saved into stream, must not be null + * @return the context + * @throws IOException it will be thrown for any transport error + * @see JBBPMapper#clearFieldCache() + * @see Bin + * @see Bin#byteOrder() + * @since 2.0.2 + */ + public JBBPOut BinForceByteOrder(final Object object) throws IOException { + return this.BinForceByteOrder(object, null); + } + + /** + * Works like {@link #Bin(Object, JBBPCustomFieldWriter)} but forcing override of all annotation byte order values by the JBBPOut byte order. + * + * @param object an object to be saved into stream, must not be null + * @param customFieldWriter a custom field writer to be used for saving of + * custom fields of the object, it can be null + * @return the context + * @see Bin#byteOrder() + * @since 2.0.2 + */ + public JBBPOut BinForceByteOrder(final Object object, final JBBPCustomFieldWriter customFieldWriter) { + if (this.processCommands) { + this.processObject(object, null, this.byteOrder, customFieldWriter); + } return this; } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/BinAnnotationWrapper.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/BinAnnotationWrapper.java new file mode 100644 index 00000000..6905d1a7 --- /dev/null +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/BinAnnotationWrapper.java @@ -0,0 +1,158 @@ +package com.igormaznitsa.jbbp.utils; + +import com.igormaznitsa.jbbp.io.JBBPBitNumber; +import com.igormaznitsa.jbbp.io.JBBPBitOrder; +import com.igormaznitsa.jbbp.io.JBBPByteOrder; +import com.igormaznitsa.jbbp.mapper.Bin; +import com.igormaznitsa.jbbp.mapper.BinType; +import java.lang.annotation.Annotation; + +/** + * Auxiliary class to replace Bin annotation fields during internal processing + * + * @since 2.0. + */ +public class BinAnnotationWrapper implements Bin { + private final Bin bin; + private String name; + private String path; + private String customType; + private String arraySizeExpr; + private BinType type; + private JBBPBitOrder bitOrder; + private Boolean custom; + private String paramExpr; + private JBBPBitNumber bitNumber; + private JBBPByteOrder byteOrder; + private Integer order; + private String comment; + + public BinAnnotationWrapper(final Bin bin) { + this.bin = bin; + } + + public BinAnnotationWrapper setName(final String value) { + this.name = value; + return this; + } + + @Override + public String name() { + return this.name == null ? this.bin.name() : this.name; + } + + public BinAnnotationWrapper setPath(final String value) { + this.path = value; + return this; + } + + @Override + public String path() { + return this.path == null ? this.bin.path() : this.path; + } + + public BinAnnotationWrapper setCustomType(final String value) { + this.customType = value; + return this; + } + + @Override + public String customType() { + return this.customType == null ? this.bin.customType() : this.customType; + } + + public BinAnnotationWrapper setArraySizeExpr(final String value) { + this.arraySizeExpr = value; + return this; + } + + @Override + public String arraySizeExpr() { + return this.arraySizeExpr == null ? this.bin.arraySizeExpr() : this.arraySizeExpr; + } + + public BinAnnotationWrapper setType(final BinType value) { + this.type = value; + return this; + } + + @Override + public BinType type() { + return this.type == null ? this.bin.type() : this.type; + } + + public BinAnnotationWrapper setBitOrder(final JBBPBitOrder value) { + this.bitOrder = value; + return this; + } + + @Override + public JBBPBitOrder bitOrder() { + return this.bitOrder == null ? this.bin.bitOrder() : this.bitOrder; + } + + public BinAnnotationWrapper setCustom(final Boolean value) { + this.custom = value; + return this; + } + + @Override + public boolean custom() { + return this.custom == null ? this.bin.custom() : this.custom; + } + + public BinAnnotationWrapper setParamExpr(final String value) { + this.paramExpr = value; + return this; + } + + @Override + public String paramExpr() { + return this.paramExpr == null ? this.bin.paramExpr() : this.paramExpr; + } + + public BinAnnotationWrapper setBitNumber(final JBBPBitNumber value) { + this.bitNumber = value; + return this; + } + + @Override + public JBBPBitNumber bitNumber() { + return this.bitNumber == null ? this.bin.bitNumber() : this.bitNumber; + } + + public BinAnnotationWrapper setByteOrder(final JBBPByteOrder value) { + this.byteOrder = value; + return this; + } + + @Override + public JBBPByteOrder byteOrder() { + return this.byteOrder == null ? this.bin.byteOrder() : this.byteOrder; + } + + public BinAnnotationWrapper setOrder(final Integer value) { + this.order = value; + return this; + } + + @Override + public int order() { + return this.order == null ? this.bin.order() : this.order; + } + + public BinAnnotationWrapper setComment(final String value) { + this.comment = value; + return this; + } + + @Override + public String comment() { + return this.comment == null ? this.bin.comment() : this.comment; + } + + @Override + public Class annotationType() { + return this.bin.getClass(); + } +} diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPTextWriter.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPTextWriter.java index a6f712da..aca3e543 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPTextWriter.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPTextWriter.java @@ -2004,7 +2004,7 @@ protected void onFieldCustom(final Object obj, final Field field, final Bin anno } public void processObject(final Object obj) { - super.processObject(obj, null, this); + super.processObject(obj, null, null, this); } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPOutTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPOutTest.java index 7b069b0a..72da9452 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPOutTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPOutTest.java @@ -773,6 +773,55 @@ class Test { assertArrayEquals(new byte[] {1, (byte) 0x80, 0}, BeginBin().Bin(new Test(true, true, false)).End().toByteArray()); } + @Test + public void testBin_ForceByteOrder() throws Exception { + class DefaultByteOrder { + @Bin + int value = 0x01020304; + } + + class BigEndianByteOrder { + @Bin(byteOrder = JBBPByteOrder.BIG_ENDIAN) + int value = 0x01020304; + } + + class LittleEndianByteOrder { + @Bin(byteOrder = JBBPByteOrder.LITTLE_ENDIAN) + int value = 0x01020304; + } + + class LittleEndianByteOrderWithStructure { + + @Bin(byteOrder = JBBPByteOrder.LITTLE_ENDIAN, order = 1) + int value = 0x01020304; + @Bin(order = 2) + Internal internal = new Internal(); + + class Internal { + @Bin(byteOrder = JBBPByteOrder.BIG_ENDIAN) + int value = 0x05060708; + } + } + + final byte[] defaultOrder = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).BinForceByteOrder(new DefaultByteOrder()).End().toByteArray(); + assertArrayEquals(new byte[] {4, 3, 2, 1}, defaultOrder); + + final byte[] bigEndianOrder = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).BinForceByteOrder(new BigEndianByteOrder()).End().toByteArray(); + assertArrayEquals(new byte[] {4, 3, 2, 1}, bigEndianOrder); + + final byte[] littleEndianOrder = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).BinForceByteOrder(new LittleEndianByteOrder()).End().toByteArray(); + assertArrayEquals(new byte[] {1, 2, 3, 4}, littleEndianOrder); + + final byte[] littleEndianOrderWithStruct = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).BinForceByteOrder(new LittleEndianByteOrderWithStructure()).End().toByteArray(); + assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}, littleEndianOrderWithStruct); + + final byte[] littleEndianOrderWithStructBin = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Bin(new LittleEndianByteOrderWithStructure()).End().toByteArray(); + assertArrayEquals(new byte[] {4, 3, 2, 1, 5, 6, 7, 8}, littleEndianOrderWithStructBin); + + final byte[] littleEndianOrderWithStructLe = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).BinForceByteOrder(new LittleEndianByteOrderWithStructure()).End().toByteArray(); + assertArrayEquals(new byte[] {4, 3, 2, 1, 8, 7, 6, 5}, littleEndianOrderWithStructLe); + } + @Test public void testBin_BitType_Bits() throws Exception { class Test { diff --git a/pom.xml b/pom.xml index 8da29226..8ee08d85 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,6 @@ jbbp - jbbp-plugins https://github.com/raydac/java-binary-block-parser @@ -116,6 +115,12 @@ + + plugins + + jbbp-plugins + + bundle From be09670b9f1cda75e2317f98991be242e0b8877c Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Sun, 26 Apr 2020 22:22:54 +0300 Subject: [PATCH 004/131] added JBBPOut.Bin to override @Bin field values in written objects --- .gitignore | 4 +-- README.md | 8 +---- changelog.txt | 1 + .../io/AbstractMappedClassFieldObserver.java | 29 +++++++++-------- .../com/igormaznitsa/jbbp/io/JBBPOut.java | 31 ++++++++++++++----- .../jbbp/utils/BinAnnotationWrapper.java | 29 +++++++++++++---- .../com/igormaznitsa/jbbp/io/JBBPOutTest.java | 25 +++++++++++++++ 7 files changed, 90 insertions(+), 37 deletions(-) diff --git a/.gitignore b/.gitignore index 7e65dc8e..9b8fe20c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ /**/target/ /target/ /nbproject/ -/.idea/ +/**/.idea/ *.iml /jbbp-plugins/jbbp-gradle/.gradle/ /jbbp-plugins/jbbp-gradle/build/ @@ -39,4 +39,4 @@ /jbbp-plugins/jbbp-gradle/bin/ /jbbp-plugins/jbbp-gradle/.classpath /jbbp-plugins/jbbp-gradle/.project -/.vscode/ +/**/.vscode/ diff --git a/README.md b/README.md index c30d4467..5fe9032e 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Java has some embedded features to parse binary data (for instance ByteBuffer), # Change log - **2.0.2 (SNAPSHOT)** + - added `JBBPOut#Bin` variant to override `@Bin` annotation fields in written objects. - [#28](https://github.com/raydac/java-binary-block-parser/issues/28) added `JBBPOut#BinForceByteOrder` to override byte order defined in `@Bin` annotations of written object. - **2.0.1 (04-feb-2020)** @@ -29,13 +30,6 @@ Java has some embedded features to parse binary data (for instance ByteBuffer), - added generating of `makeFIELD()` method for structure types in Java class converter - refactoring -- **1.4.1 (20-aug-2018)** - - fixed incompatibility in tokenizer regex syntax for Android SDK [#23](https://github.com/raydac/java-binary-block-parser/issues/23) - - added DslBinCustom annotation to provide way to mark custom type fields for JBBPDslBuilder - - fixed NPE in JBBPDslBuilder for not-provided outBitNumber attribute in annotated field marked as type BIT or BIT_ARRAY [#20](https://github.com/raydac/java-binary-block-parser/issues/20) - - naming of fields has been made more tolerant, now it is allowed to have field names with names similar to data types - - improved check of field names in JBBPDslBuilder [#21](https://github.com/raydac/java-binary-block-parser/issues/21) - [Full changelog](https://github.com/raydac/java-binary-block-parser/blob/master/changelog.txt) # Maven dependency diff --git a/changelog.txt b/changelog.txt index 5606dada..7c47ade9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,5 @@ 2.0.2 (SNAPSHOT) + - added `JBBPOut#Bin` variant to override `@Bin` annotation fields in written objects. - [#28](https://github.com/raydac/java-binary-block-parser/issues/28) added `JBBPOut#BinForceByteOrder` to override byte order defined in `@Bin` annotations of written object. 2.0.1 diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/AbstractMappedClassFieldObserver.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/AbstractMappedClassFieldObserver.java index 3ed60797..b8f47ff0 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/AbstractMappedClassFieldObserver.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/AbstractMappedClassFieldObserver.java @@ -76,12 +76,17 @@ private static void assertFieldArray(final Field field) { * * @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 forceByteOrder value to replace all byte order values in processing oject, can be null + * @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, Field field, final JBBPByteOrder forceByteOrder, final Object customFieldProcessor) { + 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 orderedFields = JBBPMapper.findAffectedFields(obj); @@ -92,13 +97,13 @@ protected void processObject(final Object obj, Field field, final JBBPByteOrder this.onStructStart(obj, field, clazzAnno == null ? fieldAnno : clazzAnno); for (final MappedFieldRecord rec : orderedFields) { - Bin binAnno = rec.binAnnotation; + 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."); + 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, forceByteOrder, binAnno, customFieldProcessor); + processObjectField(obj, rec, binAnno, customFieldProcessor); } this.onStructEnd(obj, field, clazzAnno == null ? fieldAnno : clazzAnno); @@ -109,7 +114,6 @@ protected void processObject(final Object obj, Field field, final JBBPByteOrder * * @param obj the object which field under processing, must not be null * @param fieldRecord internal record about the field, must not be null - * @param forceByteOrder byte order to replace byte order defined for field, can be null * @param annotation the annotation to be used as data source about the field, * must not be null * @param customFieldProcessor an object which will be provided for processing @@ -119,21 +123,16 @@ protected void processObject(final Object obj, Field field, final JBBPByteOrder protected void processObjectField( final Object obj, final MappedFieldRecord fieldRecord, - final JBBPByteOrder forceByteOrder, - Bin annotation, + final Bin annotation, final Object customFieldProcessor ) { final Field field = fieldRecord.mappingField; - if (forceByteOrder != null) { - annotation = new BinAnnotationWrapper(annotation).setByteOrder(forceByteOrder); - } - if (annotation.custom()) { this.onFieldCustom(obj, field, annotation, customFieldProcessor, readFieldValue(obj, fieldRecord)); } else { final Class fieldType = field.getType(); - + final BinAnnotationWrapper wrapper = annotation instanceof BinAnnotationWrapper ? (BinAnnotationWrapper) annotation : null; final BinType type; if (annotation.type() == BinType.UNDEFINED) { type = BinType.findCompatible(fieldType); @@ -249,7 +248,7 @@ protected void processObjectField( } break; case STRUCT: { - processObject(readFieldValue(obj, fieldRecord), field, forceByteOrder, customFieldProcessor); + processObject(readFieldValue(obj, fieldRecord), field, wrapper, customFieldProcessor); } break; default: { @@ -444,7 +443,7 @@ protected void processObjectField( final int len = Array.getLength(array); this.onArrayStart(obj, field, annotation, len); for (int i = 0; i < len; i++) { - this.processObject(Array.get(array, i), field, forceByteOrder, customFieldProcessor); + this.processObject(Array.get(array, i), field, wrapper, customFieldProcessor); } this.onArrayEnd(obj, field, annotation); } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java index b56ff513..1d29af75 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java @@ -20,6 +20,7 @@ import com.igormaznitsa.jbbp.mapper.Bin; import com.igormaznitsa.jbbp.mapper.JBBPMapper; import com.igormaznitsa.jbbp.model.JBBPFieldShort; +import com.igormaznitsa.jbbp.utils.BinAnnotationWrapper; import com.igormaznitsa.jbbp.utils.JBBPUtils; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -998,16 +999,18 @@ protected void assertNotEnded() { * through {@link Bin#order()} field, NB! By default Java doesn't keep field * outOrder. Ordered fields of class will be saved into internal cache for speed * but the cache can be reset through {@link JBBPMapper#clearFieldCache()} + * Warning! it doesn't affect byte order provided in Bin annotations of object. * * @param object an object to be saved into stream, must not be null * @return the context * @throws IOException it will be thrown for any transport error * @see JBBPMapper#clearFieldCache() + * @see #BinForceByteOrder(Object) * @see Bin * @since 1.1 */ public JBBPOut Bin(final Object object) throws IOException { - return this.Bin(object, null); + return this.Bin(object, null, null); } /** @@ -1015,6 +1018,7 @@ public JBBPOut Bin(final Object object) throws IOException { * through {@link Bin#order()} field, NB! By default Java doesn't keep field * outOrder. Ordered fields of class will be saved into internal cache for speed * but the cache can be reset through {@link JBBPMapper#clearFieldCache()} + * Warning! it doesn't affect byte order provided in Bin annotations of object. * * @param object an object to be saved into stream, must not be null * @param customFieldWriter a custom field writer to be used for saving of @@ -1022,11 +1026,26 @@ public JBBPOut Bin(final Object object) throws IOException { * @return the context * @see JBBPMapper#clearFieldCache() * @see Bin + * @see #BinForceByteOrder(Object, JBBPCustomFieldWriter) * @since 1.1 */ public JBBPOut Bin(final Object object, final JBBPCustomFieldWriter customFieldWriter) { + return this.Bin(object, null, customFieldWriter); + } + + /** + * Save fields of object but bin annotation wrapper can be provided to replace some annnotation field values in all field annotations. + * + * @param object an object to be saved into stream, must not be null + * @param binAnnotationWrapper wrapper for all bin annotations, can be null + * @param customFieldWriter a custom field writer to be used for saving of + * custom fields of the object, it can be null + * @return the context + * @since 2.0.2 + */ + public JBBPOut Bin(final Object object, final BinAnnotationWrapper binAnnotationWrapper, final JBBPCustomFieldWriter customFieldWriter) { if (this.processCommands) { - this.processObject(object, null, null, customFieldWriter); + this.processObject(object, null, binAnnotationWrapper, customFieldWriter); } return this; } @@ -1047,20 +1066,18 @@ public JBBPOut BinForceByteOrder(final Object object) throws IOException { } /** - * Works like {@link #Bin(Object, JBBPCustomFieldWriter)} but forcing override of all annotation byte order values by the JBBPOut byte order. + * Works like {@link #Bin(Object, JBBPCustomFieldWriter)} but forcing override of all annotation byte order values by the context byte order. * * @param object an object to be saved into stream, must not be null * @param customFieldWriter a custom field writer to be used for saving of * custom fields of the object, it can be null * @return the context + * @see #ByteOrder(JBBPByteOrder) * @see Bin#byteOrder() * @since 2.0.2 */ public JBBPOut BinForceByteOrder(final Object object, final JBBPCustomFieldWriter customFieldWriter) { - if (this.processCommands) { - this.processObject(object, null, this.byteOrder, customFieldWriter); - } - return this; + return this.Bin(object, new BinAnnotationWrapper().setByteOrder(this.byteOrder), customFieldWriter); } @Override diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/BinAnnotationWrapper.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/BinAnnotationWrapper.java index 6905d1a7..ed968a22 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/BinAnnotationWrapper.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/BinAnnotationWrapper.java @@ -8,12 +8,13 @@ import java.lang.annotation.Annotation; /** - * Auxiliary class to replace Bin annotation fields during internal processing + * Auxiliary class to replace Bin annotation field values. + * Not thread safe! * - * @since 2.0. + * @since 2.0.2 */ -public class BinAnnotationWrapper implements Bin { - private final Bin bin; +public final class BinAnnotationWrapper implements Bin { + private Bin bin; private String name; private String path; private String customType; @@ -27,8 +28,12 @@ public class BinAnnotationWrapper implements Bin { private Integer order; private String comment; - public BinAnnotationWrapper(final Bin bin) { + public BinAnnotationWrapper() { + } + + public BinAnnotationWrapper setWrapped(final Bin bin) { this.bin = bin; + return this; } public BinAnnotationWrapper setName(final String value) { @@ -38,6 +43,7 @@ public BinAnnotationWrapper setName(final String value) { @Override public String name() { + assert this.bin != null; return this.name == null ? this.bin.name() : this.name; } @@ -48,6 +54,7 @@ public BinAnnotationWrapper setPath(final String value) { @Override public String path() { + assert this.bin != null; return this.path == null ? this.bin.path() : this.path; } @@ -58,6 +65,7 @@ public BinAnnotationWrapper setCustomType(final String value) { @Override public String customType() { + assert this.bin != null; return this.customType == null ? this.bin.customType() : this.customType; } @@ -68,6 +76,7 @@ public BinAnnotationWrapper setArraySizeExpr(final String value) { @Override public String arraySizeExpr() { + assert this.bin != null; return this.arraySizeExpr == null ? this.bin.arraySizeExpr() : this.arraySizeExpr; } @@ -78,6 +87,7 @@ public BinAnnotationWrapper setType(final BinType value) { @Override public BinType type() { + assert this.bin != null; return this.type == null ? this.bin.type() : this.type; } @@ -88,6 +98,7 @@ public BinAnnotationWrapper setBitOrder(final JBBPBitOrder value) { @Override public JBBPBitOrder bitOrder() { + assert this.bin != null; return this.bitOrder == null ? this.bin.bitOrder() : this.bitOrder; } @@ -98,6 +109,7 @@ public BinAnnotationWrapper setCustom(final Boolean value) { @Override public boolean custom() { + assert this.bin != null; return this.custom == null ? this.bin.custom() : this.custom; } @@ -108,6 +120,7 @@ public BinAnnotationWrapper setParamExpr(final String value) { @Override public String paramExpr() { + assert this.bin != null; return this.paramExpr == null ? this.bin.paramExpr() : this.paramExpr; } @@ -118,6 +131,7 @@ public BinAnnotationWrapper setBitNumber(final JBBPBitNumber value) { @Override public JBBPBitNumber bitNumber() { + assert this.bin != null; return this.bitNumber == null ? this.bin.bitNumber() : this.bitNumber; } @@ -128,6 +142,7 @@ public BinAnnotationWrapper setByteOrder(final JBBPByteOrder value) { @Override public JBBPByteOrder byteOrder() { + assert this.bin != null; return this.byteOrder == null ? this.bin.byteOrder() : this.byteOrder; } @@ -138,6 +153,7 @@ public BinAnnotationWrapper setOrder(final Integer value) { @Override public int order() { + assert this.bin != null; return this.order == null ? this.bin.order() : this.order; } @@ -148,11 +164,12 @@ public BinAnnotationWrapper setComment(final String value) { @Override public String comment() { + assert this.bin != null; return this.comment == null ? this.bin.comment() : this.comment; } @Override public Class annotationType() { - return this.bin.getClass(); + return Bin.class; } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPOutTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPOutTest.java index 72da9452..2d2a79d9 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPOutTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPOutTest.java @@ -32,9 +32,12 @@ import com.igormaznitsa.jbbp.mapper.BinType; import com.igormaznitsa.jbbp.model.JBBPFieldInt; import com.igormaznitsa.jbbp.model.JBBPFieldLong; +import com.igormaznitsa.jbbp.utils.BinAnnotationWrapper; import com.igormaznitsa.jbbp.utils.JBBPUtils; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; +import java.io.IOException; +import java.lang.reflect.Field; import org.junit.jupiter.api.Test; public class JBBPOutTest { @@ -842,6 +845,28 @@ class Test { assertArrayEquals(new byte[] {(byte) 0x55, 0x0C}, BeginBin().Bin(new Test((byte) 0x05, (byte) 0x0A, (byte) 0x0C)).End().toByteArray()); } + @Test + public void testBin_OverrideAnnotationValues() throws Exception { + class Test { + @Bin(bitNumber = JBBPBitNumber.BITS_4, type = BinType.BIT) + byte a = (byte) 0b10101010; + } + + assertArrayEquals(new byte[] {(byte) 0b00001010}, BeginBin().Bin(new Test(), null, null).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0b10101010}, BeginBin().Bin(new Test(), new BinAnnotationWrapper().setBitNumber(JBBPBitNumber.BITS_8), null).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0b00000101}, BeginBin().Bin(new Test(), new BinAnnotationWrapper().setBitOrder(JBBPBitOrder.MSB0), null).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0b10101010}, BeginBin().Bin(new Test(), new BinAnnotationWrapper().setType(BinType.BYTE), null).End().toByteArray()); + + final JBBPCustomFieldWriter customFieldWriter = new JBBPCustomFieldWriter() { + @Override + public void writeCustomField(JBBPOut context, JBBPBitOutputStream outStream, Object instanceToSave, Field instanceCustomField, Bin fieldAnnotation, Object value) throws IOException { + outStream.write(123); + } + }; + + assertArrayEquals(new byte[] {(byte) 123}, BeginBin().Bin(new Test(), new BinAnnotationWrapper().setCustom(true), customFieldWriter).End().toByteArray()); + } + @Test public void testBin_UndefinedType_Short() throws Exception { class Test { From 2606b5a697799a091e55e341c892b0b664e7e4c6 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Sun, 26 Apr 2020 23:29:28 +0300 Subject: [PATCH 005/131] removed use of gradle maven plugin, reworked to use externally installed gradle through maven executor --- jbbp-plugins/jbbp-gradle/pom.xml | 33 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/jbbp-plugins/jbbp-gradle/pom.xml b/jbbp-plugins/jbbp-gradle/pom.xml index 06c47cd3..1544ef95 100644 --- a/jbbp-plugins/jbbp-gradle/pom.xml +++ b/jbbp-plugins/jbbp-gradle/pom.xml @@ -24,6 +24,7 @@ 1.8 1.8 + gradle install @@ -93,29 +94,23 @@ - org.fortasoft - gradle-maven-plugin - 1.0.8 - - - org.gradle - gradle-tooling-api - 5.2.1 - - - - - 5.4 - - clean - ${gradleGoal} - - + org.codehaus.mojo + exec-maven-plugin + gradle compile + + ${gradle.executable} + + ${gradleGoal} + -i + -S + --no-daemon + + - invoke + exec From ea8ab4223adbb7d1836fec96fba84e12b7990d51 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Thu, 9 Jul 2020 23:59:31 +0300 Subject: [PATCH 006/131] #29 added example of read-write-mapping processor for nullable byte arrays --- .../jbbp/it/BasedOnQuestionsAndCasesTest.java | 177 ++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java index f9faa9dd..882d29d5 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java @@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import com.igormaznitsa.jbbp.JBBPCustomFieldTypeProcessor; @@ -27,14 +28,18 @@ import com.igormaznitsa.jbbp.io.JBBPBitInputStream; import com.igormaznitsa.jbbp.io.JBBPBitNumber; import com.igormaznitsa.jbbp.io.JBBPBitOrder; +import com.igormaznitsa.jbbp.io.JBBPBitOutputStream; import com.igormaznitsa.jbbp.io.JBBPByteOrder; +import com.igormaznitsa.jbbp.io.JBBPCustomFieldWriter; import com.igormaznitsa.jbbp.io.JBBPOut; import com.igormaznitsa.jbbp.mapper.Bin; import com.igormaznitsa.jbbp.mapper.BinType; +import com.igormaznitsa.jbbp.mapper.JBBPMapperCustomFieldProcessor; import com.igormaznitsa.jbbp.model.JBBPAbstractField; import com.igormaznitsa.jbbp.model.JBBPFieldArrayByte; import com.igormaznitsa.jbbp.model.JBBPFieldArrayLong; import com.igormaznitsa.jbbp.model.JBBPFieldArrayString; +import com.igormaznitsa.jbbp.model.JBBPFieldArrayStruct; import com.igormaznitsa.jbbp.model.JBBPFieldInt; import com.igormaznitsa.jbbp.model.JBBPFieldLong; import com.igormaznitsa.jbbp.model.JBBPFieldString; @@ -45,10 +50,12 @@ import java.io.EOFException; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Field; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import org.junit.jupiter.api.Test; @@ -415,4 +422,174 @@ public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in, final result = sasParser.parse(new byte[] {0, 0, 0, 2, 1, 2, 3, 4}); assertEquals(2, ((JBBPNumericField) result.findFieldForName("keycount")).getAsInt()); } + + /** + * Case 09-jun-2020 + * Example how to write custom field type read-write-mapping processor for nullable byte array. + * + * @throws Exception for any error + */ + @Test + public void testNullableByteArrayField() throws Exception { + class NullableByteArrayProcessor + implements JBBPCustomFieldWriter, JBBPMapperCustomFieldProcessor, + JBBPCustomFieldTypeProcessor { + + private final String TYPE = "nullableByteArray"; + private final String[] CUSTOM_TYPE = new String[] {TYPE.toLowerCase(Locale.ENGLISH)}; + + @Override + public String[] getCustomFieldTypes() { + return CUSTOM_TYPE; + } + + @Override + public boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, + int extraData, boolean isArray) { + return !isArray; + } + + private byte[] readFromStream(JBBPByteOrder byteOrder, JBBPBitInputStream in) + throws IOException { + final int len = in.readInt(byteOrder); + return len < 0 ? null : in.readByteArray(len); + } + + @Override + public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, + int parserFlags, + JBBPFieldTypeParameterContainer customTypeFieldInfo, + JBBPNamedFieldInfo fieldName, int extraData, + boolean readWholeStream, int arrayLength) + throws IOException { + if (arrayLength < 0) { + return toStruct(fieldName, readFromStream(customTypeFieldInfo.getByteOrder(), in)); + } else { + throw new IllegalArgumentException("Array of nullable byte arrays is unsupported"); + } + } + + private void writeTo(final JBBPBitOutputStream outStream, final JBBPByteOrder order, + final byte[] data) throws IOException { + if (data == null) { + outStream.writeInt(-1, order); + } else { + outStream.writeInt(data.length, order); + outStream.write(data); + } + } + + @Override + public void writeCustomField(JBBPOut context, JBBPBitOutputStream outStream, + Object instanceToSave, Field instanceCustomField, + Bin fieldAnnotation, Object value) throws IOException { + if (fieldAnnotation.customType().equals(TYPE)) { + writeTo(outStream, fieldAnnotation.byteOrder(), (byte[]) value); + } else { + throw new IllegalArgumentException( + "Unsupported custom type: " + fieldAnnotation.customType()); + } + } + + private JBBPFieldStruct toStruct(JBBPNamedFieldInfo fieldName, final byte[] array) { + if (array == null) { + return new JBBPFieldStruct(fieldName, new JBBPAbstractField[0]); + } else { + return new JBBPFieldStruct(fieldName, + new JBBPAbstractField[] {new JBBPFieldArrayByte(null, array)}); + } + } + + private byte[] fromStruct(final JBBPFieldStruct struct) { + final JBBPAbstractField[] fields = struct.getArray(); + return fields.length == 0 ? null : ((JBBPFieldArrayByte) struct.getArray()[0]).getArray(); + } + + @Override + public Object prepareObjectForMapping(JBBPFieldStruct parsedBlock, + Bin annotation, + Field field) { + if (annotation.customType().equals(TYPE)) { + if (field.getType() == byte[][].class) { + final JBBPFieldArrayStruct structs = + parsedBlock.findFieldForNameAndType(field.getName(), JBBPFieldArrayStruct.class); + final byte[][] result = new byte[structs.size()][]; + for (int i = 0; i < structs.size(); i++) { + result[i] = fromStruct(structs.getElementAt(i)); + } + return result; + } else { + return fromStruct( + parsedBlock.findFieldForNameAndType(field.getName(), JBBPFieldStruct.class)); + } + } else { + throw new IllegalArgumentException("Unexpected custom type: " + annotation.customType()); + } + } + } + ; + + final NullableByteArrayProcessor nullableByteArrayProcessor = new NullableByteArrayProcessor(); + + class Klazz { + @Bin + int a; + @Bin(custom = true, customType = "nullableByteArray") + byte[] b; + @Bin + int c; + } + ; + + Klazz object = new Klazz(); + object.a = 12345; + object.b = null; + object.c = 7890; + + final byte[] withNullField = + JBBPOut.BeginBin().Bin(object, nullableByteArrayProcessor).End().toByteArray(); + + assertArrayEquals( + new byte[] {0, 0, 48, 57, (byte) -1, (byte) -1, (byte) -1, (byte) -1, 0, 0, 30, (byte) -46}, + withNullField); + + object = new Klazz(); + object.a = 12345; + object.b = new byte[] {1, 2, 3}; + object.c = 7890; + + final byte[] withContent = + JBBPOut.BeginBin().Bin(object, nullableByteArrayProcessor).End().toByteArray(); + assertArrayEquals(new byte[] {0, 0, 48, 57, 0, 0, 0, 3, 1, 2, 3, 0, 0, 30, (byte) -46}, + withContent); + + object = new Klazz(); + object.a = 12345; + object.b = new byte[0]; + object.c = 7890; + + final byte[] withZeroLength = + JBBPOut.BeginBin().Bin(object, nullableByteArrayProcessor).End().toByteArray(); + assertArrayEquals(new byte[] {0, 0, 48, 57, 0, 0, 0, 0, 0, 0, 30, (byte) -46}, withZeroLength); + + JBBPParser parser = + JBBPParser.prepare("int a; nullableByteArray b; int c;", nullableByteArrayProcessor); + + Klazz parsed = parser.parse(withNullField).mapTo(new Klazz(), nullableByteArrayProcessor); + + assertEquals(12345, parsed.a); + assertNull(parsed.b); + assertEquals(7890, parsed.c); + + parsed = parser.parse(withZeroLength).mapTo(new Klazz(), nullableByteArrayProcessor); + assertEquals(12345, parsed.a); + assertArrayEquals(new byte[0], parsed.b); + assertEquals(7890, parsed.c); + + parsed = parser.parse(withContent).mapTo(new Klazz(), nullableByteArrayProcessor); + assertEquals(12345, parsed.a); + assertArrayEquals(new byte[] {1, 2, 3}, parsed.b); + assertEquals(7890, parsed.c); + } + } From dac16715b522619ba04a1f4054ccd4fc9c27cae6 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Sun, 26 Jul 2020 15:44:41 +0300 Subject: [PATCH 007/131] added workaround for javadoc release build known Java 11 bug --- jbbp/pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jbbp/pom.xml b/jbbp/pom.xml index 5f1ade2c..66678a0a 100644 --- a/jbbp/pom.xml +++ b/jbbp/pom.xml @@ -158,6 +158,7 @@ org.apache.maven.plugins maven-javadoc-plugin + false true protected UTF-8 @@ -170,7 +171,7 @@ jar - 1.8 + 8 From 7265046a1f47beb6831f4f070d279465021a4d73 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Sun, 26 Jul 2020 15:45:42 +0300 Subject: [PATCH 008/131] added one more test --- .../jbbp/it/BasedOnQuestionsAndCasesTest.java | 120 ++++++++++++++---- 1 file changed, 96 insertions(+), 24 deletions(-) diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java index 882d29d5..fb9b6a2d 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java @@ -22,7 +22,10 @@ import com.igormaznitsa.jbbp.JBBPCustomFieldTypeProcessor; +import com.igormaznitsa.jbbp.JBBPExternalValueProvider; +import com.igormaznitsa.jbbp.JBBPNamedNumericFieldMap; import com.igormaznitsa.jbbp.JBBPParser; +import com.igormaznitsa.jbbp.compiler.JBBPCompiledBlock; import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import com.igormaznitsa.jbbp.compiler.tokenizer.JBBPFieldTypeParameterContainer; import com.igormaznitsa.jbbp.io.JBBPBitInputStream; @@ -85,13 +88,16 @@ class YearMonthDay { @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()); + 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()); + assertArrayEquals(new byte[] {(byte) 0x3D, (byte) 0xF8}, + JBBPOut.BeginBin(JBBPBitOrder.MSB0).Bin(parsed).End().toByteArray()); } /** @@ -122,14 +128,17 @@ class TetraTimestamp { } - 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()); + 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()); + assertArrayEquals(TEST_DATA, + JBBPOut.BeginBin(JBBPBitOrder.MSB0).Bin(parsed).End().toByteArray()); } /** @@ -200,9 +209,13 @@ public void testMutlithredUsageOfParser() throws Exception { for (int i = 0; i < ITERATIONS; i++) { try { Thread.sleep(System.nanoTime() & 0xF); - final byte[] ippacket = parserTCP.parse(theData).findFieldForNameAndType("Data", JBBPFieldArrayByte.class).getArray(); + final byte[] ippacket = + parserTCP.parse(theData).findFieldForNameAndType("Data", JBBPFieldArrayByte.class) + .getArray(); assertEquals(119, ippacket.length); - final byte[] optionsip = parserIP.parse(ippacket).findFieldForNameAndType("Options", JBBPFieldArrayByte.class).getArray(); + final byte[] optionsip = + parserIP.parse(ippacket).findFieldForNameAndType("Options", JBBPFieldArrayByte.class) + .getArray(); assertEquals(4, optionsip.length); parsingCounter.incrementAndGet(); } catch (Exception ex) { @@ -236,7 +249,8 @@ class Bits { byte[] bit; } - JBBPParser parser = JBBPParser.prepare(JBBPDslBuilder.Begin().AnnotatedClassFields(Bits.class).End()); + JBBPParser parser = + JBBPParser.prepare(JBBPDslBuilder.Begin().AnnotatedClassFields(Bits.class).End()); Bits parsed = parser.parse(new byte[] {73}).mapTo(new Bits()); @@ -253,11 +267,14 @@ class Bits { */ @Test public void testStringMsb0() throws Exception { - JBBPOut joparam = JBBPOut.BeginBin(JBBPByteOrder.BIG_ENDIAN, JBBPBitOrder.MSB0).String("zzzz").Int(12345); + JBBPOut joparam = + JBBPOut.BeginBin(JBBPByteOrder.BIG_ENDIAN, JBBPBitOrder.MSB0).String("zzzz").Int(12345); final byte[] array = joparam.End().toByteArray(); assertArrayEquals(new byte[] {32, 94, 94, 94, 94, 0, 0, 0x0C, (byte) 0x9C}, array); - final JBBPFieldStruct bitflds = JBBPParser.prepare("stringj fin; int i;", JBBPBitOrder.MSB0).parse(array); - assertEquals("zzzz", bitflds.findFieldForNameAndType("fin", JBBPFieldString.class).getAsString()); + final JBBPFieldStruct bitflds = + JBBPParser.prepare("stringj fin; int i;", JBBPBitOrder.MSB0).parse(array); + assertEquals("zzzz", + bitflds.findFieldForNameAndType("fin", JBBPFieldString.class).getAsString()); assertEquals(12345, bitflds.findFieldForNameAndType("i", JBBPFieldInt.class).getAsInt()); } @@ -324,15 +341,22 @@ private String readPascalAscIIString(final JBBPBitInputStream in) throws IOExcep } } - final JBBPParser parserSingle = JBBPParser.prepare("asciistr str1; asciistr str2;", new AscIIPascalString()); + final JBBPParser parserSingle = + JBBPParser.prepare("asciistr str1; asciistr str2;", new AscIIPascalString()); final JBBPFieldStruct parsedSingle = parserSingle.parse(new byte[] {5, 65, 66, 67, 68, 69, 0}); - assertEquals("ABCDE", parsedSingle.findFieldForNameAndType("str1", JBBPFieldString.class).getAsString()); - assertEquals("", parsedSingle.findFieldForNameAndType("str2", JBBPFieldString.class).getAsString()); - - final JBBPParser parserArray = JBBPParser.prepare("asciistr [2] str1; asciistr [_] str2;", new AscIIPascalString()); - final JBBPFieldStruct parsedArrays = parserArray.parse(new byte[] {2, 65, 66, 1, 67, 3, 68, 69, 70, 2, 71, 72, 1, 73}); - assertArrayEquals(new String[] {"AB", "C"}, parsedArrays.findFieldForNameAndType("str1", JBBPFieldArrayString.class).getArray()); - assertArrayEquals(new String[] {"DEF", "GH", "I"}, parsedArrays.findFieldForNameAndType("str2", JBBPFieldArrayString.class).getArray()); + assertEquals("ABCDE", + parsedSingle.findFieldForNameAndType("str1", JBBPFieldString.class).getAsString()); + assertEquals("", + parsedSingle.findFieldForNameAndType("str2", JBBPFieldString.class).getAsString()); + + final JBBPParser parserArray = + JBBPParser.prepare("asciistr [2] str1; asciistr [_] str2;", new AscIIPascalString()); + final JBBPFieldStruct parsedArrays = + parserArray.parse(new byte[] {2, 65, 66, 1, 67, 3, 68, 69, 70, 2, 71, 72, 1, 73}); + assertArrayEquals(new String[] {"AB", "C"}, + parsedArrays.findFieldForNameAndType("str1", JBBPFieldArrayString.class).getArray()); + assertArrayEquals(new String[] {"DEF", "GH", "I"}, + parsedArrays.findFieldForNameAndType("str2", JBBPFieldArrayString.class).getArray()); } /** @@ -349,7 +373,8 @@ final class Uint32 implements JBBPCustomFieldTypeProcessor { private final String[] TYPES = new String[] {"uint32"}; - private long uint32_read(final JBBPBitInputStream in, final JBBPByteOrder byteOrder, final JBBPBitOrder bitOrder) throws IOException { + private long uint32_read(final JBBPBitInputStream in, final JBBPByteOrder byteOrder, + final JBBPBitOrder bitOrder) throws IOException { final int signedInt = in.readInt(byteOrder); return signedInt & 0xffffffffL; } @@ -360,7 +385,8 @@ public String[] getCustomFieldTypes() { } @Override - public boolean isAllowed(final JBBPFieldTypeParameterContainer fieldType, final String fieldName, final int extraData, final boolean isArray) { + public boolean isAllowed(final JBBPFieldTypeParameterContainer fieldType, + final String fieldName, final int extraData, final boolean isArray) { return extraData == 0; } @@ -374,10 +400,14 @@ private long[] convertLongs(List longs) { } @Override - public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in, final JBBPBitOrder bitOrder, - final int parserFlags, final JBBPFieldTypeParameterContainer customTypeFieldInfo, - final JBBPNamedFieldInfo fieldName, final int extraData, - final boolean readWholeStream, final int arrayLength) throws IOException { + public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in, + final JBBPBitOrder bitOrder, + final int parserFlags, + final JBBPFieldTypeParameterContainer customTypeFieldInfo, + final JBBPNamedFieldInfo fieldName, + final int extraData, + final boolean readWholeStream, + final int arrayLength) throws IOException { if (arrayLength < 0) { final long uint32_val = uint32_read(in, customTypeFieldInfo.getByteOrder(), bitOrder); return new JBBPFieldLong(fieldName, uint32_val); @@ -423,6 +453,48 @@ public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in, final assertEquals(2, ((JBBPNumericField) result.findFieldForName("keycount")).getAsInt()); } + /** + * Case 09-jun-2020 + * Example how to use external variable value provider. + * + * @throws Exception for any error + */ + @Test + public void testByteArrayWhichLengthProvidedExternally() throws Exception { + class BKlazz { + @Bin(order = 1, type = BinType.BYTE_ARRAY) + byte[] a; + @Bin(order = 2, type = BinType.BYTE_ARRAY) + byte[] b; + @Bin(order = 3, type = BinType.BYTE_ARRAY) + byte[] c; + } + + JBBPParser parser = JBBPParser.prepare("byte [$alen] a; byte [$blen] b; byte [$clen] c;"); + + BKlazz parsed = parser.parse(new byte[] {1,2,3}, null, new JBBPExternalValueProvider() { + @Override + public int provideArraySize(String fieldName, + JBBPNamedNumericFieldMap numericFieldMap, + JBBPCompiledBlock compiledBlock) { + if ("alen".equals(fieldName)) { + return 0; + } else if ("blen".equals(fieldName)) { + return 3; + } else if ("clen".equals(fieldName)) { + return 0; + } else { + throw new IllegalArgumentException("Unknown name: " + fieldName); + } + + } + }).mapTo(new BKlazz()); + + assertArrayEquals(new byte[0], parsed.a); + assertArrayEquals(new byte[]{1,2,3}, parsed.b); + assertArrayEquals(new byte[0], parsed.c); + } + /** * Case 09-jun-2020 * Example how to write custom field type read-write-mapping processor for nullable byte array. From 178cc2be0066528752cccd7417588597c0b5809c Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Sat, 22 Aug 2020 15:03:26 +0300 Subject: [PATCH 009/131] maintenance release 2.0.2 --- README.md | 15 ++------------- jbbp-plugins/jbbp-gradle/pom.xml | 2 +- .../jbbp-maven/jbbp-maven-plugin-tests/pom.xml | 2 +- jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml | 2 +- jbbp-plugins/jbbp-maven/pom.xml | 2 +- jbbp-plugins/jbbp-plugin-common/pom.xml | 2 +- jbbp-plugins/pom.xml | 2 +- jbbp/pom.xml | 2 +- pom.xml | 4 ++-- 9 files changed, 11 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 5fe9032e..e203c585 100644 --- a/README.md +++ b/README.md @@ -12,24 +12,13 @@ Java has some embedded features to parse binary data (for instance ByteBuffer), ![Use cases](https://github.com/raydac/java-binary-block-parser/blob/master/docs/jbbp_mm.png) # Change log -- **2.0.2 (SNAPSHOT)** +- __2.0.2 (22-aug-2020)__ - added `JBBPOut#Bin` variant to override `@Bin` annotation fields in written objects. - [#28](https://github.com/raydac/java-binary-block-parser/issues/28) added `JBBPOut#BinForceByteOrder` to override byte order defined in `@Bin` annotations of written object. -- **2.0.1 (04-feb-2020)** +- __2.0.1 (04-feb-2020)__ - [#26](https://github.com/raydac/java-binary-block-parser/issues/26) fixed bug in array write with MSB0 -- **2.0.0 (20-nov-2019)** - - __removed DslBinCustom annotation, use @Bin annotation instead__ - - __renamed attributes of @Bin annotation to their correct form__ - - __reworked object mapping system, removed hacks to instantiate classes, now only mapping to objects allowed, support of private fields mapping is removed__ - - __minimal JDK version now 1.8+__ - - __minimal Android API now 3.0+__ - - added support of getters and setters into mapping - - added `Object newInstance(Class)` method support of mapped classes to generate local class member instances - - added generating of `makeFIELD()` method for structure types in Java class converter - - refactoring - [Full changelog](https://github.com/raydac/java-binary-block-parser/blob/master/changelog.txt) # Maven dependency diff --git a/jbbp-plugins/jbbp-gradle/pom.xml b/jbbp-plugins/jbbp-gradle/pom.xml index 1544ef95..7b759eac 100644 --- a/jbbp-plugins/jbbp-gradle/pom.xml +++ b/jbbp-plugins/jbbp-gradle/pom.xml @@ -6,7 +6,7 @@ com.igormaznitsa jbbp-main-plugin-pom - 2.0.2-SNAPSHOT + 2.0.2 jbbp-gradle-plugin diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml index bf1213be..c43bd23a 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-maven-plugin-pom - 2.0.2-SNAPSHOT + 2.0.2 jbbp-maven-plugin-tests diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml index 82a55537..247e5696 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-maven-plugin-pom - 2.0.2-SNAPSHOT + 2.0.2 jbbp-maven-plugin diff --git a/jbbp-plugins/jbbp-maven/pom.xml b/jbbp-plugins/jbbp-maven/pom.xml index ba435949..f5a04079 100644 --- a/jbbp-plugins/jbbp-maven/pom.xml +++ b/jbbp-plugins/jbbp-maven/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-main-plugin-pom - 2.0.2-SNAPSHOT + 2.0.2 jbbp-maven-plugin-pom diff --git a/jbbp-plugins/jbbp-plugin-common/pom.xml b/jbbp-plugins/jbbp-plugin-common/pom.xml index 418443fb..0e72018b 100644 --- a/jbbp-plugins/jbbp-plugin-common/pom.xml +++ b/jbbp-plugins/jbbp-plugin-common/pom.xml @@ -6,7 +6,7 @@ com.igormaznitsa jbbp-main-plugin-pom - 2.0.2-SNAPSHOT + 2.0.2 jbbp-plugin-common diff --git a/jbbp-plugins/pom.xml b/jbbp-plugins/pom.xml index c02ae88f..ee31c52a 100644 --- a/jbbp-plugins/pom.xml +++ b/jbbp-plugins/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-main-pom - 2.0.2-SNAPSHOT + 2.0.2 jbbp-main-plugin-pom diff --git a/jbbp/pom.xml b/jbbp/pom.xml index 66678a0a..fefd5ec7 100644 --- a/jbbp/pom.xml +++ b/jbbp/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-main-pom - 2.0.2-SNAPSHOT + 2.0.2 jbbp diff --git a/pom.xml b/pom.xml index 8ee08d85..803589b5 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.igormaznitsa jbbp-main-pom - 2.0.2-SNAPSHOT + 2.0.2 pom @@ -20,7 +20,7 @@ yyyyMMddHHmm 3.0 1.1.2 - 2.0.2-SNAPSHOT + 2.0.2 ${jbbp.version} 1.8 1.8 From 3679d378f92062cf2778909b3baeb8b77b3674e8 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Sat, 22 Aug 2020 16:05:20 +0300 Subject: [PATCH 010/131] updated --- README.md | 8 ++++---- changelog.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e203c585..945f5b36 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![License Apache 2.0](https://img.shields.io/badge/license-Apache%20License%202.0-green.svg)](http://www.apache.org/licenses/LICENSE-2.0) -[![Maven central](https://maven-badges.herokuapp.com/maven-central/com.igormaznitsa/jbbp/badge.svg)](http://search.maven.org/#artifactdetails|com.igormaznitsa|jbbp|2.0.1|jar) +[![Maven central](https://maven-badges.herokuapp.com/maven-central/com.igormaznitsa/jbbp/badge.svg)](http://search.maven.org/#artifactdetails|com.igormaznitsa|jbbp|2.0.2|jar) [![Java 1.8+](https://img.shields.io/badge/java-1.8%2b-green.svg)](http://www.oracle.com/technetwork/java/javase/downloads/index.html) [![Android 3.0+](https://img.shields.io/badge/android-3.0%2b-green.svg)](http://developer.android.com/sdk/index.html) [![PayPal donation](https://img.shields.io/badge/donation-PayPal-red.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=AHWJHJFBAWGL2) @@ -27,10 +27,10 @@ The Framework has been published in the Maven Central and can be easily added as com.igormaznitsa jbbp - 2.0.1 + 2.0.2 ``` -the precompiled library jar, javadoc and sources also can be downloaded directly from [the Maven central.](https://search.maven.org/artifact/com.igormaznitsa/jbbp/2.0.1/jar) +the precompiled library jar, javadoc and sources also can be downloaded directly from [the Maven central.](https://search.maven.org/artifact/com.igormaznitsa/jbbp/2.0.2/jar) # Hello world The library is very easy in use because in many cases only two its classes are needed - com.igormaznitsa.jbbp.JBBPParser (for data parsing) and com.igormaznitsa.jbbp.io.JBBPOut (for binary block writing). Both these classes work over low-level IO classes - com.igormaznitsa.jbbp.io.JBBPBitInputStream and com.igormaznitsa.jbbp.io.JBBPBitOutputStream, those bit stream classes are the core of the library. @@ -74,7 +74,7 @@ in Maven it can be used through snippet: com.igormaznitsa jbbp-maven-plugin - 2.0.1 + 2.0.2 gen-jbbp-src diff --git a/changelog.txt b/changelog.txt index 7c47ade9..41529851 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,4 @@ -2.0.2 (SNAPSHOT) +2.0.2 (22-aug-2020) - added `JBBPOut#Bin` variant to override `@Bin` annotation fields in written objects. - [#28](https://github.com/raydac/java-binary-block-parser/issues/28) added `JBBPOut#BinForceByteOrder` to override byte order defined in `@Bin` annotations of written object. From eaf8e27c0c5b8f13e13345e900b5543c405ff14f Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Mon, 24 Aug 2020 16:57:10 +0300 Subject: [PATCH 011/131] updated --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 945f5b36..2520f860 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +![JBBP Logo](https://github.com/raydac/java-binary-block-parser/blob/master/logo.png) + [![License Apache 2.0](https://img.shields.io/badge/license-Apache%20License%202.0-green.svg)](http://www.apache.org/licenses/LICENSE-2.0) [![Maven central](https://maven-badges.herokuapp.com/maven-central/com.igormaznitsa/jbbp/badge.svg)](http://search.maven.org/#artifactdetails|com.igormaznitsa|jbbp|2.0.2|jar) [![Java 1.8+](https://img.shields.io/badge/java-1.8%2b-green.svg)](http://www.oracle.com/technetwork/java/javase/downloads/index.html) @@ -5,8 +7,6 @@ [![PayPal donation](https://img.shields.io/badge/donation-PayPal-red.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=AHWJHJFBAWGL2) [![Yandex.Money donation](https://img.shields.io/badge/donation-Я.деньги-yellow.svg)](http://yasobe.ru/na/iamoss) -![JBBP Logo](https://github.com/raydac/java-binary-block-parser/blob/master/logo.png) - # Introduction Java has some embedded features to parse binary data (for instance ByteBuffer), but sometime it is needed to work on bit level and describe binary structures through some DSL(domain specific language). I was impressed by the [the Python Struct package](https://docs.python.org/2/library/struct.html) package and wanted to get something like that for Java. So I developed the JBBP library.
![Use cases](https://github.com/raydac/java-binary-block-parser/blob/master/docs/jbbp_mm.png) From 5b0d788f06dd547529e2f7953d180c1197541df0 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Wed, 14 Oct 2020 20:28:55 +0300 Subject: [PATCH 012/131] started 2.0.3-SNAPSHOT --- jbbp-plugins/jbbp-gradle/build.gradle | 2 +- jbbp-plugins/jbbp-gradle/pom.xml | 2 +- jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml | 2 +- jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml | 2 +- .../resources/com/igormaznitsa/jbbp/plugin/mvn/mojoConfig.xml | 2 +- jbbp-plugins/jbbp-maven/pom.xml | 2 +- jbbp-plugins/jbbp-plugin-common/pom.xml | 2 +- jbbp-plugins/pom.xml | 2 +- jbbp/pom.xml | 2 +- pom.xml | 4 ++-- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/jbbp-plugins/jbbp-gradle/build.gradle b/jbbp-plugins/jbbp-gradle/build.gradle index 561aeb4b..e5660133 100644 --- a/jbbp-plugins/jbbp-gradle/build.gradle +++ b/jbbp-plugins/jbbp-gradle/build.gradle @@ -7,7 +7,7 @@ def getProp(name, dflt) { } } -def jbbpVersion = getProp('jbbp_plugin_version', '2.0.1') +def jbbpVersion = getProp('jbbp_plugin_version', '2.0.3-SNAPSHOT') def metaLibVersion = getProp('meta_lib_version', '1.1.2') group = 'com.igormaznitsa' diff --git a/jbbp-plugins/jbbp-gradle/pom.xml b/jbbp-plugins/jbbp-gradle/pom.xml index 7b759eac..3731cce9 100644 --- a/jbbp-plugins/jbbp-gradle/pom.xml +++ b/jbbp-plugins/jbbp-gradle/pom.xml @@ -6,7 +6,7 @@ com.igormaznitsa jbbp-main-plugin-pom - 2.0.2 + 2.0.3-SNAPSHOT jbbp-gradle-plugin diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml index c43bd23a..c1b9cbab 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-maven-plugin-pom - 2.0.2 + 2.0.3-SNAPSHOT jbbp-maven-plugin-tests diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml index 247e5696..e954254b 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-maven-plugin-pom - 2.0.2 + 2.0.3-SNAPSHOT jbbp-maven-plugin diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/resources/com/igormaznitsa/jbbp/plugin/mvn/mojoConfig.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/resources/com/igormaznitsa/jbbp/plugin/mvn/mojoConfig.xml index 32c8b2f2..fb78faf8 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/resources/com/igormaznitsa/jbbp/plugin/mvn/mojoConfig.xml +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/resources/com/igormaznitsa/jbbp/plugin/mvn/mojoConfig.xml @@ -14,7 +14,7 @@ com.igormaznitsa jbbp-maven-plugin - 2.0.2-SNAPSHOT + 2.0.3-SNAPSHOT generate diff --git a/jbbp-plugins/jbbp-maven/pom.xml b/jbbp-plugins/jbbp-maven/pom.xml index f5a04079..f3526b26 100644 --- a/jbbp-plugins/jbbp-maven/pom.xml +++ b/jbbp-plugins/jbbp-maven/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-main-plugin-pom - 2.0.2 + 2.0.3-SNAPSHOT jbbp-maven-plugin-pom diff --git a/jbbp-plugins/jbbp-plugin-common/pom.xml b/jbbp-plugins/jbbp-plugin-common/pom.xml index 0e72018b..67381430 100644 --- a/jbbp-plugins/jbbp-plugin-common/pom.xml +++ b/jbbp-plugins/jbbp-plugin-common/pom.xml @@ -6,7 +6,7 @@ com.igormaznitsa jbbp-main-plugin-pom - 2.0.2 + 2.0.3-SNAPSHOT jbbp-plugin-common diff --git a/jbbp-plugins/pom.xml b/jbbp-plugins/pom.xml index ee31c52a..726ddf92 100644 --- a/jbbp-plugins/pom.xml +++ b/jbbp-plugins/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-main-pom - 2.0.2 + 2.0.3-SNAPSHOT jbbp-main-plugin-pom diff --git a/jbbp/pom.xml b/jbbp/pom.xml index fefd5ec7..19b907f8 100644 --- a/jbbp/pom.xml +++ b/jbbp/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-main-pom - 2.0.2 + 2.0.3-SNAPSHOT jbbp diff --git a/pom.xml b/pom.xml index 803589b5..e6a71f45 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.igormaznitsa jbbp-main-pom - 2.0.2 + 2.0.3-SNAPSHOT pom @@ -20,7 +20,7 @@ yyyyMMddHHmm 3.0 1.1.2 - 2.0.2 + 2.0.3-SNAPSHOT ${jbbp.version} 1.8 1.8 From ee6d620d5ce3bf9c78277703663487087ffcced3 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Thu, 10 Dec 2020 12:08:55 +0200 Subject: [PATCH 013/131] updated junit version to 4.13.1 --- jbbp-plugins/jbbp-gradle/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jbbp-plugins/jbbp-gradle/build.gradle b/jbbp-plugins/jbbp-gradle/build.gradle index e5660133..75355079 100644 --- a/jbbp-plugins/jbbp-gradle/build.gradle +++ b/jbbp-plugins/jbbp-gradle/build.gradle @@ -29,7 +29,7 @@ dependencies { compile "com.igormaznitsa:meta-annotations:" + metaLibVersion compile "com.igormaznitsa:meta-utils:" + metaLibVersion - testCompile 'junit:junit:4.12' + testCompile 'junit:junit:4.13.1' } repositories { From 43b01abdc86f156a13fc2da3f9116fee5344b3fc Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Thu, 10 Dec 2020 12:47:36 +0200 Subject: [PATCH 014/131] #30 improved JBBPTokenizerException to show error position as marked one --- .../compiler/tokenizer/JBBPTokenizer.java | 57 ++++++++---- .../exceptions/JBBPTokenizerException.java | 90 ++++++++++++++++++- .../compiler/tokenizer/JBBPTokenizerTest.java | 54 +++++++++-- .../JBBPTokenizerExceptionTest.java | 43 +++++++++ 4 files changed, 214 insertions(+), 30 deletions(-) create mode 100644 jbbp/src/test/java/com/igormaznitsa/jbbp/exceptions/JBBPTokenizerExceptionTest.java diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPTokenizer.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPTokenizer.java index 126f9944..887c9c39 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPTokenizer.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPTokenizer.java @@ -23,7 +23,6 @@ import com.igormaznitsa.jbbp.model.JBBPFieldFloat; import com.igormaznitsa.jbbp.model.JBBPFieldString; import com.igormaznitsa.jbbp.utils.JBBPUtils; - import java.util.HashSet; import java.util.Iterator; import java.util.NoSuchElementException; @@ -44,11 +43,14 @@ public final class JBBPTokenizer implements Iterable, IteratorWARNING! DO NOT UNESCAPE '}' AND '{' CHARS BECAUSE IT MAKES INCOMPATIBILITY WITH ANDROID! */ - private static final Pattern PATTERN = Pattern.compile("\\s*//.*$|\\s*(\\})|\\s*([^\\s;\\[\\]\\}\\{]+)?\\s*(?:\\[\\s*([^\\[\\]\\{\\};]+)\\s*\\])?\\s*([^\\d\\s;\\[\\]\\}\\{/][^\\s;\\[\\]\\}\\{/]*)?\\s*([\\{;])", Pattern.MULTILINE); + private static final Pattern PATTERN = Pattern.compile( + "\\s*//.*$|\\s*(\\})|\\s*([^\\s;\\[\\]\\}\\{]+)?\\s*(?:\\[\\s*([^\\[\\]\\{\\};]+)\\s*\\])?\\s*([^\\d\\s;\\[\\]\\}\\{/][^\\s;\\[\\]\\}\\{/]*)?\\s*([\\{;])", + Pattern.MULTILINE); /** * The Pattern to break field type to parameters. */ - private static final Pattern FIELD_TYPE_BREAK_PATTERN = Pattern.compile("^([<>])?([\\w][\\w$]*)(?::((?:[-]?\\d+)|(?:\\(.+\\))))?$"); + private static final Pattern FIELD_TYPE_BREAK_PATTERN = + Pattern.compile("^([<>])?([\\w][\\w$]*)(?::((?:[-]?\\d+)|(?:\\(.+\\))))?$"); /** * Inside table to keep disabled names for fields. */ @@ -102,7 +104,8 @@ public JBBPTokenizer(final String str) { * @param str a string to be parsed, must not be null. * @param customFieldTypeProcessor custom field type processor, it can be null */ - public JBBPTokenizer(final String str, final JBBPCustomFieldTypeProcessor customFieldTypeProcessor) { + public JBBPTokenizer(final String str, + final JBBPCustomFieldTypeProcessor customFieldTypeProcessor) { JBBPUtils.assertNotNull(str, "String must not be null"); if (customFieldTypeProcessor == null) { @@ -145,9 +148,12 @@ private void readNextItem() { final String groupName = this.matcher.group(4); final String groupEnder = this.matcher.group(5); - final String skipString = this.processingString.substring(Math.max(this.lastCharSubstringFound, 0), matcher.start()).trim(); + final String skipString = + this.processingString.substring(Math.max(this.lastCharSubstringFound, 0), matcher.start()) + .trim(); if (skipString.length() != 0 && !skipString.startsWith("//")) { - this.detectedException = new JBBPTokenizerException(skipString, Math.max(this.lastCharSubstringFound, 0)); + this.detectedException = + new JBBPTokenizerException(skipString, this.processingString, Math.max(this.lastCharSubstringFound, 0)); } else { JBBPTokenType type = JBBPTokenType.ATOM; @@ -157,15 +163,21 @@ private void readNextItem() { // { type = JBBPTokenType.STRUCT_START; if (groupName != null) { - final int position = matcher.start() + groupWholeFound.length() - groupWholeFoundTrimmed.length(); - this.detectedException = new JBBPTokenizerException("Wrong structure format, it must have only name (and may be array definition)", position); + final int position = + matcher.start() + groupWholeFound.length() - groupWholeFoundTrimmed.length(); + this.detectedException = new JBBPTokenizerException( + "Wrong structure format, it must have only name (and may be array definition)", + this.processingString, + position); return; } } else if (groupCloseStruct != null) { type = JBBPTokenType.STRUCT_END; } else if (groupTypeOrName == null) { - final int position = matcher.start() + groupWholeFound.length() - groupWholeFoundTrimmed.length(); - this.detectedException = new JBBPTokenizerException("Detected atomic field definition without type", position); + final int position = + matcher.start() + groupWholeFound.length() - groupWholeFoundTrimmed.length(); + this.detectedException = + new JBBPTokenizerException("Detected atomic field definition without type", this.processingString, position); return; } @@ -213,17 +225,23 @@ private void readNextItem() { } else if ("<".equals(groupTypeByteOrder)) { byteOrder = JBBPByteOrder.LITTLE_ENDIAN; } else { - throw new Error("Illegal byte order char, unexpected error, contact developer please [" + fieldType + ']'); + throw new Error( + "Illegal byte order char, unexpected error, contact developer please [" + + fieldType + ']'); } } else { byteOrder = JBBPByteOrder.BIG_ENDIAN; } - parsedType = new JBBPFieldTypeParameterContainer(byteOrder, groupTypeName, groupTypeExtraField); + parsedType = + new JBBPFieldTypeParameterContainer(byteOrder, groupTypeName, groupTypeExtraField); } if (wrongFormat) { - this.detectedException = new JBBPTokenizerException("Wrong format of type definition [" + fieldType + ']', position); + this.detectedException = + new JBBPTokenizerException("Wrong format of type definition [" + fieldType + ']', + this.processingString, + position); return; } } @@ -233,11 +251,14 @@ private void readNextItem() { } } else { if (this.lastCharSubstringFound < 0) { - this.detectedException = new JBBPTokenizerException("Wrong format of whole string", 0); + this.detectedException = new JBBPTokenizerException("Wrong format of whole string", this.processingString, 0); } else { final String restOfString = this.processingString.substring(this.lastCharSubstringFound); if (restOfString.trim().length() != 0) { - throw new JBBPTokenizerException("Can't recognize a part of script [" + restOfString + ']', this.lastCharSubstringFound); + throw new JBBPTokenizerException( + "Can't recognize a part of script [" + restOfString + ']', + this.processingString, + this.lastCharSubstringFound); } } this.nextItem = null; @@ -256,7 +277,7 @@ private JBBPTokenizerException checkFieldName(final String name, final int posit if (name != null) { final String normalized = JBBPUtils.normalizeFieldNameOrPath(name); if (normalized.indexOf('.') >= 0) { - return new JBBPTokenizerException("Field name must not contain '.' char", position); + return new JBBPTokenizerException("Field name must not contain '.' char", this.processingString, position); } if (normalized.length() > 0) { @@ -265,13 +286,13 @@ private JBBPTokenizerException checkFieldName(final String name, final int posit || normalized.startsWith("$") || Character.isDigit(normalized.charAt(0)) ) { - return new JBBPTokenizerException("'" + name + "' can't be field name", position); + return new JBBPTokenizerException("'" + name + "' can't be field name", this.processingString, position); } for (int i = 1; i < normalized.length(); i++) { final char chr = normalized.charAt(i); if (chr != '_' && !Character.isLetterOrDigit(chr)) { - return new JBBPTokenizerException("Char '" + chr + "' not allowed in name", position); + return new JBBPTokenizerException("Char '" + chr + "' not allowed in name", this.processingString, position); } } } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/exceptions/JBBPTokenizerException.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/exceptions/JBBPTokenizerException.java index 74a5c0bf..fe6d1049 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/exceptions/JBBPTokenizerException.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/exceptions/JBBPTokenizerException.java @@ -17,29 +17,45 @@ package com.igormaznitsa.jbbp.exceptions; /** - * The Exception can be thrown during parsing sources for tokens and allows to figure out the position of the problematic token. + * The Exception can be thrown during parsing sources for tokens and allows to figure + * out the position of the problematic token. * * @since 1.0 */ public class JBBPTokenizerException extends JBBPCompilationException { - private static final long serialVersionUID = -1132154077305894146L; + private static final long serialVersionUID = -1132154077305893246L; /** * The Token position. */ private final int position; + private final String errorPart; + /** - * The Constructor. + * Constructor. * * @param message the exception message. + * @param script the script contains error, can be null * @param pos the position of a problematic token inside sources. + * @since 2.0.3 */ - public JBBPTokenizerException(final String message, final int pos) { + public JBBPTokenizerException(final String message, final String script, final int pos) { super(message); + this.errorPart = script == null ? "" : extractErrorPartText(script, pos); this.position = pos; } + /** + * Get error part of script where error position marked by !>..= script.length() || errorPosition < 0) { + return ""; + } + final int maxLengthWing = 16; + final StringBuilder buffer = new StringBuilder(); + buffer.append(script.charAt(errorPosition)); + int errorPositionAtBuffer = 0; + int leftPosition = errorPosition - 1; + int rightPosition = errorPosition + 1; + int leftNonSpaceCounter = 0; + int rightNonSpaceCounter = 0; + for (int i = 0; i < maxLengthWing; i++) { + if (leftPosition >= 0) { + final char chr = script.charAt(leftPosition); + if (Character.isISOControl(chr) + || (i > 2 && leftNonSpaceCounter > 0 && Character.isSpaceChar(chr))) { + leftPosition = -1; + } else { + buffer.insert(0, chr); + leftNonSpaceCounter += Character.isSpaceChar(chr) ? 1 : 0; + errorPositionAtBuffer++; + leftPosition--; + } + } + if (rightPosition >= 0 && rightPosition < script.length()) { + final char chr = script.charAt(rightPosition); + if (Character.isISOControl(chr) + || (i > 2 && rightNonSpaceCounter > 0 && Character.isSpaceChar(chr))) { + rightPosition = -1; + } else { + buffer.append(chr); + rightNonSpaceCounter += Character.isSpaceChar(chr) ? 1 : 0; + rightPosition++; + } + } + } + final String errorMarkerLeft = " ->"; + final String errorMarkerRight = "<- "; + buffer.insert(errorPositionAtBuffer + 1, errorMarkerRight); + buffer.insert(errorPositionAtBuffer, errorMarkerLeft); + errorPositionAtBuffer += errorMarkerLeft.length(); + + if (Character.isISOControl(buffer.charAt(errorPositionAtBuffer))) { + String hex = Integer.toHexString(buffer.charAt(errorPositionAtBuffer)); + hex = "\\u" + "0000".substring(hex.length()) + hex; + + buffer.delete(errorPositionAtBuffer, errorPositionAtBuffer + 1); + buffer.insert(errorPositionAtBuffer, hex); + } + return buffer.toString().trim(); + } + + @Override + public String toString() { + return this.getLocalizedMessage() + " (pos=" + this.position + ", errorPart=\"" + this.errorPart + "\")"; + } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPTokenizerTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPTokenizerTest.java index 115638f7..f5f98354 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPTokenizerTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPTokenizerTest.java @@ -16,14 +16,20 @@ package com.igormaznitsa.jbbp.compiler.tokenizer; -import com.igormaznitsa.jbbp.exceptions.JBBPTokenizerException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.function.Executable; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import com.igormaznitsa.jbbp.JBBPParser; +import com.igormaznitsa.jbbp.exceptions.JBBPTokenizerException; import java.util.Iterator; import java.util.NoSuchElementException; - -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class JBBPTokenizerTest { @@ -57,6 +63,7 @@ public void testError_ForArrayFieldWithoutType() { fail("Must throw Tokenizer exception"); } catch (JBBPTokenizerException ex) { assertEquals(1, ex.getPosition()); + assertEquals("->[<- 123] hello;", ex.getErrorPart()); } } @@ -72,6 +79,7 @@ public void testStructureEndAndErrorForArrayFieldWithoutType() { fail("Must throw Tokenizer exception"); } catch (JBBPTokenizerException ex) { assertEquals(2, ex.getPosition()); + assertEquals("} ->[<- 123] hello;", ex.getErrorPart()); } } @@ -128,6 +136,7 @@ public void testSingleLine_ErrorForUnsupportedText() { fail("Must throw parser exception"); } catch (JBBPTokenizerException ex) { assertEquals(0, ex.getPosition()); + assertEquals("-> <- some", ex.getErrorPart()); } } @@ -222,6 +231,7 @@ public void testError_ForWrongByteOrderFormatChar() { fail("Must throw parser exception for wrong symbol of byte order"); } catch (JBBPTokenizerException ex) { assertEquals(3, ex.getPosition()); + assertEquals("->!<- int hello;", ex.getErrorPart()); } } @@ -240,6 +250,7 @@ public void testStructure_Named_Start_ErrorForDisabledCharAtName() { fail("Must throw parser exception for disabled dot char at name"); } catch (JBBPTokenizerException ex) { assertEquals(3, ex.getPosition()); + assertEquals("->s<- truct.a {", ex.getErrorPart()); } } @@ -253,6 +264,7 @@ public void testRegularField_ErrorForDisabledCharAtName() { fail("Must throw parser exception for disabled dot char at name"); } catch (JBBPTokenizerException ex) { assertEquals(3, ex.getPosition()); + assertEquals("->i<- nt.a;", ex.getErrorPart()); } } @@ -266,6 +278,7 @@ public void testStructure_Named_Start_ErrorForDollarAsTheFirstChar() { fail("Must throw parser exception for disabled dot char at name"); } catch (JBBPTokenizerException ex) { assertEquals(3, ex.getPosition()); + assertEquals("->$<- struct {", ex.getErrorPart()); } } @@ -279,6 +292,7 @@ public void testRegularField_Name_ErrorForDollarAsTheFirstChar() { fail("Must throw parser exception for disabled dot char at name"); } catch (JBBPTokenizerException ex) { assertEquals(3, ex.getPosition()); + assertEquals("->$<- int;", ex.getErrorPart()); } } @@ -361,6 +375,7 @@ public void testStructure_Array_ErrorForWrongNameSizeOrder() { fail("Must throw parser exception"); } catch (JBBPTokenizerException ex) { assertEquals(2, ex.getPosition()); + assertEquals("->[<- 333] test", ex.getErrorPart()); } } @@ -398,6 +413,7 @@ public void testStructure_Array_ErrorForTypeDefinition() { fail("Must throw parser exception for wrong struct end definition"); } catch (JBBPTokenizerException ex) { assertEquals(0, ex.getPosition()); + assertEquals("-> <- int", ex.getErrorPart()); } } @@ -412,6 +428,7 @@ public void testStructure_ErrorForTypeDefinition() { fail("Must throw parser exception for wrong struct end definition"); } catch (JBBPTokenizerException ex) { assertEquals(4, ex.getPosition()); + assertEquals("->i<- nt struct{", ex.getErrorPart()); } } @@ -429,6 +446,7 @@ public void testErrorForNonRecognizedStringInMiddleOfText() { fail("Must throw exception"); } catch (JBBPTokenizerException ex) { assertEquals(8, ex.getPosition()); + assertEquals("test ->\\u000a<- wrong", ex.getErrorPart()); } } @@ -490,7 +508,9 @@ public void testParseScript_WithoutStructures() { } } - private void assertParsedItem(final JBBPToken item, final JBBPTokenType itemType, final String fieldType, final String length, final String fieldName) { + private void assertParsedItem(final JBBPToken item, final JBBPTokenType itemType, + final String fieldType, final String length, + final String fieldName) { assertNotNull(item); assertEquals(itemType, item.getType()); if (fieldType == null) { @@ -521,12 +541,30 @@ public void testParse_Field_Nonamed_Align() { @Test public void testParse_StructureArrayStartWithComplexExpressionAsSize() { - final JBBPTokenizer parser = new JBBPTokenizer("ColorMap [ (Header.ColorMapType & 1) * Header.CMapLength] {"); + final JBBPTokenizer parser = + new JBBPTokenizer("ColorMap [ (Header.ColorMapType & 1) * Header.CMapLength] {"); final Iterator iterator = parser.iterator(); - assertParsedItem(iterator.next(), JBBPTokenType.STRUCT_START, null, "(Header.ColorMapType & 1) * Header.CMapLength", "ColorMap"); + assertParsedItem(iterator.next(), JBBPTokenType.STRUCT_START, null, + "(Header.ColorMapType & 1) * Header.CMapLength", "ColorMap"); assertFalse(iterator.hasNext()); } + @Test + public void testParse_wrongEndOfStruct() { + try { + JBBPParser.prepare( + "byte[5] blob5; " + + "accountFlags {" + + " byte[32] address; " + + "}; " + + "byte[7] blob7;" + ); + } catch (JBBPTokenizerException ex) { + assertEquals(49, ex.getPosition()); + assertEquals("address; } ->;<- byte[7]", ex.getErrorPart()); + } + } + @Test public void testParse_VarFieldArrayWithNegativeExtra() { final JBBPTokenizer parser = new JBBPTokenizer("var:-123 [size] name;"); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/exceptions/JBBPTokenizerExceptionTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/exceptions/JBBPTokenizerExceptionTest.java new file mode 100644 index 00000000..3b6c3077 --- /dev/null +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/exceptions/JBBPTokenizerExceptionTest.java @@ -0,0 +1,43 @@ +package com.igormaznitsa.jbbp.exceptions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + + +import org.junit.jupiter.api.Test; + +class JBBPTokenizerExceptionTest { + @Test + public void testNullAsArg() { + assertEquals("null (pos=0, errorPart=\"\")", + new JBBPTokenizerException(null, null, 0).toString()); + assertEquals(" (pos=0, errorPart=\"\")", new JBBPTokenizerException("", null, 0).toString()); + assertEquals("null (pos=0, errorPart=\"\")", + new JBBPTokenizerException(null, "", 0).toString()); + assertEquals("null (pos=5, errorPart=\"\")", + new JBBPTokenizerException(null, null, 5).toString()); + assertEquals(" (pos=5, errorPart=\"\")", new JBBPTokenizerException("", null, 5).toString()); + assertEquals("null (pos=5, errorPart=\"\")", + new JBBPTokenizerException(null, "", 5).toString()); + assertEquals("null (pos=-5, errorPart=\"\")", + new JBBPTokenizerException(null, null, -5).toString()); + assertEquals(" (pos=-5, errorPart=\"\")", new JBBPTokenizerException("", null, -5).toString()); + assertEquals("null (pos=-5, errorPart=\"\")", + new JBBPTokenizerException(null, "", -5).toString()); + } + + @Test + public void testWrongErrorPos() { + assertEquals("hello (pos=23, errorPart=\"\")", + new JBBPTokenizerException("hello", "world", 23).toString()); + assertEquals("hello (pos=-1, errorPart=\"\")", + new JBBPTokenizerException("hello", "world", -1).toString()); + } + + @Test + public void testCornerPositions() { + assertEquals("hello (pos=0, errorPart=\"->w<- orld\")", + new JBBPTokenizerException("hello", "world", 0).toString()); + assertEquals("hello (pos=4, errorPart=\"worl ->d<-\")", + new JBBPTokenizerException("hello", "world", 4).toString()); + } +} \ No newline at end of file From 4157867f46af10b3862e845d1e22084a9a1a11c8 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Thu, 10 Dec 2020 20:02:32 +0200 Subject: [PATCH 015/131] added JBBPUtils.traceData auxiliary methods --- .../igormaznitsa/jbbp/utils/JBBPUtils.java | 149 ++++++++++++++++-- .../jbbp/utils/JBBPUtilsTest.java | 145 ++++++++++++----- 2 files changed, 246 insertions(+), 48 deletions(-) diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPUtils.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPUtils.java index 47719ca1..eebd209c 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPUtils.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPUtils.java @@ -23,6 +23,8 @@ import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.ArrayList; @@ -109,7 +111,8 @@ public static byte[] packInt(final int value) { } else if ((value & 0xFFFF0000) == 0) { return new byte[] {(byte) 0x80, (byte) (value >>> 8), (byte) value}; } else { - return new byte[] {(byte) 0x81, (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) value}; + return new byte[] {(byte) 0x81, (byte) (value >>> 24), (byte) (value >>> 16), + (byte) (value >>> 8), (byte) value}; } } @@ -159,7 +162,8 @@ public static int unpackInt(final byte[] array, final JBBPIntCounter position) { final int result; switch (code) { case 0x80: { - result = ((array[position.getAndIncrement()] & 0xFF) << 8) | (array[position.getAndIncrement()] & 0xFF); + result = ((array[position.getAndIncrement()] & 0xFF) << 8) | + (array[position.getAndIncrement()] & 0xFF); } break; case 0x81: { @@ -170,7 +174,8 @@ public static int unpackInt(final byte[] array, final JBBPIntCounter position) { } break; default: - throw new IllegalArgumentException("Unsupported packed integer prefix [0x" + Integer.toHexString(code).toUpperCase(Locale.ENGLISH) + ']'); + throw new IllegalArgumentException("Unsupported packed integer prefix [0x" + + Integer.toHexString(code).toUpperCase(Locale.ENGLISH) + ']'); } return result; } @@ -215,7 +220,9 @@ public static String array2oct(final byte[] array) { * @param radix the base for conversion * @return the string representation of the byte array */ - public static String byteArray2String(final byte[] array, final String prefix, final String delimiter, final boolean brackets, final int radix) { + public static String byteArray2String(final byte[] array, final String prefix, + final String delimiter, final boolean brackets, + final int radix) { if (array == null) { return null; } @@ -312,7 +319,8 @@ public static String bin2str(final byte[] values, final boolean separateBytes) { * @param separateBytes if true then bytes will be separated by spaces * @return the string representation of the array */ - public static String bin2str(final byte[] values, final JBBPBitOrder bitOrder, final boolean separateBytes) { + public static String bin2str(final byte[] values, final JBBPBitOrder bitOrder, + final boolean separateBytes) { if (values == null) { return null; } @@ -489,7 +497,8 @@ public static void assertNotNull(final Object object, final String message) { * @return a string with human readable hexadecimal number representation */ public static String int2msg(final int number) { - return number + " (0x" + Long.toHexString((long) number & 0xFFFFFFFFL).toUpperCase(Locale.ENGLISH) + ')'; + return number + " (0x" + + Long.toHexString((long) number & 0xFFFFFFFFL).toUpperCase(Locale.ENGLISH) + ')'; } /** @@ -586,7 +595,8 @@ public static byte[] reverseArray(final byte[] nullableArrayToBeInverted) { * the provided buffer is null or has not enough size * @since 1.1 */ - public static byte[] splitInteger(final int value, final boolean valueInLittleEndian, final byte[] buffer) { + public static byte[] splitInteger(final int value, final boolean valueInLittleEndian, + final byte[] buffer) { final byte[] result; if (buffer == null || buffer.length < 4) { result = new byte[4]; @@ -620,7 +630,8 @@ public static byte[] splitInteger(final int value, final boolean valueInLittleEn * the provided buffer is null or has not enough size * @since 1.1 */ - public static byte[] splitLong(final long value, final boolean valueInLittleEndian, final byte[] buffer) { + public static byte[] splitLong(final long value, final boolean valueInLittleEndian, + final byte[] buffer) { final byte[] result; if (buffer == null || buffer.length < 8) { result = new byte[8]; @@ -783,7 +794,8 @@ public static String ulong2str(final long ulongValue, final int radix, final cha if (ulongValue > 0) { result = Long.toString(ulongValue, radix).toUpperCase(Locale.ENGLISH); } else { - final char[] buffer = charBuffer == null || charBuffer.length < 64 ? new char[64] : charBuffer; + final char[] buffer = + charBuffer == null || charBuffer.length < 64 ? new char[64] : charBuffer; int pos = buffer.length; long topPart = ulongValue >>> 32; long bottomPart = (ulongValue & 0xFFFFFFFFL) + ((topPart % radix) << 32); @@ -812,7 +824,8 @@ public static String ulong2str(final long ulongValue, final int radix, final cha * text has equals or greater length. * @since 1.1 */ - public static String ensureMinTextLength(final String text, final int neededLen, final char ch, final int mode) { + public static String ensureMinTextLength(final String text, final int neededLen, final char ch, + final int mode) { final int number = neededLen - text.length(); if (number <= 0) { return text; @@ -972,8 +985,7 @@ public static int makeMask(final int value) { int msk = 1; do { msk <<= 1; - } - while (msk <= value); + } while (msk <= value); return msk - 1; } @@ -995,4 +1007,117 @@ public static boolean equals(final Object o1, final Object o2) { return o1.equals(o2); } + public static String toHexString(final long value, final int charsNum) { + String result = Long.toHexString(value).toUpperCase(Locale.ENGLISH); + if (charsNum >= result.length()) { + final StringBuilder buffer = new StringBuilder(charsNum); + for (int i = 0; i < charsNum - result.length(); i++) { + buffer.append('0'); + } + buffer.append(result); + result = buffer.toString(); + } + return result; + } + + /** + * Trace an input stream into a print writer. + * + * @param inStream input stream to be traced, must not be null + * @param out destination print stream, must not be null + * @throws IOException thrown if transport error + * @see #traceData(InputStream, int, String, String, String, String, char, boolean, PrintStream) + * @since 2.0.3 + */ + public static void traceData(final InputStream inStream, final PrintStream out) + throws IOException { + traceData( + inStream, + 4, + 8, + " ", + " ", + " | ", + " ", + '.', + true, + out + ); + } + + /** + * Trace an input stream into a print writer. + * + * @param inStream an input stream to be traced, must not be null + * @param valuesPerColumn number of value in one shown column + * @param columnsNumber number of eight byte columns + * @param afterAddressDelimiter string to be written after address section, must not be null + * @param interValueDelimiter string to be written after each value, must not be null + * @param interColumnDelimiter string to be written to show column, must not be null + * @param delimiterBeforeChars string to be written before chars section, must not be null + * @param nonPrintableChar char to be used for non-printable chars in chars section + * @param printAsChars true if char section is required, false otherwise + * @param out destination writer, must not be null + * @throws IOException thrown if any transport error + * @since 2.0.3 + */ + public static void traceData(final InputStream inStream, + int valuesPerColumn, + final int columnsNumber, + final String afterAddressDelimiter, + final String interValueDelimiter, + final String interColumnDelimiter, + final String delimiterBeforeChars, + final char nonPrintableChar, + final boolean printAsChars, + final PrintStream out) + throws IOException { + long address = 0L; + valuesPerColumn = valuesPerColumn <= 0 ? 1 : valuesPerColumn; + final int bytesPerLine = columnsNumber <= 0 ? 8 : columnsNumber * valuesPerColumn; + + final StringBuilder charBuffer = printAsChars ? new StringBuilder(bytesPerLine) : null; + + int lineByteCounter = 0; + + boolean ending = false; + + while (!Thread.currentThread().isInterrupted()) { + final int nextData; + if (ending) { + nextData = -1; + } else { + nextData = inStream.read(); + ending = nextData < 0; + } + + if (lineByteCounter == 0) { + out.print(toHexString(address, 8)); + out.print(afterAddressDelimiter); + } + if (charBuffer != null) { + charBuffer.append(nextData > 0x1F && nextData < 0xFF ? (char) nextData : nonPrintableChar); + } + out.print(nextData < 0 ? "--" : toHexString(nextData, 2)); + lineByteCounter++; + if (lineByteCounter == bytesPerLine) { + if (charBuffer != null) { + out.print(delimiterBeforeChars); + out.print(charBuffer.toString()); + charBuffer.setLength(0); + } + lineByteCounter = 0; + address += bytesPerLine; + out.println(); + if (ending) { + break; + } + } else if (lineByteCounter % valuesPerColumn == 0) { + out.print(interColumnDelimiter); + } else { + out.print(interValueDelimiter); + } + } + } + } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPUtilsTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPUtilsTest.java index bd5412ce..d1864526 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPUtilsTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPUtilsTest.java @@ -16,22 +16,33 @@ package com.igormaznitsa.jbbp.utils; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + + import com.igormaznitsa.jbbp.io.JBBPBitNumber; import com.igormaznitsa.jbbp.io.JBBPBitOrder; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.function.Executable; - import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; import java.util.Random; - -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class JBBPUtilsTest { @Test public void testUtf8EncdeDecode() { - assertEquals("78634двлфодйукйДЛОД wdf", JBBPUtils.utf8ToStr(JBBPUtils.strToUtf8("78634двлфодйукйДЛОД wdf"))); + assertEquals("78634двлфодйукйДЛОД wdf", + JBBPUtils.utf8ToStr(JBBPUtils.strToUtf8("78634двлфодйукйДЛОД wdf"))); } @Test @@ -150,7 +161,8 @@ public void testUnpackInt_NPEForArrayIsNull() { @Test public void testUnpackInt_IAEForWrongPrefix() { - assertThrows(IllegalArgumentException.class, () -> JBBPUtils.unpackInt(new byte[] {(byte) 0xAA, 0, 0, 0, 0, 0}, new JBBPIntCounter())); + assertThrows(IllegalArgumentException.class, + () -> JBBPUtils.unpackInt(new byte[] {(byte) 0xAA, 0, 0, 0, 0, 0}, new JBBPIntCounter())); } @Test @@ -163,7 +175,8 @@ public void testPackUnpackIntFromByteArray() { int counter2 = 0; int counter3 = 0; - final int[] etalons = new int[] {0, -1, -89, 234, 123124, 1223112, 34323, Integer.MIN_VALUE, Integer.MAX_VALUE}; + final int[] etalons = + new int[] {0, -1, -89, 234, 123124, 1223112, 34323, Integer.MIN_VALUE, Integer.MAX_VALUE}; for (final int generated : etalons) { pos.set(0); @@ -195,19 +208,22 @@ public void testPackUnpackIntFromByteArray() { @Test public void testArray2Hex() { assertNull(JBBPUtils.array2hex(null)); - assertEquals("[0x01, 0x02, 0x03, 0xFF]", JBBPUtils.array2hex(new byte[] {1, 2, 3, (byte) 0xFF})); + assertEquals("[0x01, 0x02, 0x03, 0xFF]", + JBBPUtils.array2hex(new byte[] {1, 2, 3, (byte) 0xFF})); } @Test public void testArray2Oct() { assertNull(JBBPUtils.array2hex(null)); - assertEquals("[0o001, 0o002, 0o003, 0o377]", JBBPUtils.array2oct(new byte[] {1, 2, 3, (byte) 0xFF})); + assertEquals("[0o001, 0o002, 0o003, 0o377]", + JBBPUtils.array2oct(new byte[] {1, 2, 3, (byte) 0xFF})); } @Test public void testArray2Bin() { assertNull(JBBPUtils.array2bin(null)); - assertEquals("[0b00000001, 0b00000010, 0b00000011, 0b11111111]", JBBPUtils.array2bin(new byte[] {1, 2, 3, (byte) 0xFF})); + assertEquals("[0b00000001, 0b00000010, 0b00000011, 0b11111111]", + JBBPUtils.array2bin(new byte[] {1, 2, 3, (byte) 0xFF})); } @Test @@ -240,7 +256,8 @@ public void testBin2Str() { assertEquals("01010101 10101010", JBBPUtils.bin2str(new byte[] {0x55, (byte) 0xAA}, true)); assertEquals("0101010110101010", JBBPUtils.bin2str(new byte[] {0x55, (byte) 0xAA}, false)); assertEquals("00001001", JBBPUtils.bin2str(new byte[] {0x9}, false)); - assertEquals("1010101001010101", JBBPUtils.bin2str(new byte[] {0x55, (byte) 0xAA}, JBBPBitOrder.MSB0, false)); + assertEquals("1010101001010101", + JBBPUtils.bin2str(new byte[] {0x55, (byte) 0xAA}, JBBPBitOrder.MSB0, false)); assertEquals("0101010110101010", JBBPUtils.bin2str(new byte[] {0x55, (byte) 0xAA})); } @@ -251,8 +268,10 @@ public void testStr2Bin_Default() { assertArrayEquals(new byte[] {(byte) 0x80}, JBBPUtils.str2bin("10000000")); assertArrayEquals(new byte[] {(byte) 0x01}, JBBPUtils.str2bin("1")); assertArrayEquals(new byte[] {(byte) 0x80, 0x01}, JBBPUtils.str2bin("10000000X00x0Zz1")); - assertArrayEquals(new byte[] {(byte) 0x80, 0x01, 0x07}, JBBPUtils.str2bin("10000000000000010111")); - assertArrayEquals(new byte[] {(byte) 0x80, 0x01, 0x07}, JBBPUtils.str2bin("10000000_00000001_0111")); + assertArrayEquals(new byte[] {(byte) 0x80, 0x01, 0x07}, + JBBPUtils.str2bin("10000000000000010111")); + assertArrayEquals(new byte[] {(byte) 0x80, 0x01, 0x07}, + JBBPUtils.str2bin("10000000_00000001_0111")); try { JBBPUtils.str2bin("10001021"); @@ -269,9 +288,12 @@ public void testStr2Bin_LSB0() { assertArrayEquals(new byte[] {(byte) 0x80}, JBBPUtils.str2bin("10000000", JBBPBitOrder.LSB0)); assertArrayEquals(new byte[] {(byte) 0x01}, JBBPUtils.str2bin("1", JBBPBitOrder.LSB0)); assertArrayEquals(new byte[] {(byte) 0x01}, JBBPUtils.str2bin("00000001", JBBPBitOrder.LSB0)); - assertArrayEquals(new byte[] {(byte) 0x80, (byte) 0x01}, JBBPUtils.str2bin("10000000X00x0Zz1", JBBPBitOrder.LSB0)); - assertArrayEquals(new byte[] {(byte) 0x80, (byte) 0x01, (byte) 0x07}, JBBPUtils.str2bin("10000000000000010111", JBBPBitOrder.LSB0)); - assertArrayEquals(new byte[] {(byte) 0x80, (byte) 0x01, (byte) 0x07}, JBBPUtils.str2bin("10000000_00000001_0111", JBBPBitOrder.LSB0)); + assertArrayEquals(new byte[] {(byte) 0x80, (byte) 0x01}, + JBBPUtils.str2bin("10000000X00x0Zz1", JBBPBitOrder.LSB0)); + assertArrayEquals(new byte[] {(byte) 0x80, (byte) 0x01, (byte) 0x07}, + JBBPUtils.str2bin("10000000000000010111", JBBPBitOrder.LSB0)); + assertArrayEquals(new byte[] {(byte) 0x80, (byte) 0x01, (byte) 0x07}, + JBBPUtils.str2bin("10000000_00000001_0111", JBBPBitOrder.LSB0)); try { JBBPUtils.str2bin("10001021", JBBPBitOrder.MSB0); @@ -283,9 +305,11 @@ public void testStr2Bin_LSB0() { @Test public void testStr2Bin_LSB0_1bitShift() { - final byte[] array = JBBPUtils.str2bin("0 11111111 01010101 00011000 00000001", JBBPBitOrder.LSB0); + final byte[] array = + JBBPUtils.str2bin("0 11111111 01010101 00011000 00000001", JBBPBitOrder.LSB0); - assertArrayEquals(new byte[] {(byte) 0x7F, (byte) 0xAA, (byte) 0x8C, (byte) 0x0, (byte) 0x01}, array); + assertArrayEquals(new byte[] {(byte) 0x7F, (byte) 0xAA, (byte) 0x8C, (byte) 0x0, (byte) 0x01}, + array); } @@ -297,10 +321,14 @@ public void testStr2Bin_MSB() { assertArrayEquals(new byte[] {(byte) 0x80}, JBBPUtils.str2bin("00000001", JBBPBitOrder.MSB0)); assertArrayEquals(new byte[] {(byte) 0x01}, JBBPUtils.str2bin("10000000", JBBPBitOrder.MSB0)); assertArrayEquals(new byte[] {(byte) 0xA9}, JBBPUtils.str2bin("10010101", JBBPBitOrder.MSB0)); - assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0x80}, JBBPUtils.str2bin("10000000X00x0Zz1", JBBPBitOrder.MSB0)); - assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0x80, (byte) 0x0E}, JBBPUtils.str2bin("1000000000000001 0111", JBBPBitOrder.MSB0)); - assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0x80, (byte) 0x0E}, JBBPUtils.str2bin("10000000_00000001_0111", JBBPBitOrder.MSB0)); - assertArrayEquals(new byte[] {(byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x01}, JBBPUtils.str2bin("1_10000000_00000001_00000001", JBBPBitOrder.MSB0)); + assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0x80}, + JBBPUtils.str2bin("10000000X00x0Zz1", JBBPBitOrder.MSB0)); + assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0x80, (byte) 0x0E}, + JBBPUtils.str2bin("1000000000000001 0111", JBBPBitOrder.MSB0)); + assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0x80, (byte) 0x0E}, + JBBPUtils.str2bin("10000000_00000001_0111", JBBPBitOrder.MSB0)); + assertArrayEquals(new byte[] {(byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x01}, + JBBPUtils.str2bin("1_10000000_00000001_00000001", JBBPBitOrder.MSB0)); try { JBBPUtils.str2bin("10001021", JBBPBitOrder.MSB0); @@ -347,8 +375,10 @@ public void testReverseArray() { assertArrayEquals(new byte[] {1}, JBBPUtils.reverseArray(new byte[] {1})); assertArrayEquals(new byte[] {2, 1}, JBBPUtils.reverseArray(new byte[] {1, 2})); - assertArrayEquals(new byte[] {5, 4, 3, 2, 1}, JBBPUtils.reverseArray(new byte[] {1, 2, 3, 4, 5})); - assertArrayEquals(new byte[] {6, 5, 4, 3, 2, 1}, JBBPUtils.reverseArray(new byte[] {1, 2, 3, 4, 5, 6})); + assertArrayEquals(new byte[] {5, 4, 3, 2, 1}, + JBBPUtils.reverseArray(new byte[] {1, 2, 3, 4, 5})); + assertArrayEquals(new byte[] {6, 5, 4, 3, 2, 1}, + JBBPUtils.reverseArray(new byte[] {1, 2, 3, 4, 5, 6})); } @Test @@ -363,7 +393,8 @@ public void testSplitInteger() { assertArrayEquals(new byte[] {1, 2, 3, 4}, JBBPUtils.splitInteger(0x01020304, false, buff)); buff = new byte[8]; - assertArrayEquals(new byte[] {1, 2, 3, 4, 0, 0, 0, 0}, JBBPUtils.splitInteger(0x01020304, false, buff)); + assertArrayEquals(new byte[] {1, 2, 3, 4, 0, 0, 0, 0}, + JBBPUtils.splitInteger(0x01020304, false, buff)); buff = null; assertArrayEquals(new byte[] {4, 3, 2, 1}, JBBPUtils.splitInteger(0x01020304, true, buff)); @@ -375,40 +406,51 @@ public void testSplitInteger() { assertArrayEquals(new byte[] {4, 3, 2, 1}, JBBPUtils.splitInteger(0x01020304, true, buff)); buff = new byte[8]; - assertArrayEquals(new byte[] {4, 3, 2, 1, 0, 0, 0, 0}, JBBPUtils.splitInteger(0x01020304, true, buff)); + assertArrayEquals(new byte[] {4, 3, 2, 1, 0, 0, 0, 0}, + JBBPUtils.splitInteger(0x01020304, true, buff)); } @Test public void testSplitLong() { byte[] buff = null; - assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}, JBBPUtils.splitLong(0x0102030405060708L, false, buff)); + assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}, + JBBPUtils.splitLong(0x0102030405060708L, false, buff)); buff = new byte[2]; - assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}, JBBPUtils.splitLong(0x0102030405060708L, false, buff)); + assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}, + JBBPUtils.splitLong(0x0102030405060708L, false, buff)); buff = new byte[8]; - assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}, JBBPUtils.splitLong(0x0102030405060708L, false, buff)); + assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}, + JBBPUtils.splitLong(0x0102030405060708L, false, buff)); buff = new byte[10]; - assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 0, 0}, JBBPUtils.splitLong(0x0102030405060708L, false, buff)); + assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 0, 0}, + JBBPUtils.splitLong(0x0102030405060708L, false, buff)); buff = null; - assertArrayEquals(new byte[] {8, 7, 6, 5, 4, 3, 2, 1}, JBBPUtils.splitLong(0x0102030405060708L, true, buff)); + assertArrayEquals(new byte[] {8, 7, 6, 5, 4, 3, 2, 1}, + JBBPUtils.splitLong(0x0102030405060708L, true, buff)); buff = new byte[2]; - assertArrayEquals(new byte[] {8, 7, 6, 5, 4, 3, 2, 1}, JBBPUtils.splitLong(0x0102030405060708L, true, buff)); + assertArrayEquals(new byte[] {8, 7, 6, 5, 4, 3, 2, 1}, + JBBPUtils.splitLong(0x0102030405060708L, true, buff)); buff = new byte[8]; - assertArrayEquals(new byte[] {8, 7, 6, 5, 4, 3, 2, 1}, JBBPUtils.splitLong(0x0102030405060708L, true, buff)); + assertArrayEquals(new byte[] {8, 7, 6, 5, 4, 3, 2, 1}, + JBBPUtils.splitLong(0x0102030405060708L, true, buff)); buff = new byte[10]; - assertArrayEquals(new byte[] {8, 7, 6, 5, 4, 3, 2, 1, 0, 0}, JBBPUtils.splitLong(0x0102030405060708L, true, buff)); + assertArrayEquals(new byte[] {8, 7, 6, 5, 4, 3, 2, 1, 0, 0}, + JBBPUtils.splitLong(0x0102030405060708L, true, buff)); } @Test public void testConcat() { - assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, JBBPUtils.concat(new byte[] {1, 2, 3, 4}, new byte[] {5}, new byte[] {6, 7, 8, 9}, new byte[0], new byte[] {10})); + assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, JBBPUtils + .concat(new byte[] {1, 2, 3, 4}, new byte[] {5}, new byte[] {6, 7, 8, 9}, new byte[0], + new byte[] {10})); } @Test @@ -544,4 +586,35 @@ public void testGenerateMask() { assertEquals(0x7F, JBBPUtils.makeMask(100)); assertEquals(0xFFFF, JBBPUtils.makeMask(65535)); } + + @Test + public void testTraceData() throws Exception { + final byte[] testData = new byte[211]; + for (int i = 0; i < 111; i++) { + testData[i] = (byte) i; + } + final InputStream stream = new ByteArrayInputStream(testData); + final ByteArrayOutputStream outArray = new ByteArrayOutputStream(); + final PrintStream out = new PrintStream(outArray, true, "UTF-8"); + JBBPUtils.traceData(stream, out); + out.close(); + final String asString = + new String(outArray.toByteArray(), StandardCharsets.UTF_8).replace("\r\n", "\n") + .replace("\r", "\n"); + assertEquals( + "00000000 00 01 02 03 | 04 05 06 07 | 08 09 0A 0B | 0C 0D 0E 0F | 10 11 12 13 | 14 15 16 17 | 18 19 1A 1B | 1C 1D 1E 1F ................................\n" + + + "00000020 20 21 22 23 | 24 25 26 27 | 28 29 2A 2B | 2C 2D 2E 2F | 30 31 32 33 | 34 35 36 37 | 38 39 3A 3B | 3C 3D 3E 3F !\"#$%&'()*+,-./0123456789:;<=>?\n" + + + "00000040 40 41 42 43 | 44 45 46 47 | 48 49 4A 4B | 4C 4D 4E 4F | 50 51 52 53 | 54 55 56 57 | 58 59 5A 5B | 5C 5D 5E 5F @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\n" + + + "00000060 60 61 62 63 | 64 65 66 67 | 68 69 6A 6B | 6C 6D 6E 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 `abcdefghijklmn.................\n" + + + "00000080 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 ................................\n" + + + "000000A0 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 ................................\n" + + + "000000C0 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 -- | -- -- -- -- | -- -- -- -- | -- -- -- -- ................................\n", + asString); + } } From 86a1177de37f43e9da8b8a32424cf6ee8cb3f33e Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Thu, 10 Dec 2020 20:07:13 +0200 Subject: [PATCH 016/131] updated --- README.md | 4 ++++ changelog.txt | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/README.md b/README.md index 2520f860..c75a6456 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ Java has some embedded features to parse binary data (for instance ByteBuffer), ![Use cases](https://github.com/raydac/java-binary-block-parser/blob/master/docs/jbbp_mm.png) # Change log +- __2.0.3 (SNAPSHOT)__ + - added service methods `JBBPUtils.traceData` to print dump of an input stream into a PrintStream + - improved JBBPTokenizerException to show marked error position [#30](https://github.com/raydac/java-binary-block-parser/issues/30) + - __2.0.2 (22-aug-2020)__ - added `JBBPOut#Bin` variant to override `@Bin` annotation fields in written objects. - [#28](https://github.com/raydac/java-binary-block-parser/issues/28) added `JBBPOut#BinForceByteOrder` to override byte order defined in `@Bin` annotations of written object. diff --git a/changelog.txt b/changelog.txt index 41529851..359c7840 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,7 @@ +2.0.3 (SNAPSHOT) + - added service methods `JBBPUtils.traceData` to print dump of an input stream into a PrintStream + - improved JBBPTokenizerException to show marked error position [#30](https://github.com/raydac/java-binary-block-parser/issues/30) + 2.0.2 (22-aug-2020) - added `JBBPOut#Bin` variant to override `@Bin` annotation fields in written objects. - [#28](https://github.com/raydac/java-binary-block-parser/issues/28) added `JBBPOut#BinForceByteOrder` to override byte order defined in `@Bin` annotations of written object. From a2d773efa10a6dbce71af3ceeb9c2f961792fc87 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Thu, 10 Dec 2020 20:08:14 +0200 Subject: [PATCH 017/131] updated --- README.md | 2 +- changelog.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c75a6456..4d67f44a 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Java has some embedded features to parse binary data (for instance ByteBuffer), # Change log - __2.0.3 (SNAPSHOT)__ - added service methods `JBBPUtils.traceData` to print dump of an input stream into a PrintStream - - improved JBBPTokenizerException to show marked error position [#30](https://github.com/raydac/java-binary-block-parser/issues/30) + - improved `JBBPTokenizerException` to show marked error position [#30](https://github.com/raydac/java-binary-block-parser/issues/30) - __2.0.2 (22-aug-2020)__ - added `JBBPOut#Bin` variant to override `@Bin` annotation fields in written objects. diff --git a/changelog.txt b/changelog.txt index 359c7840..a3751a43 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,6 @@ 2.0.3 (SNAPSHOT) - added service methods `JBBPUtils.traceData` to print dump of an input stream into a PrintStream - - improved JBBPTokenizerException to show marked error position [#30](https://github.com/raydac/java-binary-block-parser/issues/30) + - improved `JBBPTokenizerException` to show marked error position [#30](https://github.com/raydac/java-binary-block-parser/issues/30) 2.0.2 (22-aug-2020) - added `JBBPOut#Bin` variant to override `@Bin` annotation fields in written objects. From 9e6b23fb107b7f1c9c08d53472b499dc82773ff5 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Fri, 11 Dec 2020 10:26:38 +0200 Subject: [PATCH 018/131] improved tests --- .../jbbp/utils/JBBPUtilsTest.java | 64 ++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPUtilsTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPUtilsTest.java index d1864526..455957f1 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPUtilsTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPUtilsTest.java @@ -588,7 +588,7 @@ public void testGenerateMask() { } @Test - public void testTraceData() throws Exception { + public void testTraceData_Defaults() throws Exception { final byte[] testData = new byte[211]; for (int i = 0; i < 111; i++) { testData[i] = (byte) i; @@ -617,4 +617,66 @@ public void testTraceData() throws Exception { "000000C0 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 -- | -- -- -- -- | -- -- -- -- | -- -- -- -- ................................\n", asString); } + + @Test + public void testTraceData_CustomWithChars() throws Exception { + final byte[] testData = new byte[211]; + for (int i = 0; i < 111; i++) { + testData[i] = (byte) i; + } + final InputStream stream = new ByteArrayInputStream(testData); + final ByteArrayOutputStream outArray = new ByteArrayOutputStream(); + final PrintStream out = new PrintStream(outArray, true, "UTF-8"); + JBBPUtils.traceData(stream, 8, 4, "#", "_", "$", "Z", '&', true, out); + out.close(); + final String asString = + new String(outArray.toByteArray(), StandardCharsets.UTF_8).replace("\r\n", "\n") + .replace("\r", "\n"); + assertEquals( + "00000000#00_01_02_03_04_05_06_07$08_09_0A_0B_0C_0D_0E_0F$10_11_12_13_14_15_16_17$18_19_1A_1B_1C_1D_1E_1FZ&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n" + + + "00000020#20_21_22_23_24_25_26_27$28_29_2A_2B_2C_2D_2E_2F$30_31_32_33_34_35_36_37$38_39_3A_3B_3C_3D_3E_3FZ !\"#$%&'()*+,-./0123456789:;<=>?\n" + + + "00000040#40_41_42_43_44_45_46_47$48_49_4A_4B_4C_4D_4E_4F$50_51_52_53_54_55_56_57$58_59_5A_5B_5C_5D_5E_5FZ@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\n" + + + "00000060#60_61_62_63_64_65_66_67$68_69_6A_6B_6C_6D_6E_00$00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00Z`abcdefghijklmn&&&&&&&&&&&&&&&&&\n" + + + "00000080#00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00Z&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n" + + + "000000A0#00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00Z&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n" + + + "000000C0#00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00$00_00_00_--_--_--_--_--$--_--_--_--_--_--_--_--Z&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n", + asString); + } + + @Test + public void testTraceData_CustomNoChars() throws Exception { + final byte[] testData = new byte[211]; + for (int i = 0; i < 111; i++) { + testData[i] = (byte) i; + } + final InputStream stream = new ByteArrayInputStream(testData); + final ByteArrayOutputStream outArray = new ByteArrayOutputStream(); + final PrintStream out = new PrintStream(outArray, true, "UTF-8"); + JBBPUtils.traceData(stream, 8, 4, "#", "_", "$", "Z", '&', false, out); + out.close(); + final String asString = + new String(outArray.toByteArray(), StandardCharsets.UTF_8).replace("\r\n", "\n") + .replace("\r", "\n"); + assertEquals( + "00000000#00_01_02_03_04_05_06_07$08_09_0A_0B_0C_0D_0E_0F$10_11_12_13_14_15_16_17$18_19_1A_1B_1C_1D_1E_1F\n" + + + "00000020#20_21_22_23_24_25_26_27$28_29_2A_2B_2C_2D_2E_2F$30_31_32_33_34_35_36_37$38_39_3A_3B_3C_3D_3E_3F\n" + + + "00000040#40_41_42_43_44_45_46_47$48_49_4A_4B_4C_4D_4E_4F$50_51_52_53_54_55_56_57$58_59_5A_5B_5C_5D_5E_5F\n" + + + "00000060#60_61_62_63_64_65_66_67$68_69_6A_6B_6C_6D_6E_00$00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00\n" + + + "00000080#00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00\n" + + + "000000A0#00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00\n" + + + "000000C0#00_00_00_00_00_00_00_00$00_00_00_00_00_00_00_00$00_00_00_--_--_--_--_--$--_--_--_--_--_--_--_--\n", + asString); + } } From 084c6f317d8ecac1408fb185691c737dc3f418f3 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Sun, 13 Dec 2020 13:21:03 +0200 Subject: [PATCH 019/131] update --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4d67f44a..1fe0d840 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ [![Maven central](https://maven-badges.herokuapp.com/maven-central/com.igormaznitsa/jbbp/badge.svg)](http://search.maven.org/#artifactdetails|com.igormaznitsa|jbbp|2.0.2|jar) [![Java 1.8+](https://img.shields.io/badge/java-1.8%2b-green.svg)](http://www.oracle.com/technetwork/java/javase/downloads/index.html) [![Android 3.0+](https://img.shields.io/badge/android-3.0%2b-green.svg)](http://developer.android.com/sdk/index.html) -[![PayPal donation](https://img.shields.io/badge/donation-PayPal-red.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=AHWJHJFBAWGL2) -[![Yandex.Money donation](https://img.shields.io/badge/donation-Я.деньги-yellow.svg)](http://yasobe.ru/na/iamoss) +[![PayPal donation](https://img.shields.io/badge/donation-PayPal-cyan.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=AHWJHJFBAWGL2) +[![YooMoney donation](https://img.shields.io/badge/donation-Yoo.money-blue.svg)](https://yoomoney.ru/to/41001158080699) # Introduction Java has some embedded features to parse binary data (for instance ByteBuffer), but sometime it is needed to work on bit level and describe binary structures through some DSL(domain specific language). I was impressed by the [the Python Struct package](https://docs.python.org/2/library/struct.html) package and wanted to get something like that for Java. So I developed the JBBP library.
From bee72adb29e22bdb46114640ca9bfe2c79a8da5b Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Fri, 25 Dec 2020 16:46:50 +0200 Subject: [PATCH 020/131] code formatting --- README.md | 242 +- .../jbbp/plugin/gradle/AbstractJBBPTask.java | 20 +- .../jbbp/plugin/gradle/JBBPCleanTask.java | 5 +- .../jbbp/plugin/gradle/JBBPGenerateTask.java | 32 +- .../jbbp/plugin/gradle/JBBPPlugin.java | 3 +- .../igormaznitsa/mvn/tst/VarCustomImpl.java | 47 +- .../mvn/test/jbbp/VarCustomTest.java | 8 +- .../jbbp/GenAnnotationsNonStaticTest.java | 9 +- .../mvn/test/jbbp/GenAnnotationsTest.java | 9 +- .../igormaznitsa/mvn/tst/VarCustomImpl.java | 46 +- .../test/jbbp/WholeStreamByteArrayTest.java | 11 +- .../jbbp/plugin/mvn/AbstractJBBPMojo.java | 14 +- .../jbbp/plugin/mvn/JBBPCleanMojo.java | 16 +- .../jbbp/plugin/mvn/JBBPGenerateMojo.java | 44 +- .../common/converters/JavaConverterTest.java | 9 +- .../jbbp/plugin/mvn/JBBPGenerateMojoTest.java | 9 +- .../converters/JBBPScriptTranslator.java | 70 +- .../common/converters/JavaConverter.java | 21 +- .../plugin/common/converters/ParserFlags.java | 3 +- .../jbbp/plugin/common/utils/CommonUtils.java | 17 +- .../plugin/common/utils/CommonUtilsTest.java | 1 + .../jbbp/JBBPCustomFieldTypeProcessor.java | 11 +- .../jbbp/JBBPExternalValueProvider.java | 3 +- .../jbbp/JBBPNamedNumericFieldMap.java | 20 +- .../com/igormaznitsa/jbbp/JBBPParser.java | 217 +- .../jbbp/JBBPVarFieldProcessor.java | 13 +- .../jbbp/compiler/JBBPCompiledBlock.java | 17 +- .../jbbp/compiler/JBBPCompiler.java | 140 +- .../jbbp/compiler/JBBPCompilerUtils.java | 26 +- .../jbbp/compiler/JBBPNamedFieldInfo.java | 10 +- .../conversion/CompiledBlockVisitor.java | 86 +- .../ExpressionEvaluatorVisitor.java | 3 +- .../conversion/IntConstValueEvaluator.java | 6 +- .../conversion/JBBPToJavaConverter.java | 538 +- .../JBBPFieldTypeParameterContainer.java | 8 +- .../jbbp/compiler/tokenizer/JBBPToken.java | 5 +- .../compiler/tokenizer/JBBPTokenizer.java | 18 +- .../compiler/varlen/JBBPEvaluatorFactory.java | 8 +- .../varlen/JBBPExpressionEvaluator.java | 80 +- .../varlen/JBBPIntegerValueEvaluator.java | 7 +- .../varlen/JBBPOnlyFieldEvaluator.java | 12 +- .../jbbp/exceptions/JBBPEvalException.java | 3 +- .../jbbp/exceptions/JBBPFinderException.java | 3 +- .../jbbp/exceptions/JBBPMapperException.java | 5 +- .../exceptions/JBBPTokenizerException.java | 41 +- .../JBBPTooManyFieldsFoundException.java | 4 +- .../io/AbstractMappedClassFieldObserver.java | 74 +- .../jbbp/io/JBBPBitInputStream.java | 29 +- .../jbbp/io/JBBPBitOutputStream.java | 3 +- .../jbbp/io/JBBPCustomFieldWriter.java | 5 +- .../com/igormaznitsa/jbbp/io/JBBPOut.java | 55 +- .../jbbp/io/JBBPOutVarProcessor.java | 3 +- .../com/igormaznitsa/jbbp/mapper/Bin.java | 2 +- .../igormaznitsa/jbbp/mapper/JBBPMapper.java | 91 +- .../JBBPMapperCustomFieldProcessor.java | 4 +- .../jbbp/mapper/MappedFieldRecord.java | 390 +- .../jbbp/model/AbstractFieldByteArray.java | 3 +- .../jbbp/model/JBBPAbstractArrayField.java | 4 +- .../jbbp/model/JBBPAbstractField.java | 1 - .../jbbp/model/JBBPFieldArrayBit.java | 9 +- .../jbbp/model/JBBPFieldArrayBoolean.java | 3 +- .../jbbp/model/JBBPFieldArrayByte.java | 3 +- .../jbbp/model/JBBPFieldArrayDouble.java | 6 +- .../jbbp/model/JBBPFieldArrayFloat.java | 6 +- .../jbbp/model/JBBPFieldArrayInt.java | 3 +- .../jbbp/model/JBBPFieldArrayLong.java | 3 +- .../jbbp/model/JBBPFieldArrayShort.java | 3 +- .../jbbp/model/JBBPFieldArrayUShort.java | 3 +- .../igormaznitsa/jbbp/model/JBBPFieldBit.java | 3 +- .../jbbp/model/JBBPFieldLong.java | 3 +- .../jbbp/model/JBBPFieldString.java | 26 +- .../jbbp/model/JBBPFieldStruct.java | 41 +- .../jbbp/model/JBBPNumericArray.java | 3 + .../com/igormaznitsa/jbbp/utils/Function.java | 4 +- ...BBPCustomFieldTypeProcessorAggregator.java | 23 +- .../jbbp/utils/JBBPDslBuilder.java | 140 +- .../jbbp/utils/JBBPSystemProperty.java | 3 +- .../jbbp/utils/JBBPTextWriter.java | 115 +- .../utils/JBBPTextWriterExtraAdapter.java | 18 +- .../igormaznitsa/jbbp/utils/ReflectUtils.java | 3 +- .../JBBPCustomFieldTypeProcessorTest.java | 78 +- .../jbbp/JBBPNamedNumericFieldMapTest.java | 76 +- .../com/igormaznitsa/jbbp/JBBPParserTest.java | 1228 +- .../java/com/igormaznitsa/jbbp/TestUtils.java | 22 +- .../jbbp/compiler/JBBPCompilerTest.java | 122 +- ...PToJBBPToJavaConverterCompilationTest.java | 221 +- ...BPToJBBPToJavaConverterExpressionTest.java | 24 +- .../JBBPToJavaConverterReadWriteTest.java | 556 +- ...JBBPToJavaClassConverterJBBPFlagsTest.java | 15 +- .../compiler/conversion/RandomAutoTest.java | 106 +- .../JBBPFieldTypeParameterContainerTest.java | 25 +- .../varlen/JBBPExpressionEvaluatorTest.java | 182 +- .../varlen/JBBPOnlyFieldEvaluatorTest.java | 68 +- .../exceptions/JBBPMapperExceptionTest.java | 19 +- .../igormaznitsa/jbbp/io/BitIOCommonTest.java | 28 +- .../jbbp/io/JBBPBitInputStreamTest.java | 358 +- .../jbbp/io/JBBPBitOutputStreamTest.java | 76 +- .../com/igormaznitsa/jbbp/io/JBBPOutTest.java | 427 +- .../it/AbstractParserIntegrationTest.java | 30 +- .../jbbp/it/BasedOnQuestionsAndCasesTest.java | 22 +- .../jbbp/it/ClassParsingTest.java | 65 +- .../jbbp/it/ConvertToJSONTest.java | 24 +- .../it/CustomThreeByteIntegerTypeTest.java | 82 +- .../jbbp/it/NetPacketParsingTest.java | 141 +- .../igormaznitsa/jbbp/it/PNGParsingTest.java | 55 +- .../jbbp/it/PackedBCDCustomFieldTest.java | 30 +- .../igormaznitsa/jbbp/it/SNAParsingTest.java | 10 +- .../igormaznitsa/jbbp/it/TAP_ParsingTest.java | 28 +- .../igormaznitsa/jbbp/it/TGAParsingTest.java | 36 +- .../igormaznitsa/jbbp/it/WAVParsingTest.java | 39 +- .../jbbp/it/Z80_v1_ParsingTest.java | 91 +- .../igormaznitsa/jbbp/mapper/BinTypeTest.java | 9 +- .../jbbp/mapper/JBBPMapperTest.java | 355 +- .../jbbp/model/JBBPFieldArrayBitTest.java | 25 +- .../jbbp/model/JBBPFieldArrayBooleanTest.java | 14 +- .../jbbp/model/JBBPFieldArrayByteTest.java | 14 +- .../jbbp/model/JBBPFieldArrayIntTest.java | 14 +- .../jbbp/model/JBBPFieldArrayLongTest.java | 34 +- .../jbbp/model/JBBPFieldArrayShortTest.java | 14 +- .../jbbp/model/JBBPFieldArrayStringTest.java | 22 +- .../jbbp/model/JBBPFieldArrayStructTest.java | 8 +- .../jbbp/model/JBBPFieldArrayUByteTest.java | 14 +- .../jbbp/model/JBBPFieldArrayUShortTest.java | 15 +- .../jbbp/model/JBBPFieldBitTest.java | 51 +- .../jbbp/model/JBBPFieldBooleanTest.java | 34 +- .../jbbp/model/JBBPFieldByteTest.java | 44 +- .../jbbp/model/JBBPFieldIntTest.java | 40 +- .../jbbp/model/JBBPFieldLongTest.java | 36 +- .../jbbp/model/JBBPFieldShortTest.java | 44 +- .../jbbp/model/JBBPFieldStringTest.java | 16 +- .../jbbp/model/JBBPFieldStructTest.java | 166 +- .../jbbp/model/JBBPFieldUByteTest.java | 44 +- .../jbbp/model/JBBPFieldUShortTest.java | 49 +- .../AbstractJBBPToJavaConverterTest.java | 55 +- .../jbbp/utils/DynamicIntBuffer.java | 1 - ...ustomFieldTypeProcessorAggregatorTest.java | 103 +- .../jbbp/utils/JBBPDslBuilderTest.java | 64 +- .../jbbp/utils/JBBPIntCounterTest.java | 5 +- .../jbbp/utils/JBBPSystemPropertyTest.java | 17 +- .../jbbp/utils/JBBPTextWriterTest.java | 222 +- .../jbbp/benchmarks/JBBP_Benchmark.java | 3 +- logo.svg | 26479 ++++++++-------- 142 files changed, 19112 insertions(+), 16188 deletions(-) diff --git a/README.md b/README.md index 1fe0d840..24451ccc 100644 --- a/README.md +++ b/README.md @@ -8,25 +8,34 @@ [![YooMoney donation](https://img.shields.io/badge/donation-Yoo.money-blue.svg)](https://yoomoney.ru/to/41001158080699) # Introduction -Java has some embedded features to parse binary data (for instance ByteBuffer), but sometime it is needed to work on bit level and describe binary structures through some DSL(domain specific language). I was impressed by the [the Python Struct package](https://docs.python.org/2/library/struct.html) package and wanted to get something like that for Java. So I developed the JBBP library.
+ +Java has some embedded features to parse binary data (for instance ByteBuffer), but sometime it is needed to work on bit +level and describe binary structures through some DSL(domain specific language). I was impressed by +the [the Python Struct package](https://docs.python.org/2/library/struct.html) package and wanted to get something like +that for Java. So I developed the JBBP library.
![Use cases](https://github.com/raydac/java-binary-block-parser/blob/master/docs/jbbp_mm.png) # Change log + - __2.0.3 (SNAPSHOT)__ - added service methods `JBBPUtils.traceData` to print dump of an input stream into a PrintStream - - improved `JBBPTokenizerException` to show marked error position [#30](https://github.com/raydac/java-binary-block-parser/issues/30) + - improved `JBBPTokenizerException` to show marked error + position [#30](https://github.com/raydac/java-binary-block-parser/issues/30) - __2.0.2 (22-aug-2020)__ - - added `JBBPOut#Bin` variant to override `@Bin` annotation fields in written objects. - - [#28](https://github.com/raydac/java-binary-block-parser/issues/28) added `JBBPOut#BinForceByteOrder` to override byte order defined in `@Bin` annotations of written object. + - added `JBBPOut#Bin` variant to override `@Bin` annotation fields in written objects. + - [#28](https://github.com/raydac/java-binary-block-parser/issues/28) added `JBBPOut#BinForceByteOrder` to override + byte order defined in `@Bin` annotations of written object. - __2.0.1 (04-feb-2020)__ - - [#26](https://github.com/raydac/java-binary-block-parser/issues/26) fixed bug in array write with MSB0 + - [#26](https://github.com/raydac/java-binary-block-parser/issues/26) fixed bug in array write with MSB0 -[Full changelog](https://github.com/raydac/java-binary-block-parser/blob/master/changelog.txt) +[Full changelog](https://github.com/raydac/java-binary-block-parser/blob/master/changelog.txt) # Maven dependency + The Framework has been published in the Maven Central and can be easily added as a dependency + ``` com.igormaznitsa @@ -34,74 +43,116 @@ The Framework has been published in the Maven Central and can be easily added as 2.0.2 ``` -the precompiled library jar, javadoc and sources also can be downloaded directly from [the Maven central.](https://search.maven.org/artifact/com.igormaznitsa/jbbp/2.0.2/jar) + +the precompiled library jar, javadoc and sources also can be downloaded directly +from [the Maven central.](https://search.maven.org/artifact/com.igormaznitsa/jbbp/2.0.2/jar) # Hello world -The library is very easy in use because in many cases only two its classes are needed - com.igormaznitsa.jbbp.JBBPParser (for data parsing) and com.igormaznitsa.jbbp.io.JBBPOut (for binary block writing). Both these classes work over low-level IO classes - com.igormaznitsa.jbbp.io.JBBPBitInputStream and com.igormaznitsa.jbbp.io.JBBPBitOutputStream, those bit stream classes are the core of the library. -The easiet use case shows parsing of whole byte array to bits. +The library is very easy in use because in many cases only two its classes are needed - +com.igormaznitsa.jbbp.JBBPParser (for data parsing) and com.igormaznitsa.jbbp.io.JBBPOut (for binary block writing). +Both these classes work over low-level IO classes - com.igormaznitsa.jbbp.io.JBBPBitInputStream and +com.igormaznitsa.jbbp.io.JBBPBitOutputStream, those bit stream classes are the core of the library. + +The easiet use case shows parsing of whole byte array to bits. + ```Java - byte [] parsedBits = JBBPParser.prepare("bit:1 [_];").parse(new byte[]{1,2,3,4,5}). - findFieldForType(JBBPFieldArrayBit.class).getArray(); + byte[]parsedBits=JBBPParser.prepare("bit:1 [_];").parse(new byte[]{1,2,3,4,5}). + findFieldForType(JBBPFieldArrayBit.class).getArray(); ``` -On start it was the only functionality but then I found that it is no so comfort way to get result, so that added some mapping of parsed result to pre-instantiated object. It works slower, because uses a lot of Java reflection but much easy in some cases. + +On start it was the only functionality but then I found that it is no so comfort way to get result, so that added some +mapping of parsed result to pre-instantiated object. It works slower, because uses a lot of Java reflection but much +easy in some cases. + ```Java -class Parsed {@Bin(type = BinType.BIT_ARRAY)byte[] parsed;} -Parsed parsedBits = JBBPParser.prepare("bit:1 [_] parsed;").parse(new byte[]{1,2,3,4,5}).mapTo(new Parsed()); +class Parsed { + @Bin(type = BinType.BIT_ARRAY) + byte[] parsed; +} + Parsed parsedBits = JBBPParser.prepare("bit:1 [_] parsed;").parse(new byte[] {1, 2, 3, 4, 5}).mapTo(new Parsed()); ``` # Relative speed of different approaches in parsing -Mainly I developed the library to help in my development of ZX-Spectrum emulator where I needed to work with data snapshots containing data on bit level. It didn't need much productivity in work. But since 1.3.0 version I added way to generate Java classes from JBBP scripts, such classes work in about five times faster than dynamic parsing and mapping approaches. + +Mainly I developed the library to help in my development of ZX-Spectrum emulator where I needed to work with data +snapshots containing data on bit level. It didn't need much productivity in work. But since 1.3.0 version I added way to +generate Java classes from JBBP scripts, such classes work in about five times faster than dynamic parsing and mapping +approaches. ![JMH results](https://github.com/raydac/java-binary-block-parser/blob/master/docs/jmh_results.png) Chart below compares speed of three provided ways to parse data with JBBP: -* __Dynamic__ - the basic parsing through interpretation of prepared JBBP DSL script. It is no so fast, but provide way to generate parsers on fly from text description. -* __Dynamic + map to class__ - parsing through interpretation of parsed JBBP script and mapping of parsed data to pre-instantiated class instance. It provides compfortable way to work with data and get result but uses a lot of Java reflection features and so fast. -* __Static class__ - the fastest way of JBBP use, some JBBP script is translated into Java class. There is no any interpretation or reflection operators so that it is very fast. [You can take a look at auxiliary class which I use in tests](https://github.com/raydac/java-binary-block-parser/blob/master/jbbp/src/test/java/com/igormaznitsa/jbbp/testaux/AbstractJBBPToJavaConverterTest.java). +* __Dynamic__ - the basic parsing through interpretation of prepared JBBP DSL script. It is no so fast, but provide way + to generate parsers on fly from text description. +* __Dynamic + map to class__ - parsing through interpretation of parsed JBBP script and mapping of parsed data to + pre-instantiated class instance. It provides compfortable way to work with data and get result but uses a lot of Java + reflection features and so fast. +* __Static class__ - the fastest way of JBBP use, some JBBP script is translated into Java class. There is no any + interpretation or reflection operators so that it is very + fast. [You can take a look at auxiliary class which I use in tests](https://github.com/raydac/java-binary-block-parser/blob/master/jbbp/src/test/java/com/igormaznitsa/jbbp/testaux/AbstractJBBPToJavaConverterTest.java) + . # Generate sources from JBBP scripts -Since 1.3.0 version, the library provides Java source generator for JBBP scripts, __(keep in mind that generated sources anyway depends on JBBP library and it is needed for their work)__. -For instance such snippet can be used to generate Java classes from a JBBP script. It also can generate multiple classes. + +Since 1.3.0 version, the library provides Java source generator for JBBP scripts, __(keep in mind that generated sources +anyway depends on JBBP library and it is needed for their work)__. For instance such snippet can be used to generate +Java classes from a JBBP script. It also can generate multiple classes. + ```Java - JBBPParser parser = JBBPParser.prepare("byte a; byte b; byte c;"); - List generated = parser.convertToSrc(TargetSources.JAVA,"com.test.jbbp.gen.SomeClazz"); - for(ResultSrcItem i : generated) { - for(Map.Entry j :i.getResult().entrySet()) { - System.out.println("Class file name "+j.getKey()); - System.out.println("Class file content "+j.getValue()); - } - } + JBBPParser parser=JBBPParser.prepare("byte a; byte b; byte c;"); + List generated=parser.convertToSrc(TargetSources.JAVA,"com.test.jbbp.gen.SomeClazz"); + for(ResultSrcItem i:generated){ + for(Map.Entry j:i.getResult().entrySet()){ + System.out.println("Class file name "+j.getKey()); + System.out.println("Class file content "+j.getValue()); + } + } ``` -also there are developed plug-ins for both Maven and Gradle to generate sources from JBBP scripts during source generate phase. + +also there are developed plug-ins for both Maven and Gradle to generate sources from JBBP scripts during source generate +phase. in Maven it can be used through snippet: + ```xml - - com.igormaznitsa - jbbp-maven-plugin - 2.0.2 - - - gen-jbbp-src - - generate - - - + + + com.igormaznitsa + jbbp-maven-plugin + 2.0.2 + + + gen-jbbp-src + + generate + + + ``` -By default the maven plug-in looks for files with `jbbp` extension in `src/jbbp` folder of the project (it can be changed through plug-in configuration) and produces resulting java classes into `target/generated-sources/jbbp` folder. [For instance, I use such approach in my ZX-Poly emulator](https://github.com/raydac/zxpoly/tree/master/zxpoly-emul/src/jbbp). + +By default the maven plug-in looks for files with `jbbp` extension in `src/jbbp` folder of the project (it can be +changed through plug-in configuration) and produces resulting java classes into `target/generated-sources/jbbp` +folder. [For instance, I use such approach in my ZX-Poly emulator](https://github.com/raydac/zxpoly/tree/master/zxpoly-emul/src/jbbp) +. # More complex example with features added as of 1.1.0 -Example below shows how to parse a byte stream written in non-standard MSB0 order (Java has LSB0 bit order) into bit fields, then print its values and pack fields back: + +Example below shows how to parse a byte stream written in non-standard MSB0 order (Java has LSB0 bit order) into bit +fields, then print its values and pack fields back: + ```Java class Flags { - @Bin(order = 1, name = "f1", type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_1, comment = "It's flag one") byte flag1; - @Bin(order = 2, name = "f2", type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_2, comment = "It's second flag") byte flag2; - @Bin(order = 3, name = "f3", type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_1, comment = "It's 3th flag") byte flag3; - @Bin(order = 4, name = "f4", type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_4, comment = "It's 4th flag") byte flag4; - } - - final int data = 0b10101010; + @Bin(order = 1, name = "f1", type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_1, comment = "It's flag one") + byte flag1; + @Bin(order = 2, name = "f2", type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_2, comment = "It's second flag") + byte flag2; + @Bin(order = 3, name = "f3", type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_1, comment = "It's 3th flag") + byte flag3; + @Bin(order = 4, name = "f4", type = BinType.BIT, bitNumber = JBBPBitNumber.BITS_4, comment = "It's 4th flag") + byte flag4; +} + + final int data = 0b10101010; Flags parsed = JBBPParser.prepare("bit:1 f1; bit:2 f2; bit:1 f3; bit:4 f4;", JBBPBitOrder.MSB0).parse(new byte[]{(byte)data}).mapTo(new Flags()); assertEquals(1,parsed.flag1); assertEquals(2,parsed.flag2); @@ -112,7 +163,9 @@ class Flags { assertEquals(data, JBBPOut.BeginBin(JBBPBitOrder.MSB0).Bin(parsed).End().toByteArray()[0] & 0xFF); ``` + The Example will print in console the text below + ``` ;-------------------------------------------------------------------------------- ; START : Flags @@ -125,32 +178,51 @@ The Example will print in console the text below ; END : Flags ;-------------------------------------------------------------------------------- ``` + # Fields -Each field can have case insensitive name which must not contain '.' (because dot is reserved for links to structure field values) and '#'(because it is also reserved for internal library use). -A field name must not be started with either number or chars '$' and '_'. *Keep in mind that field names are case insensitive!* + +Each field can have case insensitive name which must not contain '.' (because dot is reserved for links to structure +field values) and '#'(because it is also reserved for internal library use). A field name must not be started with +either number or chars '$' and '_'. *Keep in mind that field names are case insensitive!* + ``` int someNamedField; byte field1; byte field2; byte field3; ``` + ![JBBP field format, types and examples](https://github.com/raydac/java-binary-block-parser/blob/master/docs/jbbp_fields.png) ## Primitive types + JBBP supports full set of Java numeric primitives with some extra types like ubyte and bit. ![JBBP field format, types and examples](https://github.com/raydac/java-binary-block-parser/blob/master/docs/jbbp_primitives.png) + ## Complex types -JBBP provides support both arrays and structures. __In expressions you can use links only to field values which already read!__ + +JBBP provides support both arrays and structures. __In expressions you can use links only to field values which already +read!__ ![JBBP field format, types and examples](https://github.com/raydac/java-binary-block-parser/blob/master/docs/jbbp_complex_types.png) ## Custom types -It is possible to define processors for custom data types. For instance you can take a look at [case processing three byte unsigned integer types](https://github.com/raydac/java-binary-block-parser/blob/master/jbbp/src/test/java/com/igormaznitsa/jbbp/it/CustomThreeByteIntegerTypeTest.java). + +It is possible to define processors for custom data types. For instance you can take a look +at [case processing three byte unsigned integer types](https://github.com/raydac/java-binary-block-parser/blob/master/jbbp/src/test/java/com/igormaznitsa/jbbp/it/CustomThreeByteIntegerTypeTest.java) +. ### Support of float, double and String types -Since 1.4.0 in JBBP was added support of Java float, double and String values. Because they have specific format, they are named as `doublej`, `floatj` and `stringj`. + +Since 1.4.0 in JBBP was added support of Java float, double and String values. Because they have specific format, they +are named as `doublej`, `floatj` and `stringj`. ## Variable fields -If you have some data which internal structure is undefined and variable then you can use the `var` type to mark such field and provide custom processor to read data of such value. Processor should implement interface [JBBPVarFieldProcessor](https://github.com/raydac/java-binary-block-parser/blob/master/src/main/java/com/igormaznitsa/jbbp/JBBPVarFieldProcessor.java) instance. + +If you have some data which internal structure is undefined and variable then you can use the `var` type to mark such +field and provide custom processor to read data of such value. Processor should implement +interface [JBBPVarFieldProcessor](https://github.com/raydac/java-binary-block-parser/blob/master/src/main/java/com/igormaznitsa/jbbp/JBBPVarFieldProcessor.java) +instance. + ``` final JBBPParser parser = JBBPParser.prepare("short k; var; int;"); final JBBPIntCounter counter = new JBBPIntCounter(); @@ -167,24 +239,35 @@ If you have some data which internal structure is undefined and variable then yo } }, null); ``` -*NB! Some programmers trying to use only parser for complex data, it is a mistake. In the case it is much better to have several easy parsers working with the same [JBBPBitInputStream](https://github.com/raydac/java-binary-block-parser/blob/master/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitInputStream.java) instance, it allows to keep decision points on Java level and make solution easier.* + +*NB! Some programmers trying to use only parser for complex data, it is a mistake. In the case it is much better to have +several easy parsers working with the +same [JBBPBitInputStream](https://github.com/raydac/java-binary-block-parser/blob/master/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitInputStream.java) +instance, it allows to keep decision points on Java level and make solution easier.* ## Special types + Special types makes some actions to skip data in input stream ![JBBP field format, types and examples](https://github.com/raydac/java-binary-block-parser/blob/master/docs/jbbp_special_fields.png) ## Byte order + Multi-byte types can be read with different byte order. ![JBBP field format, types and examples](https://github.com/raydac/java-binary-block-parser/blob/master/docs/jbbp_byteorder.png) # Expressions -Expressions are used for calculation of length of arrays and allow brackets and integer operators which work similar to Java operators: + +Expressions are used for calculation of length of arrays and allow brackets and integer operators which work similar to +Java operators: + - Arithmetic operators: +,-,%,*,/,% - Bit operators: &,|,^,~ - Shift operators: <<,>>,>>> - Brackets: (, ) -Inside expression you can use integer numbers and named field values through their names (if you use fields from the same structure) or paths. Keep in your mind that you can't use array fields or fields placed inside structure arrays. +Inside expression you can use integer numbers and named field values through their names (if you use fields from the +same structure) or paths. Keep in your mind that you can't use array fields or fields placed inside structure arrays. + ``` int field1; struct1 { @@ -194,7 +277,10 @@ int field1; ``` # Commentaries -You can use commentaries inside a parser script, the parser supports the only comment format and recognizes as commentaries all text after '//' till the end of line. + +You can use commentaries inside a parser script, the parser supports the only comment format and recognizes as +commentaries all text after '//' till the end of line. + ``` int; // hello commentaries @@ -202,13 +288,23 @@ You can use commentaries inside a parser script, the parser supports the only co ``` # Expression macroses -Inside expression you can use field names and field paths, also you can use the special macros '$$' which represents the current input stream byte counter, all fields started with '$' will be recognized by the parser as special user defined variables and it will be requesting them from special user defined provider. If the array size contains the only '_' symbol then the field or structure will not have defined size and whole stream will be read. + +Inside expression you can use field names and field paths, also you can use the special macros '$$' which represents the +current input stream byte counter, all fields started with '$' will be recognized by the parser as special user defined +variables and it will be requesting them from special user defined provider. If the array size contains the only '_' +symbol then the field or structure will not have defined size and whole stream will be read. # How to get result of parsing -The Result of parsing is an instance of com.igormaznitsa.jbbp.model.JBBPFieldStruct class which represents the root invisible structure for the parsed data and you can use its inside methods to find desired fields for their names, paths or classes. All Fields are successors of com.igormaznitsa.jbbp.model.JBBPAbstractField class. To increase comfort, it is easier to use mapping to classes when the mapper automatically places values to fields of a Java class. + +The Result of parsing is an instance of com.igormaznitsa.jbbp.model.JBBPFieldStruct class which represents the root +invisible structure for the parsed data and you can use its inside methods to find desired fields for their names, paths +or classes. All Fields are successors of com.igormaznitsa.jbbp.model.JBBPAbstractField class. To increase comfort, it is +easier to use mapping to classes when the mapper automatically places values to fields of a Java class. # Example + Example below shows how to parse a PNG file through JBBP parser: + ```Java final InputStream pngStream = getResourceAsInputStream("picture.png"); try { @@ -243,7 +339,9 @@ final InputStream pngStream = getResourceAsInputStream("picture.png"); closeResource(pngStream); } ``` + Also it is possible to map parsed packet to class fields + ```Java final JBBPParser pngParser = JBBPParser.prepare( "long header;" @@ -276,6 +374,7 @@ final JBBPParser pngParser = JBBPParser.prepare( ``` Example shows how to parse TCP frame: + ```Java final JBBPParser tcpParser = JBBPParser.prepare( "skip:34; // skip bytes till the frame\n" @@ -308,17 +407,30 @@ final JBBPParser tcpParser = JBBPParser.prepare( ``` # F.A.Q. + ## Is it possible to use `@Bin` annotations for parsing and not only mapping? -`@Bin` annotations is used only for mapping and data writing, but there is special class [JBBPDslBuilder](/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPDslBuilder.java) which can convert `@Bin` marked class into JBBP script, for instance: + +`@Bin` annotations is used only for mapping and data writing, but there is special +class [JBBPDslBuilder](/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPDslBuilder.java) which can convert `@Bin` +marked class into JBBP script, for instance: + ```java JBBPDslBuilder.Begin().AnnotatedClass(SomeBinAnnotatetClass.class).End(true); ``` ## My Binary data format is too complex one to be decoded by a JBBP script -No problems! JBBP parser works over [com.igormaznitsa.jbbp.io.JBBPBitInputStream](/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitInputStream.java) class which can be used directly and allows read bits, bytes, count bytes and align data. For writing there is similar class [JBBPBitOutputStream](https://github.com/raydac/java-binary-block-parser/blob/master/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitOutputStream.java). + +No problems! JBBP parser works +over [com.igormaznitsa.jbbp.io.JBBPBitInputStream](/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitInputStream.java) +class which can be used directly and allows read bits, bytes, count bytes and align data. For writing there is similar +class [JBBPBitOutputStream](https://github.com/raydac/java-binary-block-parser/blob/master/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitOutputStream.java) +. ## I want to make a binary data block instead of parsing! -Library provides special helper [JBBPOut](/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java). The helper allows to generate binary blocks and provides some kind of DSL + +Library provides special helper [JBBPOut](/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java). The helper allows +to generate binary blocks and provides some kind of DSL + ```Java import static com.igormaznitsa.jbbp.io.JBBPOut.*; ... diff --git a/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/AbstractJBBPTask.java b/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/AbstractJBBPTask.java index 13ae07d9..3dbb749f 100644 --- a/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/AbstractJBBPTask.java +++ b/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/AbstractJBBPTask.java @@ -1,6 +1,12 @@ package com.igormaznitsa.jbbp.plugin.gradle; import com.igormaznitsa.meta.common.utils.GetUtils; +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.apache.commons.io.FileUtils; import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; @@ -8,13 +14,6 @@ import org.gradle.api.file.FileVisitor; import org.gradle.api.tasks.TaskAction; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.io.File; -import java.io.IOException; -import java.util.HashSet; -import java.util.Set; - public abstract class AbstractJBBPTask extends DefaultTask { public AbstractJBBPTask() { @@ -22,13 +21,16 @@ public AbstractJBBPTask() { } @Nullable - public static String getTextOrFileContent(@Nonnull final JBBPExtension extension, @Nullable final String text, @Nullable final File file) { + public static String getTextOrFileContent(@Nonnull final JBBPExtension extension, + @Nullable final String text, + @Nullable final File file) { String result = null; if (text != null) { result = text; } else if (file != null) { try { - result = FileUtils.readFileToString(file, GetUtils.ensureNonNull(extension.inEncoding, "UTF-8")); + result = + FileUtils.readFileToString(file, GetUtils.ensureNonNull(extension.inEncoding, "UTF-8")); } catch (IOException ex) { throw new GradleException("Can't read file " + file, ex); } diff --git a/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPCleanTask.java b/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPCleanTask.java index c451a395..229b8de6 100644 --- a/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPCleanTask.java +++ b/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPCleanTask.java @@ -1,11 +1,10 @@ package com.igormaznitsa.jbbp.plugin.gradle; import com.igormaznitsa.jbbp.plugin.common.converters.JBBPScriptTranslator; -import org.gradle.api.GradleException; - -import javax.annotation.Nonnull; import java.io.File; import java.io.IOException; +import javax.annotation.Nonnull; +import org.gradle.api.GradleException; /** * Task allows to delete generated files. diff --git a/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPGenerateTask.java b/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPGenerateTask.java index e71ec128..60a1cbed 100644 --- a/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPGenerateTask.java +++ b/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPGenerateTask.java @@ -54,7 +54,8 @@ protected void doTaskAction(@Nonnull final JBBPExtension ext) { final String trimmed = s.trim(); final String normalized = trimmed.toLowerCase(Locale.ENGLISH); if (!normalized.equals(trimmed)) { - getLogger().warn(String.format("Custom type name '%s' in JBBP normal form is '%s' ", trimmed, normalized)); + getLogger().warn(String + .format("Custom type name '%s' in JBBP normal form is '%s' ", trimmed, normalized)); } normalizedCustomTypeNames.add(normalized); } @@ -71,7 +72,9 @@ public String[] getCustomFieldTypes() { } @Override - public boolean isAllowed(@Nonnull final JBBPFieldTypeParameterContainer fieldType, @Nullable final String fieldName, final int extraData, final boolean isArray) { + public boolean isAllowed(@Nonnull final JBBPFieldTypeParameterContainer fieldType, + @Nullable final String fieldName, final int extraData, + final boolean isArray) { final boolean result = normalizedCustomTypeNames.contains(fieldType.getTypeName()); if (!result) { getLogger().warn("Detected not allowed custom type name : " + fieldType.getTypeName()); @@ -81,7 +84,14 @@ public boolean isAllowed(@Nonnull final JBBPFieldTypeParameterContainer fieldTyp @Override @Nonnull - public JBBPAbstractField readCustomFieldType(@Nonnull final JBBPBitInputStream in, @Nonnull final JBBPBitOrder bitOrder, final int parserFlags, @Nonnull final JBBPFieldTypeParameterContainer customTypeFieldInfo, @Nullable final JBBPNamedFieldInfo fieldName, final int extraData, final boolean readWholeStream, final int arrayLength) throws IOException { + public JBBPAbstractField readCustomFieldType(@Nonnull final JBBPBitInputStream in, + @Nonnull final JBBPBitOrder bitOrder, + final int parserFlags, @Nonnull + final JBBPFieldTypeParameterContainer customTypeFieldInfo, + @Nullable final JBBPNamedFieldInfo fieldName, + final int extraData, + final boolean readWholeStream, + final int arrayLength) throws IOException { throw new Error("Must not be called"); } }; @@ -117,19 +127,25 @@ public JBBPAbstractField readCustomFieldType(@Nonnull final JBBPBitInputStream i final Set files = target.getTranslator().translate(parameters, false); getLogger().debug("Converted " + aScript + " into " + files); for (final File f : files) { - getLogger().info(String.format("JBBP script '%s' has been converted into '%s'", aScript.getName(), f.getName())); + getLogger().info(String + .format("JBBP script '%s' has been converted into '%s'", aScript.getName(), + f.getName())); } } catch (IOException ex) { - throw new GradleException("Error during JBBP script translation : " + aScript.getAbsolutePath(), ex); + throw new GradleException( + "Error during JBBP script translation : " + aScript.getAbsolutePath(), ex); } } if (this.addSource) { - getLogger().debug("Registering path to java sources : " + Assertions.assertNotNull("Output must not be null", ext.output)); + getLogger().debug("Registering path to java sources : " + + Assertions.assertNotNull("Output must not be null", ext.output)); if (getProject().getPlugins().hasPlugin(JavaPlugin.class)) { - final JavaPluginConvention javaPluginConvention = getProject().getConvention().getPlugin(JavaPluginConvention.class); - final SourceSet main = javaPluginConvention.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME); + final JavaPluginConvention javaPluginConvention = + getProject().getConvention().getPlugin(JavaPluginConvention.class); + final SourceSet main = + javaPluginConvention.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME); main.getJava().srcDir(ext.output); getLogger().info("Source folder has been added into Java task : " + ext.output); } else { diff --git a/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPPlugin.java b/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPPlugin.java index 44e97439..60001d8c 100644 --- a/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPPlugin.java +++ b/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPPlugin.java @@ -1,10 +1,9 @@ package com.igormaznitsa.jbbp.plugin.gradle; +import javax.annotation.Nonnull; import org.gradle.api.Plugin; import org.gradle.api.Project; -import javax.annotation.Nonnull; - public class JBBPPlugin implements Plugin { @Override diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-customvars/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-customvars/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java index 69b08c68..1234feb7 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-customvars/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-customvars/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java @@ -27,42 +27,69 @@ import com.igormaznitsa.jbbp.model.JBBPFieldLong; import com.igormaznitsa.jbbp.model.JBBPFieldShort; import com.igormaznitsa.mvn.test.jbbp.VarCustom; - import java.io.IOException; public class VarCustomImpl extends VarCustom { @Override - public JBBPAbstractField readCustomFieldType(Object sourceStruct, JBBPBitInputStream inStream, JBBPFieldTypeParameterContainer typeParameterContainer, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean readWholeStream, int arraySize) throws IOException { - return new JBBPFieldShort(nullableNamedFieldInfo, (short) inStream.readUnsignedShort(typeParameterContainer.getByteOrder())); + public JBBPAbstractField readCustomFieldType(Object sourceStruct, JBBPBitInputStream inStream, + JBBPFieldTypeParameterContainer typeParameterContainer, + JBBPNamedFieldInfo nullableNamedFieldInfo, + int extraValue, boolean readWholeStream, + int arraySize) throws IOException { + return new JBBPFieldShort(nullableNamedFieldInfo, + (short) inStream.readUnsignedShort(typeParameterContainer.getByteOrder())); } @Override - public void writeCustomFieldType(Object sourceStruct, JBBPBitOutputStream outStream, JBBPAbstractField fieldValue, JBBPFieldTypeParameterContainer typeParameterContainer, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean wholeArray, int arraySize) throws IOException { - outStream.writeShort(((JBBPFieldShort) fieldValue).getAsInt(), typeParameterContainer.getByteOrder()); + public void writeCustomFieldType(Object sourceStruct, JBBPBitOutputStream outStream, + JBBPAbstractField fieldValue, + JBBPFieldTypeParameterContainer typeParameterContainer, + JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, + boolean wholeArray, int arraySize) throws IOException { + outStream.writeShort(((JBBPFieldShort) fieldValue).getAsInt(), + typeParameterContainer.getByteOrder()); } @Override - public JBBPAbstractField readVarField(Object sourceStruct, JBBPBitInputStream inStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) throws IOException { + public JBBPAbstractField readVarField(Object sourceStruct, JBBPBitInputStream inStream, + JBBPByteOrder byteOrder, + JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) + throws IOException { return new JBBPFieldLong(nullableNamedFieldInfo, inStream.readLong(byteOrder)); } @Override - public JBBPAbstractArrayField readVarArray(Object sourceStruct, JBBPBitInputStream inStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean readWholeStream, int arraySize) throws IOException { + public JBBPAbstractArrayField readVarArray(Object sourceStruct, + JBBPBitInputStream inStream, + JBBPByteOrder byteOrder, + JBBPNamedFieldInfo nullableNamedFieldInfo, + int extraValue, + boolean readWholeStream, + int arraySize) + throws IOException { if (readWholeStream) { return new JBBPFieldArrayLong(nullableNamedFieldInfo, inStream.readLongArray(-1, byteOrder)); } else { - return new JBBPFieldArrayLong(nullableNamedFieldInfo, inStream.readLongArray(arraySize, byteOrder)); + return new JBBPFieldArrayLong(nullableNamedFieldInfo, + inStream.readLongArray(arraySize, byteOrder)); } } @Override - public void writeVarField(Object sourceStruct, JBBPAbstractField value, JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) throws IOException { + public void writeVarField(Object sourceStruct, JBBPAbstractField value, + JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, + JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) + throws IOException { outStream.writeLong(((JBBPFieldLong) value).getAsLong(), byteOrder); } @Override - public void writeVarArray(Object sourceStruct, JBBPAbstractArrayField array, JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, int arraySizeToWrite) throws IOException { + public void writeVarArray(Object sourceStruct, + JBBPAbstractArrayField array, + JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, + JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, + int arraySizeToWrite) throws IOException { final JBBPFieldArrayLong a = (JBBPFieldArrayLong) array; if (arraySizeToWrite < 0) { for (final long l : a.getArray()) { diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-customvars/src/test/java/com/igormaznitsa/mvn/test/jbbp/VarCustomTest.java b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-customvars/src/test/java/com/igormaznitsa/mvn/test/jbbp/VarCustomTest.java index 58d9134e..85347e24 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-customvars/src/test/java/com/igormaznitsa/mvn/test/jbbp/VarCustomTest.java +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-customvars/src/test/java/com/igormaznitsa/mvn/test/jbbp/VarCustomTest.java @@ -16,16 +16,16 @@ package com.igormaznitsa.mvn.test.jbbp; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + + import com.igormaznitsa.jbbp.io.JBBPBitInputStream; import com.igormaznitsa.jbbp.io.JBBPBitOutputStream; import com.igormaznitsa.mvn.tst.VarCustomImpl; -import org.junit.jupiter.api.Test; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.Random; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import org.junit.jupiter.api.Test; public class VarCustomTest { diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations-nonstatic/src/test/java/com/igormaznitsa/mvn/test/jbbp/GenAnnotationsNonStaticTest.java b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations-nonstatic/src/test/java/com/igormaznitsa/mvn/test/jbbp/GenAnnotationsNonStaticTest.java index 8d99671e..ed031763 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations-nonstatic/src/test/java/com/igormaznitsa/mvn/test/jbbp/GenAnnotationsNonStaticTest.java +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations-nonstatic/src/test/java/com/igormaznitsa/mvn/test/jbbp/GenAnnotationsNonStaticTest.java @@ -32,7 +32,8 @@ class GenAnnotationsNonStaticTest { void testReadWrite() throws IOException { final byte[] testData = new byte[] {4, (byte) 0x12, (byte) 0x34, 3, 5, 6, 7}; - final GenAnnotationsNonStatic result = new GenAnnotationsNonStatic().read(new JBBPBitInputStream(new ByteArrayInputStream(testData))); + final GenAnnotationsNonStatic result = new GenAnnotationsNonStatic() + .read(new JBBPBitInputStream(new ByteArrayInputStream(testData))); assertEquals(4, result.getLEN()); assertEquals(3, result.getSOME1().getSOME2().getFIELD().length); @@ -45,10 +46,12 @@ void testReadWrite() throws IOException { + " }" + "}"; - final GenAnnotationsNonStatic instance = JBBPParser.prepare(script).parse(testData).mapTo(new GenAnnotationsNonStatic()); + final GenAnnotationsNonStatic instance = + JBBPParser.prepare(script).parse(testData).mapTo(new GenAnnotationsNonStatic()); assertEquals(result.getLEN(), instance.getLEN()); assertEquals(result.getSOME1().getLEN(), instance.getSOME1().getLEN()); assertArrayEquals(result.getSOME1().getSOMEFIELD(), instance.getSOME1().getSOMEFIELD()); - assertArrayEquals(result.getSOME1().getSOME2().getFIELD(), instance.getSOME1().getSOME2().getFIELD()); + assertArrayEquals(result.getSOME1().getSOME2().getFIELD(), + instance.getSOME1().getSOME2().getFIELD()); } } diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations/src/test/java/com/igormaznitsa/mvn/test/jbbp/GenAnnotationsTest.java b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations/src/test/java/com/igormaznitsa/mvn/test/jbbp/GenAnnotationsTest.java index 350e0b64..04873786 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations/src/test/java/com/igormaznitsa/mvn/test/jbbp/GenAnnotationsTest.java +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations/src/test/java/com/igormaznitsa/mvn/test/jbbp/GenAnnotationsTest.java @@ -32,7 +32,8 @@ class GenAnnotationsTest { void testReadWrite() throws IOException { final byte[] testData = new byte[] {4, (byte) 0x12, (byte) 0x34, 3, 5, 6, 7}; - final GenAnnotations result = new GenAnnotations().read(new JBBPBitInputStream(new ByteArrayInputStream(testData))); + final GenAnnotations result = + new GenAnnotations().read(new JBBPBitInputStream(new ByteArrayInputStream(testData))); assertEquals(4, result.getLEN()); assertEquals(3, result.getSOME1().getSOME2().getFIELD().length); @@ -45,10 +46,12 @@ void testReadWrite() throws IOException { + " }" + "}"; - final GenAnnotations instance = JBBPParser.prepare(script).parse(testData).mapTo(new GenAnnotations()); + final GenAnnotations instance = + JBBPParser.prepare(script).parse(testData).mapTo(new GenAnnotations()); assertEquals(result.getLEN(), instance.getLEN()); assertEquals(result.getSOME1().getLEN(), instance.getSOME1().getLEN()); assertArrayEquals(result.getSOME1().getSOMEFIELD(), instance.getSOME1().getSOMEFIELD()); - assertArrayEquals(result.getSOME1().getSOME2().getFIELD(), instance.getSOME1().getSOME2().getFIELD()); + assertArrayEquals(result.getSOME1().getSOME2().getFIELD(), + instance.getSOME1().getSOME2().getFIELD()); } } diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-getterssetters/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-getterssetters/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java index ac1430f0..b7c6a973 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-getterssetters/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-getterssetters/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java @@ -32,26 +32,47 @@ public class VarCustomImpl extends VarCustom { @Override - public JBBPAbstractField readCustomFieldType(Object sourceStruct, JBBPBitInputStream inStream, JBBPFieldTypeParameterContainer typeParameterContainer, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean readWholeStream, int arraySize) throws IOException { - return new JBBPFieldShort(nullableNamedFieldInfo, (short) inStream.readUnsignedShort(typeParameterContainer.getByteOrder())); + public JBBPAbstractField readCustomFieldType(Object sourceStruct, JBBPBitInputStream inStream, + JBBPFieldTypeParameterContainer typeParameterContainer, + JBBPNamedFieldInfo nullableNamedFieldInfo, + int extraValue, boolean readWholeStream, + int arraySize) throws IOException { + return new JBBPFieldShort(nullableNamedFieldInfo, + (short) inStream.readUnsignedShort(typeParameterContainer.getByteOrder())); } @Override - public void writeCustomFieldType(Object sourceStruct, JBBPBitOutputStream outStream, JBBPAbstractField fieldValue, JBBPFieldTypeParameterContainer typeParameterContainer, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean wholeArray, int arraySize) throws IOException { - outStream.writeShort(((JBBPFieldShort) fieldValue).getAsInt(), typeParameterContainer.getByteOrder()); + public void writeCustomFieldType(Object sourceStruct, JBBPBitOutputStream outStream, + JBBPAbstractField fieldValue, + JBBPFieldTypeParameterContainer typeParameterContainer, + JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, + boolean wholeArray, int arraySize) throws IOException { + outStream.writeShort(((JBBPFieldShort) fieldValue).getAsInt(), + typeParameterContainer.getByteOrder()); } @Override - public JBBPAbstractField readVarField(Object sourceStruct, JBBPBitInputStream inStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) throws IOException { + public JBBPAbstractField readVarField(Object sourceStruct, JBBPBitInputStream inStream, + JBBPByteOrder byteOrder, + JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) + throws IOException { return new JBBPFieldLong(nullableNamedFieldInfo, inStream.readLong(byteOrder)); } @Override - public JBBPAbstractArrayField readVarArray(Object sourceStruct, JBBPBitInputStream inStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean readWholeStream, int arraySize) throws IOException { + public JBBPAbstractArrayField readVarArray(Object sourceStruct, + JBBPBitInputStream inStream, + JBBPByteOrder byteOrder, + JBBPNamedFieldInfo nullableNamedFieldInfo, + int extraValue, + boolean readWholeStream, + int arraySize) + throws IOException { if (readWholeStream) { return new JBBPFieldArrayLong(nullableNamedFieldInfo, inStream.readLongArray(-1, byteOrder)); } else { - return new JBBPFieldArrayLong(nullableNamedFieldInfo, inStream.readLongArray(arraySize, byteOrder)); + return new JBBPFieldArrayLong(nullableNamedFieldInfo, + inStream.readLongArray(arraySize, byteOrder)); } } @@ -60,12 +81,19 @@ public void run() { } @Override - public void writeVarField(Object sourceStruct, JBBPAbstractField value, JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) throws IOException { + public void writeVarField(Object sourceStruct, JBBPAbstractField value, + JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, + JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) + throws IOException { outStream.writeLong(((JBBPFieldLong) value).getAsLong(), byteOrder); } @Override - public void writeVarArray(Object sourceStruct, JBBPAbstractArrayField array, JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, int arraySizeToWrite) throws IOException { + public void writeVarArray(Object sourceStruct, + JBBPAbstractArrayField array, + JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, + JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, + int arraySizeToWrite) throws IOException { final JBBPFieldArrayLong a = (JBBPFieldArrayLong) array; if (arraySizeToWrite < 0) { for (final long l : a.getArray()) { diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-primitives/src/test/java/com/igormaznitsa/mvn/test/jbbp/WholeStreamByteArrayTest.java b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-primitives/src/test/java/com/igormaznitsa/mvn/test/jbbp/WholeStreamByteArrayTest.java index 8f69face..3c9a76fc 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-primitives/src/test/java/com/igormaznitsa/mvn/test/jbbp/WholeStreamByteArrayTest.java +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-primitives/src/test/java/com/igormaznitsa/mvn/test/jbbp/WholeStreamByteArrayTest.java @@ -16,22 +16,23 @@ package com.igormaznitsa.mvn.test.jbbp; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + + import com.igormaznitsa.jbbp.io.JBBPBitInputStream; import com.igormaznitsa.jbbp.io.JBBPBitOutputStream; -import org.junit.jupiter.api.Test; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import org.junit.jupiter.api.Test; public class WholeStreamByteArrayTest { @Test public void testRead_DefaultBitOrder() throws IOException { - final WholeStreamByteArray struct = new WholeStreamByteArray().read(new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}))); + final WholeStreamByteArray struct = new WholeStreamByteArray().read(new JBBPBitInputStream( + new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}))); assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, struct.array); } diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/main/java/com/igormaznitsa/jbbp/plugin/mvn/AbstractJBBPMojo.java b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/main/java/com/igormaznitsa/jbbp/plugin/mvn/AbstractJBBPMojo.java index 85650ad3..66d95075 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/main/java/com/igormaznitsa/jbbp/plugin/mvn/AbstractJBBPMojo.java +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/main/java/com/igormaznitsa/jbbp/plugin/mvn/AbstractJBBPMojo.java @@ -3,6 +3,11 @@ import com.igormaznitsa.jbbp.plugin.common.converters.Target; import com.igormaznitsa.meta.annotation.MustNotContainNull; import com.igormaznitsa.meta.common.utils.Assertions; +import java.io.File; +import java.util.HashSet; +import java.util.Set; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -13,12 +18,6 @@ import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner; import org.codehaus.plexus.compiler.util.scan.mapping.SuffixMapping; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.io.File; -import java.util.HashSet; -import java.util.Set; - public abstract class AbstractJBBPMojo extends AbstractMojo { /** * Provides an explicit list of all the JBBP scripts that should be included @@ -170,7 +169,8 @@ protected void registerSourceRoot(@Nonnull final File outputDir) { @Nonnull public Set findSources(@Nonnull final File targetDirectory) throws MojoExecutionException { try { - final SourceInclusionScanner scanner = new SimpleSourceInclusionScanner(this.includes, this.excludes); + final SourceInclusionScanner scanner = + new SimpleSourceInclusionScanner(this.includes, this.excludes); scanner.addSourceMapping(new SuffixMapping("JBBP", "jbbp")); return scanner.getIncludedSources(this.source, targetDirectory); } catch (InclusionScanException ex) { diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/main/java/com/igormaznitsa/jbbp/plugin/mvn/JBBPCleanMojo.java b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/main/java/com/igormaznitsa/jbbp/plugin/mvn/JBBPCleanMojo.java index bbfa3b67..3bfc7a9d 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/main/java/com/igormaznitsa/jbbp/plugin/mvn/JBBPCleanMojo.java +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/main/java/com/igormaznitsa/jbbp/plugin/mvn/JBBPCleanMojo.java @@ -2,6 +2,9 @@ import com.igormaznitsa.jbbp.plugin.common.converters.JBBPScriptTranslator; import com.igormaznitsa.jbbp.plugin.common.converters.Target; +import java.io.File; +import java.io.IOException; +import java.util.Set; import org.apache.commons.io.FileUtils; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -9,10 +12,6 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; -import java.io.File; -import java.io.IOException; -import java.util.Set; - /** * The Mojo looks for all java files generated for JBBP scripts and delete them. * @@ -67,12 +66,15 @@ public void executeMojo() throws MojoExecutionException, MojoFailureException { if (f.isFile()) { if (f.delete()) { counter++; - logInfo("Deleted file '" + f.getAbsolutePath() + "' for script '" + aScript + "'", true); + logInfo("Deleted file '" + f.getAbsolutePath() + "' for script '" + aScript + "'", + true); } else { - getLog().error("Can't delete file '" + f.getAbsolutePath() + "' for script '" + aScript + "'"); + getLog().error( + "Can't delete file '" + f.getAbsolutePath() + "' for script '" + aScript + "'"); } } else { - getLog().debug("File '" + f.getAbsolutePath() + "' generated for script '" + aScript + "' is not found"); + getLog().debug("File '" + f.getAbsolutePath() + "' generated for script '" + aScript + + "' is not found"); } } } diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/main/java/com/igormaznitsa/jbbp/plugin/mvn/JBBPGenerateMojo.java b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/main/java/com/igormaznitsa/jbbp/plugin/mvn/JBBPGenerateMojo.java index 6171a8c5..1a0997c7 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/main/java/com/igormaznitsa/jbbp/plugin/mvn/JBBPGenerateMojo.java +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/main/java/com/igormaznitsa/jbbp/plugin/mvn/JBBPGenerateMojo.java @@ -202,14 +202,14 @@ public String getSuperClass() { return this.superClass; } - public void setDoAbstract(final boolean value) { - this.doAbstract = value; - } - public boolean isDoAbstract() { return this.doAbstract; } + public void setDoAbstract(final boolean value) { + this.doAbstract = value; + } + @Nonnull public Map getMapStructToInterfaces() { return this.mapStructToInterfaces; @@ -280,14 +280,14 @@ public void setDisableGenerateFields(final boolean value) { this.disableGenerateFields = value; } - public void setDoInnerClassesNonStatic(final boolean value) { - this.doInnerClassesNonStatic = value; - } - public boolean isDoInnerClassesNonStatic() { return this.doInnerClassesNonStatic; } + public void setDoInnerClassesNonStatic(final boolean value) { + this.doInnerClassesNonStatic = value; + } + @Nullable private String makeCapText(@Nonnull final String inEncoding) throws IOException { String result = null; @@ -343,7 +343,8 @@ protected void executeMojo() throws MojoExecutionException, MojoFailureException final String trimmed = s.trim(); final String normalized = trimmed.toLowerCase(Locale.ENGLISH); if (!normalized.equals(trimmed)) { - getLog().warn(String.format("Custom type name '%s' in JBBP normal form is '%s' ", trimmed, normalized)); + getLog().warn(String + .format("Custom type name '%s' in JBBP normal form is '%s' ", trimmed, normalized)); } normalizedCustomTypeNames.add(normalized); } @@ -360,7 +361,9 @@ public String[] getCustomFieldTypes() { } @Override - public boolean isAllowed(@Nonnull final JBBPFieldTypeParameterContainer fieldType, @Nullable final String fieldName, final int extraData, final boolean isArray) { + public boolean isAllowed(@Nonnull final JBBPFieldTypeParameterContainer fieldType, + @Nullable final String fieldName, final int extraData, + final boolean isArray) { final boolean result = normalizedCustomTypeNames.contains(fieldType.getTypeName()); if (!result) { getLog().warn("Detected not allowed custom type name : " + fieldType.getTypeName()); @@ -370,7 +373,14 @@ public boolean isAllowed(@Nonnull final JBBPFieldTypeParameterContainer fieldTyp @Override @Nonnull - public JBBPAbstractField readCustomFieldType(@Nonnull final JBBPBitInputStream in, @Nonnull final JBBPBitOrder bitOrder, final int parserFlags, @Nonnull final JBBPFieldTypeParameterContainer customTypeFieldInfo, @Nullable final JBBPNamedFieldInfo fieldName, final int extraData, final boolean readWholeStream, final int arrayLength) throws IOException { + public JBBPAbstractField readCustomFieldType(@Nonnull final JBBPBitInputStream in, + @Nonnull final JBBPBitOrder bitOrder, + final int parserFlags, @Nonnull + final JBBPFieldTypeParameterContainer customTypeFieldInfo, + @Nullable final JBBPNamedFieldInfo fieldName, + final int extraData, + final boolean readWholeStream, + final int arrayLength) throws IOException { throw new Error("Must not be called"); } }; @@ -407,20 +417,24 @@ public JBBPAbstractField readCustomFieldType(@Nonnull final JBBPBitInputStream i final Set files = theTarget.getTranslator().translate(parameters, false); getLog().debug("Converted " + aScript + " into " + files); for (final File f : files) { - logInfo(String.format("JBBP script '%s' has been converted into '%s'", aScript.getName(), f.getName()), false); + logInfo(String + .format("JBBP script '%s' has been converted into '%s'", aScript.getName(), + f.getName()), false); } } catch (IOException ex) { - throw new MojoExecutionException("Error during JBBP script translation : " + aScript.getAbsolutePath(), ex); + throw new MojoExecutionException( + "Error during JBBP script translation : " + aScript.getAbsolutePath(), ex); } } if (this.isAddToSourceFolders()) { - getLog().info("Add folder to compile source root: "+ this.getOutput().getAbsolutePath()); + getLog().info("Add folder to compile source root: " + this.getOutput().getAbsolutePath()); this.project.addCompileSourceRoot(this.getOutput().getAbsolutePath()); } if (this.isAddToTestSourceFolders()) { - getLog().info("Add folder to test compile source root: "+ this.getOutput().getAbsolutePath()); + getLog() + .info("Add folder to test compile source root: " + this.getOutput().getAbsolutePath()); this.project.addTestCompileSourceRoot(this.getOutput().getAbsolutePath()); } } diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/java/com/igormaznitsa/jbbp/plugin/common/converters/JavaConverterTest.java b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/java/com/igormaznitsa/jbbp/plugin/common/converters/JavaConverterTest.java index bc8aba43..430d4962 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/java/com/igormaznitsa/jbbp/plugin/common/converters/JavaConverterTest.java +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/java/com/igormaznitsa/jbbp/plugin/common/converters/JavaConverterTest.java @@ -32,9 +32,12 @@ void testTranslateParameters() { assertTrue(parameters.setDoInternalClassesNonStatic(true).isDoInternalClassesNonStatic()); assertFalse(parameters.setDoInternalClassesNonStatic(false).isDoInternalClassesNonStatic()); - assertEquals(new File("some_test"), parameters.setOutputDir(new File("some_test")).getOutputDir()); - assertEquals(new File("some_test.script"), parameters.setScriptFile(new File("some_test.script")).getScriptFile()); - assertEquals("some.test.package", parameters.setPackageName("some.test.package").getPackageName()); + assertEquals(new File("some_test"), + parameters.setOutputDir(new File("some_test")).getOutputDir()); + assertEquals(new File("some_test.script"), + parameters.setScriptFile(new File("some_test.script")).getScriptFile()); + assertEquals("some.test.package", + parameters.setPackageName("some.test.package").getPackageName()); assertEquals("bit a;", parameters.setScriptText("bit a;").getScriptText()); assertEquals("SomeSuperClass", parameters.setSuperClass("SomeSuperClass").getSuperClass()); assertEquals(1234, parameters.setParserFlags(1234).getParserFlags()); diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/java/com/igormaznitsa/jbbp/plugin/mvn/JBBPGenerateMojoTest.java b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/java/com/igormaznitsa/jbbp/plugin/mvn/JBBPGenerateMojoTest.java index 35cb965c..8127b70a 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/java/com/igormaznitsa/jbbp/plugin/mvn/JBBPGenerateMojoTest.java +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/java/com/igormaznitsa/jbbp/plugin/mvn/JBBPGenerateMojoTest.java @@ -98,9 +98,12 @@ public void testConfig() throws Exception { assertTrue(mojo.isAddToTestSourceFolders()); assertTrue(mojo.getAddGettersSetters()); assertArrayEquals(new String[] {"abc", "def"}, set2array(mojo.getCustomTypes())); - assertArrayEquals(new String[] {"com.igormaznitsa.InterfaceA", "com.igormaznitsa.InterfaceB"}, set2array(mojo.getInterfaces())); - assertArrayEquals(new String[] {"path1/**/*.jbbp", "path2/**/*.jbbp"}, set2array(mojo.getIncludes())); - assertArrayEquals(new String[] {"path3/**/*.jbbp", "path4/**/*.jbbp"}, set2array(mojo.getExcludes())); + assertArrayEquals(new String[] {"com.igormaznitsa.InterfaceA", "com.igormaznitsa.InterfaceB"}, + set2array(mojo.getInterfaces())); + assertArrayEquals(new String[] {"path1/**/*.jbbp", "path2/**/*.jbbp"}, + set2array(mojo.getIncludes())); + assertArrayEquals(new String[] {"path3/**/*.jbbp", "path4/**/*.jbbp"}, + set2array(mojo.getExcludes())); assertTrue(mojo.isDoInnerClassesNonStatic()); assertTrue(mojo.isDisableGenerateFields()); diff --git a/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/JBBPScriptTranslator.java b/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/JBBPScriptTranslator.java index 94a46b4a..ba7f365c 100644 --- a/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/JBBPScriptTranslator.java +++ b/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/JBBPScriptTranslator.java @@ -47,24 +47,27 @@ public final class Parameters { */ @Nonnull private final Map subClassSuperclasses = new HashMap(); - + /** + * Set of interface names to be implemented by the main class. + */ + @Nonnull + private final Set classImplements = new HashSet(); + /** + * Processor for custom types. + */ + @Nullable + JBBPCustomFieldTypeProcessor customFieldTypeProcessor = null; /** * Flag to not make generated subclasses as static ones. * * @since 1.4.0 */ private boolean doInternalClassesNonStatic; - /** - * Set of interface names to be implemented by the main class. - */ - @Nonnull - private final Set classImplements = new HashSet(); /** * Super class for main class. */ @Nullable private String superClass = null; - /** * Destination file name. * @@ -72,12 +75,6 @@ public final class Parameters { */ @Nullable private String destFileName = null; - - /** - * Processor for custom types. - */ - @Nullable - JBBPCustomFieldTypeProcessor customFieldTypeProcessor = null; /** * Disable generate class fields. * @@ -161,12 +158,6 @@ public Parameters setPackageName(@Nullable final String value) { return this; } - @Nonnull - public Parameters setSuperClass(@Nullable final String value) { - this.superClass = value; - return this; - } - public boolean isAddGettersSetters() { return this.addGettersSetters; } @@ -215,14 +206,22 @@ public Map getSubClassInterfaces() { return Collections.unmodifiableMap(this.subClassInterfaces); } + @Nonnull + public Parameters setSubClassInterfaces(@Nonnull final Map value) { + this.subClassInterfaces.clear(); + this.subClassInterfaces.putAll(value); + return this; + } + @Nonnull public Map getSubClassSuperclasses() { return Collections.unmodifiableMap(this.subClassSuperclasses); } @Nonnull - public Parameters setDoInternalClassesNonStatic(final boolean flag) { - this.doInternalClassesNonStatic = flag; + public Parameters setSubClassSuperclasses(@Nonnull final Map value) { + this.subClassSuperclasses.clear(); + this.subClassSuperclasses.putAll(value); return this; } @@ -230,6 +229,12 @@ public boolean isDoInternalClassesNonStatic() { return this.doInternalClassesNonStatic; } + @Nonnull + public Parameters setDoInternalClassesNonStatic(final boolean flag) { + this.doInternalClassesNonStatic = flag; + return this; + } + public boolean isAddNewInstanceMethods() { return this.addNewInstanceMethods; } @@ -250,20 +255,6 @@ public Parameters setAddBinAnnotations(final boolean flag) { return this; } - @Nonnull - public Parameters setSubClassSuperclasses(@Nonnull final Map value) { - this.subClassSuperclasses.clear(); - this.subClassSuperclasses.putAll(value); - return this; - } - - @Nonnull - public Parameters setSubClassInterfaces(@Nonnull final Map value) { - this.subClassInterfaces.clear(); - this.subClassInterfaces.putAll(value); - return this; - } - public int getParserFlags() { return this.parserFlags; } @@ -367,7 +358,8 @@ public JBBPCustomFieldTypeProcessor getCustomFieldTypeProcessor() { } @Nonnull - public Parameters setCustomFieldTypeProcessor(@Nullable final JBBPCustomFieldTypeProcessor customProcessor) { + public Parameters setCustomFieldTypeProcessor( + @Nullable final JBBPCustomFieldTypeProcessor customProcessor) { this.customFieldTypeProcessor = customProcessor; return this; } @@ -384,5 +376,11 @@ public Parameters assertAllOk() { public String getSuperClass() { return this.superClass; } + + @Nonnull + public Parameters setSuperClass(@Nullable final String value) { + this.superClass = value; + return this; + } } } diff --git a/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/JavaConverter.java b/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/JavaConverter.java index 4ccb8005..28595c4a 100644 --- a/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/JavaConverter.java +++ b/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/JavaConverter.java @@ -20,26 +20,35 @@ public class JavaConverter implements JBBPScriptTranslator { @Override @Nonnull - public Set translate(@Nonnull final Parameters parameters, final boolean dryRun) throws IOException { + public Set translate(@Nonnull final Parameters parameters, final boolean dryRun) + throws IOException { final String text; final String rawFileName; if (parameters.getScriptFile() == null) { - rawFileName = parameters.getDestFileName() == null ? "JbbpNoName" : parameters.getDestFileName(); - text = Assertions.assertNotNull("Script file is null, expected script text", parameters.getScriptText()); + rawFileName = + parameters.getDestFileName() == null ? "JbbpNoName" : parameters.getDestFileName(); + text = Assertions + .assertNotNull("Script file is null, expected script text", parameters.getScriptText()); } else { final File scriptToProcess = parameters.getScriptFile(); rawFileName = FilenameUtils.getBaseName(scriptToProcess.getName()); text = FileUtils.readFileToString(scriptToProcess, parameters.getEncodingIn()); } final String className = CommonUtils.extractClassName(rawFileName); - final String packageName = parameters.getPackageName() == null ? CommonUtils.extractPackageName(rawFileName) : parameters.getPackageName(); + final String packageName = + parameters.getPackageName() == null ? CommonUtils.extractPackageName(rawFileName) : + parameters.getPackageName(); - final Set resultFiles = Collections.singleton(CommonUtils.scriptFileToJavaFile(parameters.getOutputDir(), parameters.getPackageName(), parameters.getScriptFile())); + final Set resultFiles = Collections.singleton(CommonUtils + .scriptFileToJavaFile(parameters.getOutputDir(), parameters.getPackageName(), + parameters.getScriptFile())); if (!dryRun) { final File resultJavaFile = resultFiles.iterator().next(); - final JBBPParser parser = JBBPParser.prepare(text, JBBPBitOrder.LSB0, parameters.customFieldTypeProcessor, parameters.getParserFlags()); + final JBBPParser parser = JBBPParser + .prepare(text, JBBPBitOrder.LSB0, parameters.customFieldTypeProcessor, + parameters.getParserFlags()); final String[] implementsSorted = parameters.getClassImplements().toArray(ARRAY_STRING_EMPTY); Arrays.sort(implementsSorted); diff --git a/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/ParserFlags.java b/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/ParserFlags.java index 852afa2e..65f65acd 100644 --- a/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/ParserFlags.java +++ b/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/ParserFlags.java @@ -1,9 +1,8 @@ package com.igormaznitsa.jbbp.plugin.common.converters; import com.igormaznitsa.jbbp.JBBPParser; - -import javax.annotation.Nullable; import java.util.Set; +import javax.annotation.Nullable; /** * Allowed parser flags. diff --git a/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/utils/CommonUtils.java b/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/utils/CommonUtils.java index 9986cf6c..e4354afb 100644 --- a/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/utils/CommonUtils.java +++ b/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/utils/CommonUtils.java @@ -16,13 +16,12 @@ package com.igormaznitsa.jbbp.plugin.common.utils; -import org.apache.commons.io.FilenameUtils; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.io.File; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.apache.commons.io.FilenameUtils; /** * Misc auxiliary methods. @@ -44,7 +43,8 @@ private CommonUtils() { public static String ensureEncodingName(@Nullable final String charsetName) { final Charset defaultCharset = Charset.defaultCharset(); try { - return (charsetName == null) ? defaultCharset.name() : Charset.forName(charsetName.trim()).name(); + return (charsetName == null) ? defaultCharset.name() : + Charset.forName(charsetName.trim()).name(); } catch (IllegalCharsetNameException ex) { throw new IllegalArgumentException("Can't recognize charset for name '" + charsetName + '\''); } @@ -89,10 +89,13 @@ public static String extractPackageName(@Nonnull final String fileNameWithoutExt * @return java source file for the script file */ @Nonnull - public static File scriptFileToJavaFile(@Nullable final File targetDir, @Nullable final String classPackage, @Nonnull final File scriptFile) { + public static File scriptFileToJavaFile(@Nullable final File targetDir, + @Nullable final String classPackage, + @Nonnull final File scriptFile) { final String rawFileName = FilenameUtils.getBaseName(scriptFile.getName()); final String className = CommonUtils.extractClassName(rawFileName); - final String packageName = classPackage == null ? CommonUtils.extractPackageName(rawFileName) : classPackage; + final String packageName = + classPackage == null ? CommonUtils.extractPackageName(rawFileName) : classPackage; String fullClassName = packageName.isEmpty() ? className : packageName + '.' + className; fullClassName = fullClassName.replace('.', File.separatorChar) + ".java"; diff --git a/jbbp-plugins/jbbp-plugin-common/src/test/java/com/igormaznitsa/jbbp/plugin/common/utils/CommonUtilsTest.java b/jbbp-plugins/jbbp-plugin-common/src/test/java/com/igormaznitsa/jbbp/plugin/common/utils/CommonUtilsTest.java index fedb1916..d53ae44b 100644 --- a/jbbp-plugins/jbbp-plugin-common/src/test/java/com/igormaznitsa/jbbp/plugin/common/utils/CommonUtilsTest.java +++ b/jbbp-plugins/jbbp-plugin-common/src/test/java/com/igormaznitsa/jbbp/plugin/common/utils/CommonUtilsTest.java @@ -18,6 +18,7 @@ import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.assertEquals; public class CommonUtilsTest { diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPCustomFieldTypeProcessor.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPCustomFieldTypeProcessor.java index 25fb3452..e634278f 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPCustomFieldTypeProcessor.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPCustomFieldTypeProcessor.java @@ -21,7 +21,6 @@ import com.igormaznitsa.jbbp.io.JBBPBitInputStream; import com.igormaznitsa.jbbp.io.JBBPBitOrder; import com.igormaznitsa.jbbp.model.JBBPAbstractField; - import java.io.IOException; /** @@ -46,7 +45,8 @@ public interface JBBPCustomFieldTypeProcessor { * @param isArray flag shows that the field describes an array * @return true if such configuration allowed, false otherwise */ - boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, int extraData, boolean isArray); + boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, int extraData, + boolean isArray); /** * Read custom field from stream and return the data as a JBBP field. @@ -62,5 +62,10 @@ public interface JBBPCustomFieldTypeProcessor { * @return parsed data as JBBP field, must not be null * @throws IOException it can be thrown for transport errors */ - JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, int parserFlags, JBBPFieldTypeParameterContainer customTypeFieldInfo, JBBPNamedFieldInfo fieldName, int extraData, boolean readWholeStream, int arrayLength) throws IOException; + JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, + int parserFlags, + JBBPFieldTypeParameterContainer customTypeFieldInfo, + JBBPNamedFieldInfo fieldName, int extraData, + boolean readWholeStream, int arrayLength) + throws IOException; } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPExternalValueProvider.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPExternalValueProvider.java index 1271bb40..360e37fe 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPExternalValueProvider.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPExternalValueProvider.java @@ -32,5 +32,6 @@ public interface JBBPExternalValueProvider { * @param compiledBlock the compiled block for the script to provide extra information * @return the size of an array */ - int provideArraySize(final String fieldName, final JBBPNamedNumericFieldMap numericFieldMap, final JBBPCompiledBlock compiledBlock); + int provideArraySize(final String fieldName, final JBBPNamedNumericFieldMap numericFieldMap, + final JBBPCompiledBlock compiledBlock); } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPNamedNumericFieldMap.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPNamedNumericFieldMap.java index cfde2d4b..0dac9595 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPNamedNumericFieldMap.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPNamedNumericFieldMap.java @@ -26,7 +26,6 @@ import com.igormaznitsa.jbbp.model.JBBPNumericField; import com.igormaznitsa.jbbp.model.finder.JBBPFieldFinder; import com.igormaznitsa.jbbp.utils.JBBPUtils; - import java.util.LinkedHashMap; import java.util.Map; @@ -168,14 +167,16 @@ public T findFieldForType(final Class fieldType } @Override - public T findFieldForNameAndType(final String fieldName, final Class fieldType) { + public T findFieldForNameAndType(final String fieldName, + final Class fieldType) { final String normalizedName = JBBPUtils.normalizeFieldNameOrPath(fieldName); JBBPUtils.assertNotNull(fieldType, "Field type must not be null"); T result = null; for (final Map.Entry f : fieldMap.entrySet()) { - if (normalizedName.equals(f.getKey().getFieldName()) && fieldType.isAssignableFrom(f.getValue().getClass())) { + if (normalizedName.equals(f.getKey().getFieldName()) && + fieldType.isAssignableFrom(f.getValue().getClass())) { result = fieldType.cast(f.getValue()); break; } @@ -184,14 +185,16 @@ public T findFieldForNameAndType(final String fiel } @Override - public T findFieldForPathAndType(final String fieldPath, final Class fieldType) { + public T findFieldForPathAndType(final String fieldPath, + final Class fieldType) { final String normalizedPath = JBBPUtils.normalizeFieldNameOrPath(fieldPath); JBBPUtils.assertNotNull(fieldType, "Field type must not be null"); T result = null; for (final Map.Entry f : fieldMap.entrySet()) { - if (normalizedPath.equals(f.getKey().getFieldPath()) && fieldType.isAssignableFrom(f.getValue().getClass())) { + if (normalizedPath.equals(f.getKey().getFieldPath()) && + fieldType.isAssignableFrom(f.getValue().getClass())) { result = fieldType.cast(f.getValue()); break; } @@ -293,10 +296,13 @@ public int size() { * @return integer value for the field * @throws JBBPException if there is not any external value provider */ - public int getExternalFieldValue(final String externalFieldName, final JBBPCompiledBlock compiledBlock, final JBBPIntegerValueEvaluator evaluator) { + public int getExternalFieldValue(final String externalFieldName, + final JBBPCompiledBlock compiledBlock, + final JBBPIntegerValueEvaluator evaluator) { final String normalizedName = JBBPUtils.normalizeFieldNameOrPath(externalFieldName); if (this.externalValueProvider == null) { - throw new JBBPEvalException("Request for '" + externalFieldName + "' but there is not any value provider", evaluator); + throw new JBBPEvalException( + "Request for '" + externalFieldName + "' but there is not any value provider", evaluator); } else { return this.externalValueProvider.provideArraySize(normalizedName, this, compiledBlock); } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPParser.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPParser.java index 4550802a..0b894eee 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPParser.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPParser.java @@ -76,7 +76,7 @@ * * @since 1.0 */ -@SuppressWarnings( {"WeakerAccess"}) +@SuppressWarnings({"WeakerAccess"}) public final class JBBPParser { /** @@ -124,7 +124,8 @@ public final class JBBPParser { * @param flags special flags for parsing process * @see #FLAG_SKIP_REMAINING_FIELDS_IF_EOF */ - private JBBPParser(final String source, final JBBPBitOrder bitOrder, final JBBPCustomFieldTypeProcessor customFieldTypeProcessor, final int flags) { + private JBBPParser(final String source, final JBBPBitOrder bitOrder, + final JBBPCustomFieldTypeProcessor customFieldTypeProcessor, final int flags) { JBBPUtils.assertNotNull(source, "Script is null"); JBBPUtils.assertNotNull(bitOrder, "Bit order is null"); this.customFieldTypeProcessor = customFieldTypeProcessor; @@ -145,7 +146,9 @@ private JBBPParser(final String source, final JBBPBitOrder bitOrder, final JBBPC */ private static void assertArrayLength(final int length, final JBBPNamedFieldInfo name) { if (length < 0) { - throw new JBBPParsingException("Detected negative calculated array length for field '" + (name == null ? "" : name.getFieldPath()) + "\' [" + JBBPUtils.int2msg(length) + ']'); + throw new JBBPParsingException("Detected negative calculated array length for field '" + + (name == null ? "" : name.getFieldPath()) + "\' [" + JBBPUtils.int2msg(length) + + ']'); } } @@ -175,7 +178,8 @@ public static JBBPParser prepare(final String script, final JBBPBitOrder bitOrde * @see #FLAG_SKIP_REMAINING_FIELDS_IF_EOF * @since 1.1 */ - public static JBBPParser prepare(final String script, final JBBPBitOrder bitOrder, final int flags) { + public static JBBPParser prepare(final String script, final JBBPBitOrder bitOrder, + final int flags) { return new JBBPParser(script, bitOrder, null, flags); } @@ -193,7 +197,9 @@ public static JBBPParser prepare(final String script, final JBBPBitOrder bitOrde * @see #FLAG_SKIP_REMAINING_FIELDS_IF_EOF * @since 1.1.1 */ - public static JBBPParser prepare(final String script, final JBBPBitOrder bitOrder, final JBBPCustomFieldTypeProcessor customFieldTypeProcessor, final int flags) { + public static JBBPParser prepare(final String script, final JBBPBitOrder bitOrder, + final JBBPCustomFieldTypeProcessor customFieldTypeProcessor, + final int flags) { return new JBBPParser(script, bitOrder, customFieldTypeProcessor, flags); } @@ -218,7 +224,8 @@ public static JBBPParser prepare(final String script) { * @see JBBPBitOrder#LSB0 * @since 1.2.0 */ - public static JBBPParser prepare(final String script, final JBBPCustomFieldTypeProcessor customFieldTypeProcessor) { + public static JBBPParser prepare(final String script, + final JBBPCustomFieldTypeProcessor customFieldTypeProcessor) { return JBBPParser.prepare(script, JBBPBitOrder.LSB0, customFieldTypeProcessor, 0); } @@ -255,7 +262,14 @@ public static JBBPParser prepare(final String script, final int flags) { * @return list of read fields for the structure * @throws IOException it will be thrown for transport errors */ - private List parseStruct(final JBBPBitInputStream inStream, final JBBPIntCounter positionAtCompiledBlock, final JBBPVarFieldProcessor varFieldProcessor, final JBBPNamedNumericFieldMap namedNumericFieldMap, final JBBPIntCounter positionAtNamedFieldList, final JBBPIntCounter positionAtVarLengthProcessors, final boolean skipStructureFields) throws IOException { + private List parseStruct(final JBBPBitInputStream inStream, + final JBBPIntCounter positionAtCompiledBlock, + final JBBPVarFieldProcessor varFieldProcessor, + final JBBPNamedNumericFieldMap namedNumericFieldMap, + final JBBPIntCounter positionAtNamedFieldList, + final JBBPIntCounter positionAtVarLengthProcessors, + final boolean skipStructureFields) + throws IOException { final List structureFields = skipStructureFields ? null : new ArrayList<>(); final byte[] compiled = this.compiledBlock.getCompiledData(); @@ -274,17 +288,24 @@ private List parseStruct(final JBBPBitInputStream inStream, f final int code = (ec << 8) | c; final boolean fieldTypeDiff = (ec & JBBPCompiler.EXT_FLAG_EXTRA_DIFF_TYPE) != 0; - final JBBPNamedFieldInfo name = (code & JBBPCompiler.FLAG_NAMED) == 0 ? null : compiledBlock.getNamedFields()[positionAtNamedFieldList.getAndIncrement()]; - final JBBPByteOrder byteOrder = (code & JBBPCompiler.FLAG_LITTLE_ENDIAN) == 0 ? JBBPByteOrder.BIG_ENDIAN : JBBPByteOrder.LITTLE_ENDIAN; + final JBBPNamedFieldInfo name = (code & JBBPCompiler.FLAG_NAMED) == 0 ? null : + compiledBlock.getNamedFields()[positionAtNamedFieldList.getAndIncrement()]; + final JBBPByteOrder byteOrder = + (code & JBBPCompiler.FLAG_LITTLE_ENDIAN) == 0 ? JBBPByteOrder.BIG_ENDIAN : + JBBPByteOrder.LITTLE_ENDIAN; final boolean resultNotIgnored = !skipStructureFields; final int extraFieldNumExprResult; if (extraFieldNumAsExpr) { - final JBBPIntegerValueEvaluator evaluator = this.compiledBlock.getArraySizeEvaluators()[positionAtVarLengthProcessors.getAndIncrement()]; + final JBBPIntegerValueEvaluator evaluator = + this.compiledBlock.getArraySizeEvaluators()[positionAtVarLengthProcessors + .getAndIncrement()]; int resultOfExpression; if (resultNotIgnored) { - resultOfExpression = evaluator.eval(inStream, positionAtCompiledBlock.get(), this.compiledBlock, namedNumericFieldMap); + resultOfExpression = evaluator + .eval(inStream, positionAtCompiledBlock.get(), this.compiledBlock, + namedNumericFieldMap); if ((this.flags & FLAG_NEGATIVE_EXPRESSION_RESULT_AS_ZERO) != 0) { resultOfExpression = Math.max(resultOfExpression, 0); } @@ -299,7 +320,8 @@ private List parseStruct(final JBBPBitInputStream inStream, f final boolean wholeStreamArray; final int arrayLength; final int packedArraySizeOffset; - switch (code & (JBBPCompiler.FLAG_ARRAY | (JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM << 8))) { + switch (code & + (JBBPCompiler.FLAG_ARRAY | (JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM << 8))) { case JBBPCompiler.FLAG_ARRAY: { final int pos = positionAtCompiledBlock.get(); arrayLength = JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); @@ -314,10 +336,14 @@ private List parseStruct(final JBBPBitInputStream inStream, f } break; case JBBPCompiler.FLAG_ARRAY | (JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM << 8): { - final JBBPIntegerValueEvaluator evaluator = this.compiledBlock.getArraySizeEvaluators()[positionAtVarLengthProcessors.getAndIncrement()]; + final JBBPIntegerValueEvaluator evaluator = + this.compiledBlock.getArraySizeEvaluators()[positionAtVarLengthProcessors + .getAndIncrement()]; int resultOfExpression; if (resultNotIgnored) { - resultOfExpression = evaluator.eval(inStream, positionAtCompiledBlock.get(), this.compiledBlock, namedNumericFieldMap); + resultOfExpression = evaluator + .eval(inStream, positionAtCompiledBlock.get(), this.compiledBlock, + namedNumericFieldMap); if ((this.flags & FLAG_NEGATIVE_EXPRESSION_RESULT_AS_ZERO) != 0) { resultOfExpression = Math.max(resultOfExpression, 0); } @@ -349,14 +375,16 @@ private List parseStruct(final JBBPBitInputStream inStream, f } break; case JBBPCompiler.CODE_ALIGN: { - final int alignValue = extraFieldNumAsExpr ? extraFieldNumExprResult : JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); + final int alignValue = extraFieldNumAsExpr ? extraFieldNumExprResult : + JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); if (resultNotIgnored) { inStream.align(alignValue); } } break; case JBBPCompiler.CODE_SKIP: { - final int skipByteNumber = extraFieldNumAsExpr ? extraFieldNumExprResult : JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); + final int skipByteNumber = extraFieldNumAsExpr ? extraFieldNumExprResult : + JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); if (resultNotIgnored) { if (fieldTypeDiff) { singleAtomicField = new JBBPFieldInt(name, skipByteNumber); @@ -364,7 +392,9 @@ private List parseStruct(final JBBPBitInputStream inStream, f if (skipByteNumber > 0) { final long skippedBytes = inStream.skip(skipByteNumber); if (skippedBytes != skipByteNumber) { - throw new EOFException("Can't skip " + skipByteNumber + " byte(s), skipped only " + skippedBytes + " byte(s)"); + throw new EOFException( + "Can't skip " + skipByteNumber + " byte(s), skipped only " + skippedBytes + + " byte(s)"); } } } @@ -372,35 +402,51 @@ private List parseStruct(final JBBPBitInputStream inStream, f } break; case JBBPCompiler.CODE_BIT: { - final int numberOfBits = extraFieldNumAsExpr ? extraFieldNumExprResult : JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); + final int numberOfBits = extraFieldNumAsExpr ? extraFieldNumExprResult : + JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); if (resultNotIgnored) { final JBBPBitNumber bitNumber = JBBPBitNumber.decode(numberOfBits); if (arrayLength < 0) { final int read = inStream.readBitField(bitNumber); singleAtomicField = new JBBPFieldBit(name, read & 0xFF, bitNumber); } else { - structureFields.add(new JBBPFieldArrayBit(name, inStream.readBitsArray(wholeStreamArray ? -1 : arrayLength, bitNumber), bitNumber)); + structureFields.add(new JBBPFieldArrayBit(name, + inStream.readBitsArray(wholeStreamArray ? -1 : arrayLength, bitNumber), + bitNumber)); } } } break; case JBBPCompiler.CODE_VAR: { - final int extraField = extraFieldNumAsExpr ? extraFieldNumExprResult : JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); + final int extraField = extraFieldNumAsExpr ? extraFieldNumExprResult : + JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); if (resultNotIgnored) { if (arrayLength < 0) { - singleAtomicField = varFieldProcessor.readVarField(inStream, name, extraField, byteOrder, namedNumericFieldMap); - JBBPUtils.assertNotNull(singleAtomicField, "A Var processor must not return null as a result of a field reading"); + singleAtomicField = varFieldProcessor + .readVarField(inStream, name, extraField, byteOrder, namedNumericFieldMap); + JBBPUtils.assertNotNull(singleAtomicField, + "A Var processor must not return null as a result of a field reading"); if (singleAtomicField instanceof JBBPAbstractArrayField) { - throw new JBBPParsingException("A Var field processor has returned an array value instead of a field value [" + name + ':' + extraField + ']'); + throw new JBBPParsingException( + "A Var field processor has returned an array value instead of a field value [" + + name + ':' + extraField + ']'); } if (singleAtomicField.getNameInfo() != name) { - throw new JBBPParsingException("Detected wrong name for a read field , must be " + name + " but detected " + singleAtomicField.getNameInfo() + ']'); + throw new JBBPParsingException( + "Detected wrong name for a read field , must be " + name + " but detected " + + singleAtomicField.getNameInfo() + ']'); } } else { - final JBBPAbstractArrayField array = varFieldProcessor.readVarArray(inStream, wholeStreamArray ? -1 : arrayLength, name, extraField, byteOrder, namedNumericFieldMap); - JBBPUtils.assertNotNull(array, "A Var processor must not return null as a result of an array field reading [" + name + ':' + extraField + ']'); + final JBBPAbstractArrayField array = varFieldProcessor + .readVarArray(inStream, wholeStreamArray ? -1 : arrayLength, name, extraField, + byteOrder, namedNumericFieldMap); + JBBPUtils.assertNotNull(array, + "A Var processor must not return null as a result of an array field reading [" + + name + ':' + extraField + ']'); if (array.getNameInfo() != name) { - throw new JBBPParsingException("Detected wrong name for a read field array, must be " + name + " but detected " + array.getNameInfo() + ']'); + throw new JBBPParsingException( + "Detected wrong name for a read field array, must be " + name + + " but detected " + array.getNameInfo() + ']'); } structureFields.add(array); } @@ -408,10 +454,15 @@ private List parseStruct(final JBBPBitInputStream inStream, f } break; case JBBPCompiler.CODE_CUSTOMTYPE: { - final int extraData = extraFieldNumAsExpr ? extraFieldNumExprResult : JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); + final int extraData = extraFieldNumAsExpr ? extraFieldNumExprResult : + JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); if (resultNotIgnored) { - final JBBPFieldTypeParameterContainer fieldTypeInfo = this.compiledBlock.getCustomTypeFields()[JBBPUtils.unpackInt(compiled, positionAtCompiledBlock)]; - final JBBPAbstractField field = this.customFieldTypeProcessor.readCustomFieldType(inStream, this.bitOrder, this.flags, fieldTypeInfo, name, extraData, wholeStreamArray, arrayLength); + final JBBPFieldTypeParameterContainer fieldTypeInfo = + this.compiledBlock.getCustomTypeFields()[JBBPUtils + .unpackInt(compiled, positionAtCompiledBlock)]; + final JBBPAbstractField field = this.customFieldTypeProcessor + .readCustomFieldType(inStream, this.bitOrder, this.flags, fieldTypeInfo, name, + extraData, wholeStreamArray, arrayLength); JBBPUtils.assertNotNull(field, "Must not return null as read result"); if (arrayLength < 0) { @@ -427,7 +478,8 @@ private List parseStruct(final JBBPBitInputStream inStream, f if (arrayLength < 0) { singleAtomicField = new JBBPFieldByte(name, (byte) inStream.readByte()); } else { - structureFields.add(new JBBPFieldArrayByte(name, inStream.readByteArray(wholeStreamArray ? -1 : arrayLength, byteOrder))); + structureFields.add(new JBBPFieldArrayByte(name, + inStream.readByteArray(wholeStreamArray ? -1 : arrayLength, byteOrder))); } } } @@ -437,7 +489,8 @@ private List parseStruct(final JBBPBitInputStream inStream, f if (arrayLength < 0) { singleAtomicField = new JBBPFieldUByte(name, (byte) inStream.readByte()); } else { - structureFields.add(new JBBPFieldArrayUByte(name, inStream.readByteArray(wholeStreamArray ? -1 : arrayLength, byteOrder))); + structureFields.add(new JBBPFieldArrayUByte(name, + inStream.readByteArray(wholeStreamArray ? -1 : arrayLength, byteOrder))); } } } @@ -445,11 +498,15 @@ private List parseStruct(final JBBPBitInputStream inStream, f case JBBPCompiler.CODE_BOOL: { if (resultNotIgnored) { if (arrayLength < 0) { - singleAtomicField = fieldTypeDiff ? new JBBPFieldString(name, inStream.readString(byteOrder)) : new JBBPFieldBoolean(name, inStream.readBoolean()); + singleAtomicField = + fieldTypeDiff ? new JBBPFieldString(name, inStream.readString(byteOrder)) : + new JBBPFieldBoolean(name, inStream.readBoolean()); } else { structureFields.add(fieldTypeDiff ? - new JBBPFieldArrayString(name, inStream.readStringArray(wholeStreamArray ? -1 : arrayLength, byteOrder)) : - new JBBPFieldArrayBoolean(name, inStream.readBoolArray(wholeStreamArray ? -1 : arrayLength)) + new JBBPFieldArrayString(name, + inStream.readStringArray(wholeStreamArray ? -1 : arrayLength, byteOrder)) : + new JBBPFieldArrayBoolean(name, + inStream.readBoolArray(wholeStreamArray ? -1 : arrayLength)) ); } } @@ -458,11 +515,15 @@ private List parseStruct(final JBBPBitInputStream inStream, f case JBBPCompiler.CODE_INT: { if (resultNotIgnored) { if (arrayLength < 0) { - singleAtomicField = fieldTypeDiff ? new JBBPFieldFloat(name, inStream.readFloat(byteOrder)) : new JBBPFieldInt(name, inStream.readInt(byteOrder)); + singleAtomicField = + fieldTypeDiff ? new JBBPFieldFloat(name, inStream.readFloat(byteOrder)) : + new JBBPFieldInt(name, inStream.readInt(byteOrder)); } else { structureFields.add(fieldTypeDiff ? - new JBBPFieldArrayFloat(name, inStream.readFloatArray(wholeStreamArray ? -1 : arrayLength, byteOrder)) : - new JBBPFieldArrayInt(name, inStream.readIntArray(wholeStreamArray ? -1 : arrayLength, byteOrder)) + new JBBPFieldArrayFloat(name, + inStream.readFloatArray(wholeStreamArray ? -1 : arrayLength, byteOrder)) : + new JBBPFieldArrayInt(name, + inStream.readIntArray(wholeStreamArray ? -1 : arrayLength, byteOrder)) ); } } @@ -471,11 +532,15 @@ private List parseStruct(final JBBPBitInputStream inStream, f case JBBPCompiler.CODE_LONG: { if (resultNotIgnored) { if (arrayLength < 0) { - singleAtomicField = fieldTypeDiff ? new JBBPFieldDouble(name, inStream.readDouble(byteOrder)) : new JBBPFieldLong(name, inStream.readLong(byteOrder)); + singleAtomicField = + fieldTypeDiff ? new JBBPFieldDouble(name, inStream.readDouble(byteOrder)) : + new JBBPFieldLong(name, inStream.readLong(byteOrder)); } else { structureFields.add(fieldTypeDiff ? - new JBBPFieldArrayDouble(name, inStream.readDoubleArray(wholeStreamArray ? -1 : arrayLength, byteOrder)) : - new JBBPFieldArrayLong(name, inStream.readLongArray(wholeStreamArray ? -1 : arrayLength, byteOrder)) + new JBBPFieldArrayDouble(name, + inStream.readDoubleArray(wholeStreamArray ? -1 : arrayLength, byteOrder)) : + new JBBPFieldArrayLong(name, + inStream.readLongArray(wholeStreamArray ? -1 : arrayLength, byteOrder)) ); } } @@ -487,7 +552,8 @@ private List parseStruct(final JBBPBitInputStream inStream, f final int value = inStream.readUnsignedShort(byteOrder); singleAtomicField = new JBBPFieldShort(name, (short) value); } else { - structureFields.add(new JBBPFieldArrayShort(name, inStream.readShortArray(wholeStreamArray ? -1 : arrayLength, byteOrder))); + structureFields.add(new JBBPFieldArrayShort(name, + inStream.readShortArray(wholeStreamArray ? -1 : arrayLength, byteOrder))); } } } @@ -498,18 +564,23 @@ private List parseStruct(final JBBPBitInputStream inStream, f final int value = inStream.readUnsignedShort(byteOrder); singleAtomicField = new JBBPFieldUShort(name, (short) value); } else { - structureFields.add(new JBBPFieldArrayUShort(name, inStream.readShortArray(wholeStreamArray ? -1 : arrayLength, byteOrder))); + structureFields.add(new JBBPFieldArrayUShort(name, + inStream.readShortArray(wholeStreamArray ? -1 : arrayLength, byteOrder))); } } } break; case JBBPCompiler.CODE_STRUCT_START: { if (arrayLength < 0) { - final List structFields = parseStruct(inStream, positionAtCompiledBlock, varFieldProcessor, namedNumericFieldMap, positionAtNamedFieldList, positionAtVarLengthProcessors, skipStructureFields); + final List structFields = + parseStruct(inStream, positionAtCompiledBlock, varFieldProcessor, + namedNumericFieldMap, positionAtNamedFieldList, positionAtVarLengthProcessors, + skipStructureFields); // skip offset JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); if (resultNotIgnored) { - structureFields.add(new JBBPFieldStruct(name, structFields.toArray(ARRAY_FIELD_EMPTY))); + structureFields + .add(new JBBPFieldStruct(name, structFields.toArray(ARRAY_FIELD_EMPTY))); } } else { final int nameFieldCurrent = positionAtNamedFieldList.get(); @@ -524,7 +595,10 @@ private List parseStruct(final JBBPBitInputStream inStream, f positionAtNamedFieldList.set(nameFieldCurrent); positionAtVarLengthProcessors.set(varLenProcCurrent); - final List fieldsForStruct = parseStruct(inStream, positionAtCompiledBlock, varFieldProcessor, namedNumericFieldMap, positionAtNamedFieldList, positionAtVarLengthProcessors, skipStructureFields); + final List fieldsForStruct = + parseStruct(inStream, positionAtCompiledBlock, varFieldProcessor, + namedNumericFieldMap, positionAtNamedFieldList, + positionAtVarLengthProcessors, skipStructureFields); list.add(new JBBPFieldStruct(name, fieldsForStruct)); final int structStart = JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); @@ -540,14 +614,20 @@ private List parseStruct(final JBBPBitInputStream inStream, f if (arrayLength == 0) { // skip the structure result = EMPTY_STRUCT_ARRAY; - parseStruct(inStream, positionAtCompiledBlock, varFieldProcessor, namedNumericFieldMap, positionAtNamedFieldList, positionAtVarLengthProcessors, true); + parseStruct(inStream, positionAtCompiledBlock, varFieldProcessor, + namedNumericFieldMap, positionAtNamedFieldList, + positionAtVarLengthProcessors, true); JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); } else { result = new JBBPFieldStruct[arrayLength]; for (int i = 0; i < arrayLength; i++) { - final List fieldsForStruct = parseStruct(inStream, positionAtCompiledBlock, varFieldProcessor, namedNumericFieldMap, positionAtNamedFieldList, positionAtVarLengthProcessors, skipStructureFields); - final int structBodyStart = JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); + final List fieldsForStruct = + parseStruct(inStream, positionAtCompiledBlock, varFieldProcessor, + namedNumericFieldMap, positionAtNamedFieldList, + positionAtVarLengthProcessors, skipStructureFields); + final int structBodyStart = + JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); result[i] = new JBBPFieldStruct(name, fieldsForStruct); @@ -555,7 +635,8 @@ private List parseStruct(final JBBPBitInputStream inStream, f // not the last positionAtNamedFieldList.set(nameFieldCurrent); positionAtVarLengthProcessors.set(varLenProcCurrent); - positionAtCompiledBlock.set(structBodyStart + packedArraySizeOffset + (wideCode ? 2 : 1)); + positionAtCompiledBlock + .set(structBodyStart + packedArraySizeOffset + (wideCode ? 2 : 1)); } } } @@ -565,7 +646,9 @@ private List parseStruct(final JBBPBitInputStream inStream, f structureFields.add(new JBBPFieldArrayStruct(name, result)); } } else { - parseStruct(inStream, positionAtCompiledBlock, varFieldProcessor, namedNumericFieldMap, positionAtNamedFieldList, positionAtVarLengthProcessors, skipStructureFields); + parseStruct(inStream, positionAtCompiledBlock, varFieldProcessor, + namedNumericFieldMap, positionAtNamedFieldList, positionAtVarLengthProcessors, + skipStructureFields); JBBPUtils.unpackInt(compiled, positionAtCompiledBlock); } } @@ -583,13 +666,15 @@ private List parseStruct(final JBBPBitInputStream inStream, f if (name == null) { throw ex; } else { - throw new JBBPParsingException("Can't parse field '" + name.getFieldPath() + "' for IOException", ex); + throw new JBBPParsingException( + "Can't parse field '" + name.getFieldPath() + "' for IOException", ex); } } if (singleAtomicField != null) { structureFields.add(singleAtomicField); - if (namedNumericFieldMap != null && singleAtomicField instanceof JBBPNumericField && name != null) { + if (namedNumericFieldMap != null && singleAtomicField instanceof JBBPNumericField && + name != null) { namedNumericFieldMap.putField((JBBPNumericField) singleAtomicField); } } @@ -622,8 +707,12 @@ public JBBPFieldStruct parse(final InputStream in) throws IOException { * @return the parsed content as the root structure * @throws IOException it will be thrown for transport errors */ - public JBBPFieldStruct parse(final InputStream in, final JBBPVarFieldProcessor varFieldProcessor, final JBBPExternalValueProvider externalValueProvider) throws IOException { - final JBBPBitInputStream bitInStream = in instanceof JBBPBitInputStream ? (JBBPBitInputStream) in : new JBBPBitInputStream(in, bitOrder); + public JBBPFieldStruct parse(final InputStream in, final JBBPVarFieldProcessor varFieldProcessor, + final JBBPExternalValueProvider externalValueProvider) + throws IOException { + final JBBPBitInputStream bitInStream = + in instanceof JBBPBitInputStream ? (JBBPBitInputStream) in : + new JBBPBitInputStream(in, bitOrder); this.finalStreamByteCounter = bitInStream.getCounter(); final JBBPNamedNumericFieldMap fieldMap; @@ -634,10 +723,13 @@ public JBBPFieldStruct parse(final InputStream in, final JBBPVarFieldProcessor v } if (this.compiledBlock.hasVarFields()) { - JBBPUtils.assertNotNull(varFieldProcessor, "The Script contains VAR fields, a var field processor must be provided"); + JBBPUtils.assertNotNull(varFieldProcessor, + "The Script contains VAR fields, a var field processor must be provided"); } try { - return new JBBPFieldStruct(new JBBPNamedFieldInfo("", "", -1), parseStruct(bitInStream, new JBBPIntCounter(), varFieldProcessor, fieldMap, new JBBPIntCounter(), new JBBPIntCounter(), false)); + return new JBBPFieldStruct(new JBBPNamedFieldInfo("", "", -1), + parseStruct(bitInStream, new JBBPIntCounter(), varFieldProcessor, fieldMap, + new JBBPIntCounter(), new JBBPIntCounter(), false)); } finally { this.finalStreamByteCounter = bitInStream.getCounter(); } @@ -678,7 +770,9 @@ public JBBPFieldStruct parse(final byte[] array) throws IOException { * @return the parsed content as the root structure * @throws IOException it will be thrown for transport errors */ - public JBBPFieldStruct parse(final byte[] array, final JBBPVarFieldProcessor varFieldProcessor, final JBBPExternalValueProvider externalValueProvider) throws IOException { + public JBBPFieldStruct parse(final byte[] array, final JBBPVarFieldProcessor varFieldProcessor, + final JBBPExternalValueProvider externalValueProvider) + throws IOException { JBBPUtils.assertNotNull(array, "Array must not be null"); return this.parse(new ByteArrayInputStream(array), varFieldProcessor, externalValueProvider); } @@ -737,8 +831,11 @@ public List convertToSrc(final TargetSources target, final String className = name.substring(nameStart + 1); } - final String resultSources = JBBPToJavaConverter.makeBuilder(this).setMainClassPackage(packageName).setMainClassName(className).build().convert(); - final Map resultMap = Collections.singletonMap(name.replace('.', '/') + ".java", resultSources); + final String resultSources = + JBBPToJavaConverter.makeBuilder(this).setMainClassPackage(packageName) + .setMainClassName(className).build().convert(); + final Map resultMap = + Collections.singletonMap(name.replace('.', '/') + ".java", resultSources); return Collections.singletonList(new ResultSrcItem() { @Override diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPVarFieldProcessor.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPVarFieldProcessor.java index ec7aebf4..8afbc15c 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPVarFieldProcessor.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPVarFieldProcessor.java @@ -21,7 +21,6 @@ import com.igormaznitsa.jbbp.io.JBBPByteOrder; import com.igormaznitsa.jbbp.model.JBBPAbstractArrayField; import com.igormaznitsa.jbbp.model.JBBPAbstractField; - import java.io.IOException; /** @@ -42,7 +41,13 @@ public interface JBBPVarFieldProcessor { * @return a field array without nulls as values, it must not return null * @throws IOException it can be thrown for transport errors or another process exceptions */ - JBBPAbstractArrayField readVarArray(JBBPBitInputStream inStream, int arraySize, JBBPNamedFieldInfo fieldName, int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) throws IOException; + JBBPAbstractArrayField readVarArray(JBBPBitInputStream inStream, + int arraySize, + JBBPNamedFieldInfo fieldName, + int extraValue, + JBBPByteOrder byteOrder, + JBBPNamedNumericFieldMap numericFieldMap) + throws IOException; /** * Read a field from a stream. The Method must read a field from a stream and return it with the provided name field info. @@ -59,5 +64,7 @@ public interface JBBPVarFieldProcessor { * @return a read field object, it must not return null * @throws IOException it should be thrown for transport errors */ - JBBPAbstractField readVarField(JBBPBitInputStream inStream, JBBPNamedFieldInfo fieldName, int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) throws IOException; + JBBPAbstractField readVarField(JBBPBitInputStream inStream, JBBPNamedFieldInfo fieldName, + int extraValue, JBBPByteOrder byteOrder, + JBBPNamedNumericFieldMap numericFieldMap) throws IOException; } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompiledBlock.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompiledBlock.java index 7a92cdd7..7a9aab5c 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompiledBlock.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompiledBlock.java @@ -21,7 +21,6 @@ import com.igormaznitsa.jbbp.exceptions.JBBPException; import com.igormaznitsa.jbbp.exceptions.JBBPIllegalArgumentException; import com.igormaznitsa.jbbp.utils.JBBPUtils; - import java.util.ArrayList; import java.util.List; @@ -34,8 +33,10 @@ public final class JBBPCompiledBlock { private static final JBBPNamedFieldInfo[] ARRAY_FIELDINFO_EMPTY = new JBBPNamedFieldInfo[0]; - private static final JBBPIntegerValueEvaluator[] ARRAY_INTEVALUATOR_EMPTY = new JBBPIntegerValueEvaluator[0]; - private static final JBBPFieldTypeParameterContainer[] ARRAY_FIELDTYPE_EMPTY = new JBBPFieldTypeParameterContainer[0]; + private static final JBBPIntegerValueEvaluator[] ARRAY_INTEVALUATOR_EMPTY = + new JBBPIntegerValueEvaluator[0]; + private static final JBBPFieldTypeParameterContainer[] ARRAY_FIELDTYPE_EMPTY = + new JBBPFieldTypeParameterContainer[0]; /** * The Array of named field info items. @@ -74,7 +75,10 @@ public final class JBBPCompiledBlock { * @param compiledData compiled data block * @param hasVarFields the flag shows that te block contains var fields */ - private JBBPCompiledBlock(final String source, final JBBPNamedFieldInfo[] namedFields, final JBBPIntegerValueEvaluator[] arraySizeEvaluators, final byte[] compiledData, final boolean hasVarFields, final JBBPFieldTypeParameterContainer[] customTypeFields) { + private JBBPCompiledBlock(final String source, final JBBPNamedFieldInfo[] namedFields, + final JBBPIntegerValueEvaluator[] arraySizeEvaluators, + final byte[] compiledData, final boolean hasVarFields, + final JBBPFieldTypeParameterContainer[] customTypeFields) { this.source = source; this.namedFieldData = namedFields; this.hasVarFields = hasVarFields; @@ -215,7 +219,10 @@ public JBBPCompiledBlock build() { JBBPUtils.assertNotNull(source, "Source is not defined"); JBBPUtils.assertNotNull(compiledData, "Compiled data is not defined"); - return new JBBPCompiledBlock(this.source, this.namedFields.toArray(ARRAY_FIELDINFO_EMPTY), this.varLenProcessors.isEmpty() ? null : this.varLenProcessors.toArray(ARRAY_INTEVALUATOR_EMPTY), this.compiledData, this.hasVarFields, this.customTypeFields.toArray(ARRAY_FIELDTYPE_EMPTY)); + return new JBBPCompiledBlock(this.source, this.namedFields.toArray(ARRAY_FIELDINFO_EMPTY), + this.varLenProcessors.isEmpty() ? null : + this.varLenProcessors.toArray(ARRAY_INTEVALUATOR_EMPTY), this.compiledData, + this.hasVarFields, this.customTypeFields.toArray(ARRAY_FIELDTYPE_EMPTY)); } /** diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompiler.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompiler.java index 8c0891d0..b2165283 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompiler.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompiler.java @@ -29,7 +29,6 @@ import com.igormaznitsa.jbbp.model.JBBPFieldFloat; import com.igormaznitsa.jbbp.model.JBBPFieldString; import com.igormaznitsa.jbbp.utils.JBBPUtils; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -157,7 +156,8 @@ public static JBBPCompiledBlock compile(final String script) throws IOException private static void assertTokenNotArray(final String fieldType, final JBBPToken token) { if (token.getArraySizeAsString() != null) { final String fieldName = token.getFieldName() == null ? "" : token.getFieldName(); - throw new JBBPCompilationException('\'' + fieldType + "' can't be array (" + fieldName + ')', token); + throw new JBBPCompilationException('\'' + fieldType + "' can't be array (" + fieldName + ')', + token); } } @@ -169,7 +169,8 @@ private static void assertTokenNamed(final String fieldType, final JBBPToken tok private static void assertTokenNotNamed(final String fieldType, final JBBPToken token) { if (token.getFieldName() != null) { - throw new JBBPCompilationException('\'' + fieldType + "' must not be named (" + token.getFieldName() + ')', token); + throw new JBBPCompilationException( + '\'' + fieldType + "' must not be named (" + token.getFieldName() + ')', token); } } @@ -179,7 +180,8 @@ private static void assertTokenHasExtraData(final String fieldType, final JBBPTo } } - private static void assertTokenDoesntHaveExtraData(final String fieldType, final JBBPToken token) { + private static void assertTokenDoesntHaveExtraData(final String fieldType, + final JBBPToken token) { if (token.getFieldTypeParameters().getExtraData() != null) { throw new JBBPCompilationException('\'' + fieldType + "\' has extra value", token); } @@ -196,7 +198,9 @@ private static void assertTokenDoesntHaveExtraData(final String fieldType, final * @throws JBBPException it will be thrown for any logical or work exception * for the parser and compiler */ - public static JBBPCompiledBlock compile(final String script, final JBBPCustomFieldTypeProcessor customTypeFieldProcessor) throws IOException { + public static JBBPCompiledBlock compile(final String script, + final JBBPCustomFieldTypeProcessor customTypeFieldProcessor) + throws IOException { JBBPUtils.assertNotNull(script, "Script must not be null"); final JBBPCompiledBlock.Builder builder = JBBPCompiledBlock.prepare().setSource(script); @@ -238,7 +242,8 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie int extraFieldNumberAsInt = -1; int customTypeFieldIndex = -1; - final boolean extraFieldNumericDataAsExpression = ((code >>> 8) & EXT_FLAG_EXTRA_AS_EXPRESSION) != 0; + final boolean extraFieldNumericDataAsExpression = + ((code >>> 8) & EXT_FLAG_EXTRA_AS_EXPRESSION) != 0; final boolean fieldTypeDiff = ((code >>> 8) & EXT_FLAG_EXTRA_DIFF_TYPE) != 0; switch (code & 0xF) { @@ -252,7 +257,9 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie case CODE_LONG: { if ((code & 0x0F) == CODE_CUSTOMTYPE) { if (extraFieldNumericDataAsExpression) { - varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance().make(token.getFieldTypeParameters().getExtraDataExpression(), namedFields, out.toByteArray())); + varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance() + .make(token.getFieldTypeParameters().getExtraDataExpression(), namedFields, + out.toByteArray())); } else { final String extraDataAsStr = token.getFieldTypeParameters().getExtraData(); if (extraDataAsStr == null) { @@ -261,12 +268,15 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie try { extraFieldNumberAsInt = Integer.parseInt(extraDataAsStr); } catch (NumberFormatException ex) { - throw new JBBPCompilationException("Can't parse extra data, must be numeric", token); + throw new JBBPCompilationException("Can't parse extra data, must be numeric", + token); } } writeExtraFieldNumberInCompiled = true; } - if (customTypeFieldProcessor.isAllowed(token.getFieldTypeParameters(), token.getFieldName(), extraFieldNumberAsInt, token.isArray())) { + if (customTypeFieldProcessor + .isAllowed(token.getFieldTypeParameters(), token.getFieldName(), + extraFieldNumberAsInt, token.isArray())) { customTypeFieldIndex = customTypeFields.size(); customTypeFields.add(token.getFieldTypeParameters()); } else { @@ -285,7 +295,9 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie assertTokenNotNamed("skip", token); } if (extraFieldNumericDataAsExpression) { - varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance().make(token.getFieldTypeParameters().getExtraDataExpression(), namedFields, out.toByteArray())); + varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance() + .make(token.getFieldTypeParameters().getExtraDataExpression(), namedFields, + out.toByteArray())); } else { final String extraNumberAsStr = token.getFieldTypeParameters().getExtraData(); writeExtraFieldNumberInCompiled = true; @@ -309,7 +321,9 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie assertTokenNotNamed("align", token); if (extraFieldNumericDataAsExpression) { - varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance().make(token.getFieldTypeParameters().getExtraDataExpression(), namedFields, out.toByteArray())); + varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance() + .make(token.getFieldTypeParameters().getExtraDataExpression(), namedFields, + out.toByteArray())); } else { final String extraNumberAsStr = token.getFieldTypeParameters().getExtraData(); writeExtraFieldNumberInCompiled = true; @@ -323,7 +337,8 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie extraFieldNumberAsInt = -1; } if (extraFieldNumberAsInt <= 0) { - throw new JBBPCompilationException("'align' size must be greater than zero [" + token.getFieldTypeParameters().getExtraData() + ']', token); + throw new JBBPCompilationException("'align' size must be greater than zero [" + + token.getFieldTypeParameters().getExtraData() + ']', token); } } } @@ -331,7 +346,9 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie break; case CODE_BIT: { if (extraFieldNumericDataAsExpression) { - varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance().make(token.getFieldTypeParameters().getExtraDataExpression(), namedFields, out.toByteArray())); + varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance() + .make(token.getFieldTypeParameters().getExtraDataExpression(), namedFields, + out.toByteArray())); } else { final String extraFieldNumAsStr = token.getFieldTypeParameters().getExtraData(); writeExtraFieldNumberInCompiled = true; @@ -345,7 +362,9 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie extraFieldNumberAsInt = -1; } if (extraFieldNumberAsInt < 1 || extraFieldNumberAsInt > 8) { - throw new JBBPCompilationException("Bit-width must be 1..8 [" + token.getFieldTypeParameters().getExtraData() + ']', token); + throw new JBBPCompilationException( + "Bit-width must be 1..8 [" + token.getFieldTypeParameters().getExtraData() + + ']', token); } } } @@ -354,7 +373,9 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie case CODE_VAR: { hasVarFields = true; if (extraFieldNumericDataAsExpression) { - varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance().make(token.getFieldTypeParameters().getExtraDataExpression(), namedFields, out.toByteArray())); + varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance() + .make(token.getFieldTypeParameters().getExtraDataExpression(), namedFields, + out.toByteArray())); } else { final String extraFieldNumStr = token.getFieldTypeParameters().getExtraData(); writeExtraFieldNumberInCompiled = true; @@ -364,7 +385,9 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie try { extraFieldNumberAsInt = Integer.parseInt(extraFieldNumStr); } catch (NumberFormatException ex) { - throw new JBBPCompilationException("Can't parse the extra value of a VAR field, must be integer [" + token.getFieldTypeParameters().getExtraData() + ']', token); + throw new JBBPCompilationException( + "Can't parse the extra value of a VAR field, must be integer [" + + token.getFieldTypeParameters().getExtraData() + ']', token); } } } @@ -377,18 +400,26 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie } break; case CODE_STRUCT_START: { - final boolean arrayReadTillEnd = (code & FLAG_ARRAY) != 0 && (extraCode & EXT_FLAG_EXPRESSION_OR_WHOLESTREAM) != 0 && "_".equals(token.getArraySizeAsString()); - structureStack.add(new StructStackItem(namedFields.size() + ((code & JBBPCompiler.FLAG_NAMED) == 0 ? 0 : 1), startFieldOffset, arrayReadTillEnd, code, token)); + final boolean arrayReadTillEnd = + (code & FLAG_ARRAY) != 0 && (extraCode & EXT_FLAG_EXPRESSION_OR_WHOLESTREAM) != 0 && + "_".equals(token.getArraySizeAsString()); + structureStack.add(new StructStackItem( + namedFields.size() + ((code & JBBPCompiler.FLAG_NAMED) == 0 ? 0 : 1), + startFieldOffset, arrayReadTillEnd, code, token)); } break; case CODE_STRUCT_END: { if (structureStack.isEmpty()) { - throw new JBBPCompilationException("Detected structure close tag without opening one", token); + throw new JBBPCompilationException("Detected structure close tag without opening one", + token); } else { if (fieldUnrestrictedArrayOffset >= 0) { final StructStackItem startOfStruct = structureStack.get(structureStack.size() - 1); - if (startOfStruct.arrayToReadTillEndOfStream && fieldUnrestrictedArrayOffset != startOfStruct.startStructureOffset) { - throw new JBBPCompilationException("Detected unlimited array of structures but there is already presented one", token); + if (startOfStruct.arrayToReadTillEndOfStream && + fieldUnrestrictedArrayOffset != startOfStruct.startStructureOffset) { + throw new JBBPCompilationException( + "Detected unlimited array of structures but there is already presented one", + token); } } @@ -398,28 +429,33 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie } break; default: - throw new Error("Detected unsupported compiled code, notify the developer please [" + code + ']'); + throw new Error( + "Detected unsupported compiled code, notify the developer please [" + code + ']'); } if ((code & FLAG_ARRAY) == 0) { - if (structureStack.isEmpty() && (code & 0x0F) != CODE_STRUCT_END && fieldUnrestrictedArrayOffset >= 0) { - throw new JBBPCompilationException("Detected field defined after unlimited array", token); + if (structureStack.isEmpty() && (code & 0x0F) != CODE_STRUCT_END && + fieldUnrestrictedArrayOffset >= 0) { + throw new JBBPCompilationException("Detected field defined after unlimited array", token); } } else { if ((extraCode & EXT_FLAG_EXPRESSION_OR_WHOLESTREAM) != 0) { if ("_".equals(token.getArraySizeAsString())) { if (fieldUnrestrictedArrayOffset >= 0) { - throw new JBBPCompilationException("Detected two or more unlimited arrays [" + script + ']', token); + throw new JBBPCompilationException( + "Detected two or more unlimited arrays [" + script + ']', token); } else { fieldUnrestrictedArrayOffset = startFieldOffset; } } else { - varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance().make(token.getArraySizeAsString(), namedFields, out.toByteArray())); + varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance() + .make(token.getArraySizeAsString(), namedFields, out.toByteArray())); } } else { final int fixedArraySize = token.getArraySizeAsInt(); if (fixedArraySize <= 0) { - throw new JBBPCompilationException("Detected an array with negative or zero fixed length", token); + throw new JBBPCompilationException( + "Detected an array with negative or zero fixed length", token); } offset += writePackedInt(out, fixedArraySize); } @@ -436,31 +472,37 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie if ((code & FLAG_NAMED) != 0) { final String normalizedName = JBBPUtils.normalizeFieldNameOrPath(token.getFieldName()); assertName(normalizedName, token); - registerNamedField(normalizedName, structureStack.isEmpty() ? 0 : structureStack.get(structureStack.size() - 1).namedFieldCounter, startFieldOffset, namedFields, token); + registerNamedField(normalizedName, structureStack.isEmpty() ? 0 : + structureStack.get(structureStack.size() - 1).namedFieldCounter, startFieldOffset, + namedFields, token); } else { if (currentClosedStructure != null && (currentClosedStructure.code & FLAG_NAMED) != 0) { // it is structure, process field names - final String normalizedName = JBBPUtils.normalizeFieldNameOrPath(currentClosedStructure.token.getFieldName()); + final String normalizedName = + JBBPUtils.normalizeFieldNameOrPath(currentClosedStructure.token.getFieldName()); for (int i = namedFields.size() - 1; i >= 0; i--) { final JBBPNamedFieldInfo f = namedFields.get(i); if (f.getFieldOffsetInCompiledBlock() <= currentClosedStructure.startStructureOffset) { break; } final String newFullName = normalizedName + '.' + f.getFieldPath(); - namedFields.set(i, new JBBPNamedFieldInfo(newFullName, f.getFieldName(), f.getFieldOffsetInCompiledBlock())); + namedFields.set(i, new JBBPNamedFieldInfo(newFullName, f.getFieldName(), + f.getFieldOffsetInCompiledBlock())); } } } } if (!structureStack.isEmpty()) { - throw new JBBPCompilationException("Detected non-closed " + structureStack.size() + " structure(s)"); + throw new JBBPCompilationException( + "Detected non-closed " + structureStack.size() + " structure(s)"); } final byte[] compiledBlock = out.toByteArray(); if (fieldUnrestrictedArrayOffset >= 0) { - compiledBlock[fieldUnrestrictedArrayOffset] = (byte) (compiledBlock[fieldUnrestrictedArrayOffset] & ~FLAG_ARRAY); + compiledBlock[fieldUnrestrictedArrayOffset] = + (byte) (compiledBlock[fieldUnrestrictedArrayOffset] & ~FLAG_ARRAY); } return builder @@ -481,7 +523,9 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie */ private static void assertNonNegativeValue(final int value, final JBBPToken token) { if (value < 0) { - throw new JBBPCompilationException("Detected unsupported negative value for a field must have only zero or a positive one", token); + throw new JBBPCompilationException( + "Detected unsupported negative value for a field must have only zero or a positive one", + token); } } @@ -494,7 +538,8 @@ private static void assertNonNegativeValue(final int value, final JBBPToken toke */ private static void assertName(final String name, final JBBPToken token) { if (name.indexOf('.') >= 0) { - throw new JBBPCompilationException("Detected disallowed char '.' in name [" + name + ']', token); + throw new JBBPCompilationException("Detected disallowed char '.' in name [" + name + ']', + token); } } @@ -508,11 +553,15 @@ private static void assertName(final String name, final JBBPToken token) { * @throws JBBPCompilationException if there is already a registered field for * the path */ - private static void registerNamedField(final String normalizedName, final int structureBorder, final int offset, final List namedFields, final JBBPToken token) { + private static void registerNamedField(final String normalizedName, final int structureBorder, + final int offset, + final List namedFields, + final JBBPToken token) { for (int i = namedFields.size() - 1; i >= structureBorder; i--) { final JBBPNamedFieldInfo info = namedFields.get(i); if (info.getFieldPath().equals(normalizedName)) { - throw new JBBPCompilationException("Duplicated named field detected [" + normalizedName + ']', token); + throw new JBBPCompilationException( + "Duplicated named field detected [" + normalizedName + ']', token); } } namedFields.add(new JBBPNamedFieldInfo(normalizedName, normalizedName, offset)); @@ -540,7 +589,8 @@ private static int writePackedInt(final OutputStream out, final int value) throw * it can be null * @return the prepared byte code for the token */ - private static int prepareCodeForToken(final JBBPToken token, final JBBPCustomFieldTypeProcessor customTypeFieldProcessor) { + private static int prepareCodeForToken(final JBBPToken token, + final JBBPCustomFieldTypeProcessor customTypeFieldProcessor) { int result = -1; switch (token.getType()) { case ATOM: { @@ -550,9 +600,11 @@ private static int prepareCodeForToken(final JBBPToken token, final JBBPCustomFi final boolean hasExpressionAsExtraNumber = descriptor.hasExpressionAsExtraData(); - result |= token.getArraySizeAsString() == null ? 0 : (token.isVarArrayLength() ? FLAG_ARRAY | FLAG_WIDE | (EXT_FLAG_EXPRESSION_OR_WHOLESTREAM << 8) : FLAG_ARRAY); + result |= token.getArraySizeAsString() == null ? 0 : (token.isVarArrayLength() ? + FLAG_ARRAY | FLAG_WIDE | (EXT_FLAG_EXPRESSION_OR_WHOLESTREAM << 8) : FLAG_ARRAY); result |= hasExpressionAsExtraNumber ? FLAG_WIDE | (EXT_FLAG_EXTRA_AS_EXPRESSION << 8) : 0; - result |= token.getFieldTypeParameters().isSpecialField() ? FLAG_WIDE | (EXT_FLAG_EXTRA_DIFF_TYPE << 8) : 0; + result |= token.getFieldTypeParameters().isSpecialField() ? + FLAG_WIDE | (EXT_FLAG_EXTRA_DIFF_TYPE << 8) : 0; result |= token.getFieldName() == null ? 0 : FLAG_NAMED; final String name = descriptor.getTypeName().toLowerCase(Locale.ENGLISH); @@ -609,7 +661,8 @@ private static int prepareCodeForToken(final JBBPToken token, final JBBPCustomFi } } if (unsupportedType) { - throw new JBBPCompilationException("Unsupported type [" + descriptor.getTypeName() + ']', token); + throw new JBBPCompilationException( + "Unsupported type [" + descriptor.getTypeName() + ']', token); } break; } @@ -620,7 +673,8 @@ private static int prepareCodeForToken(final JBBPToken token, final JBBPCustomFi } break; case STRUCT_START: { - result = token.getArraySizeAsString() == null ? 0 : (token.isVarArrayLength() ? FLAG_ARRAY | FLAG_WIDE | (EXT_FLAG_EXPRESSION_OR_WHOLESTREAM << 8) : FLAG_ARRAY); + result = token.getArraySizeAsString() == null ? 0 : (token.isVarArrayLength() ? + FLAG_ARRAY | FLAG_WIDE | (EXT_FLAG_EXPRESSION_OR_WHOLESTREAM << 8) : FLAG_ARRAY); result |= token.getFieldName() == null ? 0 : FLAG_NAMED; result |= CODE_STRUCT_START; } @@ -674,7 +728,9 @@ private static final class StructStackItem { * @param code the start byte code * @param token the token */ - private StructStackItem(final int namedFieldCounter, final int startStructureOffset, final boolean arrayToReadTillEnd, final int code, final JBBPToken token) { + private StructStackItem(final int namedFieldCounter, final int startStructureOffset, + final boolean arrayToReadTillEnd, final int code, + final JBBPToken token) { this.namedFieldCounter = namedFieldCounter; this.arrayToReadTillEndOfStream = arrayToReadTillEnd; this.startStructureOffset = startStructureOffset; diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompilerUtils.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompilerUtils.java index 6194a67e..02aec283 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompilerUtils.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompilerUtils.java @@ -16,13 +16,13 @@ package com.igormaznitsa.jbbp.compiler; +import static com.igormaznitsa.jbbp.compiler.JBBPCompiler.FLAG_ARRAY; + + import com.igormaznitsa.jbbp.exceptions.JBBPCompilationException; import com.igormaznitsa.jbbp.utils.JBBPUtils; - import java.util.List; -import static com.igormaznitsa.jbbp.compiler.JBBPCompiler.FLAG_ARRAY; - /** * Class contains specific common auxiliary methods for parser and compiler classes. * @@ -39,7 +39,8 @@ private JBBPCompilerUtils() { * @param namedFields a list contains named field info items. * @return the index of a field for the path if found one, -1 otherwise */ - public static int findIndexForFieldPath(final String fieldPath, final List namedFields) { + public static int findIndexForFieldPath(final String fieldPath, + final List namedFields) { final String normalized = JBBPUtils.normalizeFieldNameOrPath(fieldPath); int result = -1; for (int i = namedFields.size() - 1; i >= 0; i--) { @@ -59,7 +60,8 @@ public static int findIndexForFieldPath(final String fieldPath, final List namedFields) { + public static JBBPNamedFieldInfo findForFieldPath(final String fieldPath, + final List namedFields) { final String normalized = JBBPUtils.normalizeFieldNameOrPath(fieldPath); JBBPNamedFieldInfo result = null; for (int i = namedFields.size() - 1; i >= 0; i--) { @@ -79,10 +81,13 @@ public static JBBPNamedFieldInfo findForFieldPath(final String fieldPath, final * @param namedFieldList a named field info list, must not be null. * @param compiledScript a compiled script body */ - public static void assertFieldIsNotArrayOrInArray(final JBBPNamedFieldInfo fieldToCheck, final List namedFieldList, final byte[] compiledScript) { + public static void assertFieldIsNotArrayOrInArray(final JBBPNamedFieldInfo fieldToCheck, + final List namedFieldList, + final byte[] compiledScript) { // check that the field is not array if ((compiledScript[fieldToCheck.getFieldOffsetInCompiledBlock()] & FLAG_ARRAY) != 0) { - throw new JBBPCompilationException("An Array field can't be used as array size [" + fieldToCheck.getFieldPath() + ']'); + throw new JBBPCompilationException( + "An Array field can't be used as array size [" + fieldToCheck.getFieldPath() + ']'); } if (fieldToCheck.getFieldPath().indexOf('.') >= 0) { // the field in structure, check that the structure is not an array or not in an array @@ -94,9 +99,12 @@ public static void assertFieldIsNotArrayOrInArray(final JBBPNamedFieldInfo field fieldPath.append('.'); } fieldPath.append(splittedFieldPath[i]); - final JBBPNamedFieldInfo structureEnd = JBBPCompilerUtils.findForFieldPath(fieldPath.toString(), namedFieldList); + final JBBPNamedFieldInfo structureEnd = + JBBPCompilerUtils.findForFieldPath(fieldPath.toString(), namedFieldList); if ((compiledScript[structureEnd.getFieldOffsetInCompiledBlock()] & FLAG_ARRAY) != 0) { - throw new JBBPCompilationException("Field from structure array can't be use as array size [" + fieldToCheck.getFieldPath() + ';' + structureEnd.getFieldPath() + ']'); + throw new JBBPCompilationException( + "Field from structure array can't be use as array size [" + + fieldToCheck.getFieldPath() + ';' + structureEnd.getFieldPath() + ']'); } } } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPNamedFieldInfo.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPNamedFieldInfo.java index 4b1d4bed..1396b17d 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPNamedFieldInfo.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPNamedFieldInfo.java @@ -17,7 +17,6 @@ package com.igormaznitsa.jbbp.compiler; import com.igormaznitsa.jbbp.utils.JBBPUtils; - import java.io.Serializable; /** @@ -49,7 +48,8 @@ public final class JBBPNamedFieldInfo implements Serializable { * @param fieldName the field name * @param offsetInCompiledBlock the offset in the compiled block for the field */ - public JBBPNamedFieldInfo(final String fieldPath, final String fieldName, final int offsetInCompiledBlock) { + public JBBPNamedFieldInfo(final String fieldPath, final String fieldName, + final int offsetInCompiledBlock) { this.fieldPath = JBBPUtils.normalizeFieldNameOrPath(fieldPath); this.fieldName = JBBPUtils.normalizeFieldNameOrPath(fieldName); this.offsetInCompiledBlock = offsetInCompiledBlock; @@ -95,7 +95,8 @@ public boolean equals(final Object obj) { if (obj instanceof JBBPNamedFieldInfo) { final JBBPNamedFieldInfo that = (JBBPNamedFieldInfo) obj; - result = this.fieldPath.equals(that.fieldPath) && this.offsetInCompiledBlock == that.offsetInCompiledBlock; + result = this.fieldPath.equals(that.fieldPath) && + this.offsetInCompiledBlock == that.offsetInCompiledBlock; } return result; } @@ -107,7 +108,8 @@ public int hashCode() { @Override public String toString() { - return this.getClass().getSimpleName() + "[fieldPath=" + this.fieldPath + ", fieldName=" + this.fieldName + ", offsetInCompiledBlock=" + this.offsetInCompiledBlock + ']'; + return this.getClass().getSimpleName() + "[fieldPath=" + this.fieldPath + ", fieldName=" + + this.fieldName + ", offsetInCompiledBlock=" + this.offsetInCompiledBlock + ']'; } } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/CompiledBlockVisitor.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/CompiledBlockVisitor.java index c3734bf1..7f02704f 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/CompiledBlockVisitor.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/CompiledBlockVisitor.java @@ -88,12 +88,16 @@ public final CompiledBlockVisitor visit() { final boolean extraFieldNumAsExpr = (ec & JBBPCompiler.EXT_FLAG_EXTRA_AS_EXPRESSION) != 0; final int code = (ec << 8) | c; - final JBBPNamedFieldInfo name = (code & JBBPCompiler.FLAG_NAMED) == 0 ? null : this.compiledBlock.getNamedFields()[positionAtNamedFieldList++]; - final JBBPByteOrder byteOrder = (code & JBBPCompiler.FLAG_LITTLE_ENDIAN) == 0 ? JBBPByteOrder.BIG_ENDIAN : JBBPByteOrder.LITTLE_ENDIAN; + final JBBPNamedFieldInfo name = (code & JBBPCompiler.FLAG_NAMED) == 0 ? null : + this.compiledBlock.getNamedFields()[positionAtNamedFieldList++]; + final JBBPByteOrder byteOrder = + (code & JBBPCompiler.FLAG_LITTLE_ENDIAN) == 0 ? JBBPByteOrder.BIG_ENDIAN : + JBBPByteOrder.LITTLE_ENDIAN; final JBBPIntegerValueEvaluator extraFieldValueEvaluator; if (extraFieldNumAsExpr) { - extraFieldValueEvaluator = this.compiledBlock.getArraySizeEvaluators()[positionAtVarLengthProcessors++]; + extraFieldValueEvaluator = + this.compiledBlock.getArraySizeEvaluators()[positionAtVarLengthProcessors++]; } else { extraFieldValueEvaluator = null; } @@ -102,9 +106,11 @@ public final CompiledBlockVisitor visit() { boolean readWholeStream = false; - switch (code & (JBBPCompiler.FLAG_ARRAY | (JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM << 8))) { + switch (code & + (JBBPCompiler.FLAG_ARRAY | (JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM << 8))) { case JBBPCompiler.FLAG_ARRAY: { - arraySizeEvaluator = new IntConstValueEvaluator(JBBPUtils.unpackInt(compiledData, positionAtCompiledBlock)); + arraySizeEvaluator = new IntConstValueEvaluator( + JBBPUtils.unpackInt(compiledData, positionAtCompiledBlock)); } break; case (JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM << 8): { @@ -113,7 +119,8 @@ public final CompiledBlockVisitor visit() { } break; case JBBPCompiler.FLAG_ARRAY | (JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM << 8): { - arraySizeEvaluator = this.compiledBlock.getArraySizeEvaluators()[positionAtVarLengthProcessors++]; + arraySizeEvaluator = + this.compiledBlock.getArraySizeEvaluators()[positionAtVarLengthProcessors++]; } break; default: { @@ -132,7 +139,9 @@ public final CompiledBlockVisitor visit() { break; case JBBPCompiler.CODE_SKIP: case JBBPCompiler.CODE_ALIGN: { - final JBBPIntegerValueEvaluator evaluator = extraFieldNumAsExpr ? extraFieldValueEvaluator : new IntConstValueEvaluator(JBBPUtils.unpackInt(compiledData, positionAtCompiledBlock)); + final JBBPIntegerValueEvaluator evaluator = + extraFieldNumAsExpr ? extraFieldValueEvaluator : new IntConstValueEvaluator( + JBBPUtils.unpackInt(compiledData, positionAtCompiledBlock)); if (altFileType) { if (theCode == JBBPCompiler.CODE_SKIP) { visitValField(theOffset, byteOrder, name, evaluator); @@ -146,7 +155,9 @@ public final CompiledBlockVisitor visit() { break; case JBBPCompiler.CODE_BIT: { - final JBBPIntegerValueEvaluator numberOfBits = extraFieldNumAsExpr ? extraFieldValueEvaluator : new IntConstValueEvaluator(JBBPUtils.unpackInt(compiledData, positionAtCompiledBlock)); + final JBBPIntegerValueEvaluator numberOfBits = + extraFieldNumAsExpr ? extraFieldValueEvaluator : new IntConstValueEvaluator( + JBBPUtils.unpackInt(compiledData, positionAtCompiledBlock)); visitBitField(theOffset, byteOrder, name, numberOfBits, arraySizeEvaluator); } break; @@ -158,7 +169,8 @@ public final CompiledBlockVisitor visit() { case JBBPCompiler.CODE_USHORT: case JBBPCompiler.CODE_INT: case JBBPCompiler.CODE_LONG: { - visitPrimitiveField(theOffset, theCode, name, byteOrder, readWholeStream, altFileType, arraySizeEvaluator); + visitPrimitiveField(theOffset, theCode, name, byteOrder, readWholeStream, altFileType, + arraySizeEvaluator); } break; @@ -174,15 +186,23 @@ public final CompiledBlockVisitor visit() { break; case JBBPCompiler.CODE_VAR: { - final JBBPIntegerValueEvaluator extraDataValueEvaluator = extraFieldNumAsExpr ? extraFieldValueEvaluator : new IntConstValueEvaluator(JBBPUtils.unpackInt(compiledData, positionAtCompiledBlock)); - visitVarField(theOffset, name, byteOrder, readWholeStream, arraySizeEvaluator, extraDataValueEvaluator); + final JBBPIntegerValueEvaluator extraDataValueEvaluator = + extraFieldNumAsExpr ? extraFieldValueEvaluator : new IntConstValueEvaluator( + JBBPUtils.unpackInt(compiledData, positionAtCompiledBlock)); + visitVarField(theOffset, name, byteOrder, readWholeStream, arraySizeEvaluator, + extraDataValueEvaluator); } break; case JBBPCompiler.CODE_CUSTOMTYPE: { - final JBBPIntegerValueEvaluator extraDataValueEvaluator = extraFieldNumAsExpr ? extraFieldValueEvaluator : new IntConstValueEvaluator(JBBPUtils.unpackInt(compiledData, positionAtCompiledBlock)); - final JBBPFieldTypeParameterContainer fieldTypeInfo = this.compiledBlock.getCustomTypeFields()[JBBPUtils.unpackInt(compiledData, positionAtCompiledBlock)]; - visitCustomField(theOffset, fieldTypeInfo, name, byteOrder, readWholeStream, arraySizeEvaluator, extraDataValueEvaluator); + final JBBPIntegerValueEvaluator extraDataValueEvaluator = + extraFieldNumAsExpr ? extraFieldValueEvaluator : new IntConstValueEvaluator( + JBBPUtils.unpackInt(compiledData, positionAtCompiledBlock)); + final JBBPFieldTypeParameterContainer fieldTypeInfo = + this.compiledBlock.getCustomTypeFields()[JBBPUtils + .unpackInt(compiledData, positionAtCompiledBlock)]; + visitCustomField(theOffset, fieldTypeInfo, name, byteOrder, readWholeStream, + arraySizeEvaluator, extraDataValueEvaluator); } break; default: @@ -205,19 +225,22 @@ public final CompiledBlockVisitor visit() { * @see JBBPCompiler#CODE_ALIGN * @see JBBPCompiler#CODE_SKIP */ - public void visitActionItem(int offsetInCompiledBlock, int actionType, JBBPIntegerValueEvaluator nullableArgument) { + public void visitActionItem(int offsetInCompiledBlock, int actionType, + JBBPIntegerValueEvaluator nullableArgument) { } /** * Visit field contains virtual field with VAL type. * * @param offsetInCompiledBlock offset in the compiled block - * @param byteOrder byteOrder + * @param byteOrder byteOrder * @param nameFieldInfo name of the field, must not be null * @param expression expression to calculate value * @since 1.4.0 */ - public void visitValField(int offsetInCompiledBlock, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nameFieldInfo, JBBPIntegerValueEvaluator expression) { + public void visitValField(int offsetInCompiledBlock, JBBPByteOrder byteOrder, + JBBPNamedFieldInfo nameFieldInfo, + JBBPIntegerValueEvaluator expression) { } /** @@ -239,7 +262,10 @@ public void visitValField(int offsetInCompiledBlock, JBBPByteOrder byteOrder, JB * @see JBBPCompiler#CODE_LONG * @see JBBPCompiler#CODE_SKIP */ - public void visitPrimitiveField(int offsetInCompiledBlock, int primitiveType, JBBPNamedFieldInfo nullableNameFieldInfo, JBBPByteOrder byteOrder, boolean readWholeStreamAsArray, boolean altFieldType, JBBPIntegerValueEvaluator nullableArraySize) { + public void visitPrimitiveField(int offsetInCompiledBlock, int primitiveType, + JBBPNamedFieldInfo nullableNameFieldInfo, JBBPByteOrder byteOrder, + boolean readWholeStreamAsArray, boolean altFieldType, + JBBPIntegerValueEvaluator nullableArraySize) { } /** @@ -252,19 +278,33 @@ public void visitPrimitiveField(int offsetInCompiledBlock, int primitiveType, JB * @param nullableArraySize if not null then evaluator of array size to be read from stream * @param extraDataValueEvaluator if not null then extra data evaluator for the var field */ - public void visitVarField(int offsetInCompiledBlock, JBBPNamedFieldInfo nullableNameFieldInfo, JBBPByteOrder byteOrder, boolean readWholeStreamIntoArray, JBBPIntegerValueEvaluator nullableArraySize, JBBPIntegerValueEvaluator extraDataValueEvaluator) { + public void visitVarField(int offsetInCompiledBlock, JBBPNamedFieldInfo nullableNameFieldInfo, + JBBPByteOrder byteOrder, boolean readWholeStreamIntoArray, + JBBPIntegerValueEvaluator nullableArraySize, + JBBPIntegerValueEvaluator extraDataValueEvaluator) { } - public void visitCustomField(int offsetInCompiledBlock, JBBPFieldTypeParameterContainer notNullFieldType, JBBPNamedFieldInfo nullableNameFieldInfo, JBBPByteOrder byteOrder, boolean readWholeStream, JBBPIntegerValueEvaluator nullableArraySizeEvaluator, JBBPIntegerValueEvaluator extraDataValueEvaluator) { + public void visitCustomField(int offsetInCompiledBlock, + JBBPFieldTypeParameterContainer notNullFieldType, + JBBPNamedFieldInfo nullableNameFieldInfo, JBBPByteOrder byteOrder, + boolean readWholeStream, + JBBPIntegerValueEvaluator nullableArraySizeEvaluator, + JBBPIntegerValueEvaluator extraDataValueEvaluator) { } - public void visitBitField(int offsetInCompiledBlock, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNameFieldInfo, JBBPIntegerValueEvaluator notNullFieldSize, JBBPIntegerValueEvaluator nullableArraySize) { + public void visitBitField(int offsetInCompiledBlock, JBBPByteOrder byteOrder, + JBBPNamedFieldInfo nullableNameFieldInfo, + JBBPIntegerValueEvaluator notNullFieldSize, + JBBPIntegerValueEvaluator nullableArraySize) { } - public void visitStructureStart(int offsetInCompiledBlock, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNameFieldInfo, JBBPIntegerValueEvaluator nullableArraySize) { + public void visitStructureStart(int offsetInCompiledBlock, JBBPByteOrder byteOrder, + JBBPNamedFieldInfo nullableNameFieldInfo, + JBBPIntegerValueEvaluator nullableArraySize) { } - public void visitStructureEnd(int offsetInCompiledBlock, JBBPNamedFieldInfo nullableNameFieldInfo) { + public void visitStructureEnd(int offsetInCompiledBlock, + JBBPNamedFieldInfo nullableNameFieldInfo) { } public void visitStart() { diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/ExpressionEvaluatorVisitor.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/ExpressionEvaluatorVisitor.java index 8d7059e0..365bee08 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/ExpressionEvaluatorVisitor.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/ExpressionEvaluatorVisitor.java @@ -47,7 +47,8 @@ public interface ExpressionEvaluatorVisitor { * @param nullableExternalFieldName name of external field, it will be null for regular field * @return the visitor instance, must not be null */ - ExpressionEvaluatorVisitor visitField(JBBPNamedFieldInfo nullableNameFieldInfo, String nullableExternalFieldName); + ExpressionEvaluatorVisitor visitField(JBBPNamedFieldInfo nullableNameFieldInfo, + String nullableExternalFieldName); /** * Visit operator diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/IntConstValueEvaluator.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/IntConstValueEvaluator.java index 36c3868f..006a0c68 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/IntConstValueEvaluator.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/IntConstValueEvaluator.java @@ -40,12 +40,14 @@ final class IntConstValueEvaluator implements JBBPIntegerValueEvaluator { } @Override - public int eval(final JBBPBitInputStream inStream, final int currentCompiledBlockOffset, final JBBPCompiledBlock block, final JBBPNamedNumericFieldMap fieldMap) { + public int eval(final JBBPBitInputStream inStream, final int currentCompiledBlockOffset, + final JBBPCompiledBlock block, final JBBPNamedNumericFieldMap fieldMap) { return this.value; } @Override - public void visitItems(JBBPCompiledBlock block, int currentCompiledBlockOffset, ExpressionEvaluatorVisitor visitor) { + public void visitItems(JBBPCompiledBlock block, int currentCompiledBlockOffset, + ExpressionEvaluatorVisitor visitor) { visitor.visitStart(); visitor.visitConstant(this.value); visitor.visitEnd(); diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJavaConverter.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJavaConverter.java index 51a96c6f..15d9c374 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJavaConverter.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJavaConverter.java @@ -64,6 +64,23 @@ public final class JBBPToJavaConverter extends CompiledBlockVisitor { private static final int FLAG_ADD_ASSERT_NOT_NEGATIVE_EXPR = 8; private static final Set RESERVED_JAVA_KEYWORDS; + /** + * Name of the field to be used as link to the root structure instance in + * child structures. + */ + private static final String NAME_ROOT_STRUCT = "_Root_"; + /** + * Name of the field to keep information about parser flags. + */ + private static final String NAME_PARSER_FLAGS = "_ParserFlags_"; + /** + * Name of the input stream argument. + */ + private static final String NAME_INPUT_STREAM = "In"; + /** + * Name of the output stream argument. + */ + private static final String NAME_OUTPUT_STREAM = "Out"; static { final Set reserved = new HashSet<>(); @@ -126,23 +143,6 @@ public final class JBBPToJavaConverter extends CompiledBlockVisitor { RESERVED_JAVA_KEYWORDS = Collections.unmodifiableSet(reserved); } - /** - * Name of the field to be used as link to the root structure instance in - * child structures. - */ - private static final String NAME_ROOT_STRUCT = "_Root_"; - /** - * Name of the field to keep information about parser flags. - */ - private static final String NAME_PARSER_FLAGS = "_ParserFlags_"; - /** - * Name of the input stream argument. - */ - private static final String NAME_INPUT_STREAM = "In"; - /** - * Name of the output stream argument. - */ - private static final String NAME_OUTPUT_STREAM = "Out"; /** * Detected flags. */ @@ -218,7 +218,8 @@ private void registerNamedField(final JBBPNamedFieldInfo fieldInfo, final FieldT if (this.foundNamedFields.containsKey(fieldInfo)) { throw new Error("Detected duplication of named field : " + fieldInfo); } - this.foundNamedFields.put(fieldInfo, new NamedFieldInfo(fieldInfo, this.getCurrentStruct(), fieldType)); + this.foundNamedFields + .put(fieldInfo, new NamedFieldInfo(fieldInfo, this.getCurrentStruct(), fieldType)); } } @@ -279,61 +280,82 @@ public void visitEnd() { buffer.println(); this.specialSection.println(); - this.specialSection.printJavaDocLinesWithIndent("The Constant contains parser flags\n@see JBBPParser#FLAG_SKIP_REMAINING_FIELDS_IF_EOF\n@see JBBPParser#FLAG_NEGATIVE_EXPRESSION_RESULT_AS_ZERO"); - this.specialSection.indent().printf("protected static final int %s = %d;", NAME_PARSER_FLAGS, this.parserFlags); + this.specialSection.printJavaDocLinesWithIndent( + "The Constant contains parser flags\n@see JBBPParser#FLAG_SKIP_REMAINING_FIELDS_IF_EOF\n@see JBBPParser#FLAG_NEGATIVE_EXPRESSION_RESULT_AS_ZERO"); + this.specialSection.indent() + .printf("protected static final int %s = %d;", NAME_PARSER_FLAGS, this.parserFlags); final int detected = this.flagSet.get(); if ((detected & FLAG_DETECTED_CUSTOM_FIELDS) != 0) { - this.specialMethods.printJavaDocLinesWithIndent("Reading of custom fields\n@param sourceStruct source structure holding the field, must not be null\n@param inStream the input stream, must not be null\n@param typeParameterContainer info about field type, must not be null\n@param nullableNamedFieldInfo info abut field name, it can be null\n@param extraValue value from extra field part, default value 0\n@param readWholeStream flag to read the stream as array till the stream end if true\n@param arraySize if array then it is zero or great\n@exception IOException if data can't be read\n@return read value as abstract field, must not be null"); - this.specialMethods.println("public abstract JBBPAbstractField readCustomFieldType(Object sourceStruct, JBBPBitInputStream inStream, JBBPFieldTypeParameterContainer typeParameterContainer, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean readWholeStream, int arraySize) throws IOException;"); + this.specialMethods.printJavaDocLinesWithIndent( + "Reading of custom fields\n@param sourceStruct source structure holding the field, must not be null\n@param inStream the input stream, must not be null\n@param typeParameterContainer info about field type, must not be null\n@param nullableNamedFieldInfo info abut field name, it can be null\n@param extraValue value from extra field part, default value 0\n@param readWholeStream flag to read the stream as array till the stream end if true\n@param arraySize if array then it is zero or great\n@exception IOException if data can't be read\n@return read value as abstract field, must not be null"); + this.specialMethods.println( + "public abstract JBBPAbstractField readCustomFieldType(Object sourceStruct, JBBPBitInputStream inStream, JBBPFieldTypeParameterContainer typeParameterContainer, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean readWholeStream, int arraySize) throws IOException;"); this.specialMethods.println(); - this.specialMethods.printJavaDocLinesWithIndent("Writing custom fields\n@param sourceStruct source structure holding the field, must not be null\n@param outStream the output stream, must not be null\n@param fieldValue value to be written\n@param typeParameterContainer info about field type, must not be null\n@param nullableNamedFieldInfo info abut field name, it can be null\n@param extraValue value from extra field part, default value is 0\n@param wholeArray true if to write whole array\n@param arraySize if array then it is zero or great\n@exception IOException if data can't be written"); - this.specialMethods.println("public abstract void writeCustomFieldType(Object sourceStruct, JBBPBitOutputStream outStream, JBBPAbstractField fieldValue, JBBPFieldTypeParameterContainer typeParameterContainer, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean wholeArray, int arraySize) throws IOException;"); + this.specialMethods.printJavaDocLinesWithIndent( + "Writing custom fields\n@param sourceStruct source structure holding the field, must not be null\n@param outStream the output stream, must not be null\n@param fieldValue value to be written\n@param typeParameterContainer info about field type, must not be null\n@param nullableNamedFieldInfo info abut field name, it can be null\n@param extraValue value from extra field part, default value is 0\n@param wholeArray true if to write whole array\n@param arraySize if array then it is zero or great\n@exception IOException if data can't be written"); + this.specialMethods.println( + "public abstract void writeCustomFieldType(Object sourceStruct, JBBPBitOutputStream outStream, JBBPAbstractField fieldValue, JBBPFieldTypeParameterContainer typeParameterContainer, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean wholeArray, int arraySize) throws IOException;"); } if ((detected & FLAG_DETECTED_EXTERNAL_FIELDS) != 0) { if (!this.specialMethods.isEmpty()) { this.specialMethods.println(); } - this.specialMethods.printJavaDocLinesWithIndent("Method is called from expressions to provide value\n@param sourceStruct source structure holding the field, must not be null\n@param valueName name of value to be provided, must not be null\n@return integer value for the named parameter"); - this.specialMethods.println("public abstract int getNamedValue(Object sourceStruct, String valueName);"); + this.specialMethods.printJavaDocLinesWithIndent( + "Method is called from expressions to provide value\n@param sourceStruct source structure holding the field, must not be null\n@param valueName name of value to be provided, must not be null\n@return integer value for the named parameter"); + this.specialMethods + .println("public abstract int getNamedValue(Object sourceStruct, String valueName);"); } if ((detected & FLAG_DETECTED_VAR_FIELDS) != 0) { if (!this.specialMethods.isEmpty()) { this.specialMethods.println(); } - this.specialMethods.printJavaDocLinesWithIndent("Read variable field\n@param sourceStruct source structure holding the field, must not be null\n@param inStream the input stream, must not be null\n@param byteOrder\n@param nullableNamedFieldInfo info abut field name, it can be null\n@param extraValue value from extra field part, -1 if not defined\n@return\n@exception IOException"); - this.specialMethods.println("public abstract JBBPAbstractField readVarField(Object sourceStruct, JBBPBitInputStream inStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) throws IOException;"); + this.specialMethods.printJavaDocLinesWithIndent( + "Read variable field\n@param sourceStruct source structure holding the field, must not be null\n@param inStream the input stream, must not be null\n@param byteOrder\n@param nullableNamedFieldInfo info abut field name, it can be null\n@param extraValue value from extra field part, -1 if not defined\n@return\n@exception IOException"); + this.specialMethods.println( + "public abstract JBBPAbstractField readVarField(Object sourceStruct, JBBPBitInputStream inStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) throws IOException;"); this.specialMethods.println(); - this.specialMethods.printJavaDocLinesWithIndent("Read variable array field\n@param sourceStruct source structure holding the field, must not be null\n@param inStream the input stream, must not be null\n@param byteOrder byte order to be used for reading, must not be null\n@param nullableNamedFieldInfo info abut field name, it can be null\n@param extraValue value from extra field part, -1 if not defined\n@param readWholeStream if true then whole stream should be read\n@param arraySize size of array to read (if whole stream flag is false)\n@return array object contains read data, must not be null\n@exception IOException if error during data reading"); - this.specialMethods.println("public abstract JBBPAbstractArrayField readVarArray(Object sourceStruct, JBBPBitInputStream inStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean readWholeStream, int arraySize) throws IOException;"); + this.specialMethods.printJavaDocLinesWithIndent( + "Read variable array field\n@param sourceStruct source structure holding the field, must not be null\n@param inStream the input stream, must not be null\n@param byteOrder byte order to be used for reading, must not be null\n@param nullableNamedFieldInfo info abut field name, it can be null\n@param extraValue value from extra field part, -1 if not defined\n@param readWholeStream if true then whole stream should be read\n@param arraySize size of array to read (if whole stream flag is false)\n@return array object contains read data, must not be null\n@exception IOException if error during data reading"); + this.specialMethods.println( + "public abstract JBBPAbstractArrayField readVarArray(Object sourceStruct, JBBPBitInputStream inStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean readWholeStream, int arraySize) throws IOException;"); this.specialMethods.println(); - this.specialMethods.printJavaDocLinesWithIndent("Read variable field\n@param sourceStruct source structure holding the field, must not be null\n@param value field value, must not be null\n@param outStream the output stream, must not be null,\n@param byteOrder byte order to be used for reading, must not be null\n@param nullableNamedFieldInfo info abut field name, it can be null\n@param extraValue value from extra field part, -1 if not defined\n@exception IOException it is thrown if any transport error during operation"); - this.specialMethods.println("public abstract void writeVarField(Object sourceStruct, JBBPAbstractField value, JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) throws IOException;"); + this.specialMethods.printJavaDocLinesWithIndent( + "Read variable field\n@param sourceStruct source structure holding the field, must not be null\n@param value field value, must not be null\n@param outStream the output stream, must not be null,\n@param byteOrder byte order to be used for reading, must not be null\n@param nullableNamedFieldInfo info abut field name, it can be null\n@param extraValue value from extra field part, -1 if not defined\n@exception IOException it is thrown if any transport error during operation"); + this.specialMethods.println( + "public abstract void writeVarField(Object sourceStruct, JBBPAbstractField value, JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) throws IOException;"); this.specialMethods.println(); - this.specialMethods.printJavaDocLinesWithIndent("Write variable array\n@param sourceStruct source structure holding the field, must not be null\n@param array array value to be written, must not be null\n@param outStream the output stream, must not be null\n@param byteOrder byte order to be used for reading, must not be null\n@param nullableNamedFieldInfo info abut field name, it can be null\n@param extraValue value from extra field part, -1 if not defined\n@param arraySizeToWrite\n@exception IOException it is thrown if any transport error during operation"); - this.specialMethods.println("public abstract void writeVarArray(Object sourceStruct, JBBPAbstractArrayField array, JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, int arraySizeToWrite) throws IOException;"); + this.specialMethods.printJavaDocLinesWithIndent( + "Write variable array\n@param sourceStruct source structure holding the field, must not be null\n@param array array value to be written, must not be null\n@param outStream the output stream, must not be null\n@param byteOrder byte order to be used for reading, must not be null\n@param nullableNamedFieldInfo info abut field name, it can be null\n@param extraValue value from extra field part, -1 if not defined\n@param arraySizeToWrite\n@exception IOException it is thrown if any transport error during operation"); + this.specialMethods.println( + "public abstract void writeVarArray(Object sourceStruct, JBBPAbstractArrayField array, JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, int arraySizeToWrite) throws IOException;"); } if ((detected & FLAG_ADD_ASSERT_NOT_NEGATIVE_EXPR) != 0) { if (!this.specialMethods.isEmpty()) { this.specialMethods.println(); } - this.specialMethods.println("private static int assrtExprNotNeg(final int value) { if (value<0) throw new IllegalArgumentException(\"Negative value in expression\"); return value; }"); + this.specialMethods.println( + "private static int assrtExprNotNeg(final int value) { if (value<0) throw new IllegalArgumentException(\"Negative value in expression\"); return value; }"); } final String specialMethodsText = this.specialMethods.toString(); - final boolean hasAbstractMethods = (this.flagSet.get() & (FLAG_DETECTED_CUSTOM_FIELDS | FLAG_DETECTED_VAR_FIELDS | FLAG_DETECTED_EXTERNAL_FIELDS)) != 0 || this.builder.doMainClassAbstract; + final boolean hasAbstractMethods = (this.flagSet.get() & + (FLAG_DETECTED_CUSTOM_FIELDS | FLAG_DETECTED_VAR_FIELDS | FLAG_DETECTED_EXTERNAL_FIELDS)) != + 0 || this.builder.doMainClassAbstract; - buffer.printJavaDocLinesWithIndent("Generated from JBBP script by internal JBBP Class Source Generator"); + buffer.printJavaDocLinesWithIndent( + "Generated from JBBP script by internal JBBP Class Source Generator"); final Struct rootStruct = this.structStack.get(0); if (this.builder.addNewInstanceMethods) { - rootStruct.misc.println(String.format("public Object %s(Class aClass) {", JBBPMapper.MAKE_CLASS_INSTANCE_METHOD_NAME)); + rootStruct.misc.println(String.format("public Object %s(Class aClass) {", + JBBPMapper.MAKE_CLASS_INSTANCE_METHOD_NAME)); rootStruct.misc.incIndent(); for (final Struct c : rootStruct.children) { @@ -365,12 +387,20 @@ public void visitEnd() { } @Override - public void visitStructureStart(final int offsetInCompiledBlock, final JBBPByteOrder byteOrder, final JBBPNamedFieldInfo nullableNameFieldInfo, final JBBPIntegerValueEvaluator nullableArraySize) { - final String structName = (nullableNameFieldInfo == null ? makeAnonymousStructName() : prepFldName(nullableNameFieldInfo.getFieldName())).toLowerCase(Locale.ENGLISH); + public void visitStructureStart(final int offsetInCompiledBlock, final JBBPByteOrder byteOrder, + final JBBPNamedFieldInfo nullableNameFieldInfo, + final JBBPIntegerValueEvaluator nullableArraySize) { + final String structName = (nullableNameFieldInfo == null ? makeAnonymousStructName() : + prepFldName(nullableNameFieldInfo.getFieldName())).toLowerCase(Locale.ENGLISH); final String structBaseTypeName = structName.toUpperCase(Locale.ENGLISH); - final String arraySizeIn = nullableArraySize == null ? null : evaluatorToString(NAME_INPUT_STREAM, offsetInCompiledBlock, nullableArraySize, this.flagSet, true); - final String arraySizeOut = nullableArraySize == null ? null : evaluatorToString(NAME_OUTPUT_STREAM, offsetInCompiledBlock, nullableArraySize, this.flagSet, true); - final Struct newStruct = new Struct(this.getCurrentStruct(), structBaseTypeName, "public" + (builder.internalClassesNotStatic ? "" : " static")); + final String arraySizeIn = nullableArraySize == null ? null : + evaluatorToString(NAME_INPUT_STREAM, offsetInCompiledBlock, nullableArraySize, this.flagSet, + true); + final String arraySizeOut = nullableArraySize == null ? null : + evaluatorToString(NAME_OUTPUT_STREAM, offsetInCompiledBlock, nullableArraySize, + this.flagSet, true); + final Struct newStruct = new Struct(this.getCurrentStruct(), structBaseTypeName, + "public" + (builder.internalClassesNotStatic ? "" : " static")); final String fieldModifier = makeModifier(nullableNameFieldInfo); @@ -388,43 +418,60 @@ public void visitStructureStart(final int offsetInCompiledBlock, final JBBPByteO if (nullableArraySize == null) { structType = structBaseTypeName; if (this.builder.generateFields) { - printField(nullableNameFieldInfo, byteOrder, false, offsetInCompiledBlock, getCurrentStruct().getFields().indent(), null, fieldModifier, structType, structName); + printField(nullableNameFieldInfo, byteOrder, false, offsetInCompiledBlock, + getCurrentStruct().getFields().indent(), null, fieldModifier, structType, structName); } processSkipRemainingFlag(); processSkipRemainingFlagForWriting("this." + structName); this.getCurrentStruct().getReadFunc().indent() - .printf("if ( this.%1$s == null) { this.%1$s = new %2$s(%3$s);}", structName, structType, pathToRootObject) - .printf(" %s.read(%s);%n", toType.length() == 0 ? "this." + structName : '(' + toType + "this." + structName + ')', NAME_INPUT_STREAM); - this.getCurrentStruct().getWriteFunc().indent().print(toType.length() == 0 ? structName : '(' + toType + structName + ')').println(".write(Out);"); + .printf("if ( this.%1$s == null) { this.%1$s = new %2$s(%3$s);}", structName, structType, + pathToRootObject) + .printf(" %s.read(%s);%n", toType.length() == 0 ? "this." + structName : + '(' + toType + "this." + structName + ')', NAME_INPUT_STREAM); + this.getCurrentStruct().getWriteFunc().indent() + .print(toType.length() == 0 ? structName : '(' + toType + structName + ')') + .println(".write(Out);"); } else { structType = structBaseTypeName + " []"; if (this.builder.generateFields) { - printField(nullableNameFieldInfo, byteOrder, true, offsetInCompiledBlock, getCurrentStruct().getFields().indent(), null, fieldModifier, structType, structName); + printField(nullableNameFieldInfo, byteOrder, true, offsetInCompiledBlock, + getCurrentStruct().getFields().indent(), null, fieldModifier, structType, structName); } processSkipRemainingFlag(); processSkipRemainingFlagForWriting("this." + structName); if ("-1".equals(arraySizeIn)) { this.getCurrentStruct().getReadFunc().indent() - .printf("List<%3$s> __%1$s_tmplst__ = new ArrayList<%3$s>(); while (%5$s.hasAvailableData()){ __%1$s_tmplst__.add(new %3$s(%4$s).read(%5$s));} this.%1$s = __%1$s_tmplst__.toArray(new %3$s[__%1$s_tmplst__.size()]);__%1$s_tmplst__ = null;%n", + .printf( + "List<%3$s> __%1$s_tmplst__ = new ArrayList<%3$s>(); while (%5$s.hasAvailableData()){ __%1$s_tmplst__.add(new %3$s(%4$s).read(%5$s));} this.%1$s = __%1$s_tmplst__.toArray(new %3$s[__%1$s_tmplst__.size()]);__%1$s_tmplst__ = null;%n", structName, arraySizeIn, structBaseTypeName, pathToRootObject, NAME_INPUT_STREAM); - this.getCurrentStruct().getWriteFunc().indent().printf("for (int I=0;I mapClassName * @return the builder instance, must not be null * @since 1.4.0 */ - public Builder setMapSubClassesSuperclasses(final Map mapClassNameToSuperclasses) { + public Builder setMapSubClassesSuperclasses( + final Map mapClassNameToSuperclasses) { assertNonLocked(); this.mapSubClassesSuperclasses.clear(); if (mapClassNameToSuperclasses != null) { @@ -1569,7 +1769,8 @@ private static class Struct { private final String path; private Struct(final Struct parent, final String className, final String classModifiers) { - this.path = parent == null ? "" : parent.path + (parent.path.length() == 0 ? "" : ".") + className.toLowerCase(Locale.ENGLISH); + this.path = parent == null ? "" : parent.path + (parent.path.length() == 0 ? "" : ".") + + className.toLowerCase(Locale.ENGLISH); this.classModifiers = classModifiers; this.className = className; this.parent = parent; @@ -1615,7 +1816,8 @@ void write( final String specialMethods, final String customText, final boolean useSuperclassForReadWrite) { - final String interfaceForGetSet = mapStructInterfaces == null ? null : mapStructInterfaces.get(this.getPath()); + final String interfaceForGetSet = + mapStructInterfaces == null ? null : mapStructInterfaces.get(this.getPath()); buffer.indent().printf( "%s%sclass %s%s%s {%n", @@ -1623,7 +1825,10 @@ void write( extraModifier == null ? " " : ' ' + extraModifier + ' ', this.className, superClass != null ? " extends " + superClass + ' ' : "", - interfaceForGetSet == null ? implementedInterfaces != null && !implementedInterfaces.isEmpty() ? " implements " + interfaces2str(implementedInterfaces) + ' ' : "" : " implements " + interfaceForGetSet + interfaceForGetSet == null ? + implementedInterfaces != null && !implementedInterfaces.isEmpty() ? + " implements " + interfaces2str(implementedInterfaces) + ' ' : "" : + " implements " + interfaceForGetSet ); buffer.incIndent(); @@ -1632,13 +1837,15 @@ void write( } for (final Struct c : this.children) { - c.write(buffer, null, mapStructSuperclasses.get(c.getPath()), null, mapStructInterfaces, mapStructSuperclasses, null, null, null, false); + c.write(buffer, null, mapStructSuperclasses.get(c.getPath()), null, mapStructInterfaces, + mapStructSuperclasses, null, null, null, false); } buffer.println(); buffer.printLinesWithIndent(this.fields.toString()); if (this.parent != null) { - buffer.indent().println("private final " + findRoot().className + ' ' + NAME_ROOT_STRUCT + ';'); + buffer.indent() + .println("private final " + findRoot().className + ' ' + NAME_ROOT_STRUCT + ';'); } buffer.println(); @@ -1656,7 +1863,8 @@ void write( buffer.println(); - buffer.indent().printf("public %s read(final JBBPBitInputStream In) throws IOException {%n", useSuperclassForReadWrite && superClass != null ? superClass : this.className); + buffer.indent().printf("public %s read(final JBBPBitInputStream In) throws IOException {%n", + useSuperclassForReadWrite && superClass != null ? superClass : this.className); buffer.incIndent(); buffer.printLinesWithIndent(this.readFunc.toString()); buffer.indent().println("return this;"); @@ -1665,7 +1873,9 @@ void write( buffer.println(); - buffer.indent().printf("public %s write(final JBBPBitOutputStream Out) throws IOException {%n", useSuperclassForReadWrite && superClass != null ? superClass : this.className); + buffer.indent() + .printf("public %s write(final JBBPBitOutputStream Out) throws IOException {%n", + useSuperclassForReadWrite && superClass != null ? superClass : this.className); buffer.incIndent(); buffer.printLinesWithIndent(this.writeFunc.toString()); buffer.indent().println("return this;"); diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPFieldTypeParameterContainer.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPFieldTypeParameterContainer.java index d74ebb38..dbf3f084 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPFieldTypeParameterContainer.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPFieldTypeParameterContainer.java @@ -20,7 +20,6 @@ import com.igormaznitsa.jbbp.model.JBBPFieldDouble; import com.igormaznitsa.jbbp.model.JBBPFieldFloat; import com.igormaznitsa.jbbp.model.JBBPFieldString; - import java.io.Serializable; /** @@ -52,7 +51,8 @@ public final class JBBPFieldTypeParameterContainer implements Serializable { * @param typeName the type of the field, can be null * @param extraData the extra data placed after ':' char, can be null */ - public JBBPFieldTypeParameterContainer(final JBBPByteOrder byteOrder, final String typeName, final String extraData) { + public JBBPFieldTypeParameterContainer(final JBBPByteOrder byteOrder, final String typeName, + final String extraData) { this.byteOrder = byteOrder; this.typeName = typeName; this.extraData = extraData; @@ -117,7 +117,9 @@ public boolean hasExpressionAsExtraData() { * @since 1.4.0 */ public boolean isSpecialField() { - return this.typeName.equals(JBBPFieldFloat.TYPE_NAME) || this.typeName.equals(JBBPFieldDouble.TYPE_NAME) || this.typeName.equals(JBBPFieldString.TYPE_NAME) || this.typeName.equals("val"); + return this.typeName.equals(JBBPFieldFloat.TYPE_NAME) || + this.typeName.equals(JBBPFieldDouble.TYPE_NAME) || + this.typeName.equals(JBBPFieldString.TYPE_NAME) || this.typeName.equals("val"); } @Override diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPToken.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPToken.java index 60b61ba3..7f248fb7 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPToken.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPToken.java @@ -17,7 +17,6 @@ package com.igormaznitsa.jbbp.compiler.tokenizer; import com.igormaznitsa.jbbp.utils.JBBPUtils; - import java.io.Serializable; /** @@ -59,7 +58,9 @@ public final class JBBPToken implements Serializable { * @param arrayLength the string value of array size, it can be null * @param fieldName the field name, it can be null */ - JBBPToken(final JBBPTokenType type, final int position, final JBBPFieldTypeParameterContainer fieldTypeParameters, final String arrayLength, final String fieldName) { + JBBPToken(final JBBPTokenType type, final int position, + final JBBPFieldTypeParameterContainer fieldTypeParameters, final String arrayLength, + final String fieldName) { JBBPUtils.assertNotNull(type, "Type must not be null"); this.type = type; this.position = position; diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPTokenizer.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPTokenizer.java index 887c9c39..eedb4828 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPTokenizer.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPTokenizer.java @@ -153,7 +153,8 @@ private void readNextItem() { .trim(); if (skipString.length() != 0 && !skipString.startsWith("//")) { this.detectedException = - new JBBPTokenizerException(skipString, this.processingString, Math.max(this.lastCharSubstringFound, 0)); + new JBBPTokenizerException(skipString, this.processingString, + Math.max(this.lastCharSubstringFound, 0)); } else { JBBPTokenType type = JBBPTokenType.ATOM; @@ -177,7 +178,8 @@ private void readNextItem() { final int position = matcher.start() + groupWholeFound.length() - groupWholeFoundTrimmed.length(); this.detectedException = - new JBBPTokenizerException("Detected atomic field definition without type", this.processingString, position); + new JBBPTokenizerException("Detected atomic field definition without type", + this.processingString, position); return; } @@ -251,7 +253,8 @@ private void readNextItem() { } } else { if (this.lastCharSubstringFound < 0) { - this.detectedException = new JBBPTokenizerException("Wrong format of whole string", this.processingString, 0); + this.detectedException = + new JBBPTokenizerException("Wrong format of whole string", this.processingString, 0); } else { final String restOfString = this.processingString.substring(this.lastCharSubstringFound); if (restOfString.trim().length() != 0) { @@ -277,7 +280,8 @@ private JBBPTokenizerException checkFieldName(final String name, final int posit if (name != null) { final String normalized = JBBPUtils.normalizeFieldNameOrPath(name); if (normalized.indexOf('.') >= 0) { - return new JBBPTokenizerException("Field name must not contain '.' char", this.processingString, position); + return new JBBPTokenizerException("Field name must not contain '.' char", + this.processingString, position); } if (normalized.length() > 0) { @@ -286,13 +290,15 @@ private JBBPTokenizerException checkFieldName(final String name, final int posit || normalized.startsWith("$") || Character.isDigit(normalized.charAt(0)) ) { - return new JBBPTokenizerException("'" + name + "' can't be field name", this.processingString, position); + return new JBBPTokenizerException("'" + name + "' can't be field name", + this.processingString, position); } for (int i = 1; i < normalized.length(); i++) { final char chr = normalized.charAt(i); if (chr != '_' && !Character.isLetterOrDigit(chr)) { - return new JBBPTokenizerException("Char '" + chr + "' not allowed in name", this.processingString, position); + return new JBBPTokenizerException("Char '" + chr + "' not allowed in name", + this.processingString, position); } } } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/varlen/JBBPEvaluatorFactory.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/varlen/JBBPEvaluatorFactory.java index 2d78d932..2cafd9b1 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/varlen/JBBPEvaluatorFactory.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/varlen/JBBPEvaluatorFactory.java @@ -18,7 +18,6 @@ import com.igormaznitsa.jbbp.compiler.JBBPCompilerUtils; import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; - import java.util.List; /** @@ -53,7 +52,9 @@ public static JBBPEvaluatorFactory getInstance() { * @see JBBPExpressionEvaluator * @see JBBPOnlyFieldEvaluator */ - public JBBPIntegerValueEvaluator make(final String expression, final List namedFields, final byte[] compiledScript) { + public JBBPIntegerValueEvaluator make(final String expression, + final List namedFields, + final byte[] compiledScript) { final JBBPIntegerValueEvaluator result; if (JBBPExpressionEvaluator.hasExpressionOperators(expression)) { @@ -75,7 +76,8 @@ public JBBPIntegerValueEvaluator make(final String expression, final List>", ">>>"}; + private static final String[] SYMBOLS = + new String[] {"(", "", "", "", "~", "-", "+", "+", "-", "*", "/", "%", "|", "^", "&", "<<", + ">>", ">>>"}; /** * Array of first chars of operators to recognize a string as possible expression. */ - private static final char[] OPERATOR_FIRST_CHARS = new char[] {'(', '+', '-', '*', '/', '%', '|', '&', '^', '~', ')', '>', '<'}; + private static final char[] OPERATOR_FIRST_CHARS = + new char[] {'(', '+', '-', '*', '/', '%', '|', '&', '^', '~', ')', '>', '<'}; /** * The Pattern to parse an expression. */ - private static final Pattern PATTERN = Pattern.compile("([0-9]+)|([()])|(<<|>>>|>>|[%*+\\-/&|^~])|([\\S][^<>\\s+%*\\-/()&|^~]*)"); + private static final Pattern PATTERN = + Pattern.compile("([0-9]+)|([()])|(<<|>>>|>>|[%*+\\-/&|^~])|([\\S][^<>\\s+%*\\-/()&|^~]*)"); /** * The Array contains byte code of compiled expression. */ @@ -162,7 +168,9 @@ public final class JBBPExpressionEvaluator implements JBBPIntegerValueEvaluator * @param compiledData the current compiled data block of JBBP parent script for the expression, must not be null * @throws JBBPCompilationException if any problem in compilation */ - public JBBPExpressionEvaluator(final String expression, final List namedFields, final byte[] compiledData) { + public JBBPExpressionEvaluator(final String expression, + final List namedFields, + final byte[] compiledData) { this.expressionSource = expression; final Matcher matcher = PATTERN.matcher(expression); @@ -187,7 +195,8 @@ public JBBPExpressionEvaluator(final String expression, final List 0) { - throw new JBBPCompilationException("Unary operator without argument '" + SYMBOLS[unaryOperatorCode] + "' [" + this.expressionSource + ']'); + throw new JBBPCompilationException( + "Unary operator without argument '" + SYMBOLS[unaryOperatorCode] + "' [" + + this.expressionSource + ']'); } if (counterOperators == 0) { @@ -404,17 +420,20 @@ public JBBPExpressionEvaluator(final String expression, final List fieldType) { + public JBBPTooManyFieldsFoundException(final int numberOfInstances, final String message, + final String nameOrPath, + final Class fieldType) { super(message, nameOrPath, fieldType); this.numberOfInstances = numberOfInstances; } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/AbstractMappedClassFieldObserver.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/AbstractMappedClassFieldObserver.java index b8f47ff0..96c92cb6 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/AbstractMappedClassFieldObserver.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/AbstractMappedClassFieldObserver.java @@ -67,7 +67,8 @@ private static Object readFieldValue(final Object obj, final MappedFieldRecord r */ private static void assertFieldArray(final Field field) { if (!field.getType().isArray()) { - throw new IllegalArgumentException("Detected non-array field marked to be written as an array [" + field + ']'); + throw new IllegalArgumentException( + "Detected non-array field marked to be written as an array [" + field + ']'); } } @@ -97,10 +98,14 @@ protected void processObject( this.onStructStart(obj, field, clazzAnno == null ? fieldAnno : clazzAnno); for (final MappedFieldRecord rec : orderedFields) { - final Bin binAnno = binAnnotationWrapper == null ? rec.binAnnotation : binAnnotationWrapper.setWrapped(rec.binAnnotation); + 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."); + 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); @@ -129,10 +134,12 @@ protected void processObjectField( final Field field = fieldRecord.mappingField; if (annotation.custom()) { - this.onFieldCustom(obj, field, annotation, customFieldProcessor, readFieldValue(obj, fieldRecord)); + this.onFieldCustom(obj, field, annotation, customFieldProcessor, + readFieldValue(obj, fieldRecord)); } else { final Class fieldType = field.getType(); - final BinAnnotationWrapper wrapper = annotation instanceof BinAnnotationWrapper ? (BinAnnotationWrapper) annotation : null; + final BinAnnotationWrapper wrapper = + annotation instanceof BinAnnotationWrapper ? (BinAnnotationWrapper) annotation : null; final BinType type; if (annotation.type() == BinType.UNDEFINED) { type = BinType.findCompatible(fieldType); @@ -146,7 +153,8 @@ protected void processObjectField( case BIT: { final JBBPBitNumber bitNumber = annotation.bitNumber(); if (fieldType == boolean.class) { - this.onFieldBits(obj, field, annotation, bitNumber, ((Boolean) readFieldValue(obj, fieldRecord)) ? 0xFF : 0x00); + this.onFieldBits(obj, field, annotation, bitNumber, + ((Boolean) readFieldValue(obj, fieldRecord)) ? 0xFF : 0x00); } else { byte value = ((Number) readFieldValue(obj, fieldRecord)).byteValue(); if (reverseBits) { @@ -160,7 +168,8 @@ protected void processObjectField( if (fieldType == boolean.class) { onFieldBool(obj, field, annotation, (Boolean) readFieldValue(obj, fieldRecord)); } else { - onFieldBool(obj, field, annotation, ((Number) readFieldValue(obj, fieldRecord)).longValue() != 0); + onFieldBool(obj, field, annotation, + ((Number) readFieldValue(obj, fieldRecord)).longValue() != 0); } } break; @@ -204,7 +213,8 @@ protected void processObjectField( value = ((Number) readFieldValue(obj, fieldRecord)).floatValue(); } if (reverseBits) { - value = Float.intBitsToFloat((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(value))); + value = + Float.intBitsToFloat((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(value))); } this.onFieldFloat(obj, field, annotation, value); } @@ -242,7 +252,8 @@ protected void processObjectField( } if (reverseBits) { - value = Double.longBitsToDouble(JBBPFieldLong.reverseBits(Double.doubleToLongBits(value))); + value = + Double.longBitsToDouble(JBBPFieldLong.reverseBits(Double.doubleToLongBits(value))); } this.onFieldDouble(obj, field, annotation, value); } @@ -264,7 +275,8 @@ protected void processObjectField( if (fieldType.getComponentType() == boolean.class) { for (int i = 0; i < len; i++) { - this.onFieldBits(obj, field, annotation, bitNumber, (Boolean) Array.get(array, i) ? 0xFF : 0x00); + this.onFieldBits(obj, field, annotation, bitNumber, + (Boolean) Array.get(array, i) ? 0xFF : 0x00); } } else { for (int i = 0; i < len; i++) { @@ -373,7 +385,8 @@ protected void processObjectField( for (int i = 0; i < len; i++) { float value = Array.getFloat(array, i); if (reverseBits) { - value = Float.intBitsToFloat((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(value))); + value = Float + .intBitsToFloat((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(value))); } this.onFieldFloat(obj, field, annotation, value); } @@ -431,7 +444,8 @@ protected void processObjectField( for (int i = 0; i < len; i++) { double value = ((Number) Array.get(array, i)).doubleValue(); if (reverseBits) { - value = Double.longBitsToDouble(JBBPFieldLong.reverseBits(Double.doubleToLongBits(value))); + value = Double + .longBitsToDouble(JBBPFieldLong.reverseBits(Double.doubleToLongBits(value))); } this.onFieldDouble(obj, field, annotation, value); } @@ -449,7 +463,8 @@ protected void processObjectField( } break; default: { - throw new Error("Unexpected situation for field type, contact developer [" + type + ']'); + throw new Error( + "Unexpected situation for field type, contact developer [" + type + ']'); } } } @@ -467,7 +482,8 @@ protected void processObjectField( * @param customFieldProcessor processor for custom fields, must not be null * @param value the value of the custom field */ - protected void onFieldCustom(final Object obj, final Field field, final Bin annotation, final Object customFieldProcessor, final Object value) { + protected void onFieldCustom(final Object obj, final Field field, final Bin annotation, + final Object customFieldProcessor, final Object value) { } @@ -480,7 +496,8 @@ protected void onFieldCustom(final Object obj, final Field field, final Bin anno * @param bitNumber number of bits for the field, must not be null * @param value the value of the field */ - protected void onFieldBits(final Object obj, final Field field, final Bin annotation, final JBBPBitNumber bitNumber, final int value) { + protected void onFieldBits(final Object obj, final Field field, final Bin annotation, + final JBBPBitNumber bitNumber, final int value) { } @@ -492,7 +509,8 @@ protected void onFieldBits(final Object obj, final Field field, final Bin annota * @param annotation the annotation for field, must not be null * @param value the value of the field */ - protected void onFieldBool(final Object obj, final Field field, final Bin annotation, final boolean value) { + protected void onFieldBool(final Object obj, final Field field, final Bin annotation, + final boolean value) { } @@ -505,7 +523,8 @@ protected void onFieldBool(final Object obj, final Field field, final Bin annota * @param signed flag shows that the field id signed * @param value the value of the field */ - protected void onFieldByte(final Object obj, final Field field, final Bin annotation, final boolean signed, final int value) { + protected void onFieldByte(final Object obj, final Field field, final Bin annotation, + final boolean signed, final int value) { } @@ -518,7 +537,8 @@ protected void onFieldByte(final Object obj, final Field field, final Bin annota * @param signed flag shows that the field id signed * @param value the value of the field */ - protected void onFieldShort(final Object obj, final Field field, final Bin annotation, final boolean signed, final int value) { + protected void onFieldShort(final Object obj, final Field field, final Bin annotation, + final boolean signed, final int value) { } @@ -530,7 +550,8 @@ protected void onFieldShort(final Object obj, final Field field, final Bin annot * @param annotation the annotation for field, must not be null * @param value the value of the field */ - protected void onFieldInt(final Object obj, final Field field, final Bin annotation, final int value) { + protected void onFieldInt(final Object obj, final Field field, final Bin annotation, + final int value) { } @@ -543,7 +564,8 @@ protected void onFieldInt(final Object obj, final Field field, final Bin annotat * @param value the value of the field * @since 1.4.0 */ - protected void onFieldFloat(final Object obj, final Field field, final Bin annotation, final float value) { + protected void onFieldFloat(final Object obj, final Field field, final Bin annotation, + final float value) { } @@ -556,7 +578,8 @@ protected void onFieldFloat(final Object obj, final Field field, final Bin annot * @param value the value of the field * @since 1.4.0 */ - protected void onFieldString(final Object obj, final Field field, final Bin annotation, final String value) { + protected void onFieldString(final Object obj, final Field field, final Bin annotation, + final String value) { } @@ -569,7 +592,8 @@ protected void onFieldString(final Object obj, final Field field, final Bin anno * @param value the value of the field * @since 1.4.0 */ - protected void onFieldDouble(final Object obj, final Field field, final Bin annotation, final double value) { + protected void onFieldDouble(final Object obj, final Field field, final Bin annotation, + final double value) { } @@ -581,7 +605,8 @@ protected void onFieldDouble(final Object obj, final Field field, final Bin anno * @param annotation the annotation for field, must not be null * @param value the value of the field */ - protected void onFieldLong(final Object obj, final Field field, final Bin annotation, final long value) { + protected void onFieldLong(final Object obj, final Field field, final Bin annotation, + final long value) { } @@ -615,7 +640,8 @@ protected void onStructEnd(final Object obj, final Field field, final Bin annota * @param annotation the annotation for field, must not be null * @param length the length of the array */ - protected void onArrayStart(final Object obj, final Field field, final Bin annotation, final int length) { + protected void onArrayStart(final Object obj, final Field field, final Bin annotation, + final int length) { } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitInputStream.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitInputStream.java index 796a8231..a702fc1d 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitInputStream.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitInputStream.java @@ -18,7 +18,6 @@ import com.igormaznitsa.jbbp.utils.JBBPSystemProperty; import com.igormaznitsa.jbbp.utils.JBBPUtils; - import java.io.EOFException; import java.io.FilterInputStream; import java.io.IOException; @@ -36,7 +35,8 @@ public class JBBPBitInputStream extends FilterInputStream implements JBBPCountab /** * The Initial an Array buffer size for whole stream read. */ - protected static final int INITIAL_ARRAY_BUFFER_SIZE = JBBPSystemProperty.PROPERTY_INPUT_INITIAL_ARRAY_BUFFER_SIZE.getAsInteger(32); + protected static final int INITIAL_ARRAY_BUFFER_SIZE = + JBBPSystemProperty.PROPERTY_INPUT_INITIAL_ARRAY_BUFFER_SIZE.getAsInteger(32); /** * Flag shows that bit operations must be processed for MSB0 (most significant * bit 0) mode. @@ -169,7 +169,8 @@ private byte[] _readArray(final int items, final JBBPBitNumber bitNumber) throws if (readByteArray) { final int read = this.read(buffer, 0, items); if (read != items) { - throw new EOFException("Have read only " + read + " byte(s) instead of " + items + " byte(s)"); + throw new EOFException( + "Have read only " + read + " byte(s) instead of " + items + " byte(s)"); } } else { for (int i = 0; i < items; i++) { @@ -456,7 +457,8 @@ public long[] readLongArray(final int items, final JBBPByteOrder byteOrder) thro * @see JBBPByteOrder#LITTLE_ENDIAN * @since 1.4.0 */ - public double[] readDoubleArray(final int items, final JBBPByteOrder byteOrder) throws IOException { + public double[] readDoubleArray(final int items, final JBBPByteOrder byteOrder) + throws IOException { int pos = 0; if (items < 0) { double[] buffer = new double[INITIAL_ARRAY_BUFFER_SIZE]; @@ -563,9 +565,11 @@ public float readFloat(final JBBPByteOrder byteOrder) throws IOException { */ public long readLong(final JBBPByteOrder byteOrder) throws IOException { if (byteOrder == JBBPByteOrder.BIG_ENDIAN) { - return (((long) readInt(byteOrder) & 0xFFFFFFFFL) << 32) | ((long) readInt(byteOrder) & 0xFFFFFFFFL); + return (((long) readInt(byteOrder) & 0xFFFFFFFFL) << 32) | + ((long) readInt(byteOrder) & 0xFFFFFFFFL); } else { - return ((long) readInt(byteOrder) & 0xFFFFFFFFL) | (((long) readInt(byteOrder) & 0xFFFFFFFFL) << 32); + return ((long) readInt(byteOrder) & 0xFFFFFFFFL) | + (((long) readInt(byteOrder) & 0xFFFFFFFFL) << 32); } } @@ -584,9 +588,11 @@ public long readLong(final JBBPByteOrder byteOrder) throws IOException { public double readDouble(final JBBPByteOrder byteOrder) throws IOException { final long value; if (byteOrder == JBBPByteOrder.BIG_ENDIAN) { - value = (((long) readInt(byteOrder) & 0xFFFFFFFFL) << 32) | ((long) readInt(byteOrder) & 0xFFFFFFFFL); + value = (((long) readInt(byteOrder) & 0xFFFFFFFFL) << 32) | + ((long) readInt(byteOrder) & 0xFFFFFFFFL); } else { - value = ((long) readInt(byteOrder) & 0xFFFFFFFFL) | (((long) readInt(byteOrder) & 0xFFFFFFFFL) << 32); + value = ((long) readInt(byteOrder) & 0xFFFFFFFFL) | + (((long) readInt(byteOrder) & 0xFFFFFFFFL) << 32); } return Double.longBitsToDouble(value); } @@ -716,7 +722,9 @@ public int readBits(final JBBPBitNumber numOfBitsToRead) throws IOException { this.bitBuffer = theBitBuffer; this.bitsInBuffer = theBitBufferCounter; - return JBBPUtils.reverseBitsInByte(JBBPBitNumber.decode(numOfBitsAsNumber - i), (byte) result) & 0xFF; + return + JBBPUtils.reverseBitsInByte(JBBPBitNumber.decode(numOfBitsAsNumber - i), (byte) result) & + 0xFF; } } @@ -1027,7 +1035,8 @@ public String readString(final JBBPByteOrder byteOrder) throws IOException { * @see JBBPBitOutputStream#writeStringArray(String[], JBBPByteOrder) * @since 1.4.0 */ - public String[] readStringArray(final int items, final JBBPByteOrder byteOrder) throws IOException { + public String[] readStringArray(final int items, final JBBPByteOrder byteOrder) + throws IOException { int pos = 0; if (items < 0) { String[] buffer = new String[INITIAL_ARRAY_BUFFER_SIZE]; diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitOutputStream.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitOutputStream.java index 69a84f2d..13bf5b7f 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitOutputStream.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitOutputStream.java @@ -346,7 +346,8 @@ public void write(final int value) throws IOException { * @see JBBPByteOrder#LITTLE_ENDIAN * @since 1.3.0 */ - public void writeBytes(final byte[] array, final int length, final JBBPByteOrder byteOrder) throws IOException { + public void writeBytes(final byte[] array, final int length, final JBBPByteOrder byteOrder) + throws IOException { if (byteOrder == JBBPByteOrder.LITTLE_ENDIAN) { int i = length < 0 ? array.length - 1 : length - 1; while (i >= 0) { diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPCustomFieldWriter.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPCustomFieldWriter.java index 45123923..c3764e3e 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPCustomFieldWriter.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPCustomFieldWriter.java @@ -17,7 +17,6 @@ package com.igormaznitsa.jbbp.io; import com.igormaznitsa.jbbp.mapper.Bin; - import java.io.IOException; import java.lang.reflect.Field; @@ -40,5 +39,7 @@ public interface JBBPCustomFieldWriter { * @param value the value found in the field, can be null * @throws IOException it will be thrown if it is impossible to process field data and save them into the stream */ - void writeCustomField(final JBBPOut context, final JBBPBitOutputStream outStream, final Object instanceToSave, final Field instanceCustomField, final Bin fieldAnnotation, final Object value) throws IOException; + void writeCustomField(final JBBPOut context, final JBBPBitOutputStream outStream, + final Object instanceToSave, final Field instanceCustomField, + final Bin fieldAnnotation, final Object value) throws IOException; } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java index 1d29af75..2af272f2 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOut.java @@ -78,15 +78,19 @@ public final class JBBPOut extends AbstractMappedClassFieldObserver { * @throws IllegalArgumentException if defined a bit stream which parameters * incompatible with defined ones */ - private JBBPOut(final OutputStream outStream, final JBBPByteOrder byteOrder, final JBBPBitOrder bitOrder) { + private JBBPOut(final OutputStream outStream, final JBBPByteOrder byteOrder, + final JBBPBitOrder bitOrder) { JBBPUtils.assertNotNull(outStream, "Out stream must not be null"); JBBPUtils.assertNotNull(byteOrder, "Byte order must not be null"); JBBPUtils.assertNotNull(bitOrder, "Bit order must not be null"); - this.outStream = outStream instanceof JBBPBitOutputStream ? (JBBPBitOutputStream) outStream : new JBBPBitOutputStream(outStream, bitOrder); + this.outStream = outStream instanceof JBBPBitOutputStream ? (JBBPBitOutputStream) outStream : + new JBBPBitOutputStream(outStream, bitOrder); this.bitOrder = this.outStream.getBitOrder(); if (this.bitOrder != bitOrder) { - throw new IllegalArgumentException("Detected JBBPBitOutputStream as argument with already defined different bit order [" + this.bitOrder + ']'); + throw new IllegalArgumentException( + "Detected JBBPBitOutputStream as argument with already defined different bit order [" + + this.bitOrder + ']'); } this.byteOrder = byteOrder; @@ -117,7 +121,8 @@ public static JBBPOut BeginBin(final JBBPByteOrder byteOrder, final JBBPBitOrder * @param bitOrder the bit outOrder for the session * @return the new DSL session generated for the stream with parameters */ - public static JBBPOut BeginBin(final OutputStream out, final JBBPByteOrder byteOrder, final JBBPBitOrder bitOrder) { + public static JBBPOut BeginBin(final OutputStream out, final JBBPByteOrder byteOrder, + final JBBPBitOrder bitOrder) { return new JBBPOut(out, byteOrder, bitOrder); } @@ -141,7 +146,8 @@ public static JBBPOut BeginBin() { * inside byte array stream. */ public static JBBPOut BeginBin(final int initialSize) { - return new JBBPOut(new ByteArrayOutputStream(initialSize), DEFAULT_BYTE_ORDER, DEFAULT_BIT_ORDER); + return new JBBPOut(new ByteArrayOutputStream(initialSize), DEFAULT_BYTE_ORDER, + DEFAULT_BIT_ORDER); } /** @@ -1043,7 +1049,8 @@ public JBBPOut Bin(final Object object, final JBBPCustomFieldWriter customFieldW * @return the context * @since 2.0.2 */ - public JBBPOut Bin(final Object object, final BinAnnotationWrapper binAnnotationWrapper, final JBBPCustomFieldWriter customFieldWriter) { + public JBBPOut Bin(final Object object, final BinAnnotationWrapper binAnnotationWrapper, + final JBBPCustomFieldWriter customFieldWriter) { if (this.processCommands) { this.processObject(object, null, binAnnotationWrapper, customFieldWriter); } @@ -1076,12 +1083,15 @@ public JBBPOut BinForceByteOrder(final Object object) throws IOException { * @see Bin#byteOrder() * @since 2.0.2 */ - public JBBPOut BinForceByteOrder(final Object object, final JBBPCustomFieldWriter customFieldWriter) { - return this.Bin(object, new BinAnnotationWrapper().setByteOrder(this.byteOrder), customFieldWriter); + public JBBPOut BinForceByteOrder(final Object object, + final JBBPCustomFieldWriter customFieldWriter) { + return this + .Bin(object, new BinAnnotationWrapper().setByteOrder(this.byteOrder), customFieldWriter); } @Override - protected void onFieldFloat(final Object obj, final Field field, final Bin annotation, final float value) { + 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(); @@ -1094,7 +1104,8 @@ protected void onFieldFloat(final Object obj, final Field field, final Bin annot } @Override - protected void onFieldString(final Object obj, final Field field, final Bin annotation, final String value) { + 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(); @@ -1107,7 +1118,8 @@ protected void onFieldString(final Object obj, final Field field, final Bin anno } @Override - protected void onFieldDouble(final Object obj, final Field field, final Bin annotation, final double value) { + 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(); @@ -1120,7 +1132,8 @@ protected void onFieldDouble(final Object obj, final Field field, final Bin anno } @Override - protected void onFieldLong(final Object obj, final Field field, final Bin annotation, final long value) { + protected void onFieldLong(final Object obj, final Field field, final Bin annotation, + final long value) { final JBBPByteOrder old = this.byteOrder; try { this.byteOrder = annotation.byteOrder(); @@ -1133,7 +1146,8 @@ protected void onFieldLong(final Object obj, final Field field, final Bin annota } @Override - protected void onFieldInt(final Object obj, final Field field, final Bin annotation, final int value) { + 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(); @@ -1146,7 +1160,8 @@ protected void onFieldInt(final Object obj, final Field field, final Bin annotat } @Override - protected void onFieldShort(final Object obj, final Field field, final Bin annotation, final boolean signed, final int value) { + 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(); @@ -1159,7 +1174,8 @@ protected void onFieldShort(final Object obj, final Field field, final Bin annot } @Override - protected void onFieldByte(final Object obj, final Field field, final Bin annotation, final boolean signed, final int value) { + 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) { @@ -1168,7 +1184,8 @@ protected void onFieldByte(final Object obj, final Field field, final Bin annota } @Override - protected void onFieldBool(final Object obj, final Field field, final Bin annotation, final boolean value) { + protected void onFieldBool(final Object obj, final Field field, final Bin annotation, + final boolean value) { try { this.Bool(value, annotation.bitOrder()); } catch (IOException ex) { @@ -1177,7 +1194,8 @@ protected void onFieldBool(final Object obj, final Field field, final Bin annota } @Override - protected void onFieldBits(final Object obj, final Field field, final Bin annotation, final JBBPBitNumber bitNumber, final int value) { + 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) { @@ -1186,7 +1204,8 @@ protected void onFieldBits(final Object obj, final Field field, final Bin annota } @Override - protected void onFieldCustom(final Object obj, final Field field, final Bin annotation, final Object customFieldProcessor, final Object value) { + 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); diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOutVarProcessor.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOutVarProcessor.java index 973b84fb..b83fbc12 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOutVarProcessor.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPOutVarProcessor.java @@ -33,5 +33,6 @@ public interface JBBPOutVarProcessor { * @return true is to continue processing of DSL commands, false skip all commands till the End() * @throws IOException it should be thrown for transport errors */ - boolean processVarOut(JBBPOut context, JBBPBitOutputStream outStream, Object... args) throws IOException; + boolean processVarOut(JBBPOut context, JBBPBitOutputStream outStream, Object... args) + throws IOException; } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/Bin.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/Bin.java index 2988d34a..40f4aef7 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/Bin.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/Bin.java @@ -38,7 +38,7 @@ * @since 1.0 */ @Retention(RetentionPolicy.RUNTIME) -@Target( {ElementType.FIELD, ElementType.TYPE}) +@Target({ElementType.FIELD, ElementType.TYPE}) @Inherited public @interface Bin { diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/JBBPMapper.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/JBBPMapper.java index 93144865..f269039f 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/JBBPMapper.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/JBBPMapper.java @@ -49,7 +49,8 @@ public final class JBBPMapper { * @since 1.1 */ public static final int FLAG_IGNORE_MISSING_VALUES = 1; - private static final Map, List> CACHED_FIELDS = new ConcurrentHashMap<>(); + private static final Map, List> CACHED_FIELDS = + new ConcurrentHashMap<>(); /** * Create a class instance, map binary data of a structure for its path to its @@ -66,7 +67,8 @@ public final class JBBPMapper { * @since 2.0.0 */ @SafeVarargs - public static T map(final JBBPFieldStruct root, final String structPath, final T instance, final Function, Object>... instantiators) { + public static T map(final JBBPFieldStruct root, final String structPath, final T instance, + final Function, Object>... instantiators) { return map(root, structPath, instance, null, instantiators); } @@ -88,7 +90,8 @@ public static T map(final JBBPFieldStruct root, final String structPath, fin * @since 2.0.0 */ @SafeVarargs - public static T map(final JBBPFieldStruct root, final String structPath, final T instance, final int flags, final Function, Object>... instantiators) { + public static T map(final JBBPFieldStruct root, final String structPath, final T instance, + final int flags, final Function, Object>... instantiators) { return map(root, structPath, instance, null, flags, instantiators); } @@ -111,7 +114,9 @@ public static T map(final JBBPFieldStruct root, final String structPath, fin * @since 2.0.0 */ @SafeVarargs - public static T map(final JBBPFieldStruct root, final String structPath, final T instance, final JBBPMapperCustomFieldProcessor customFieldProcessor, final Function, Object>... instantiators) { + public static T map(final JBBPFieldStruct root, final String structPath, final T instance, + final JBBPMapperCustomFieldProcessor customFieldProcessor, + final Function, Object>... instantiators) { return map(root, structPath, instance, customFieldProcessor, 0, instantiators); } @@ -136,11 +141,15 @@ public static T map(final JBBPFieldStruct root, final String structPath, fin * @since 2.0.0 */ @SafeVarargs - public static T map(final JBBPFieldStruct root, final String structPath, final T instance, final JBBPMapperCustomFieldProcessor customFieldProcessor, final int flags, final Function, Object>... instantiators) { + public static T map(final JBBPFieldStruct root, final String structPath, final T instance, + final JBBPMapperCustomFieldProcessor customFieldProcessor, + final int flags, final Function, Object>... instantiators) { JBBPUtils.assertNotNull(structPath, "Path must not be null"); final JBBPFieldStruct struct = root.findFieldForPathAndType(structPath, JBBPFieldStruct.class); if (struct == null) { - throw new JBBPMapperException("Can't find a structure field for its path [" + structPath + ']', null, instance.getClass(), null, null); + throw new JBBPMapperException( + "Can't find a structure field for its path [" + structPath + ']', null, + instance.getClass(), null, null); } return map(struct, instance, customFieldProcessor, flags, instantiators); } @@ -161,7 +170,8 @@ public static T map(final JBBPFieldStruct root, final String structPath, fin * @since 2.0.0 */ @SafeVarargs - public static T map(final JBBPFieldStruct root, final T instance, final Function, Object>... instantiators) { + public static T map(final JBBPFieldStruct root, final T instance, + final Function, Object>... instantiators) { return map(root, instance, null, instantiators); } @@ -184,7 +194,8 @@ public static T map(final JBBPFieldStruct root, final T instance, final Func * @since 2.0.0 */ @SafeVarargs - public static T map(final JBBPFieldStruct root, final T instance, final int flags, final Function, Object>... instantiators) { + public static T map(final JBBPFieldStruct root, final T instance, final int flags, + final Function, Object>... instantiators) { return map(root, instance, null, flags, instantiators); } @@ -205,7 +216,9 @@ public static T map(final JBBPFieldStruct root, final T instance, final int * @throws JBBPMapperException for any error */ @SafeVarargs - public static T map(final JBBPFieldStruct rootStructure, final T instance, final JBBPMapperCustomFieldProcessor customFieldProcessor, final Function, Object>... instantiators) { + public static T map(final JBBPFieldStruct rootStructure, final T instance, + final JBBPMapperCustomFieldProcessor customFieldProcessor, + final Function, Object>... instantiators) { return map(rootStructure, instance, customFieldProcessor, 0, instantiators); } @@ -220,29 +233,41 @@ private static void processFieldOfMappedClass( final Function, Object>... instantiators ) { if (record.binAnnotation.custom()) { - JBBPUtils.assertNotNull(customFieldProcessor, "There is a custom mapping field, in the case you must provide a custom mapping field processor"); - final Object value = customFieldProcessor.prepareObjectForMapping(rootStructure, record.binAnnotation, record.mappingField); + JBBPUtils.assertNotNull(customFieldProcessor, + "There is a custom mapping field, in the case you must provide a custom mapping field processor"); + final Object value = customFieldProcessor + .prepareObjectForMapping(rootStructure, record.binAnnotation, record.mappingField); MappedFieldRecord.setFieldValue(instance, record.setter, record.mappingField, null, value); } else { final JBBPAbstractField binField; if (record.fieldPath.length() == 0) { - binField = record.fieldName.length() == 0 ? rootStructure.findFieldForType(record.fieldType.getFieldClass()) : rootStructure.findFieldForNameAndType(record.fieldName, record.fieldType.getFieldClass()); + binField = record.fieldName.length() == 0 ? + rootStructure.findFieldForType(record.fieldType.getFieldClass()) : rootStructure + .findFieldForNameAndType(record.fieldName, record.fieldType.getFieldClass()); } else { - binField = rootStructure.findFieldForPathAndType(record.fieldPath, record.fieldType.getFieldClass()); + binField = rootStructure + .findFieldForPathAndType(record.fieldPath, record.fieldType.getFieldClass()); } if (binField == null) { if ((flags & FLAG_IGNORE_MISSING_VALUES) != 0) { return; } - throw new JBBPMapperException("Can't find value for mapping field [" + record.mappingField + ']', null, record.mappingClass, record.mappingField, null); + throw new JBBPMapperException( + "Can't find value for mapping field [" + record.mappingField + ']', null, + record.mappingClass, record.mappingField, null); } - if (record.bitWideField && record.mappedBitNumber != JBBPBitNumber.BITS_8 && ((BitEntity) binField).getBitWidth() != record.mappedBitNumber) { - throw new JBBPMapperException("Can't map mapping field because wrong field bitness [" + record.mappedBitNumber + "!=" + ((BitEntity) binField).getBitWidth().getBitNumber() + ']', null, record.mappingClass, record.mappingField, null); + if (record.bitWideField && record.mappedBitNumber != JBBPBitNumber.BITS_8 && + ((BitEntity) binField).getBitWidth() != record.mappedBitNumber) { + throw new JBBPMapperException( + "Can't map mapping field because wrong field bitness [" + record.mappedBitNumber + + "!=" + ((BitEntity) binField).getBitWidth().getBitNumber() + ']', null, + record.mappingClass, record.mappingField, null); } - record.proc.apply(record, rootStructure, instance, customFieldProcessor, binField, flags, instantiators); + record.proc.apply(record, rootStructure, instance, customFieldProcessor, binField, flags, + instantiators); } } @@ -267,7 +292,9 @@ private static void processFieldOfMappedClass( */ @SafeVarargs @SuppressWarnings("varargs") - public static T map(final JBBPFieldStruct rootStructure, final T instance, final JBBPMapperCustomFieldProcessor customFieldProcessor, final int flags, final Function, Object>... instantiators) { + public static T map(final JBBPFieldStruct rootStructure, final T instance, + final JBBPMapperCustomFieldProcessor customFieldProcessor, + final int flags, final Function, Object>... instantiators) { JBBPUtils.assertNotNull(rootStructure, "The Root structure must not be null"); JBBPUtils.assertNotNull(instance, "The Mapping class instance must not be null"); @@ -334,7 +361,8 @@ public static List findAffectedFields(final Object instance) final Bin fieldAnno = mappingField.getAnnotation(Bin.class); final Bin mappedAnno; - if ((fieldAnno == null && defaultAnno == null) || mappingField.getName().indexOf('$') >= 0) { + if ((fieldAnno == null && defaultAnno == null) || + mappingField.getName().indexOf('$') >= 0) { continue; } mappedAnno = fieldAnno == null ? defaultAnno : fieldAnno; @@ -355,26 +383,33 @@ public static List findAffectedFields(final Object instance) disallowedModifier = null; } if (disallowedModifier != null) { - throw new JBBPMapperException("Detected @Bin marked " + disallowedModifier + " field", null, processingClazz, mappingField, null); + throw new JBBPMapperException("Detected @Bin marked " + disallowedModifier + " field", + null, processingClazz, mappingField, null); } } - final NullableTriple auxMethods = findAuxFieldMethods(processingClazz, mappingField); + final NullableTriple auxMethods = + findAuxFieldMethods(processingClazz, mappingField); final Method fieldGenerator = auxMethods.getA(); final Method fieldGetter = auxMethods.getB(); final Method fieldSetter = auxMethods.getC(); - if (mappingField.getType().isPrimitive() && fieldSetter == null && Modifier.isPrivate(mappingField.getModifiers())) { - throw new JBBPMapperException("Detected private primitive field, mapping requires setter", null, processingClazz, mappingField, null); + if (mappingField.getType().isPrimitive() && fieldSetter == null && + Modifier.isPrivate(mappingField.getModifiers())) { + throw new JBBPMapperException( + "Detected private primitive field, mapping requires setter", null, processingClazz, + mappingField, null); } - if (fieldGetter == null && fieldGenerator == null && !ReflectUtils.isPotentiallyAccessibleField(mappingField)) { + if (fieldGetter == null && fieldGenerator == null && + !ReflectUtils.isPotentiallyAccessibleField(mappingField)) { mappingField = ReflectUtils.makeAccessible(mappingField); } try { - result.add(new MappedFieldRecord(mappingField, fieldGenerator, fieldSetter, fieldGetter, mappingClass, mappedAnno)); + result.add(new MappedFieldRecord(mappingField, fieldGenerator, fieldSetter, fieldGetter, + mappingClass, mappedAnno)); } catch (IllegalStateException ex) { throw new JBBPMapperException(ex.getMessage(), null, mappingClass, mappingField, ex); } @@ -389,7 +424,8 @@ public static List findAffectedFields(final Object instance) return result; } - private static NullableTriple findAuxFieldMethods(final Class klazz, final Field field) { + private static NullableTriple findAuxFieldMethods(final Class klazz, + final Field field) { final String lowerCasedFieldName = field.getName().toLowerCase(Locale.ENGLISH); final String generatorName = "make" + lowerCasedFieldName; final String getterName = "get" + lowerCasedFieldName; @@ -417,7 +453,8 @@ private static NullableTriple findAuxFieldMethods(final } } - if (args.length == 1 && setter == null && lcMethodName.equals(setterName) && field.getType().isAssignableFrom(args[0])) { + if (args.length == 1 && setter == null && lcMethodName.equals(setterName) && + field.getType().isAssignableFrom(args[0])) { setter = m; } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/JBBPMapperCustomFieldProcessor.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/JBBPMapperCustomFieldProcessor.java index 3a5a6d55..a46bca3e 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/JBBPMapperCustomFieldProcessor.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/JBBPMapperCustomFieldProcessor.java @@ -17,7 +17,6 @@ package com.igormaznitsa.jbbp.mapper; import com.igormaznitsa.jbbp.model.JBBPFieldStruct; - import java.lang.reflect.Field; /** @@ -34,5 +33,6 @@ public interface JBBPMapperCustomFieldProcessor { * @param field the mapping field in a mapping class, must not be null * @return an object which will be set to the field in a mapping class instance, it can be null for non-primitive fields */ - Object prepareObjectForMapping(final JBBPFieldStruct parsedBlock, final Bin annotation, final Field field); + Object prepareObjectForMapping(final JBBPFieldStruct parsedBlock, final Bin annotation, + final Field field); } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/MappedFieldRecord.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/MappedFieldRecord.java index bb1131fd..fc575e73 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/MappedFieldRecord.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/mapper/MappedFieldRecord.java @@ -29,128 +29,162 @@ import java.lang.reflect.Modifier; public final class MappedFieldRecord implements Comparable { - private static final Function, Object> STATIC_MAKE_CLASS_INSTANCE_INSTANTIATOR = (Class klazz) -> { - Class currentClass = klazz; - Object result = null; - boolean find; - do { - try { - final Method method = currentClass.getMethod(MAKE_CLASS_INSTANCE_METHOD_NAME, Class.class); - if (Modifier.isStatic(method.getModifiers())) { - result = method.invoke(null, klazz); - } - } catch (IllegalAccessException ex) { - throw new RuntimeException(String.format("Can't get access to static method %s(%ss) in %s", MAKE_CLASS_INSTANCE_METHOD_NAME, klazz, currentClass), ex); - } catch (InvocationTargetException ex) { - throw new RuntimeException(String.format("Can't call static method %s(%s) in %s", MAKE_CLASS_INSTANCE_METHOD_NAME, klazz, currentClass), ex); - } catch (NoSuchMethodException ex) { - // do nothing! - } - if (result == null) { - if (currentClass.isLocalClass()) { - currentClass = currentClass.getEnclosingClass(); - find = currentClass != null; - } else { - find = false; + private static final Function, Object> STATIC_MAKE_CLASS_INSTANCE_INSTANTIATOR = + (Class klazz) -> { + Class currentClass = klazz; + Object result = null; + boolean find; + do { + try { + final Method method = + currentClass.getMethod(MAKE_CLASS_INSTANCE_METHOD_NAME, Class.class); + if (Modifier.isStatic(method.getModifiers())) { + result = method.invoke(null, klazz); + } + } catch (IllegalAccessException ex) { + throw new RuntimeException(String + .format("Can't get access to static method %s(%ss) in %s", + MAKE_CLASS_INSTANCE_METHOD_NAME, klazz, currentClass), ex); + } catch (InvocationTargetException ex) { + throw new RuntimeException(String + .format("Can't call static method %s(%s) in %s", MAKE_CLASS_INSTANCE_METHOD_NAME, + klazz, currentClass), ex); + } catch (NoSuchMethodException ex) { + // do nothing! + } + if (result == null) { + if (currentClass.isLocalClass()) { + currentClass = currentClass.getEnclosingClass(); + find = currentClass != null; + } else { + find = false; + } + } else { + find = false; + } + } while (find); + return result; + }; + private static final Function, Object> DEFAULT_CONSTRUCTOR_INSTANTIATOR = + (Class aClass) -> { + try { + if (!aClass.isLocalClass() || Modifier.isStatic(aClass.getModifiers())) { + return aClass.getConstructor().newInstance(); + } else { + return null; + } + } catch (NoSuchMethodException ex) { + return null; + } catch (InvocationTargetException ex) { + throw new RuntimeException( + String.format("Error during default constructor call, class %s", aClass), ex); + } catch (IllegalAccessException ex) { + throw new RuntimeException( + String.format("Can't get access to default constructor , class %s", aClass), ex); + } catch (InstantiationException ex) { + throw new RuntimeException(String.format("Can't make instance of class %s", aClass), ex); } - } else { - find = false; - } - } while (find); - return result; - }; - private static final Function, Object> DEFAULT_CONSTRUCTOR_INSTANTIATOR = (Class aClass) -> { - try { - if (!aClass.isLocalClass() || Modifier.isStatic(aClass.getModifiers())) { - return aClass.getConstructor().newInstance(); - } else { - return null; - } - } catch (NoSuchMethodException ex) { - return null; - } catch (InvocationTargetException ex) { - throw new RuntimeException(String.format("Error during default constructor call, class %s", aClass), ex); - } catch (IllegalAccessException ex) { - throw new RuntimeException(String.format("Can't get access to default constructor , class %s", aClass), ex); - } catch (InstantiationException ex) { - throw new RuntimeException(String.format("Can't make instance of class %s", aClass), ex); - } - }; - private static final FieldProcessor PROC_ARRAYS = (record, rootStructure, instance, customFieldProcessor, binField, flags, instantiators) -> { + }; + private static final FieldProcessor PROC_ARRAYS = + (record, rootStructure, instance, customFieldProcessor, binField, flags, instantiators) -> { - if (binField instanceof JBBPAbstractArrayField) { - if (binField instanceof JBBPFieldArrayStruct) { - // structure - final JBBPFieldArrayStruct structArray = (JBBPFieldArrayStruct) binField; - final Class componentType = record.mappingField.getType().getComponentType(); + if (binField instanceof JBBPAbstractArrayField) { + if (binField instanceof JBBPFieldArrayStruct) { + // structure + final JBBPFieldArrayStruct structArray = (JBBPFieldArrayStruct) binField; + final Class componentType = record.mappingField.getType().getComponentType(); - Object valueArray = getFieldValue(instance, record.getter, record.mappingField); + Object valueArray = getFieldValue(instance, record.getter, record.mappingField); - valueArray = valueArray == null ? Array.newInstance(componentType, structArray.size()) : valueArray; + valueArray = valueArray == null ? Array.newInstance(componentType, structArray.size()) : + valueArray; - if (Array.getLength(valueArray) != structArray.size()) { - throw new JBBPMapperException("Can't map an array field for different expected size [" + Array.getLength(valueArray) + "!=" + structArray.size() + ']', binField, record.mappingClass, record.mappingField, null); - } + if (Array.getLength(valueArray) != structArray.size()) { + throw new JBBPMapperException( + "Can't map an array field for different expected size [" + + Array.getLength(valueArray) + "!=" + structArray.size() + ']', binField, + record.mappingClass, record.mappingField, null); + } - for (int i = 0; i < structArray.size(); i++) { - final Object curInstance = Array.get(valueArray, i); - if (curInstance == null) { - Array.set(valueArray, i, JBBPMapper.map(structArray.getElementAt(i), tryMakeInstance(componentType, binField, instance, record.mappingField, instantiators), customFieldProcessor, instantiators)); + for (int i = 0; i < structArray.size(); i++) { + final Object curInstance = Array.get(valueArray, i); + if (curInstance == null) { + Array.set(valueArray, i, JBBPMapper.map(structArray.getElementAt(i), + tryMakeInstance(componentType, binField, instance, record.mappingField, + instantiators), customFieldProcessor, instantiators)); + } else { + Array.set(valueArray, i, + JBBPMapper.map(structArray.getElementAt(i), curInstance, customFieldProcessor)); + } + } + setFieldValue(instance, record.setter, record.mappingField, binField, valueArray); } else { - Array.set(valueArray, i, JBBPMapper.map(structArray.getElementAt(i), curInstance, customFieldProcessor)); + // primitive + mapArrayField(instance, record.setter, record.mappingField, + (JBBPAbstractArrayField) binField, + record.binAnnotation.bitOrder() == JBBPBitOrder.MSB0); } + } else { + throw new JBBPMapperException("Can't map a non-array value to an array mapping field", + binField, record.mappingClass, record.mappingField, null); } - setFieldValue(instance, record.setter, record.mappingField, binField, valueArray); - } else { - // primitive - mapArrayField(instance, record.setter, record.mappingField, (JBBPAbstractArrayField) binField, record.binAnnotation.bitOrder() == JBBPBitOrder.MSB0); - } - } else { - throw new JBBPMapperException("Can't map a non-array value to an array mapping field", binField, record.mappingClass, record.mappingField, null); - } - }; - private static final FieldProcessor PROC_NUM = (record, rootStructure, instance, customFieldProcessor, binField, flags, instantiators) -> { - if (binField instanceof JBBPNumericField) { - mapNumericField(instance, record.setter, record.mappingField, (JBBPNumericField) binField, record.binAnnotation.bitOrder() == JBBPBitOrder.MSB0); - } else if (binField instanceof JBBPFieldString) { - if (record.mappingField.getType().isPrimitive()) { - throw new JBBPMapperException("Can't map string to a primitive mapping field", binField, record.mappingClass, record.mappingField, null); - } else { - setFieldValue(instance, record.setter, record.mappingField, binField, ((JBBPFieldString) binField).getAsString()); - } - } else if (binField instanceof JBBPFieldStruct) { - if (record.mappingField.getType().isPrimitive()) { - throw new JBBPMapperException("Can't map structure to a primitive mapping field", binField, record.mappingClass, record.mappingField, null); - } else { - final Object curValue = getFieldValue(instance, record.getter, record.mappingField); - if (curValue == null) { - if (record.instanceMaker == null) { - setFieldValue(instance, record.setter, record.mappingField, binField, JBBPMapper.map((JBBPFieldStruct) binField, tryMakeInstance(record.mappingField.getType(), binField, instance, record.mappingField, instantiators), customFieldProcessor)); + }; + private static final FieldProcessor PROC_NUM = + (record, rootStructure, instance, customFieldProcessor, binField, flags, instantiators) -> { + if (binField instanceof JBBPNumericField) { + mapNumericField(instance, record.setter, record.mappingField, (JBBPNumericField) binField, + record.binAnnotation.bitOrder() == JBBPBitOrder.MSB0); + } else if (binField instanceof JBBPFieldString) { + if (record.mappingField.getType().isPrimitive()) { + throw new JBBPMapperException("Can't map string to a primitive mapping field", binField, + record.mappingClass, record.mappingField, null); + } else { + setFieldValue(instance, record.setter, record.mappingField, binField, + ((JBBPFieldString) binField).getAsString()); + } + } else if (binField instanceof JBBPFieldStruct) { + if (record.mappingField.getType().isPrimitive()) { + throw new JBBPMapperException("Can't map structure to a primitive mapping field", + binField, record.mappingClass, record.mappingField, null); } else { - try { - JBBPMapper.map((JBBPFieldStruct) binField, record.instanceMaker.invoke(instance)); - } catch (Exception ex) { - throw new JBBPMapperException("Can't map field which member generatet by instance", binField, record.mappingClass, record.mappingField, ex); + final Object curValue = getFieldValue(instance, record.getter, record.mappingField); + if (curValue == null) { + if (record.instanceMaker == null) { + setFieldValue(instance, record.setter, record.mappingField, binField, JBBPMapper + .map((JBBPFieldStruct) binField, + tryMakeInstance(record.mappingField.getType(), binField, instance, + record.mappingField, instantiators), customFieldProcessor)); + } else { + try { + JBBPMapper.map((JBBPFieldStruct) binField, record.instanceMaker.invoke(instance)); + } catch (Exception ex) { + throw new JBBPMapperException( + "Can't map field which member generatet by instance", binField, + record.mappingClass, record.mappingField, ex); + } + } + } else { + setFieldValue(instance, record.setter, record.mappingField, binField, + JBBPMapper.map((JBBPFieldStruct) binField, curValue, customFieldProcessor)); } } } else { - setFieldValue(instance, record.setter, record.mappingField, binField, JBBPMapper.map((JBBPFieldStruct) binField, curValue, customFieldProcessor)); - } - } - } else { - boolean processed = false; - if (record.mappingField.getType() == String.class && binField instanceof JBBPAbstractArrayField) { - final String convertedValue = convertFieldValueToString((JBBPAbstractArrayField) binField); - if (convertedValue != null) { - setFieldValue(instance, record.setter, record.mappingField, binField, convertedValue); - processed = true; + boolean processed = false; + if (record.mappingField.getType() == String.class && + binField instanceof JBBPAbstractArrayField) { + final String convertedValue = + convertFieldValueToString((JBBPAbstractArrayField) binField); + if (convertedValue != null) { + setFieldValue(instance, record.setter, record.mappingField, binField, convertedValue); + processed = true; + } + } + if (!processed) { + throw new JBBPMapperException("Can't map a field for its value incompatibility", + binField, record.mappingClass, record.mappingField, null); + } } - } - if (!processed) { - throw new JBBPMapperException("Can't map a field for its value incompatibility", binField, record.mappingClass, record.mappingField, null); - } - } - }; + }; public final Field mappingField; public final Class mappingClass; @@ -185,7 +219,8 @@ public final class MappedFieldRecord implements Comparable { BinType thetype = BinType.findCompatible(mappingField.getType()); if (thetype == null) { throw new IllegalStateException("Can't find compatible mapped type for field"); - } else if (this.mappedBitNumber.getBitNumber() < 8 && !(thetype == BinType.STRUCT || thetype == BinType.STRUCT_ARRAY)) { + } else if (this.mappedBitNumber.getBitNumber() < 8 && + !(thetype == BinType.STRUCT || thetype == BinType.STRUCT_ARRAY)) { thetype = thetype.isArray() ? BinType.BIT_ARRAY : BinType.BIT; } this.fieldType = thetype; @@ -194,7 +229,8 @@ public final class MappedFieldRecord implements Comparable { } this.bitWideField = this.fieldType == BinType.BIT || fieldType == BinType.BIT_ARRAY; - this.fieldName = binAnnotation.name().length() == 0 ? mappingField.getName() : binAnnotation.name(); + this.fieldName = + binAnnotation.name().length() == 0 ? mappingField.getName() : binAnnotation.name(); this.fieldPath = binAnnotation.path(); if (this.mappingField.getType().isArray()) { @@ -215,24 +251,30 @@ public final class MappedFieldRecord implements Comparable { * @param invertBitOrder flag shows that values of an array must be bit * reversed before set */ - private static void mapArrayField(final Object mappingClassInstance, final Method setter, final Field mappingField, final JBBPAbstractArrayField arrayField, final boolean invertBitOrder) { + private static void mapArrayField(final Object mappingClassInstance, final Method setter, + final Field mappingField, + final JBBPAbstractArrayField arrayField, + final boolean invertBitOrder) { try { final Object value; - if (arrayField instanceof JBBPFieldArrayLong && mappingField.getType().getComponentType() == double.class) { + if (arrayField instanceof JBBPFieldArrayLong && + mappingField.getType().getComponentType() == double.class) { final long[] longarray = (long[]) arrayField.getValueArrayAsObject(invertBitOrder); final double[] doublearray = new double[longarray.length]; for (int i = 0; i < longarray.length; i++) { doublearray[i] = Double.longBitsToDouble(longarray[i]); } value = doublearray; - } else if (arrayField instanceof JBBPFieldArrayInt && mappingField.getType().getComponentType() == float.class) { + } else if (arrayField instanceof JBBPFieldArrayInt && + mappingField.getType().getComponentType() == float.class) { final int[] intarray = (int[]) arrayField.getValueArrayAsObject(invertBitOrder); final float[] floatarray = new float[intarray.length]; for (int i = 0; i < intarray.length; i++) { floatarray[i] = Float.intBitsToFloat(intarray[i]); } value = floatarray; - } else if (arrayField instanceof JBBPFieldArrayUShort && mappingField.getType().getComponentType() == char.class) { + } else if (arrayField instanceof JBBPFieldArrayUShort && + mappingField.getType().getComponentType() == char.class) { final short[] shortarray = (short[]) arrayField.getValueArrayAsObject(invertBitOrder); final char[] chararray = new char[shortarray.length]; for (int i = 0; i < shortarray.length; i++) { @@ -248,11 +290,14 @@ private static void mapArrayField(final Object mappingClassInstance, final Metho setter.invoke(mappingClassInstance, value); } } catch (IllegalAccessException ex) { - throw new JBBPMapperException("Can't get access to a mapping field", arrayField, mappingClassInstance.getClass(), mappingField, ex); + throw new JBBPMapperException("Can't get access to a mapping field", arrayField, + mappingClassInstance.getClass(), mappingField, ex); } catch (IllegalArgumentException ex) { - throw new JBBPMapperException("Can't set argument to a mapping field", arrayField, mappingClassInstance.getClass(), mappingField, ex); + throw new JBBPMapperException("Can't set argument to a mapping field", arrayField, + mappingClassInstance.getClass(), mappingField, ex); } catch (InvocationTargetException ex) { - throw new JBBPMapperException("Can't set argument to field through setter", arrayField, mappingClassInstance.getClass(), mappingField, ex); + throw new JBBPMapperException("Can't set argument to field through setter", arrayField, + mappingClassInstance.getClass(), mappingField, ex); } } @@ -313,11 +358,14 @@ private static String convertFieldValueToString(final JBBPAbstractArrayField * @param invertBitOrder flag shows that the parsed numeric field value must * be reversed in its bit before setting */ - private static void mapNumericField(final Object mappingClassInstance, final Method setter, final Field mappingField, final JBBPNumericField numericField, final boolean invertBitOrder) { + private static void mapNumericField(final Object mappingClassInstance, final Method setter, + final Field mappingField, final JBBPNumericField numericField, + final boolean invertBitOrder) { final Class fieldClass = mappingField.getType(); try { if (fieldClass == byte.class) { - final byte value = (byte) (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsInt()); + final byte value = (byte) (invertBitOrder ? numericField.getAsInvertedBitOrder() : + numericField.getAsInt()); if (setter == null) { mappingField.setByte(mappingClassInstance, value); } else { @@ -330,28 +378,32 @@ private static void mapNumericField(final Object mappingClassInstance, final Met setter.invoke(mappingClassInstance, numericField.getAsBool()); } } else if (fieldClass == char.class) { - final char value = (char) (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsInt()); + final char value = (char) (invertBitOrder ? numericField.getAsInvertedBitOrder() : + numericField.getAsInt()); if (setter == null) { mappingField.setChar(mappingClassInstance, value); } else { setter.invoke(mappingClassInstance, value); } } else if (fieldClass == short.class) { - final short value = (short) (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsInt()); + final short value = (short) (invertBitOrder ? numericField.getAsInvertedBitOrder() : + numericField.getAsInt()); if (setter == null) { mappingField.setShort(mappingClassInstance, value); } else { setter.invoke(mappingClassInstance, value); } } else if (fieldClass == int.class) { - final int value = (int) (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsInt()); + final int value = + (int) (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsInt()); if (setter == null) { mappingField.setInt(mappingClassInstance, value); } else { setter.invoke(mappingClassInstance, value); } } else if (fieldClass == long.class) { - final long value = (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsLong()); + final long value = + (invertBitOrder ? numericField.getAsInvertedBitOrder() : numericField.getAsLong()); if (setter == null) { mappingField.setLong(mappingClassInstance, value); } else { @@ -360,9 +412,13 @@ private static void mapNumericField(final Object mappingClassInstance, final Met } else if (fieldClass == float.class) { final float value; if (numericField instanceof JBBPFieldInt) { - value = invertBitOrder ? Float.intBitsToFloat((int) numericField.getAsInvertedBitOrder()) : Float.intBitsToFloat(numericField.getAsInt()); + value = + invertBitOrder ? Float.intBitsToFloat((int) numericField.getAsInvertedBitOrder()) : + Float.intBitsToFloat(numericField.getAsInt()); } else { - value = invertBitOrder ? Float.intBitsToFloat((int) numericField.getAsInvertedBitOrder()) : numericField.getAsFloat(); + value = + invertBitOrder ? Float.intBitsToFloat((int) numericField.getAsInvertedBitOrder()) : + numericField.getAsFloat(); } if (setter == null) { mappingField.setFloat(mappingClassInstance, value); @@ -372,9 +428,11 @@ private static void mapNumericField(final Object mappingClassInstance, final Met } else if (fieldClass == double.class) { final double value; if (numericField instanceof JBBPFieldLong) { - value = invertBitOrder ? Double.longBitsToDouble(numericField.getAsInvertedBitOrder()) : Double.longBitsToDouble(numericField.getAsLong()); + value = invertBitOrder ? Double.longBitsToDouble(numericField.getAsInvertedBitOrder()) : + Double.longBitsToDouble(numericField.getAsLong()); } else { - value = invertBitOrder ? Double.longBitsToDouble(numericField.getAsInvertedBitOrder()) : numericField.getAsDouble(); + value = invertBitOrder ? Double.longBitsToDouble(numericField.getAsInvertedBitOrder()) : + numericField.getAsDouble(); } if (setter == null) { mappingField.setDouble(mappingClassInstance, value); @@ -382,14 +440,19 @@ private static void mapNumericField(final Object mappingClassInstance, final Met setter.invoke(mappingClassInstance, value); } } else { - throw new JBBPMapperException("Unsupported mapping class field type to be mapped for binary parsed data", (JBBPAbstractField) numericField, mappingClassInstance.getClass(), mappingField, null); + throw new JBBPMapperException( + "Unsupported mapping class field type to be mapped for binary parsed data", + (JBBPAbstractField) numericField, mappingClassInstance.getClass(), mappingField, null); } } catch (IllegalAccessException ex) { - throw new JBBPMapperException("Can't get access to a mapping field", (JBBPAbstractField) numericField, mappingClassInstance.getClass(), mappingField, ex); + throw new JBBPMapperException("Can't get access to a mapping field", + (JBBPAbstractField) numericField, mappingClassInstance.getClass(), mappingField, ex); } catch (IllegalArgumentException ex) { - throw new JBBPMapperException("Can't set argument to a mapping field", (JBBPAbstractField) numericField, mappingClassInstance.getClass(), mappingField, ex); + throw new JBBPMapperException("Can't set argument to a mapping field", + (JBBPAbstractField) numericField, mappingClassInstance.getClass(), mappingField, ex); } catch (InvocationTargetException ex) { - throw new JBBPMapperException("Can't set argument to a mapping field through setter", (JBBPAbstractField) numericField, mappingClassInstance.getClass(), mappingField, ex); + throw new JBBPMapperException("Can't set argument to a mapping field through setter", + (JBBPAbstractField) numericField, mappingClassInstance.getClass(), mappingField, ex); } } @@ -402,7 +465,8 @@ private static void mapNumericField(final Object mappingClassInstance, final Met * null * @return the field value for the class instance */ - private static Object getFieldValue(final Object classInstance, final Method getter, final Field classField) { + private static Object getFieldValue(final Object classInstance, final Method getter, + final Field classField) { try { if (getter == null) { return classField.get(classInstance); @@ -410,11 +474,14 @@ private static Object getFieldValue(final Object classInstance, final Method get return getter.invoke(classInstance); } } catch (IllegalArgumentException ex) { - throw new JBBPMapperException("Can't set get value from a mapping field", null, classInstance.getClass(), classField, ex); + throw new JBBPMapperException("Can't set get value from a mapping field", null, + classInstance.getClass(), classField, ex); } catch (IllegalAccessException ex) { - throw new JBBPMapperException("Can't get access to a mapping field", null, classInstance.getClass(), classField, ex); + throw new JBBPMapperException("Can't get access to a mapping field", null, + classInstance.getClass(), classField, ex); } catch (InvocationTargetException ex) { - throw new JBBPMapperException("Can't get field value through getter", null, classInstance.getClass(), classField, ex); + throw new JBBPMapperException("Can't get field value through getter", null, + classInstance.getClass(), classField, ex); } } @@ -429,7 +496,8 @@ private static Object getFieldValue(final Object classInstance, final Method get * @param binField a parsed bin field which value will be set, can be null * @param value a value to be set to the class field */ - static void setFieldValue(final Object classInstance, final Method setter, final Field classField, final JBBPAbstractField binField, final Object value) { + static void setFieldValue(final Object classInstance, final Method setter, final Field classField, + final JBBPAbstractField binField, final Object value) { try { if (setter == null) { classField.set(classInstance, value); @@ -437,11 +505,14 @@ static void setFieldValue(final Object classInstance, final Method setter, final setter.invoke(classInstance, value); } } catch (IllegalArgumentException ex) { - throw new JBBPMapperException("Can't set value to a mapping field", binField, classInstance.getClass(), classField, ex); + throw new JBBPMapperException("Can't set value to a mapping field", binField, + classInstance.getClass(), classField, ex); } catch (IllegalAccessException ex) { - throw new JBBPMapperException("Can't get access to a mapping field", binField, classInstance.getClass(), classField, ex); + throw new JBBPMapperException("Can't get access to a mapping field", binField, + classInstance.getClass(), classField, ex); } catch (InvocationTargetException ex) { - throw new JBBPMapperException("Can't set field value through setter", binField, classInstance.getClass(), classField, ex); + throw new JBBPMapperException("Can't set field value through setter", binField, + classInstance.getClass(), classField, ex); } } @@ -464,9 +535,12 @@ private static T tryMakeInstance( if (result == null) { Exception detectedException = null; try { - final Method method = mappingObject.getClass().getMethod(MAKE_CLASS_INSTANCE_METHOD_NAME, Class.class); + final Method method = + mappingObject.getClass().getMethod(MAKE_CLASS_INSTANCE_METHOD_NAME, Class.class); if (!Modifier.isStatic(method.getModifiers())) { - result = type.cast(mappingObject.getClass().getMethod(MAKE_CLASS_INSTANCE_METHOD_NAME, Class.class).invoke(mappingObject, type)); + result = type.cast( + mappingObject.getClass().getMethod(MAKE_CLASS_INSTANCE_METHOD_NAME, Class.class) + .invoke(mappingObject, type)); } } catch (NoSuchMethodException ex) { // do nothing @@ -478,7 +552,9 @@ private static T tryMakeInstance( } if (detectedException != null) { - throw new RuntimeException(String.format("Error during %s(%s) call", MAKE_CLASS_INSTANCE_METHOD_NAME, mappingObject.getClass()), detectedException); + throw new RuntimeException(String + .format("Error during %s(%s) call", MAKE_CLASS_INSTANCE_METHOD_NAME, + mappingObject.getClass()), detectedException); } if (result == null) { @@ -489,26 +565,13 @@ private static T tryMakeInstance( } if (result == null) { - throw new JBBPMapperException(String.format("Can't create instance of %s", type), binField, mappingObject.getClass(), mappingField, null); + throw new JBBPMapperException(String.format("Can't create instance of %s", type), binField, + mappingObject.getClass(), mappingField, null); } } return result; } - - interface FieldProcessor { - @SuppressWarnings("unchecked") - void apply( - MappedFieldRecord record, - JBBPFieldStruct rootStructure, - Object instance, - JBBPMapperCustomFieldProcessor customFieldProcessor, - JBBPAbstractField binField, - int flags, - Function, Object>... instantiators - ); - } - @Override public int compareTo(final MappedFieldRecord o) { final int thisOrder = this.binAnnotation.order(); @@ -522,4 +585,17 @@ public int compareTo(final MappedFieldRecord o) { } return result; } + + interface FieldProcessor { + @SuppressWarnings("unchecked") + void apply( + MappedFieldRecord record, + JBBPFieldStruct rootStructure, + Object instance, + JBBPMapperCustomFieldProcessor customFieldProcessor, + JBBPAbstractField binField, + int flags, + Function, Object>... instantiators + ); + } } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/AbstractFieldByteArray.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/AbstractFieldByteArray.java index e268b3c2..19d81373 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/AbstractFieldByteArray.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/AbstractFieldByteArray.java @@ -25,7 +25,8 @@ * @param type of array item. * @since 1.1.1 */ -abstract class AbstractFieldByteArray extends JBBPAbstractArrayField implements JBBPNumericArray { +abstract class AbstractFieldByteArray extends JBBPAbstractArrayField + implements JBBPNumericArray { private static final long serialVersionUID = -884448637983315505L; protected final byte[] array; diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPAbstractArrayField.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPAbstractArrayField.java index 29cdd2e1..3dd11651 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPAbstractArrayField.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPAbstractArrayField.java @@ -17,7 +17,6 @@ package com.igormaznitsa.jbbp.model; import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; - import java.util.Iterator; import java.util.NoSuchElementException; @@ -27,7 +26,8 @@ * @param type of field which can be contained in the array * @since 1.0 */ -public abstract class JBBPAbstractArrayField extends JBBPAbstractField implements Iterable { +public abstract class JBBPAbstractArrayField extends JBBPAbstractField + implements Iterable { private static final long serialVersionUID = -9007994400543951290L; /** diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPAbstractField.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPAbstractField.java index 199edcfb..a5c381f2 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPAbstractField.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPAbstractField.java @@ -17,7 +17,6 @@ package com.igormaznitsa.jbbp.model; import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; - import java.io.Serializable; /** diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayBit.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayBit.java index 26e7af9f..2111feea 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayBit.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayBit.java @@ -25,7 +25,8 @@ * * @since 1.0 */ -public final class JBBPFieldArrayBit extends JBBPAbstractArrayField implements BitEntity, JBBPNumericArray { +public final class JBBPFieldArrayBit extends JBBPAbstractArrayField + implements BitEntity, JBBPNumericArray { private static final long serialVersionUID = -4589044511663149591L; /** @@ -46,7 +47,8 @@ public final class JBBPFieldArrayBit extends JBBPAbstractArrayField implements JBBPNumericArray { +public final class JBBPFieldArrayBoolean extends JBBPAbstractArrayField + implements JBBPNumericArray { private static final long serialVersionUID = -7896549257985728694L; /** * The Inside value storage. diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayByte.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayByte.java index 48591cf0..cac10922 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayByte.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayByte.java @@ -23,7 +23,8 @@ * * @since 1.0 */ -public final class JBBPFieldArrayByte extends AbstractFieldByteArray implements JBBPNumericArray { +public final class JBBPFieldArrayByte extends AbstractFieldByteArray + implements JBBPNumericArray { private static final long serialVersionUID = -8100947416351943918L; /** diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayDouble.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayDouble.java index bcd5b434..bdb3b9de 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayDouble.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayDouble.java @@ -24,7 +24,8 @@ * * @since 1.4.0 */ -public final class JBBPFieldArrayDouble extends JBBPAbstractArrayField implements JBBPNumericArray { +public final class JBBPFieldArrayDouble extends JBBPAbstractArrayField + implements JBBPNumericArray { private static final long serialVersionUID = -2146959311724853264L; /** * Inside value storage. @@ -89,7 +90,8 @@ public Object getValueArrayAsObject(final boolean reverseBits) { if (reverseBits) { result = this.array.clone(); for (int i = 0; i < result.length; i++) { - result[i] = Double.longBitsToDouble(JBBPFieldLong.reverseBits(Double.doubleToLongBits(result[i]))); + result[i] = + Double.longBitsToDouble(JBBPFieldLong.reverseBits(Double.doubleToLongBits(result[i]))); } } else { result = this.array.clone(); diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayFloat.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayFloat.java index 3da153f9..7d3c0457 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayFloat.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayFloat.java @@ -24,7 +24,8 @@ * * @since 1.4.0 */ -public final class JBBPFieldArrayFloat extends JBBPAbstractArrayField implements JBBPNumericArray { +public final class JBBPFieldArrayFloat extends JBBPAbstractArrayField + implements JBBPNumericArray { private static final long serialVersionUID = 6839868800303265190L; /** * Inside storage. @@ -89,7 +90,8 @@ public Object getValueArrayAsObject(final boolean reverseBits) { if (reverseBits) { result = this.array.clone(); for (int i = 0; i < result.length; i++) { - result[i] = Float.intBitsToFloat((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(result[i]))); + result[i] = + Float.intBitsToFloat((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(result[i]))); } } else { result = this.array.clone(); diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayInt.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayInt.java index 7eb02052..c82dafdc 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayInt.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayInt.java @@ -24,7 +24,8 @@ * * @since 1.0 */ -public final class JBBPFieldArrayInt extends JBBPAbstractArrayField implements JBBPNumericArray { +public final class JBBPFieldArrayInt extends JBBPAbstractArrayField + implements JBBPNumericArray { private static final long serialVersionUID = 6839868800303265190L; /** * Inside storage. diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayLong.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayLong.java index ebcd3eb9..c7df0276 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayLong.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayLong.java @@ -24,7 +24,8 @@ * * @since 1.0 */ -public final class JBBPFieldArrayLong extends JBBPAbstractArrayField implements JBBPNumericArray { +public final class JBBPFieldArrayLong extends JBBPAbstractArrayField + implements JBBPNumericArray { private static final long serialVersionUID = -2146959300724853264L; /** * Inside value storage. diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayShort.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayShort.java index 2f317873..7bcb74e0 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayShort.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayShort.java @@ -24,7 +24,8 @@ * * @since 1.0 */ -public final class JBBPFieldArrayShort extends JBBPAbstractArrayField implements JBBPNumericArray { +public final class JBBPFieldArrayShort extends JBBPAbstractArrayField + implements JBBPNumericArray { private static final long serialVersionUID = 6119269534023759155L; /** * Inside value storage. diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayUShort.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayUShort.java index 826016e6..3e7ce4c1 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayUShort.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayUShort.java @@ -24,7 +24,8 @@ * * @since 1.0 */ -public final class JBBPFieldArrayUShort extends JBBPAbstractArrayField implements JBBPNumericArray { +public final class JBBPFieldArrayUShort extends JBBPAbstractArrayField + implements JBBPNumericArray { private static final long serialVersionUID = -220078798710257343L; /** * Inside value storage. diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldBit.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldBit.java index 326588dc..7b04e17e 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldBit.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldBit.java @@ -44,7 +44,8 @@ public final class JBBPFieldBit extends JBBPAbstractField implements JBBPNumeric * @param value the field value * @param bitNumber number of valuable bits in the value, must not be null */ - public JBBPFieldBit(final JBBPNamedFieldInfo name, final int value, final JBBPBitNumber bitNumber) { + public JBBPFieldBit(final JBBPNamedFieldInfo name, final int value, + final JBBPBitNumber bitNumber) { super(name); JBBPUtils.assertNotNull(bitNumber, "Number of bits must not be null"); this.bitNumber = bitNumber; diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldLong.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldLong.java index 06ebe83a..9adc6574 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldLong.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldLong.java @@ -58,7 +58,8 @@ public static long reverseBits(final long value) { final long b6 = JBBPUtils.reverseBitsInByte((byte) (value >> 48)) & 0xFFL; final long b7 = JBBPUtils.reverseBitsInByte((byte) (value >> 56)) & 0xFFL; - return (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; + return (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | + b7; } @Override diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldString.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldString.java index f13055d2..8154f6d0 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldString.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPFieldString.java @@ -25,15 +25,14 @@ */ public final class JBBPFieldString extends JBBPAbstractField { - private static final long serialVersionUID = -2861961302858335702L; public static final String TYPE_NAME = "stringj"; - + private static final long serialVersionUID = -2861961302858335702L; private final String str; /** * A Constructor. * - * @param name a field name info, it can be null + * @param name a field name info, it can be null * @param nullableValue a value, it can be null */ public JBBPFieldString(final JBBPNamedFieldInfo name, final String nullableValue) { @@ -41,14 +40,6 @@ public JBBPFieldString(final JBBPNamedFieldInfo name, final String nullableValue this.str = nullableValue; } - /** - * Get the saved value. - * @return the value as String, it can be null - */ - public String getAsString() { - return this.str; - } - /** * Get the reversed bit representation of the value. * @@ -60,8 +51,8 @@ public static String reverseBits(final String value) { if (value != null) { final char[] chars = value.toCharArray(); - for(int i=0; i T findFieldForType(final Class fieldType } } if (counter > 1) { - throw new JBBPTooManyFieldsFoundException(counter, "Detected more than one field", null, fieldType); + throw new JBBPTooManyFieldsFoundException(counter, "Detected more than one field", null, + fieldType); } return result; } @@ -164,7 +168,8 @@ public T findLastFieldForType(final Class field } @Override - public T findFieldForNameAndType(final String fieldName, final Class fieldType) { + public T findFieldForNameAndType(final String fieldName, + final Class fieldType) { final String normalizedName = JBBPUtils.normalizeFieldNameOrPath(fieldName); T result = null; @@ -209,7 +214,8 @@ public boolean pathExists(final String fieldPath) { } @Override - public T findFieldForPathAndType(final String fieldPath, final Class fieldType) { + public T findFieldForPathAndType(final String fieldPath, + final Class fieldType) { final JBBPAbstractField field = this.findFieldForPath(fieldPath); T result = null; @@ -232,7 +238,8 @@ public T findFieldForPathAndType(final String fiel * @since 2.0.0 */ @SafeVarargs - public final T mapTo(final String path, final T instance, final Function, Object>... instantiators) { + public final T mapTo(final String path, final T instance, + final Function, Object>... instantiators) { return JBBPMapper.map(this, path, instance, instantiators); } @@ -250,7 +257,8 @@ public final T mapTo(final String path, final T instance, final Function T mapTo(final String path, final T instance, final int flags, final Function, Object>... instantiators) { + public final T mapTo(final String path, final T instance, final int flags, + final Function, Object>... instantiators) { return JBBPMapper.map(this, path, instance, flags, instantiators); } @@ -267,7 +275,9 @@ public final T mapTo(final String path, final T instance, final int flags, f * @since 2.0.0 */ @SafeVarargs - public final T mapTo(final String path, final T instance, final JBBPMapperCustomFieldProcessor customFieldProcessor, final Function, Object>... instantiators) { + public final T mapTo(final String path, final T instance, + final JBBPMapperCustomFieldProcessor customFieldProcessor, + final Function, Object>... instantiators) { return JBBPMapper.map(this, path, instance, customFieldProcessor, instantiators); } @@ -286,7 +296,9 @@ public final T mapTo(final String path, final T instance, final JBBPMapperCu * @since 2.0.0 */ @SafeVarargs - public final T mapTo(final String path, final T instance, final JBBPMapperCustomFieldProcessor customFieldProcessor, final int flags, final Function, Object>... instantiators) { + public final T mapTo(final String path, final T instance, + final JBBPMapperCustomFieldProcessor customFieldProcessor, + final int flags, final Function, Object>... instantiators) { return JBBPMapper.map(this, path, instance, customFieldProcessor, flags, instantiators); } @@ -318,7 +330,8 @@ public final T mapTo(final T objectToMap, final Function, Object>.. * @since 2.0.0 */ @SafeVarargs - public final T mapTo(final T instance, final int flags, final Function, Object>... instantiators) { + public final T mapTo(final T instance, final int flags, + final Function, Object>... instantiators) { return this.mapTo(instance, null, flags, instantiators); } @@ -335,7 +348,9 @@ public final T mapTo(final T instance, final int flags, final Function T mapTo(final T instance, final JBBPMapperCustomFieldProcessor customFieldProcessor, final Function, Object>... instantiators) { + public final T mapTo(final T instance, + final JBBPMapperCustomFieldProcessor customFieldProcessor, + final Function, Object>... instantiators) { return JBBPMapper.map(this, instance, customFieldProcessor, instantiators); } @@ -355,7 +370,9 @@ public final T mapTo(final T instance, final JBBPMapperCustomFieldProcessor * @since 1.1 */ @SafeVarargs - public final T mapTo(final T objectToMap, final JBBPMapperCustomFieldProcessor customFieldProcessor, final int flags, final Function, Object>... instantiators) { + public final T mapTo(final T objectToMap, + final JBBPMapperCustomFieldProcessor customFieldProcessor, + final int flags, final Function, Object>... instantiators) { return JBBPMapper.map(this, objectToMap, customFieldProcessor, flags, instantiators); } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPNumericArray.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPNumericArray.java index e9618310..b4e8ffa1 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPNumericArray.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/model/JBBPNumericArray.java @@ -25,6 +25,7 @@ public interface JBBPNumericArray { /** * Get element as integer. + * * @param index index of element in array * @return the element as integer */ @@ -32,6 +33,7 @@ public interface JBBPNumericArray { /** * Get element as long. + * * @param index index of element in array * @return the element as long */ @@ -39,6 +41,7 @@ public interface JBBPNumericArray { /** * Get element as boolean. + * * @param index index of element in array * @return the element as boolean */ diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/Function.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/Function.java index a4a489c6..c77ca8b1 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/Function.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/Function.java @@ -13,14 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.igormaznitsa.jbbp.utils; /** * Auxiliary functional interface. Added to support Android 3. + * * @param the type of the input to the function * @param the type of the result of the function * @since 2.0.0 */ public interface Function { - R apply(T t); + R apply(T t); } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPCustomFieldTypeProcessorAggregator.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPCustomFieldTypeProcessorAggregator.java index f9c4e0cd..6c051914 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPCustomFieldTypeProcessorAggregator.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPCustomFieldTypeProcessorAggregator.java @@ -16,19 +16,19 @@ package com.igormaznitsa.jbbp.utils; +import static com.igormaznitsa.jbbp.utils.JBBPUtils.ARRAY_STRING_EMPTY; + + import com.igormaznitsa.jbbp.JBBPCustomFieldTypeProcessor; import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import com.igormaznitsa.jbbp.compiler.tokenizer.JBBPFieldTypeParameterContainer; import com.igormaznitsa.jbbp.io.JBBPBitInputStream; import com.igormaznitsa.jbbp.io.JBBPBitOrder; import com.igormaznitsa.jbbp.model.JBBPAbstractField; - import java.io.IOException; import java.util.HashMap; import java.util.Map; -import static com.igormaznitsa.jbbp.utils.JBBPUtils.ARRAY_STRING_EMPTY; - /** * The Aggregator allows to join several custom field type processors. * @@ -63,12 +63,21 @@ public String[] getCustomFieldTypes() { } @Override - public boolean isAllowed(final JBBPFieldTypeParameterContainer fieldType, final String fieldName, final int extraData, final boolean isArray) { - return this.customTypeMap.get(fieldType.getTypeName()).isAllowed(fieldType, fieldName, extraData, isArray); + public boolean isAllowed(final JBBPFieldTypeParameterContainer fieldType, final String fieldName, + final int extraData, final boolean isArray) { + return this.customTypeMap.get(fieldType.getTypeName()) + .isAllowed(fieldType, fieldName, extraData, isArray); } @Override - public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, int parserFlags, JBBPFieldTypeParameterContainer fieldType, JBBPNamedFieldInfo fieldName, int extraData, boolean readWholeStream, int arrayLength) throws IOException { - return this.customTypeMap.get(fieldType.getTypeName()).readCustomFieldType(in, bitOrder, parserFlags, fieldType, fieldName, extraData, readWholeStream, arrayLength); + public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, + int parserFlags, + JBBPFieldTypeParameterContainer fieldType, + JBBPNamedFieldInfo fieldName, int extraData, + boolean readWholeStream, int arrayLength) + throws IOException { + return this.customTypeMap.get(fieldType.getTypeName()) + .readCustomFieldType(in, bitOrder, parserFlags, fieldType, fieldName, extraData, + readWholeStream, arrayLength); } } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPDslBuilder.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPDslBuilder.java index c4add02b..4cd3ce98 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPDslBuilder.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPDslBuilder.java @@ -52,38 +52,6 @@ public static JBBPDslBuilder Begin() { return new JBBPDslBuilder(); } - protected void addItem(final Item item) { - if (item instanceof ItemComment || item.name == null || item.name.length() == 0) { - this.items.add(item); - } else { - int structCounter = 0; - for (int i = this.items.size() - 1; i >= 0; i--) { - final Item itm = this.items.get(i); - - if (itm instanceof ItemComment) { - continue; - } - - if (itm.type == BinType.STRUCT || itm.type == BinType.STRUCT_ARRAY) { - if (structCounter == 0) { - break; - } - structCounter++; - } else if (itm instanceof ItemStructEnd) { - structCounter--; - } - - if (structCounter == 0) { - final String thatName = itm.name; - if (thatName != null && thatName.length() > 0 && item.name.equalsIgnoreCase(thatName)) { - throw new IllegalArgumentException("Duplicated item name '" + item.name + '\''); - } - } - } - this.items.add(item); - } - } - protected static String assertTextNotNullAndTrimmedNotEmpty(final String text) { if (text == null) { throw new NullPointerException("Must not be null"); @@ -107,7 +75,8 @@ protected static String assertNameIfNotNull(final String name) { } if (!Character.isLetterOrDigit(c) && c != '_') { - throw new IllegalArgumentException("Only letters, digits and underscore allowed: " + name); + throw new IllegalArgumentException( + "Only letters, digits and underscore allowed: " + name); } } } @@ -154,7 +123,8 @@ protected static int assertNotNegativeAndZero(final int value) { return value; } - protected static StringBuilder doTabs(final boolean enable, final StringBuilder buffer, int tabs) { + protected static StringBuilder doTabs(final boolean enable, final StringBuilder buffer, + int tabs) { if (enable) { while (tabs > 0) { buffer.append('\t'); @@ -164,6 +134,38 @@ protected static StringBuilder doTabs(final boolean enable, final StringBuilder return buffer; } + protected void addItem(final Item item) { + if (item instanceof ItemComment || item.name == null || item.name.length() == 0) { + this.items.add(item); + } else { + int structCounter = 0; + for (int i = this.items.size() - 1; i >= 0; i--) { + final Item itm = this.items.get(i); + + if (itm instanceof ItemComment) { + continue; + } + + if (itm.type == BinType.STRUCT || itm.type == BinType.STRUCT_ARRAY) { + if (structCounter == 0) { + break; + } + structCounter++; + } else if (itm instanceof ItemStructEnd) { + structCounter--; + } + + if (structCounter == 0) { + final String thatName = itm.name; + if (thatName != null && thatName.length() > 0 && item.name.equalsIgnoreCase(thatName)) { + throw new IllegalArgumentException("Duplicated item name '" + item.name + '\''); + } + } + } + this.items.add(item); + } + } + /** * Get number of items added into internal item list. * @@ -471,7 +473,8 @@ public JBBPDslBuilder VarArray(final String name, final int size, final String p * @param param optional parameter for the field, can be null * @return the builder instance, must not be null */ - public JBBPDslBuilder VarArray(final String name, final String sizeExpression, final String param) { + public JBBPDslBuilder VarArray(final String name, final String sizeExpression, + final String param) { return this.CustomArray("var", name, sizeExpression, param); } @@ -530,7 +533,8 @@ public JBBPDslBuilder CustomArray(final String type, final String name, final in * @param param optional parameter for the field, can be null * @return the builder instance, must not be null */ - public JBBPDslBuilder CustomArray(final String type, final String name, final int size, final String param) { + public JBBPDslBuilder CustomArray(final String type, final String name, final int size, + final String param) { return this.CustomArray(type, name, arraySizeToString(size), param); } @@ -543,7 +547,8 @@ public JBBPDslBuilder CustomArray(final String type, final String name, final in * @param param optional parameter for the field, can be null * @return the builder instance, must not be null */ - public JBBPDslBuilder CustomArray(final String type, final String name, final String sizeExpression, final String param) { + public JBBPDslBuilder CustomArray(final String type, final String name, + final String sizeExpression, final String param) { final ItemCustom item = new ItemCustom(type, name, this.byteOrder); item.array = true; item.bitLenExpression = param == null ? null : assertExpressionChars(param); @@ -719,7 +724,8 @@ public JBBPDslBuilder BitArray(final String bitLenExpression, final String sizeE * @param sizeExpression expression to be used to calculate array size, must not be null * @return the builder instance, must not be null */ - public JBBPDslBuilder BitArray(final String name, final JBBPBitNumber bits, final String sizeExpression) { + public JBBPDslBuilder BitArray(final String name, final JBBPBitNumber bits, + final String sizeExpression) { final Item item = new Item(BinType.BIT_ARRAY, name, this.byteOrder); item.bitNumber = bits; item.sizeExpression = assertExpressionChars(sizeExpression); @@ -735,7 +741,8 @@ public JBBPDslBuilder BitArray(final String name, final JBBPBitNumber bits, fina * @param sizeExpression expression to be used to calculate array size, must not be null * @return the builder instance, must not be null */ - public JBBPDslBuilder BitArray(final String name, final String bitLenExpression, final String sizeExpression) { + public JBBPDslBuilder BitArray(final String name, final String bitLenExpression, + final String sizeExpression) { final Item item = new Item(BinType.BIT_ARRAY, name, this.byteOrder); item.bitLenExpression = assertExpressionChars(bitLenExpression); item.sizeExpression = assertExpressionChars(sizeExpression); @@ -1466,12 +1473,14 @@ public String End(final boolean format) { for (final Item item : this.items) { switch (item.type) { case STRUCT: { - doTabs(format, buffer, structCounter).append(item.name == null ? "" : item.name).append('{'); + doTabs(format, buffer, structCounter).append(item.name == null ? "" : item.name) + .append('{'); structCounter++; } break; case STRUCT_ARRAY: { - doTabs(format, buffer, structCounter).append(item.name == null ? "" : item.name).append('[').append(item.sizeExpression).append(']').append('{'); + doTabs(format, buffer, structCounter).append(item.name == null ? "" : item.name) + .append('[').append(item.sizeExpression).append(']').append('{'); structCounter++; } break; @@ -1493,13 +1502,19 @@ public String End(final boolean format) { } else if (item instanceof ItemCustom) { doTabs(format, buffer, structCounter).append(item.toString()); } else if (item instanceof ItemAlign) { - doTabs(format, buffer, structCounter).append("align").append(item.sizeExpression == null ? "" : ':' + item.makeExpressionForExtraField(item.sizeExpression)).append(';'); + doTabs(format, buffer, structCounter).append("align").append( + item.sizeExpression == null ? "" : + ':' + item.makeExpressionForExtraField(item.sizeExpression)).append(';'); } else if (item instanceof ItemVal) { - doTabs(format, buffer, structCounter).append("val").append(':').append(item.makeExpressionForExtraField(item.sizeExpression)).append(' ').append(item.name).append(';'); + doTabs(format, buffer, structCounter).append("val").append(':') + .append(item.makeExpressionForExtraField(item.sizeExpression)).append(' ') + .append(item.name).append(';'); } else if (item instanceof ItemResetCounter) { doTabs(format, buffer, structCounter).append("reset$$;"); } else if (item instanceof ItemSkip) { - doTabs(format, buffer, structCounter).append("skip").append(item.sizeExpression == null ? "" : ':' + item.makeExpressionForExtraField(item.sizeExpression)).append(';'); + doTabs(format, buffer, structCounter).append("skip").append( + item.sizeExpression == null ? "" : + ':' + item.makeExpressionForExtraField(item.sizeExpression)).append(';'); } else if (item instanceof ItemComment) { final ItemComment comment = (ItemComment) item; final String commentText = comment.getComment().replace("\n", " "); @@ -1570,13 +1585,16 @@ protected BinFieldContainer collectAnnotatedFields(final Class annotatedClass } for (final Field f : annotatedClass.getDeclaredFields()) { - if ((f.getModifiers() & (Modifier.NATIVE | Modifier.STATIC | Modifier.FINAL | Modifier.PRIVATE | Modifier.TRANSIENT)) == 0) { + if ((f.getModifiers() & + (Modifier.NATIVE | Modifier.STATIC | Modifier.FINAL | Modifier.PRIVATE | + Modifier.TRANSIENT)) == 0) { final Bin foundFieldBin = f.getAnnotation(Bin.class); if (foundFieldBin != null || defautBin != null) { validateAnnotatedField(defautBin, foundFieldBin, f); - final Class type = f.getType().isArray() ? f.getType().getComponentType() : f.getType(); + final Class type = + f.getType().isArray() ? f.getType().getComponentType() : f.getType(); if (type.isPrimitive() || type == String.class) { if (foundFieldBin != null) { result.addBinField(foundFieldBin, true, f); @@ -1621,7 +1639,8 @@ private void validateAnnotatedField( && field.getType().isArray() || bin.type().name().endsWith("_ARRAY")) && bin.arraySizeExpr().isEmpty()) { - throw new IllegalArgumentException(field.toString() + ": missing expression in Bin#arraySizeExpression"); + throw new IllegalArgumentException( + field.toString() + ": missing expression in Bin#arraySizeExpression"); } } @@ -1652,7 +1671,8 @@ public JBBPDslBuilder AnnotatedClassFields(final Class annotatedClass) { return addAnnotatedClass(annotatedClass, true); } - protected JBBPDslBuilder addAnnotatedClass(final Class annotatedClass, final boolean onlyFields) { + protected JBBPDslBuilder addAnnotatedClass(final Class annotatedClass, + final boolean onlyFields) { final BinFieldContainer collected = collectAnnotatedFields(annotatedClass); final JBBPByteOrder old = this.byteOrder; @@ -1712,9 +1732,11 @@ class Pair { switch (type) { case BIT_ARRAY: { if (field.bin.paramExpr().isEmpty()) { - this.BitArray(field.getName(), pair.container.getBitNumber(field), field.bin.arraySizeExpr()); + this.BitArray(field.getName(), pair.container.getBitNumber(field), + field.bin.arraySizeExpr()); } else { - this.CustomArray("bit", field.getName(), field.bin.arraySizeExpr(), field.bin.paramExpr()); + this.CustomArray("bit", field.getName(), field.bin.arraySizeExpr(), + field.bin.paramExpr()); } } break; @@ -1810,7 +1832,8 @@ class Pair { if (!field.getCustomType().isEmpty()) { this.ByteOrder(pair.container.getByteOrder(field)); if (field.isArrayField() || !field.bin.arraySizeExpr().isEmpty()) { - this.CustomArray(field.bin.customType(), field.getName(), field.bin.arraySizeExpr(), field.bin.paramExpr()); + this.CustomArray(field.bin.customType(), field.getName(), + field.bin.arraySizeExpr(), field.bin.paramExpr()); } else { this.Custom(field.bin.customType(), field.getName(), field.bin.arraySizeExpr()); } @@ -1854,7 +1877,8 @@ protected static class Item { Item(final BinType type, final String name, final JBBPByteOrder byteOrder) { this.type = type; - this.name = name == null ? null : assertNameIfNotNull(assertTextNotNullAndTrimmedNotEmpty(name)).trim(); + this.name = name == null ? null : + assertNameIfNotNull(assertTextNotNullAndTrimmedNotEmpty(name)).trim(); this.byteOrder = byteOrder; } @@ -1969,7 +1993,8 @@ BinType findType() { return BinType.STRUCT; } if (this.bin.type() == BinType.UNDEFINED) { - return this.bin.customType().isEmpty() ? BinType.findCompatible(this.field.getType()) : this.bin.type(); + return this.bin.customType().isEmpty() ? BinType.findCompatible(this.field.getType()) : + this.bin.type(); } else { return this.bin.type(); } @@ -2039,12 +2064,12 @@ String getCustomType() { } protected static class BinFieldContainer extends BinField { + static final BinFieldContainer END_STRUCT = new BinFieldContainer(null, null); final List fields = new ArrayList<>(); final Class klazz; - static final BinFieldContainer END_STRUCT = new BinFieldContainer(null, null); - - BinFieldContainer(final Class klazz, final Bin bin, final boolean fieldLocalAnnotation, final Field field) { + BinFieldContainer(final Class klazz, final Bin bin, final boolean fieldLocalAnnotation, + final Field field) { super(bin, fieldLocalAnnotation, field); this.klazz = klazz; } @@ -2119,7 +2144,8 @@ protected static class ItemAlign extends Item { protected static class ItemVal extends Item { ItemVal(final String name, final String sizeExpression) { super(BinType.UNDEFINED, assertTextNotNullAndTrimmedNotEmpty(name), JBBPByteOrder.BIG_ENDIAN); - this.sizeExpression = assertExpressionChars(assertTextNotNullAndTrimmedNotEmpty(sizeExpression).trim()); + this.sizeExpression = + assertExpressionChars(assertTextNotNullAndTrimmedNotEmpty(sizeExpression).trim()); } } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPSystemProperty.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPSystemProperty.java index 888305a2..7c88362e 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPSystemProperty.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPSystemProperty.java @@ -90,7 +90,8 @@ public int getAsInteger(final int defaultValue) { try { result = Integer.parseInt(value); } catch (NumberFormatException ex) { - throw new Error("Can't get the system property '" + this.propertyName + "' as integer value, may be wrong format [" + value + ']', ex); + throw new Error("Can't get the system property '" + this.propertyName + + "' as integer value, may be wrong format [" + value + ']', ex); } } return result; diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPTextWriter.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPTextWriter.java index aca3e543..b928bfbf 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPTextWriter.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPTextWriter.java @@ -259,7 +259,9 @@ public class JBBPTextWriter extends FilterWriter { * The Default constructor. A StringWriter will be used inside. */ public JBBPTextWriter() { - this(new StringWriter(1024), JBBPByteOrder.BIG_ENDIAN, System.getProperty("line.separator"), DEFAULT_RADIX, DEFAULT_VALUE_PREFIX, DEFAULT_FIRST_VALUE_LINE_PREFIX, DEFAULT_COMMENT_PREFIX, DEFAULT_HR_PREFIX, DEFAULT_VALUE_DELIMITER); + this(new StringWriter(1024), JBBPByteOrder.BIG_ENDIAN, System.getProperty("line.separator"), + DEFAULT_RADIX, DEFAULT_VALUE_PREFIX, DEFAULT_FIRST_VALUE_LINE_PREFIX, + DEFAULT_COMMENT_PREFIX, DEFAULT_HR_PREFIX, DEFAULT_VALUE_DELIMITER); } /** @@ -268,7 +270,9 @@ public JBBPTextWriter() { * @param out a writer to be wrapped, must not be null. */ public JBBPTextWriter(final Writer out) { - this(out, JBBPByteOrder.BIG_ENDIAN, System.getProperty("line.separator"), DEFAULT_RADIX, DEFAULT_VALUE_PREFIX, DEFAULT_FIRST_VALUE_LINE_PREFIX, DEFAULT_COMMENT_PREFIX, DEFAULT_HR_PREFIX, DEFAULT_VALUE_DELIMITER); + this(out, JBBPByteOrder.BIG_ENDIAN, System.getProperty("line.separator"), DEFAULT_RADIX, + DEFAULT_VALUE_PREFIX, DEFAULT_FIRST_VALUE_LINE_PREFIX, DEFAULT_COMMENT_PREFIX, + DEFAULT_HR_PREFIX, DEFAULT_VALUE_DELIMITER); } /** @@ -278,7 +282,9 @@ public JBBPTextWriter(final Writer out) { * @param byteOrder a byte order to be used, it must not be null. */ public JBBPTextWriter(final Writer out, final JBBPByteOrder byteOrder) { - this(out, byteOrder, System.getProperty("line.separator"), DEFAULT_RADIX, DEFAULT_VALUE_PREFIX, DEFAULT_FIRST_VALUE_LINE_PREFIX, DEFAULT_COMMENT_PREFIX, DEFAULT_HR_PREFIX, DEFAULT_VALUE_DELIMITER); + this(out, byteOrder, System.getProperty("line.separator"), DEFAULT_RADIX, DEFAULT_VALUE_PREFIX, + DEFAULT_FIRST_VALUE_LINE_PREFIX, DEFAULT_COMMENT_PREFIX, DEFAULT_HR_PREFIX, + DEFAULT_VALUE_DELIMITER); } /** @@ -330,7 +336,8 @@ public JBBPTextWriter( */ public static JBBPTextWriter makeStrWriter() { final String lineSeparator = System.setProperty("line.separator", "\n"); - return new JBBPTextWriter(new StringWriter(), JBBPByteOrder.BIG_ENDIAN, lineSeparator, 16, "0x", ".", ";", "~", ","); + return new JBBPTextWriter(new StringWriter(), JBBPByteOrder.BIG_ENDIAN, lineSeparator, 16, "0x", + ".", ";", "~", ","); } protected static String makeFieldComment(final JBBPAbstractField field) { @@ -579,7 +586,9 @@ public JBBPTextWriter Byte(final int value) throws IOException { } if (convertedByExtras == null) { - printValueString(JBBPUtils.ensureMinTextLength(JBBPUtils.ulong2str(value & 0xFF, this.radix, CHAR_BUFFER), this.maxCharsRadixForByte, '0', 0)); + printValueString(JBBPUtils + .ensureMinTextLength(JBBPUtils.ulong2str(value & 0xFF, this.radix, CHAR_BUFFER), + this.maxCharsRadixForByte, '0', 0)); } else { printValueString(convertedByExtras); } @@ -762,7 +771,8 @@ public JBBPTextWriter SetMaxValuesPerLine(final int value) { */ public JBBPTextWriter SetTabSpaces(final int numberOfSpacesPerTab) { if (numberOfSpacesPerTab <= 0) { - throw new IllegalArgumentException("Tab must contains positive number of space chars [" + numberOfSpacesPerTab + ']'); + throw new IllegalArgumentException( + "Tab must contains positive number of space chars [" + numberOfSpacesPerTab + ']'); } final int currentIdentSteps = this.indent / this.spacesInTab; this.spacesInTab = numberOfSpacesPerTab; @@ -796,7 +806,8 @@ public final JBBPTextWriter Radix(final int radix) { this.maxCharsRadixForByte = JBBPUtils.ulong2str(0xFFL, this.radix, CHAR_BUFFER).length(); this.maxCharsRadixForShort = JBBPUtils.ulong2str(0xFFFFL, this.radix, CHAR_BUFFER).length(); this.maxCharsRadixForInt = JBBPUtils.ulong2str(0xFFFFFFFFL, this.radix, CHAR_BUFFER).length(); - this.maxCharsRadixForLong = JBBPUtils.ulong2str(0xFFFFFFFFFFFFFFFFL, this.radix, CHAR_BUFFER).length(); + this.maxCharsRadixForLong = + JBBPUtils.ulong2str(0xFFFFFFFFFFFFFFFFL, this.radix, CHAR_BUFFER).length(); return this; } @@ -825,7 +836,9 @@ public JBBPTextWriter Short(final int value) throws IOException { } else { valueToWrite = value; } - printValueString(JBBPUtils.ensureMinTextLength(JBBPUtils.ulong2str(valueToWrite & 0xFFFFL, this.radix, CHAR_BUFFER), this.maxCharsRadixForShort, '0', 0)); + printValueString(JBBPUtils + .ensureMinTextLength(JBBPUtils.ulong2str(valueToWrite & 0xFFFFL, this.radix, CHAR_BUFFER), + this.maxCharsRadixForShort, '0', 0)); } else { printValueString(convertedByExtras); } @@ -853,11 +866,13 @@ public JBBPTextWriter Float(final float value) throws IOException { if (convertedByExtras == null) { final float valueToWrite; if (this.byteOrder == JBBPByteOrder.LITTLE_ENDIAN) { - valueToWrite = Float.intBitsToFloat((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(value))); + valueToWrite = + Float.intBitsToFloat((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(value))); } else { valueToWrite = value; } - printValueString(JBBPUtils.ensureMinTextLength(JBBPUtils.float2str(valueToWrite, this.radix), this.maxCharsRadixForShort, '0', 0)); + printValueString(JBBPUtils.ensureMinTextLength(JBBPUtils.float2str(valueToWrite, this.radix), + this.maxCharsRadixForShort, '0', 0)); } else { printValueString(convertedByExtras); } @@ -885,11 +900,13 @@ public JBBPTextWriter Double(final double value) throws IOException { if (convertedByExtras == null) { final double valueToWrite; if (this.byteOrder == JBBPByteOrder.LITTLE_ENDIAN) { - valueToWrite = Double.longBitsToDouble(JBBPFieldLong.reverseBits(Double.doubleToLongBits(value))); + valueToWrite = + Double.longBitsToDouble(JBBPFieldLong.reverseBits(Double.doubleToLongBits(value))); } else { valueToWrite = value; } - printValueString(JBBPUtils.ensureMinTextLength(JBBPUtils.double2str(valueToWrite, this.radix), this.maxCharsRadixForShort, '0', 0)); + printValueString(JBBPUtils.ensureMinTextLength(JBBPUtils.double2str(valueToWrite, this.radix), + this.maxCharsRadixForShort, '0', 0)); } else { printValueString(convertedByExtras); } @@ -1020,7 +1037,9 @@ public JBBPTextWriter Int(final int value) throws IOException { } else { valueToWrite = value; } - printValueString(JBBPUtils.ensureMinTextLength(JBBPUtils.ulong2str(valueToWrite & 0xFFFFFFFFL, this.radix, CHAR_BUFFER), this.maxCharsRadixForInt, '0', 0)); + printValueString(JBBPUtils.ensureMinTextLength( + JBBPUtils.ulong2str(valueToWrite & 0xFFFFFFFFL, this.radix, CHAR_BUFFER), + this.maxCharsRadixForInt, '0', 0)); } else { printValueString(convertedByExtras); } @@ -1129,7 +1148,9 @@ public JBBPTextWriter Long(final long value) throws IOException { } else { valueToWrite = value; } - printValueString(JBBPUtils.ensureMinTextLength(JBBPUtils.ulong2str(valueToWrite, this.radix, CHAR_BUFFER), this.maxCharsRadixForLong, '0', 0)); + printValueString(JBBPUtils + .ensureMinTextLength(JBBPUtils.ulong2str(valueToWrite, this.radix, CHAR_BUFFER), + this.maxCharsRadixForLong, '0', 0)); } else { printValueString(convertedByExtras); } @@ -1255,7 +1276,8 @@ public String toString() { if (this.out instanceof StringWriter) { result = this.out.toString(); } else { - result = JBBPTextWriter.class.getName() + '(' + this.out.getClass().getName() + ")@" + System.identityHashCode(this); + result = JBBPTextWriter.class.getName() + '(' + this.out.getClass().getName() + ")@" + + System.identityHashCode(this); } return result; } @@ -1300,7 +1322,8 @@ public JBBPTextWriter Obj(final int objId, final Object... obj) throws IOExcepti * @return the context * @throws IOException it will be thrown for transport errors */ - public JBBPTextWriter Obj(final int objId, final Object[] array, int off, int len) throws IOException { + public JBBPTextWriter Obj(final int objId, final Object[] array, int off, int len) + throws IOException { while (len-- > 0) { this.Obj(objId, array[off++]); } @@ -1340,7 +1363,8 @@ public JBBPTextWriter Bin(final Object... objs) throws IOException { return this; } - protected void printAbstractFieldObject(final String postText, final JBBPAbstractField field) throws IOException { + protected void printAbstractFieldObject(final String postText, final JBBPAbstractField field) + throws IOException { final String postfix = (postText == null ? "" : " " + postText); if (field instanceof JBBPAbstractArrayField || field instanceof JBBPFieldStruct) { @@ -1349,7 +1373,8 @@ protected void printAbstractFieldObject(final String postText, final JBBPAbstrac HR(); IndentInc(); if (field instanceof JBBPAbstractArrayField) { - final JBBPAbstractArrayField array = (JBBPAbstractArrayField) field; + final JBBPAbstractArrayField array = + (JBBPAbstractArrayField) field; if (array.size() > 0) { if (array instanceof JBBPFieldArrayBit) { Byte(((JBBPFieldArrayBit) array).getArray()); @@ -1735,7 +1760,8 @@ public interface Extra { * anything * @throws IOException it will be thrown for transport error */ - String doConvertCustomField(JBBPTextWriter context, final Object obj, final Field field, final Bin annotation) throws IOException; + String doConvertCustomField(JBBPTextWriter context, final Object obj, final Field field, + final Bin annotation) throws IOException; } private final class MappedObjectLogger extends AbstractMappedClassFieldObserver { @@ -1761,7 +1787,8 @@ private String makeFieldDescription(final Field field, final Bin annotation) { return result.toString(); } - private String makeStructDescription(final Object obj, final Field field, final Bin annotation) { + private String makeStructDescription(final Object obj, final Field field, + final Bin annotation) { final StringBuilder result = new StringBuilder(); final Class objClass = obj.getClass(); @@ -1776,12 +1803,16 @@ private String makeStructDescription(final Object obj, final Field field, final typeName = obj.getClass().getSimpleName(); } else { final Class fieldType = field.getType(); - typeName = fieldType.isArray() ? fieldType.getComponentType().getSimpleName() : fieldType.getSimpleName(); + typeName = fieldType.isArray() ? fieldType.getComponentType().getSimpleName() : + fieldType.getSimpleName(); } - final String name = annotation == null || annotation.name().length() == 0 ? typeName : annotation.name(); - final String fieldComment = annotation == null || annotation.comment().length() == 0 ? null : annotation.comment(); - final String objectComment = classAnno == null || classAnno.comment().length() == 0 ? null : classAnno.comment(); + final String name = + annotation == null || annotation.name().length() == 0 ? typeName : annotation.name(); + final String fieldComment = + annotation == null || annotation.comment().length() == 0 ? null : annotation.comment(); + final String objectComment = + classAnno == null || classAnno.comment().length() == 0 ? null : classAnno.comment(); result.append(name); if (fieldComment != null) { @@ -1822,13 +1853,15 @@ protected void onArrayEnd(final Object obj, final Field field, final Bin annotat } @Override - protected void onArrayStart(final Object obj, final Field field, final Bin annotation, final int length) { + 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 + ']'); + Comment("START ARRAY : " + makeArrayDescription(field, annotation) + " OF " + + field.getType().getComponentType().getSimpleName() + " [" + length + ']'); } HR(); IndentInc(); @@ -1867,7 +1900,8 @@ protected void onStructStart(final Object obj, final Field field, final Bin anno } @Override - protected void onFieldLong(final Object obj, final Field field, final Bin annotation, final long value) { + protected void onFieldLong(final Object obj, final Field field, final Bin annotation, + final long value) { try { Long(value); if (this.arrayCounter == 0) { @@ -1879,7 +1913,8 @@ protected void onFieldLong(final Object obj, final Field field, final Bin annota } @Override - protected void onFieldInt(final Object obj, final Field field, final Bin annotation, final int value) { + protected void onFieldInt(final Object obj, final Field field, final Bin annotation, + final int value) { try { Int(value); if (this.arrayCounter == 0) { @@ -1891,7 +1926,8 @@ protected void onFieldInt(final Object obj, final Field field, final Bin annotat } @Override - protected void onFieldFloat(final Object obj, final Field field, final Bin annotation, final float value) { + protected void onFieldFloat(final Object obj, final Field field, final Bin annotation, + final float value) { try { Float(value); if (this.arrayCounter == 0) { @@ -1903,7 +1939,8 @@ protected void onFieldFloat(final Object obj, final Field field, final Bin annot } @Override - protected void onFieldString(final Object obj, final Field field, final Bin annotation, final String value) { + protected void onFieldString(final Object obj, final Field field, final Bin annotation, + final String value) { try { ensureValueMode(); final String prefix = prefixValue; @@ -1919,7 +1956,8 @@ protected void onFieldString(final Object obj, final Field field, final Bin anno } @Override - protected void onFieldDouble(final Object obj, final Field field, final Bin annotation, final double value) { + protected void onFieldDouble(final Object obj, final Field field, final Bin annotation, + final double value) { try { Double(value); if (this.arrayCounter == 0) { @@ -1931,7 +1969,8 @@ protected void onFieldDouble(final Object obj, final Field field, final Bin anno } @Override - protected void onFieldShort(final Object obj, final Field field, final Bin annotation, final boolean signed, final int value) { + protected void onFieldShort(final Object obj, final Field field, final Bin annotation, + final boolean signed, final int value) { try { Short(value); if (this.arrayCounter == 0) { @@ -1943,7 +1982,8 @@ protected void onFieldShort(final Object obj, final Field field, final Bin annot } @Override - protected void onFieldByte(final Object obj, final Field field, final Bin annotation, final boolean signed, final int value) { + protected void onFieldByte(final Object obj, final Field field, final Bin annotation, + final boolean signed, final int value) { try { Byte(value); if (this.arrayCounter == 0) { @@ -1955,7 +1995,8 @@ protected void onFieldByte(final Object obj, final Field field, final Bin annota } @Override - protected void onFieldBool(final Object obj, final Field field, final Bin annotation, final boolean value) { + protected void onFieldBool(final Object obj, final Field field, final Bin annotation, + final boolean value) { try { Byte(value ? 0x01 : 0x00); if (this.arrayCounter == 0) { @@ -1967,7 +2008,8 @@ protected void onFieldBool(final Object obj, final Field field, final Bin annota } @Override - protected void onFieldBits(final Object obj, final Field field, final Bin annotation, final JBBPBitNumber bitNumber, final int value) { + protected void onFieldBits(final Object obj, final Field field, final Bin annotation, + final JBBPBitNumber bitNumber, final int value) { try { Byte(value & bitNumber.getMask()); if (this.arrayCounter == 0) { @@ -1979,7 +2021,8 @@ protected void onFieldBits(final Object obj, final Field field, final Bin annota } @Override - protected void onFieldCustom(final Object obj, final Field field, final Bin annotation, final Object customFieldProcessor, final Object value) { + 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"); diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPTextWriterExtraAdapter.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPTextWriterExtraAdapter.java index 61813d2b..3a9b0b88 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPTextWriterExtraAdapter.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPTextWriterExtraAdapter.java @@ -41,12 +41,14 @@ public void onClose(final JBBPTextWriter context) throws IOException { } @Override - public String doConvertByteToStr(final JBBPTextWriter context, final int value) throws IOException { + public String doConvertByteToStr(final JBBPTextWriter context, final int value) + throws IOException { return null; } @Override - public String doConvertShortToStr(final JBBPTextWriter context, final int value) throws IOException { + public String doConvertShortToStr(final JBBPTextWriter context, final int value) + throws IOException { return null; } @@ -61,22 +63,26 @@ public String doConvertDoubleToStr(JBBPTextWriter context, double value) throws } @Override - public String doConvertIntToStr(final JBBPTextWriter context, final int value) throws IOException { + public String doConvertIntToStr(final JBBPTextWriter context, final int value) + throws IOException { return null; } @Override - public String doConvertLongToStr(final JBBPTextWriter context, final long value) throws IOException { + public String doConvertLongToStr(final JBBPTextWriter context, final long value) + throws IOException { return null; } @Override - public String doConvertObjToStr(final JBBPTextWriter context, final int id, final Object obj) throws IOException { + public String doConvertObjToStr(final JBBPTextWriter context, final int id, final Object obj) + throws IOException { return null; } @Override - public String doConvertCustomField(final JBBPTextWriter context, final Object obj, final Field field, final Bin annotation) throws IOException { + public String doConvertCustomField(final JBBPTextWriter context, final Object obj, + final Field field, final Bin annotation) throws IOException { return null; } diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/ReflectUtils.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/ReflectUtils.java index d1710da7..c7d627af 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/ReflectUtils.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/ReflectUtils.java @@ -71,7 +71,8 @@ public static T newInstance(final Class klazz) { try { return klazz.getConstructor().newInstance(); } catch (Exception ex) { - throw new RuntimeException(String.format("Can't create instance of %s for error %s", klazz, ex.getMessage()), ex); + throw new RuntimeException( + String.format("Can't create instance of %s for error %s", klazz, ex.getMessage()), ex); } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/JBBPCustomFieldTypeProcessorTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/JBBPCustomFieldTypeProcessorTest.java index 6c007e0a..c5a22039 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/JBBPCustomFieldTypeProcessorTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/JBBPCustomFieldTypeProcessorTest.java @@ -16,6 +16,14 @@ package com.igormaznitsa.jbbp; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + + import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import com.igormaznitsa.jbbp.compiler.tokenizer.JBBPFieldTypeParameterContainer; import com.igormaznitsa.jbbp.io.JBBPBitInputStream; @@ -28,12 +36,9 @@ import com.igormaznitsa.jbbp.model.JBBPFieldLong; import com.igormaznitsa.jbbp.model.JBBPFieldShort; import com.igormaznitsa.jbbp.model.JBBPFieldStruct; -import org.junit.jupiter.api.Test; - import java.io.IOException; import java.util.concurrent.atomic.AtomicInteger; - -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class JBBPCustomFieldTypeProcessorTest { @@ -50,7 +55,8 @@ public String[] getCustomFieldTypes() { } @Override - public boolean isAllowed(final JBBPFieldTypeParameterContainer fieldType, final String fieldName, final int extraData, final boolean isArray) { + public boolean isAllowed(final JBBPFieldTypeParameterContainer fieldType, + final String fieldName, final int extraData, final boolean isArray) { callCounter.incrementAndGet(); assertNotNull(fieldType); @@ -83,13 +89,21 @@ public boolean isAllowed(final JBBPFieldTypeParameterContainer fieldType, final } @Override - public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in, final JBBPBitOrder bitOrder, final int parserFlags, final JBBPFieldTypeParameterContainer customFieldTypeInfo, final JBBPNamedFieldInfo fieldName, final int extraData, final boolean readWholeStream, final int arrayLength) throws IOException { + public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in, + final JBBPBitOrder bitOrder, + final int parserFlags, + final JBBPFieldTypeParameterContainer customFieldTypeInfo, + final JBBPNamedFieldInfo fieldName, + final int extraData, + final boolean readWholeStream, + final int arrayLength) throws IOException { final String type = customFieldTypeInfo.getTypeName(); assertEquals(JBBPBitOrder.LSB0, bitOrder); assertEquals(JBBPParser.FLAG_SKIP_REMAINING_FIELDS_IF_EOF, parserFlags); - assertEquals(type.equals("some1") ? JBBPByteOrder.LITTLE_ENDIAN : JBBPByteOrder.BIG_ENDIAN, customFieldTypeInfo.getByteOrder()); + assertEquals(type.equals("some1") ? JBBPByteOrder.LITTLE_ENDIAN : JBBPByteOrder.BIG_ENDIAN, + customFieldTypeInfo.getByteOrder()); switch (type) { case "some1": @@ -103,7 +117,8 @@ public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in, final assertEquals("c", fieldName.getFieldName()); assertFalse(readWholeStream); assertEquals(-1, arrayLength); - return new JBBPFieldShort(fieldName, (short) in.readUnsignedShort(customFieldTypeInfo.getByteOrder())); + return new JBBPFieldShort(fieldName, + (short) in.readUnsignedShort(customFieldTypeInfo.getByteOrder())); case "some3": assertEquals(0, extraData); assertEquals("e", fieldName.getFieldName()); @@ -117,23 +132,29 @@ public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in, final } }; - final JBBPParser parser = JBBPParser.prepare("int a; JBBPParser.prepare("bool Field1; byte field1;")); + assertThrows(JBBPCompilationException.class, + () -> JBBPParser.prepare("bool Field1; byte field1;")); } @Test @@ -182,35 +183,47 @@ public void testCompile_Value_CompilationErrors() { @Test public void testParse_Value_Constant() throws Exception { final JBBPBitInputStream stream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[0])); - assertEquals(34, JBBPParser.prepare("val:34 value;").parse(stream).findFieldForType(JBBPFieldInt.class).getAsInt()); + assertEquals(34, + JBBPParser.prepare("val:34 value;").parse(stream).findFieldForType(JBBPFieldInt.class) + .getAsInt()); assertEquals(0L, stream.getCounter()); } @Test public void testParse_Value_NegativeConstant() throws Exception { final JBBPBitInputStream stream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[0])); - assertEquals(-34, JBBPParser.prepare("val:-34 value;").parse(stream).findFieldForType(JBBPFieldInt.class).getAsInt()); + assertEquals(-34, + JBBPParser.prepare("val:-34 value;").parse(stream).findFieldForType(JBBPFieldInt.class) + .getAsInt()); assertEquals(0L, stream.getCounter()); } @Test public void testParse_Value_Expression() throws Exception { - final JBBPBitInputStream stream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2})); - assertEquals(3, JBBPParser.prepare("ubyte a; ubyte b; val:(a+b) value;").parse(stream).findFieldForType(JBBPFieldInt.class).getAsInt()); + final JBBPBitInputStream stream = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2})); + assertEquals(3, JBBPParser.prepare("ubyte a; ubyte b; val:(a+b) value;").parse(stream) + .findFieldForType(JBBPFieldInt.class).getAsInt()); assertEquals(2L, stream.getCounter()); } @Test public void testParse_Value_UseInExpression_NegativeResult() throws Exception { - final JBBPBitInputStream stream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2})); - assertEquals(-2, JBBPParser.prepare("ubyte a; ubyte b; val:(a-b) value; val:(value*2) secondvalue;").parse(stream).findFieldForNameAndType("secondvalue", JBBPFieldInt.class).getAsInt()); + final JBBPBitInputStream stream = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2})); + assertEquals(-2, + JBBPParser.prepare("ubyte a; ubyte b; val:(a-b) value; val:(value*2) secondvalue;") + .parse(stream).findFieldForNameAndType("secondvalue", JBBPFieldInt.class).getAsInt()); assertEquals(2L, stream.getCounter()); } @Test public void testParse_Value_UseInExpression() throws Exception { - final JBBPBitInputStream stream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2})); - assertEquals(6, JBBPParser.prepare("ubyte a; ubyte b; val:(a+b) value; val:(value*2) secondvalue;").parse(stream).findFieldForNameAndType("secondvalue", JBBPFieldInt.class).getAsInt()); + final JBBPBitInputStream stream = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2})); + assertEquals(6, + JBBPParser.prepare("ubyte a; ubyte b; val:(a+b) value; val:(value*2) secondvalue;") + .parse(stream).findFieldForNameAndType("secondvalue", JBBPFieldInt.class).getAsInt()); assertEquals(2L, stream.getCounter()); } @@ -305,21 +318,24 @@ public void testParse_UShort_ErrorForEOF() throws Exception { public void testParse_SingleDefaultNonamedUShort_Default() throws Exception { final JBBPParser parser = JBBPParser.prepare("ushort;"); final JBBPFieldStruct result = parser.parse(new byte[] {-1, -2}); - assertEquals(((-1 << 8) | (-2 & 0xFF)) & 0xFFFF, result.findFieldForType(JBBPFieldUShort.class).getAsInt()); + assertEquals(((-1 << 8) | (-2 & 0xFF)) & 0xFFFF, + result.findFieldForType(JBBPFieldUShort.class).getAsInt()); } @Test public void testParse_SingleDefaultNonamedUShort_BigEndian() throws Exception { final JBBPParser parser = JBBPParser.prepare(">ushort;"); final JBBPFieldStruct result = parser.parse(new byte[] {-1, -2}); - assertEquals(((-1 << 8) | (-2 & 0xFF)) & 0xFFFF, result.findFieldForType(JBBPFieldUShort.class).getAsInt()); + assertEquals(((-1 << 8) | (-2 & 0xFF)) & 0xFFFF, + result.findFieldForType(JBBPFieldUShort.class).getAsInt()); } @Test public void testParse_SingleDefaultNonamedUShort_LittleEndian() throws Exception { final JBBPParser parser = JBBPParser.prepare("floatj;"); final JBBPFieldStruct result = parser.parse(new byte[] {1, 2, 3, 4}); - assertEquals(2.3879393E-38f, result.findFieldForType(JBBPFieldFloat.class).getAsFloat(), TestUtils.FLOAT_DELTA); + assertEquals(2.3879393E-38f, result.findFieldForType(JBBPFieldFloat.class).getAsFloat(), + TestUtils.FLOAT_DELTA); } @Test public void testParse_SingleDefaultNonamedFloat_LittleEndian() throws Exception { final JBBPParser parser = JBBPParser.prepare("doublej;"); final JBBPFieldStruct result = parser.parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}); - assertEquals(8.20788039913184E-304d, result.findFieldForType(JBBPFieldDouble.class).getAsDouble(), TestUtils.FLOAT_DELTA); + assertEquals(8.20788039913184E-304d, + result.findFieldForType(JBBPFieldDouble.class).getAsDouble(), TestUtils.FLOAT_DELTA); } @Test public void testParse_SingleDefaultNonamedDouble_LittleEndian() throws Exception { final JBBPParser parser = JBBPParser.prepare(" readVarArray(final JBBPBitInputStream inStream, final int arraySize, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - - @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - assertNotNull(inStream); - final int value = inStream.readByte(); - assertEquals(33, value); - assertEquals(0x0908, numericFieldMap.findFieldForType(JBBPFieldShort.class).getAsInt()); - - assertNull(fieldName); - assertEquals(0, extraValue); - assertEquals(JBBPByteOrder.BIG_ENDIAN, byteOrder); - - counter.incrementAndGet(); - - return new JBBPFieldByte(fieldName, (byte) value); - } - }, null); + final JBBPFieldStruct struct = + parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { + + @Override + public JBBPAbstractArrayField readVarArray( + final JBBPBitInputStream inStream, final int arraySize, + final JBBPNamedFieldInfo fieldName, final int extraValue, + final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + + @Override + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + assertNotNull(inStream); + final int value = inStream.readByte(); + assertEquals(33, value); + assertEquals(0x0908, numericFieldMap.findFieldForType(JBBPFieldShort.class).getAsInt()); + + assertNull(fieldName); + assertEquals(0, extraValue); + assertEquals(JBBPByteOrder.BIG_ENDIAN, byteOrder); + + counter.incrementAndGet(); + + return new JBBPFieldByte(fieldName, (byte) value); + } + }, null); assertNotNull(struct); assertEquals(33, struct.findFieldForType(JBBPFieldByte.class).getAsInt()); @@ -473,7 +504,8 @@ public void testGetFlags() throws Exception { @Test public void testParse_Bit_ExtraNumericFieldAsExpression() throws Exception { - final JBBPParser parser = JBBPParser.prepare("ubyte a; bit:(a*4-12) b; bit:(a) c; bit:(a*2) d;"); + final JBBPParser parser = + JBBPParser.prepare("ubyte a; bit:(a*4-12) b; bit:(a) c; bit:(a*2) d;"); final JBBPFieldStruct parsed = parser.parse(new byte[] {4, 0x12, 0x34}); assertEquals(4, parsed.findFieldForNameAndType("a", JBBPFieldUByte.class).getAsInt()); assertEquals(2, parsed.findFieldForNameAndType("b", JBBPFieldBit.class).getAsInt()); @@ -483,11 +515,13 @@ public void testParse_Bit_ExtraNumericFieldAsExpression() throws Exception { @Test public void testParse_BitArray_ExtraNumericFieldAsExpression() throws Exception { - final JBBPParser parser = JBBPParser.prepare("ubyte s; ubyte a; bit:(a*4-12) [s] b; bit:(a*2) d;"); + final JBBPParser parser = + JBBPParser.prepare("ubyte s; ubyte a; bit:(a*4-12) [s] b; bit:(a*2) d;"); final JBBPFieldStruct parsed = parser.parse(new byte[] {2, 4, 0x12, 0x34}); assertEquals(2, parsed.findFieldForNameAndType("s", JBBPFieldUByte.class).getAsInt()); assertEquals(4, parsed.findFieldForNameAndType("a", JBBPFieldUByte.class).getAsInt()); - assertArrayEquals(new byte[] {2, 1}, parsed.findFieldForNameAndType("b", JBBPFieldArrayBit.class).getArray()); + assertArrayEquals(new byte[] {2, 1}, + parsed.findFieldForNameAndType("b", JBBPFieldArrayBit.class).getArray()); assertEquals(0x34, parsed.findFieldForNameAndType("d", JBBPFieldBit.class).getAsInt()); } @@ -510,20 +544,29 @@ public void testParse_Align_ExtraNumericFieldAsExpression() throws Exception { @Test public void testParse_Var_ExtraNumericFieldAsExpression() throws Exception { final JBBPParser parser = JBBPParser.prepare("ubyte a; var:(a/21) vvv; ubyte b;"); - final JBBPFieldStruct parsed = parser.parse(new byte[] {(byte) 123, 0x12, 0x34, 0x11, 0x22, 0x56}, new JBBPVarFieldProcessor() { - - @Override - public JBBPAbstractArrayField readVarArray(JBBPBitInputStream inStream, int arraySize, JBBPNamedFieldInfo fieldName, int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - inStream.skip(3); - assertEquals(123 / 21, extraValue); - return new JBBPFieldInt(fieldName, 666); - } - }, null); + final JBBPFieldStruct parsed = parser + .parse(new byte[] {(byte) 123, 0x12, 0x34, 0x11, 0x22, 0x56}, new JBBPVarFieldProcessor() { + + @Override + public JBBPAbstractArrayField readVarArray( + JBBPBitInputStream inStream, int arraySize, JBBPNamedFieldInfo fieldName, + int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + throw new UnsupportedOperationException( + "Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, final JBBPByteOrder byteOrder, + JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + inStream.skip(3); + assertEquals(123 / 21, extraValue); + return new JBBPFieldInt(fieldName, 666); + } + }, null); assertEquals(123, parsed.findFieldForNameAndType("a", JBBPFieldUByte.class).getAsInt()); assertEquals(666, parsed.findFieldForNameAndType("vvv", JBBPFieldInt.class).getAsInt()); assertEquals(0x22, parsed.findFieldForNameAndType("b", JBBPFieldUByte.class).getAsInt()); @@ -531,24 +574,37 @@ public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final J @Test public void testParse_VarArray_ExtraNumericFieldAsExpression() throws Exception { - final JBBPParser parser = JBBPParser.prepare("ubyte s; ubyte a; var:(a/21) [s*2] vvv; ubyte b;"); - final JBBPFieldStruct parsed = parser.parse(new byte[] {4, (byte) 123, 0x12, 0x34, 0x11, 0x22, 0x56}, new JBBPVarFieldProcessor() { - - @Override - public JBBPAbstractArrayField readVarArray(JBBPBitInputStream inStream, int arraySize, JBBPNamedFieldInfo fieldName, int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - inStream.skip(3); - assertEquals(123 / 21, extraValue); - assertEquals(8, arraySize); - return new JBBPFieldArrayByte(fieldName, new byte[] {1, 2, 3, 4, 5, 6, 7, 8}); - } - - @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - }, null); + final JBBPParser parser = + JBBPParser.prepare("ubyte s; ubyte a; var:(a/21) [s*2] vvv; ubyte b;"); + final JBBPFieldStruct parsed = parser + .parse(new byte[] {4, (byte) 123, 0x12, 0x34, 0x11, 0x22, 0x56}, + new JBBPVarFieldProcessor() { + + @Override + public JBBPAbstractArrayField readVarArray( + JBBPBitInputStream inStream, int arraySize, JBBPNamedFieldInfo fieldName, + int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + inStream.skip(3); + assertEquals(123 / 21, extraValue); + assertEquals(8, arraySize); + return new JBBPFieldArrayByte(fieldName, new byte[] {1, 2, 3, 4, 5, 6, 7, 8}); + } + + @Override + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, + final JBBPByteOrder byteOrder, + JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + throw new UnsupportedOperationException( + "Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + }, null); assertEquals(123, parsed.findFieldForNameAndType("a", JBBPFieldUByte.class).getAsInt()); - assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}, parsed.findFieldForNameAndType("vvv", JBBPFieldArrayByte.class).getArray()); + assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}, + parsed.findFieldForNameAndType("vvv", JBBPFieldArrayByte.class).getArray()); assertEquals(0x22, parsed.findFieldForNameAndType("b", JBBPFieldUByte.class).getAsInt()); } @@ -557,30 +613,39 @@ public void testParse_NamedVarWithCustomOrder() throws Exception { final JBBPParser parser = JBBPParser.prepare("short k; readVarArray(final JBBPBitInputStream inStream, final int arraySize, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - - @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - assertNotNull(inStream); - final int value = inStream.readByte(); - assertEquals(33, value); - assertEquals(0x0908, numericFieldMap.findFieldForType(JBBPFieldShort.class).getAsInt()); - - assertEquals("some", fieldName.getFieldName()); - assertEquals(-12345, extraValue); - assertEquals(JBBPByteOrder.LITTLE_ENDIAN, byteOrder); - - counter.incrementAndGet(); - - return new JBBPFieldByte(fieldName, (byte) value); - } - }, null); + final JBBPFieldStruct struct = + parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { + + @Override + public JBBPAbstractArrayField readVarArray( + final JBBPBitInputStream inStream, final int arraySize, + final JBBPNamedFieldInfo fieldName, final int extraValue, + final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + + @Override + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + assertNotNull(inStream); + final int value = inStream.readByte(); + assertEquals(33, value); + assertEquals(0x0908, numericFieldMap.findFieldForType(JBBPFieldShort.class).getAsInt()); + + assertEquals("some", fieldName.getFieldName()); + assertEquals(-12345, extraValue); + assertEquals(JBBPByteOrder.LITTLE_ENDIAN, byteOrder); + + counter.incrementAndGet(); + + return new JBBPFieldByte(fieldName, (byte) value); + } + }, null); assertEquals(33, struct.findFieldForNameAndType("some", JBBPFieldByte.class).getAsInt()); assertEquals(1, counter.get()); @@ -595,32 +660,45 @@ public void testParse_StringFieldInExpression_NoErrorDuringCompilation() throws @Test public void testParse_StringFieldInArihmeticExpression_ArihmeticException() throws Exception { final JBBPParser parser = JBBPParser.prepare("byte a; stringj b; byte[a+b];"); - assertThrows(ArithmeticException.class, () -> parser.parse(new byte[] {1, 3, 65, 66, 67, 0, 1, 2, 3})); + assertThrows(ArithmeticException.class, + () -> parser.parse(new byte[] {1, 3, 65, 66, 67, 0, 1, 2, 3})); } @Test - public void testParse_StringFieldAsSingleVariableInExpression_ArihmeticException() throws Exception { + public void testParse_StringFieldAsSingleVariableInExpression_ArihmeticException() + throws Exception { final JBBPParser parser = JBBPParser.prepare("stringj b; byte[b];"); - assertThrows(ArithmeticException.class, () -> parser.parse(new byte[] {3, 65, 66, 67, 0, 1, 2, 3})); + assertThrows(ArithmeticException.class, + () -> parser.parse(new byte[] {3, 65, 66, 67, 0, 1, 2, 3})); } @Test public void testParse_SingleNonamedVar_ErrorForNullResult() throws Exception { final JBBPParser parser = JBBPParser.prepare("short k; var; int;"); assertThrows(NullPointerException.class, () -> { - final JBBPFieldStruct struct = parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { - - @Override - public JBBPAbstractArrayField readVarArray(final JBBPBitInputStream inStream, final int arraySize, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - - @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - return null; - } - }, null); + final JBBPFieldStruct struct = + parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { + + @Override + public JBBPAbstractArrayField readVarArray( + final JBBPBitInputStream inStream, final int arraySize, + final JBBPNamedFieldInfo fieldName, final int extraValue, + final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + + @Override + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, + final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + return null; + } + }, null); }); } @@ -629,19 +707,29 @@ public void testParse_SingleNonamedVar_ErrorForArrayResult() throws Exception { final JBBPParser parser = JBBPParser.prepare("short k; var; int;"); assertThrows(JBBPParsingException.class, () -> { - final JBBPFieldStruct struct = parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { - - @Override - public JBBPAbstractArrayField readVarArray(final JBBPBitInputStream inStream, final int arraySize, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - - @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - return new JBBPFieldArrayByte(fieldName, new byte[] {1, 2, 3}); - } - }, null); + final JBBPFieldStruct struct = + parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { + + @Override + public JBBPAbstractArrayField readVarArray( + final JBBPBitInputStream inStream, final int arraySize, + final JBBPNamedFieldInfo fieldName, final int extraValue, + final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + + @Override + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, + final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + return new JBBPFieldArrayByte(fieldName, new byte[] {1, 2, 3}); + } + }, null); }); } @@ -650,20 +738,30 @@ public void testParse_SingleNonamedVar_ErrorForDifferentName() throws Exception final JBBPParser parser = JBBPParser.prepare("short k; var name; int;"); assertThrows(JBBPParsingException.class, () -> { - final JBBPFieldStruct struct = parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { - - @Override - public JBBPAbstractArrayField readVarArray(final JBBPBitInputStream inStream, final int arraySize, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - - @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - assertNotNull(fieldName); - return new JBBPFieldByte(new JBBPNamedFieldInfo("jskdjhsd", "dlkjsf", 0), (byte) 1); - } - }, null); + final JBBPFieldStruct struct = + parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { + + @Override + public JBBPAbstractArrayField readVarArray( + final JBBPBitInputStream inStream, final int arraySize, + final JBBPNamedFieldInfo fieldName, final int extraValue, + final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + + @Override + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, + final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + assertNotNull(fieldName); + return new JBBPFieldByte(new JBBPNamedFieldInfo("jskdjhsd", "dlkjsf", 0), (byte) 1); + } + }, null); }); } @@ -673,34 +771,44 @@ public void testParse_SingleNonamedVarArray() throws Exception { final JBBPIntCounter counter = new JBBPIntCounter(); - final JBBPFieldStruct struct = parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { - - @Override - public JBBPAbstractArrayField readVarArray(final JBBPBitInputStream inStream, final int arraySize, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - assertNotNull(inStream); - final int value = inStream.readByte(); - assertEquals(33, value); - assertEquals(0x0908, numericFieldMap.findFieldForType(JBBPFieldShort.class).getAsInt()); - - assertNull(fieldName); - assertEquals(0, extraValue); - assertEquals(18, arraySize); - assertEquals(JBBPByteOrder.BIG_ENDIAN, byteOrder); - - counter.incrementAndGet(); - - return new JBBPFieldArrayByte(fieldName, new byte[] {(byte) value}); - } - - @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - }, null); + final JBBPFieldStruct struct = + parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { + + @Override + public JBBPAbstractArrayField readVarArray( + final JBBPBitInputStream inStream, final int arraySize, + final JBBPNamedFieldInfo fieldName, final int extraValue, + final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + assertNotNull(inStream); + final int value = inStream.readByte(); + assertEquals(33, value); + assertEquals(0x0908, numericFieldMap.findFieldForType(JBBPFieldShort.class).getAsInt()); + + assertNull(fieldName); + assertEquals(0, extraValue); + assertEquals(18, arraySize); + assertEquals(JBBPByteOrder.BIG_ENDIAN, byteOrder); + + counter.incrementAndGet(); + + return new JBBPFieldArrayByte(fieldName, new byte[] {(byte) value}); + } + + @Override + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + }, null); assertNotNull(struct); - assertArrayEquals(new byte[] {33}, struct.findFieldForType(JBBPFieldArrayByte.class).getArray()); + assertArrayEquals(new byte[] {33}, + struct.findFieldForType(JBBPFieldArrayByte.class).getArray()); assertEquals(1, counter.get()); } @@ -710,34 +818,44 @@ public void testParse_NamedVarArrayWithCustomOrder() throws Exception { final JBBPIntCounter counter = new JBBPIntCounter(); - final JBBPFieldStruct struct = parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { - - @Override - public JBBPAbstractArrayField readVarArray(final JBBPBitInputStream inStream, final int arraySize, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - assertNotNull(inStream); - final int value = inStream.readByte(); - assertEquals(33, value); - assertEquals(0x0908, numericFieldMap.findFieldForType(JBBPFieldShort.class).getAsInt()); - - assertEquals("some", fieldName.getFieldName()); - assertEquals(-12345, extraValue); - assertEquals(2334, arraySize); - assertEquals(JBBPByteOrder.LITTLE_ENDIAN, byteOrder); - - counter.incrementAndGet(); - - return new JBBPFieldArrayByte(fieldName, new byte[] {(byte) value}); - } - - @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - }, null); + final JBBPFieldStruct struct = + parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { + + @Override + public JBBPAbstractArrayField readVarArray( + final JBBPBitInputStream inStream, final int arraySize, + final JBBPNamedFieldInfo fieldName, final int extraValue, + final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + assertNotNull(inStream); + final int value = inStream.readByte(); + assertEquals(33, value); + assertEquals(0x0908, numericFieldMap.findFieldForType(JBBPFieldShort.class).getAsInt()); + + assertEquals("some", fieldName.getFieldName()); + assertEquals(-12345, extraValue); + assertEquals(2334, arraySize); + assertEquals(JBBPByteOrder.LITTLE_ENDIAN, byteOrder); + + counter.incrementAndGet(); + + return new JBBPFieldArrayByte(fieldName, new byte[] {(byte) value}); + } + + @Override + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + }, null); assertNotNull(struct); - assertArrayEquals(new byte[] {33}, struct.findFieldForNameAndType("some", JBBPFieldArrayByte.class).getArray()); + assertArrayEquals(new byte[] {33}, + struct.findFieldForNameAndType("some", JBBPFieldArrayByte.class).getArray()); assertEquals(1, counter.get()); } @@ -747,33 +865,43 @@ public void testParse_NamedVarArrayTillEndOfStream() throws Exception { final JBBPIntCounter counter = new JBBPIntCounter(); - final JBBPFieldStruct struct = parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { + final JBBPFieldStruct struct = + parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { - @Override - public JBBPAbstractArrayField readVarArray(final JBBPBitInputStream inStream, final int arraySize, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - assertNotNull(inStream); + @Override + public JBBPAbstractArrayField readVarArray( + final JBBPBitInputStream inStream, final int arraySize, + final JBBPNamedFieldInfo fieldName, final int extraValue, + final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + assertNotNull(inStream); - assertEquals(0x0908, numericFieldMap.findFieldForType(JBBPFieldShort.class).getAsInt()); + assertEquals(0x0908, numericFieldMap.findFieldForType(JBBPFieldShort.class).getAsInt()); - assertEquals("some", fieldName.getFieldName()); - assertEquals(0, extraValue); - assertTrue(arraySize < 0); - assertEquals(JBBPByteOrder.BIG_ENDIAN, byteOrder); + assertEquals("some", fieldName.getFieldName()); + assertEquals(0, extraValue); + assertTrue(arraySize < 0); + assertEquals(JBBPByteOrder.BIG_ENDIAN, byteOrder); - counter.incrementAndGet(); + counter.incrementAndGet(); - return new JBBPFieldArrayByte(fieldName, inStream.readByteArray(-1)); - } + return new JBBPFieldArrayByte(fieldName, inStream.readByteArray(-1)); + } - @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - }, null); + @Override + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + }, null); assertNotNull(struct); - assertArrayEquals(new byte[] {33, 1, 2, 3, 4}, struct.findFieldForNameAndType("some", JBBPFieldArrayByte.class).getArray()); + assertArrayEquals(new byte[] {33, 1, 2, 3, 4}, + struct.findFieldForNameAndType("some", JBBPFieldArrayByte.class).getArray()); assertEquals(1, counter.get()); } @@ -784,13 +912,20 @@ public void testParse_NamedVarArrayForZeroLength() throws Exception { final JBBPFieldStruct struct = parser.parse(new byte[] {0, 0}, new JBBPVarFieldProcessor() { @Override - public JBBPAbstractArrayField readVarArray(final JBBPBitInputStream inStream, final int arraySize, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { + public JBBPAbstractArrayField readVarArray( + final JBBPBitInputStream inStream, final int arraySize, + final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { assertEquals(0, arraySize); return new JBBPFieldArrayByte(fieldName, new byte[0]); } @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { fail("Must not be called"); return null; } @@ -805,20 +940,30 @@ public void testParse_SingleNonamedVarArray_ErrorForNullResult() throws Exceptio final JBBPParser parser = JBBPParser.prepare("short k; var [k]; int;"); assertThrows(NullPointerException.class, () -> { - final JBBPFieldStruct struct = parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { - - @Override - public JBBPAbstractArrayField readVarArray(final JBBPBitInputStream inStream, final int arraySize, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - assertEquals(0x0908, arraySize); - return null; - } - - @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - }, null); + final JBBPFieldStruct struct = + parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { + + @Override + public JBBPAbstractArrayField readVarArray( + final JBBPBitInputStream inStream, final int arraySize, + final JBBPNamedFieldInfo fieldName, final int extraValue, + final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + assertEquals(0x0908, arraySize); + return null; + } + + @Override + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, + final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + }, null); }); } @@ -827,20 +972,31 @@ public void testParse_SingleNonamedVarArray_ErrorForDifferentName() throws Excep final JBBPParser parser = JBBPParser.prepare("short k; var [234] name; int;"); assertThrows(JBBPParsingException.class, () -> { - final JBBPFieldStruct struct = parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { - - @Override - public JBBPAbstractArrayField readVarArray(final JBBPBitInputStream inStream, final int arraySize, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - assertNotNull(fieldName); - return new JBBPFieldArrayByte(new JBBPNamedFieldInfo("jskdjhsd", "dlkjsf", 0), new byte[] {1}); - } - - @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - }, null); + final JBBPFieldStruct struct = + parser.parse(new byte[] {9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { + + @Override + public JBBPAbstractArrayField readVarArray( + final JBBPBitInputStream inStream, final int arraySize, + final JBBPNamedFieldInfo fieldName, final int extraValue, + final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + assertNotNull(fieldName); + return new JBBPFieldArrayByte(new JBBPNamedFieldInfo("jskdjhsd", "dlkjsf", 0), + new byte[] {1}); + } + + @Override + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, + final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + }, null); }); } @@ -851,14 +1007,22 @@ public void testParse_BitFields_EOF() throws Exception { @Test public void testParse_BitFields_SizeProvidedThroughExpression() throws Exception { - assertEquals(4, JBBPParser.prepare("ubyte a; ubyte b; bit:(a+b) c;").parse(new byte[] {1, 2, (byte) 0xB4}).findFieldForType(JBBPFieldBit.class).getAsInt()); - assertEquals(20, JBBPParser.prepare("ubyte a; ubyte b; bit:(a+b) c;").parse(new byte[] {3, 2, (byte) 0xB4}).findFieldForType(JBBPFieldBit.class).getAsInt()); + assertEquals(4, + JBBPParser.prepare("ubyte a; ubyte b; bit:(a+b) c;").parse(new byte[] {1, 2, (byte) 0xB4}) + .findFieldForType(JBBPFieldBit.class).getAsInt()); + assertEquals(20, + JBBPParser.prepare("ubyte a; ubyte b; bit:(a+b) c;").parse(new byte[] {3, 2, (byte) 0xB4}) + .findFieldForType(JBBPFieldBit.class).getAsInt()); } @Test public void testParse_BitFields_ErrorForWrongValueOfBitFieldLength() throws Exception { - assertThrows(IllegalArgumentException.class, () -> JBBPParser.prepare("ubyte a; ubyte b; bit:(a+b) c;").parse(new byte[] {11, 2, (byte) 0xB4})); - assertThrows(IllegalArgumentException.class, () -> JBBPParser.prepare("ubyte a; ubyte b; bit:(a-b) c;").parse(new byte[] {2, 2, (byte) 0xB4})); + assertThrows(IllegalArgumentException.class, + () -> JBBPParser.prepare("ubyte a; ubyte b; bit:(a+b) c;") + .parse(new byte[] {11, 2, (byte) 0xB4})); + assertThrows(IllegalArgumentException.class, + () -> JBBPParser.prepare("ubyte a; ubyte b; bit:(a-b) c;") + .parse(new byte[] {2, 2, (byte) 0xB4})); } @Test @@ -868,13 +1032,17 @@ public void testParse_BitFieldArray_EOF() throws Exception { @Test public void testParse_BitFieldArrayWholeStream_Empty() throws Exception { - assertEquals(0, JBBPParser.prepare("bit:4 [_];").parse(new byte[0]).findFieldForType(JBBPFieldArrayBit.class).size()); + assertEquals(0, JBBPParser.prepare("bit:4 [_];").parse(new byte[0]) + .findFieldForType(JBBPFieldArrayBit.class).size()); } @Test public void testParse_SeveralPrimitiveFields() throws Exception { - final JBBPParser parser = JBBPParser.prepare("bit:4; bit:4; bool; byte; ubyte; short; ushort; int; long;"); - final JBBPFieldStruct result = parser.parse(new byte[] {0x12, 1, 87, (byte) 0xF3, 1, 2, (byte) 0xFE, 4, 6, 7, 8, 9, (byte) 0xFF, 1, 2, 3, 5, 6, 7, 8, 9}); + final JBBPParser parser = + JBBPParser.prepare("bit:4; bit:4; bool; byte; ubyte; short; ushort; int; long;"); + final JBBPFieldStruct result = parser.parse( + new byte[] {0x12, 1, 87, (byte) 0xF3, 1, 2, (byte) 0xFE, 4, 6, 7, 8, 9, (byte) 0xFF, 1, 2, + 3, 5, 6, 7, 8, 9}); assertEquals(2, result.findFirstFieldForType(JBBPFieldBit.class).getAsInt()); assertEquals(1, result.findLastFieldForType(JBBPFieldBit.class).getAsInt()); @@ -902,13 +1070,17 @@ public void testParse_Align_Default_EmptyStream_NoErrors() throws Exception { @Test public void testParse_Align_ErrorForEOF() throws Exception { - assertThrows(EOFException.class, () -> JBBPParser.prepare("byte; align:34;").parse(new byte[] {1})); + assertThrows(EOFException.class, + () -> JBBPParser.prepare("byte; align:34;").parse(new byte[] {1})); } @Test public void testParse_Align_Default() throws Exception { - final JBBPParser parser = JBBPParser.prepare("bit:4; align; bool; byte; ubyte; short; ushort; int; long;"); - final JBBPFieldStruct result = parser.parse(new byte[] {0x12, 1, 87, (byte) 0xF3, 1, 2, (byte) 0xFE, 4, 6, 7, 8, 9, (byte) 0xFF, 1, 2, 3, 5, 6, 7, 8, 9}); + final JBBPParser parser = + JBBPParser.prepare("bit:4; align; bool; byte; ubyte; short; ushort; int; long;"); + final JBBPFieldStruct result = parser.parse( + new byte[] {0x12, 1, 87, (byte) 0xF3, 1, 2, (byte) 0xFE, 4, 6, 7, 8, 9, (byte) 0xFF, 1, 2, + 3, 5, 6, 7, 8, 9}); assertEquals(2, result.findFieldForType(JBBPFieldBit.class).getAsInt()); assertTrue(result.findFieldForType(JBBPFieldBoolean.class).getAsBool()); assertEquals(87, result.findFieldForType(JBBPFieldByte.class).getAsInt()); @@ -941,7 +1113,8 @@ public void testParse_Skip_Default_ErrorForEOF() throws Exception { @Test public void testParse_Skip_ErrorForEOF() throws Exception { - assertThrows(EOFException.class, () -> JBBPParser.prepare("byte; skip:34;").parse(new byte[] {1})); + assertThrows(EOFException.class, + () -> JBBPParser.prepare("byte; skip:34;").parse(new byte[] {1})); } @Test @@ -998,56 +1171,78 @@ public void testParse_Align_Int_WithoutEffect() throws Exception { @Test public void testParse_FixedBitArray_EOFException() throws Exception { - assertThrows(EOFException.class, () -> JBBPParser.prepare("byte; bit:4[1];").parse(new byte[] {1})); + assertThrows(EOFException.class, + () -> JBBPParser.prepare("byte; bit:4[1];").parse(new byte[] {1})); } @Test public void testParse_NonFixedBitArray_ParsedAsEmptyArray() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte; bit:4[_] array;").parse(new byte[] {1}); + final JBBPFieldStruct parsed = + JBBPParser.prepare("byte; bit:4[_] array;").parse(new byte[] {1}); assertEquals(0, parsed.findFieldForNameAndType("array", JBBPFieldArrayBit.class).size()); } @Test public void testParse_ProcessingOfExtraFieldValuesInSkippedStructureFields() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; struct1 [len] { int a; var:23231223 [1024] helloarray; int b; bit:3; bit:7 [10233]; var:-1332 hello; skip:34221223; bit:7; bit:1; align:3445; bit:2; int skippedInt; long lng; insidestruct {bit:1; bit:2; bit:3;} } int end; ").parse(new byte[] {0, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { - - @Override - public JBBPAbstractArrayField readVarArray(JBBPBitInputStream inStream, int arraySize, JBBPNamedFieldInfo fieldName, int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - - @Override - public JBBPAbstractField readVarField(JBBPBitInputStream inStream, JBBPNamedFieldInfo fieldName, int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - }, null); + final JBBPFieldStruct parsed = JBBPParser.prepare( + "byte len; struct1 [len] { int a; var:23231223 [1024] helloarray; int b; bit:3; bit:7 [10233]; var:-1332 hello; skip:34221223; bit:7; bit:1; align:3445; bit:2; int skippedInt; long lng; insidestruct {bit:1; bit:2; bit:3;} } int end; ") + .parse(new byte[] {0, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { + + @Override + public JBBPAbstractArrayField readVarArray( + JBBPBitInputStream inStream, int arraySize, JBBPNamedFieldInfo fieldName, + int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + + @Override + public JBBPAbstractField readVarField(JBBPBitInputStream inStream, + JBBPNamedFieldInfo fieldName, int extraValue, + JBBPByteOrder byteOrder, + JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + }, null); assertEquals(0x01020304, parsed.findFieldForNameAndType("end", JBBPFieldInt.class).getAsInt()); } @Test public void testParse_ProcessingOfExtraFieldValuesInSkippedStructureFields1() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; struct1 [len] {var:-1332 hello; align:3445; } int end; ").parse(new byte[] {0, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { - - @Override - public JBBPAbstractArrayField readVarArray(JBBPBitInputStream inStream, int arraySize, JBBPNamedFieldInfo fieldName, int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - - @Override - public JBBPAbstractField readVarField(JBBPBitInputStream inStream, JBBPNamedFieldInfo fieldName, int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) throws IOException { - fail("Must not be called"); - return null; - } - }, null); + final JBBPFieldStruct parsed = + JBBPParser.prepare("byte len; struct1 [len] {var:-1332 hello; align:3445; } int end; ") + .parse(new byte[] {0, 1, 2, 3, 4}, new JBBPVarFieldProcessor() { + + @Override + public JBBPAbstractArrayField readVarArray( + JBBPBitInputStream inStream, int arraySize, JBBPNamedFieldInfo fieldName, + int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + + @Override + public JBBPAbstractField readVarField(JBBPBitInputStream inStream, + JBBPNamedFieldInfo fieldName, int extraValue, + JBBPByteOrder byteOrder, + JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { + fail("Must not be called"); + return null; + } + }, null); assertEquals(0x01020304, parsed.findFieldForNameAndType("end", JBBPFieldInt.class).getAsInt()); } @Test public void testParse_FixedBitArray() throws Exception { - final JBBPFieldArrayBit bits = JBBPParser.prepare("bit:4 [8];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}).findFieldForType(JBBPFieldArrayBit.class); + final JBBPFieldArrayBit bits = + JBBPParser.prepare("bit:4 [8];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}) + .findFieldForType(JBBPFieldArrayBit.class); assertEquals(8, bits.size()); assertEquals(1, bits.getAsInt(0)); assertEquals(2, bits.getAsInt(1)); @@ -1061,7 +1256,9 @@ public void testParse_FixedBitArray() throws Exception { @Test public void testParse_NonFixedBitArray() throws Exception { - final JBBPFieldArrayBit bits = JBBPParser.prepare("bit:4 [_];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}).findFieldForType(JBBPFieldArrayBit.class); + final JBBPFieldArrayBit bits = + JBBPParser.prepare("bit:4 [_];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}) + .findFieldForType(JBBPFieldArrayBit.class); assertEquals(8, bits.size()); assertEquals(1, bits.getAsInt(0)); assertEquals(2, bits.getAsInt(1)); @@ -1075,7 +1272,8 @@ public void testParse_NonFixedBitArray() throws Exception { @Test public void testParse_FixedByteArray_EOFException() throws Exception { - assertThrows(EOFException.class, () -> JBBPParser.prepare("byte; byte[1];").parse(new byte[] {1})); + assertThrows(EOFException.class, + () -> JBBPParser.prepare("byte; byte[1];").parse(new byte[] {1})); } @Test @@ -1086,7 +1284,9 @@ public void testParse_NonFixedByteArray_ParsedAsEmptyArray() throws Exception { @Test public void testParse_FixedByteArray_Default() throws Exception { - final JBBPFieldArrayByte bytes = JBBPParser.prepare("byte[4];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}).findFieldForType(JBBPFieldArrayByte.class); + final JBBPFieldArrayByte bytes = + JBBPParser.prepare("byte[4];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}) + .findFieldForType(JBBPFieldArrayByte.class); assertEquals(4, bytes.size()); assertEquals(0x21, bytes.getAsInt(0) & 0xFF); assertEquals(0x43, bytes.getAsInt(1) & 0xFF); @@ -1096,7 +1296,9 @@ public void testParse_FixedByteArray_Default() throws Exception { @Test public void testParse_FixedByteArray_BigEndian() throws Exception { - final JBBPFieldArrayByte bytes = JBBPParser.prepare(">byte[4];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}).findFieldForType(JBBPFieldArrayByte.class); + final JBBPFieldArrayByte bytes = + JBBPParser.prepare(">byte[4];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}) + .findFieldForType(JBBPFieldArrayByte.class); assertEquals(4, bytes.size()); assertEquals(0x21, bytes.getAsInt(0) & 0xFF); assertEquals(0x43, bytes.getAsInt(1) & 0xFF); @@ -1106,7 +1308,9 @@ public void testParse_FixedByteArray_BigEndian() throws Exception { @Test public void testParse_FixedByteArray_LittleEndian() throws Exception { - final JBBPFieldArrayByte bytes = JBBPParser.prepare("byte[_];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}).findFieldForType(JBBPFieldArrayByte.class); + final JBBPFieldArrayByte bytes = + JBBPParser.prepare(">byte[_];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}) + .findFieldForType(JBBPFieldArrayByte.class); assertEquals(4, bytes.size()); assertEquals(0x21, bytes.getAsInt(0) & 0xFF); assertEquals(0x43, bytes.getAsInt(1) & 0xFF); @@ -1136,7 +1344,9 @@ public void testParse_NonFixedByteArray_BigEndian() throws Exception { @Test public void testParse_NonFixedByteArray_LittleEndian() throws Exception { - final JBBPFieldArrayByte bytes = JBBPParser.prepare(" JBBPParser.prepare("byte; ubyte[1];").parse(new byte[] {1})); + assertThrows(EOFException.class, + () -> JBBPParser.prepare("byte; ubyte[1];").parse(new byte[] {1})); } @Test public void testParse_NonFixedUByteArray_ParsedAsEmptyArray() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte; ubyte[_] array;").parse(new byte[] {1}); + final JBBPFieldStruct parsed = + JBBPParser.prepare("byte; ubyte[_] array;").parse(new byte[] {1}); assertEquals(0, parsed.findFieldForNameAndType("array", JBBPFieldArrayUByte.class).size()); } @Test public void testParse_FixedUByteArray_Default() throws Exception { - final JBBPFieldArrayUByte bytes = JBBPParser.prepare("ubyte[4];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}).findFieldForType(JBBPFieldArrayUByte.class); + final JBBPFieldArrayUByte bytes = + JBBPParser.prepare("ubyte[4];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}) + .findFieldForType(JBBPFieldArrayUByte.class); assertEquals(4, bytes.size()); assertEquals(0x21, bytes.getAsInt(0)); assertEquals(0x43, bytes.getAsInt(1)); @@ -1167,7 +1381,9 @@ public void testParse_FixedUByteArray_Default() throws Exception { @Test public void testParse_FixedUByteArray_BigEndian() throws Exception { - final JBBPFieldArrayUByte bytes = JBBPParser.prepare(">ubyte[4];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}).findFieldForType(JBBPFieldArrayUByte.class); + final JBBPFieldArrayUByte bytes = + JBBPParser.prepare(">ubyte[4];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}) + .findFieldForType(JBBPFieldArrayUByte.class); assertEquals(4, bytes.size()); assertEquals(0x21, bytes.getAsInt(0)); assertEquals(0x43, bytes.getAsInt(1)); @@ -1177,7 +1393,9 @@ public void testParse_FixedUByteArray_BigEndian() throws Exception { @Test public void testParse_FixedUByteArray_LittleEndian() throws Exception { - final JBBPFieldArrayUByte bytes = JBBPParser.prepare("ubyte[_];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}).findFieldForType(JBBPFieldArrayUByte.class); + final JBBPFieldArrayUByte bytes = + JBBPParser.prepare(">ubyte[_];").parse(new byte[] {0x21, 0x43, 0x65, (byte) 0x87}) + .findFieldForType(JBBPFieldArrayUByte.class); assertEquals(4, bytes.size()); assertEquals(0x21, bytes.getAsInt(0)); assertEquals(0x43, bytes.getAsInt(1)); @@ -1207,7 +1429,9 @@ public void testParse_NonFixedUByteArray_BigEndian() throws Exception { @Test public void testParse_NonFixedUByteArray_LittleEndian() throws Exception { - final JBBPFieldArrayUByte bytes = JBBPParser.prepare(" JBBPParser.prepare("byte; bool[1];").parse(new byte[] {1})); + assertThrows(EOFException.class, + () -> JBBPParser.prepare("byte; bool[1];").parse(new byte[] {1})); } @Test @@ -1228,7 +1453,9 @@ public void testParse_NonFixedBoolArray_ParsedAsEmptyArray() throws Exception { @Test public void testParse_FixedBooleanArray_Default() throws Exception { - final JBBPFieldArrayBoolean bools = JBBPParser.prepare("bool[4];").parse(new byte[] {0, 0x43, 0x65, 0}).findFieldForType(JBBPFieldArrayBoolean.class); + final JBBPFieldArrayBoolean bools = + JBBPParser.prepare("bool[4];").parse(new byte[] {0, 0x43, 0x65, 0}) + .findFieldForType(JBBPFieldArrayBoolean.class); assertEquals(4, bools.size()); assertFalse(bools.getAsBool(0)); assertTrue(bools.getAsBool(1)); @@ -1238,7 +1465,9 @@ public void testParse_FixedBooleanArray_Default() throws Exception { @Test public void testParse_FixedBooleanArray_BigEndian() throws Exception { - final JBBPFieldArrayBoolean bools = JBBPParser.prepare(">bool[4];").parse(new byte[] {0, 0x43, 0x65, 0}).findFieldForType(JBBPFieldArrayBoolean.class); + final JBBPFieldArrayBoolean bools = + JBBPParser.prepare(">bool[4];").parse(new byte[] {0, 0x43, 0x65, 0}) + .findFieldForType(JBBPFieldArrayBoolean.class); assertEquals(4, bools.size()); assertFalse(bools.getAsBool(0)); assertTrue(bools.getAsBool(1)); @@ -1248,7 +1477,9 @@ public void testParse_FixedBooleanArray_BigEndian() throws Exception { @Test public void testParse_FixedBooleanArray_LittleEndian() throws Exception { - final JBBPFieldArrayBoolean bools = JBBPParser.prepare("bool[_];").parse(new byte[] {0, 0x43, 0x65, 0}).findFieldForType(JBBPFieldArrayBoolean.class); + final JBBPFieldArrayBoolean bools = + JBBPParser.prepare(">bool[_];").parse(new byte[] {0, 0x43, 0x65, 0}) + .findFieldForType(JBBPFieldArrayBoolean.class); assertEquals(4, bools.size()); assertFalse(bools.getAsBool(0)); assertTrue(bools.getAsBool(1)); @@ -1278,7 +1513,9 @@ public void testParse_NonFixedBooleanArray_BigEndian() throws Exception { @Test public void testParse_NonFixedBooleanArray_LittleEndian() throws Exception { - final JBBPFieldArrayBoolean bools = JBBPParser.prepare(" JBBPParser.prepare("byte; short[1];").parse(new byte[] {1})); + assertThrows(EOFException.class, + () -> JBBPParser.prepare("byte; short[1];").parse(new byte[] {1})); } @Test public void testParse_NonFixedShortArray_ParsedAsEmptyArray() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte; short[_] array;").parse(new byte[] {1}); + final JBBPFieldStruct parsed = + JBBPParser.prepare("byte; short[_] array;").parse(new byte[] {1}); assertEquals(0, parsed.findFieldForNameAndType("array", JBBPFieldArrayShort.class).size()); } @Test public void testParse_FixedShortArray_Default() throws Exception { - final JBBPFieldArrayShort shorts = JBBPParser.prepare("short[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0}).findFieldForType(JBBPFieldArrayShort.class); + final JBBPFieldArrayShort shorts = + JBBPParser.prepare("short[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0}) + .findFieldForType(JBBPFieldArrayShort.class); assertEquals(2, shorts.size()); assertEquals((short) 0xF743, shorts.getAsInt(0)); assertEquals((short) 0x6500, shorts.getAsInt(1)); @@ -1307,7 +1548,9 @@ public void testParse_FixedShortArray_Default() throws Exception { @Test public void testParse_FixedShortArray_BigEndian() throws Exception { - final JBBPFieldArrayShort shorts = JBBPParser.prepare(">short[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0}).findFieldForType(JBBPFieldArrayShort.class); + final JBBPFieldArrayShort shorts = + JBBPParser.prepare(">short[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0}) + .findFieldForType(JBBPFieldArrayShort.class); assertEquals(2, shorts.size()); assertEquals((short) 0xF743, shorts.getAsInt(0)); assertEquals((short) 0x6500, shorts.getAsInt(1)); @@ -1315,7 +1558,9 @@ public void testParse_FixedShortArray_BigEndian() throws Exception { @Test public void testParse_FixedShortArray_LittleEndian() throws Exception { - final JBBPFieldArrayShort shorts = JBBPParser.prepare("short[_];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0}).findFieldForType(JBBPFieldArrayShort.class); + final JBBPFieldArrayShort shorts = + JBBPParser.prepare(">short[_];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0}) + .findFieldForType(JBBPFieldArrayShort.class); assertEquals(2, shorts.size()); assertEquals((short) 0xF743, shorts.getAsInt(0)); assertEquals((short) 0x6500, shorts.getAsInt(1)); @@ -1339,7 +1588,9 @@ public void testParse_NonFixedShortArray_BigEndian() throws Exception { @Test public void testParse_NonFixedShortArray_LittleEndian() throws Exception { - final JBBPFieldArrayShort shorts = JBBPParser.prepare(" JBBPParser.prepare("byte; ushort[1];").parse(new byte[] {1})); + assertThrows(EOFException.class, + () -> JBBPParser.prepare("byte; ushort[1];").parse(new byte[] {1})); } @Test public void testParse_NonFixedUShortArray_ParsedAsEmptyArray() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte; ushort[_] array;").parse(new byte[] {1}); + final JBBPFieldStruct parsed = + JBBPParser.prepare("byte; ushort[_] array;").parse(new byte[] {1}); assertEquals(0, parsed.findFieldForNameAndType("array", JBBPFieldArrayUShort.class).size()); } @Test public void testParse_FixedUShortArray_Default() throws Exception { - final JBBPFieldArrayUShort shorts = JBBPParser.prepare("ushort[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0}).findFieldForType(JBBPFieldArrayUShort.class); + final JBBPFieldArrayUShort shorts = + JBBPParser.prepare("ushort[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0}) + .findFieldForType(JBBPFieldArrayUShort.class); assertEquals(2, shorts.size()); assertEquals(0xF743, shorts.getAsInt(0)); assertEquals(0x6500, shorts.getAsInt(1)); @@ -1366,7 +1621,9 @@ public void testParse_FixedUShortArray_Default() throws Exception { @Test public void testParse_FixedUShortArray_BigEndian() throws Exception { - final JBBPFieldArrayUShort shorts = JBBPParser.prepare(">ushort[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0}).findFieldForType(JBBPFieldArrayUShort.class); + final JBBPFieldArrayUShort shorts = + JBBPParser.prepare(">ushort[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0}) + .findFieldForType(JBBPFieldArrayUShort.class); assertEquals(2, shorts.size()); assertEquals(0xF743, shorts.getAsInt(0)); assertEquals(0x6500, shorts.getAsInt(1)); @@ -1374,7 +1631,9 @@ public void testParse_FixedUShortArray_BigEndian() throws Exception { @Test public void testParse_FixedUShortArray_LittleEndian() throws Exception { - final JBBPFieldArrayUShort shorts = JBBPParser.prepare("ushort[_];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0}).findFieldForType(JBBPFieldArrayUShort.class); + final JBBPFieldArrayUShort shorts = + JBBPParser.prepare(">ushort[_];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0}) + .findFieldForType(JBBPFieldArrayUShort.class); assertEquals(2, shorts.size()); assertEquals(0xF743, shorts.getAsInt(0)); assertEquals(0x6500, shorts.getAsInt(1)); @@ -1398,7 +1661,9 @@ public void testParse_NonFixedUShortArray_BigEndian() throws Exception { @Test public void testParse_NonFixedUShortArray_LittleEndian() throws Exception { - final JBBPFieldArrayUShort shorts = JBBPParser.prepare(" JBBPParser.prepare("byte; int[1];").parse(new byte[] {1})); + assertThrows(EOFException.class, + () -> JBBPParser.prepare("byte; int[1];").parse(new byte[] {1})); } @Test @@ -1417,7 +1683,9 @@ public void testParse_NonFixedIntArray_ParsedAsEmptyArray() throws Exception { @Test public void testParse_FixedIntArray_Default() throws Exception { - final JBBPFieldArrayInt ints = JBBPParser.prepare("int[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0}).findFieldForType(JBBPFieldArrayInt.class); + final JBBPFieldArrayInt ints = JBBPParser.prepare("int[2];") + .parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0}) + .findFieldForType(JBBPFieldArrayInt.class); assertEquals(2, ints.size()); assertEquals(0xF7436510, ints.getAsInt(0)); assertEquals(0x352367A0, ints.getAsInt(1)); @@ -1425,7 +1693,9 @@ public void testParse_FixedIntArray_Default() throws Exception { @Test public void testParse_FixedIntArray_BigEndian() throws Exception { - final JBBPFieldArrayInt ints = JBBPParser.prepare(">int[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0}).findFieldForType(JBBPFieldArrayInt.class); + final JBBPFieldArrayInt ints = JBBPParser.prepare(">int[2];") + .parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0}) + .findFieldForType(JBBPFieldArrayInt.class); assertEquals(2, ints.size()); assertEquals(0xF7436510, ints.getAsInt(0)); assertEquals(0x352367A0, ints.getAsInt(1)); @@ -1433,7 +1703,9 @@ public void testParse_FixedIntArray_BigEndian() throws Exception { @Test public void testParse_FixedIntArray_LittleEndian() throws Exception { - final JBBPFieldArrayInt ints = JBBPParser.prepare("int[_];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0}).findFieldForType(JBBPFieldArrayInt.class); + final JBBPFieldArrayInt ints = JBBPParser.prepare(">int[_];") + .parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0}) + .findFieldForType(JBBPFieldArrayInt.class); assertEquals(2, ints.size()); assertEquals(0xF7436510, ints.getAsInt(0)); assertEquals(0x352367A0, ints.getAsInt(1)); @@ -1457,7 +1733,9 @@ public void testParse_NonFixedIntArray_BigEndian() throws Exception { @Test public void testParse_NonFixedIntArray_LittleEndian() throws Exception { - final JBBPFieldArrayInt ints = JBBPParser.prepare(" JBBPParser.prepare("byte; floatj[1];").parse(new byte[] {1})); + assertThrows(EOFException.class, + () -> JBBPParser.prepare("byte; floatj[1];").parse(new byte[] {1})); } @Test public void testParse_NonFixedFloatArray_ParsedAsEmptyArray() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte; floatj[_] array;").parse(new byte[] {1}); + final JBBPFieldStruct parsed = + JBBPParser.prepare("byte; floatj[_] array;").parse(new byte[] {1}); assertEquals(0, parsed.findFieldForNameAndType("array", JBBPFieldArrayFloat.class).size()); } @Test public void testParse_FixedFloatArray_Default() throws Exception { - final JBBPFieldArrayFloat ints = JBBPParser.prepare("floatj[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0}).findFieldForType(JBBPFieldArrayFloat.class); + final JBBPFieldArrayFloat ints = JBBPParser.prepare("floatj[2];") + .parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0}) + .findFieldForType(JBBPFieldArrayFloat.class); assertEquals(2, ints.size()); assertEquals(-3.963077E33f, ints.getAsFloat(0), TestUtils.FLOAT_DELTA); assertEquals(6.0873026E-7f, ints.getAsFloat(1), TestUtils.FLOAT_DELTA); @@ -1484,7 +1766,9 @@ public void testParse_FixedFloatArray_Default() throws Exception { @Test public void testParse_FixedFloatArray_BigEndian() throws Exception { - final JBBPFieldArrayFloat ints = JBBPParser.prepare(">floatj[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0}).findFieldForType(JBBPFieldArrayFloat.class); + final JBBPFieldArrayFloat ints = JBBPParser.prepare(">floatj[2];") + .parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0}) + .findFieldForType(JBBPFieldArrayFloat.class); assertEquals(2, ints.size()); assertEquals(-3.963077E33f, ints.getAsFloat(0), TestUtils.FLOAT_DELTA); assertEquals(6.0873026E-7f, ints.getAsFloat(1), TestUtils.FLOAT_DELTA); @@ -1492,7 +1776,9 @@ public void testParse_FixedFloatArray_BigEndian() throws Exception { @Test public void testParse_FixedFloatArray_LittleEndian() throws Exception { - final JBBPFieldArrayFloat ints = JBBPParser.prepare("floatj[_];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0}).findFieldForType(JBBPFieldArrayFloat.class); + final JBBPFieldArrayFloat ints = JBBPParser.prepare(">floatj[_];") + .parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0}) + .findFieldForType(JBBPFieldArrayFloat.class); assertEquals(2, ints.size()); assertEquals(-3.963077E33f, ints.getAsFloat(0), TestUtils.FLOAT_DELTA); assertEquals(6.0873026E-7f, ints.getAsFloat(1), TestUtils.FLOAT_DELTA); @@ -1516,7 +1806,9 @@ public void testParse_NonFixedFloatArray_BigEndian() throws Exception { @Test public void testParse_NonFixedFloatArray_LittleEndian() throws Exception { - final JBBPFieldArrayFloat ints = JBBPParser.prepare(" JBBPParser.prepare("byte; long[1];").parse(new byte[] {1})); + assertThrows(EOFException.class, + () -> JBBPParser.prepare("byte; long[1];").parse(new byte[] {1})); } @Test @@ -1535,7 +1828,9 @@ public void testParse_NonFixedLongArray_ParsedAsEmptyArray() throws Exception { @Test public void testParse_FixedLongArray_Default() throws Exception { - final JBBPFieldArrayLong longs = JBBPParser.prepare("long[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0, 0x32, 0x33, 0x61, (byte) 0xCA, (byte) 0xBE, 0x22, 0x12, 0x30}).findFieldForType(JBBPFieldArrayLong.class); + final JBBPFieldArrayLong longs = JBBPParser.prepare("long[2];").parse( + new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0, 0x32, 0x33, 0x61, + (byte) 0xCA, (byte) 0xBE, 0x22, 0x12, 0x30}).findFieldForType(JBBPFieldArrayLong.class); assertEquals(2, longs.size()); assertEquals(0xF7436510352367A0L, longs.getAsLong(0)); assertEquals(0x323361CABE221230L, longs.getAsLong(1)); @@ -1543,7 +1838,9 @@ public void testParse_FixedLongArray_Default() throws Exception { @Test public void testParse_FixedLongArray_BigEndian() throws Exception { - final JBBPFieldArrayLong longs = JBBPParser.prepare(">long[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0, 0x32, 0x33, 0x61, (byte) 0xCA, (byte) 0xBE, 0x22, 0x12, 0x30}).findFieldForType(JBBPFieldArrayLong.class); + final JBBPFieldArrayLong longs = JBBPParser.prepare(">long[2];").parse( + new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0, 0x32, 0x33, 0x61, + (byte) 0xCA, (byte) 0xBE, 0x22, 0x12, 0x30}).findFieldForType(JBBPFieldArrayLong.class); assertEquals(2, longs.size()); assertEquals(0xF7436510352367A0L, longs.getAsLong(0)); assertEquals(0x323361CABE221230L, longs.getAsLong(1)); @@ -1551,7 +1848,9 @@ public void testParse_FixedLongArray_BigEndian() throws Exception { @Test public void testParse_FixedLongArray_LittleEndian() throws Exception { - final JBBPFieldArrayLong longs = JBBPParser.prepare("long[_];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0, 0x32, 0x33, 0x61, (byte) 0xCA, (byte) 0xBE, 0x22, 0x12, 0x30}).findFieldForType(JBBPFieldArrayLong.class); + final JBBPFieldArrayLong longs = JBBPParser.prepare(">long[_];").parse( + new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0, 0x32, 0x33, 0x61, + (byte) 0xCA, (byte) 0xBE, 0x22, 0x12, 0x30}).findFieldForType(JBBPFieldArrayLong.class); assertEquals(2, longs.size()); assertEquals(0xF7436510352367A0L, longs.getAsLong(0)); assertEquals(0x323361CABE221230L, longs.getAsLong(1)); @@ -1575,7 +1878,9 @@ public void testParse_NonFixedLongArray_BigEndian() throws Exception { @Test public void testParse_NonFixedLongArray_LittleEndian() throws Exception { - final JBBPFieldArrayLong longs = JBBPParser.prepare(" JBBPParser.prepare("byte; doublej[1];").parse(new byte[] {1})); + assertThrows(EOFException.class, + () -> JBBPParser.prepare("byte; doublej[1];").parse(new byte[] {1})); } @Test public void testParse_NonFixedDoubleArray_ParsedAsEmptyArray() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte; doublej[_] array;").parse(new byte[] {1}); + final JBBPFieldStruct parsed = + JBBPParser.prepare("byte; doublej[_] array;").parse(new byte[] {1}); assertEquals(0, parsed.findFieldForNameAndType("array", JBBPFieldArrayDouble.class).size()); } @Test public void testParse_FixedDoubleArray_Default() throws Exception { - final JBBPFieldArrayDouble longs = JBBPParser.prepare("doublej[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0, 0x32, 0x33, 0x61, (byte) 0xCA, (byte) 0xBE, 0x22, 0x12, 0x30}).findFieldForType(JBBPFieldArrayDouble.class); + final JBBPFieldArrayDouble longs = JBBPParser.prepare("doublej[2];").parse( + new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0, 0x32, 0x33, 0x61, + (byte) 0xCA, (byte) 0xBE, 0x22, 0x12, 0x30}) + .findFieldForType(JBBPFieldArrayDouble.class); assertEquals(2, longs.size()); assertEquals(-3.126878492655484E266d, longs.getAsDouble(0), TestUtils.FLOAT_DELTA); assertEquals(7.189183308668011E-67d, longs.getAsDouble(1), TestUtils.FLOAT_DELTA); @@ -1602,7 +1912,10 @@ public void testParse_FixedDoubleArray_Default() throws Exception { @Test public void testParse_FixedDoubleArray_BigEndian() throws Exception { - final JBBPFieldArrayDouble longs = JBBPParser.prepare(">doublej[2];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0, 0x32, 0x33, 0x61, (byte) 0xCA, (byte) 0xBE, 0x22, 0x12, 0x30}).findFieldForType(JBBPFieldArrayDouble.class); + final JBBPFieldArrayDouble longs = JBBPParser.prepare(">doublej[2];").parse( + new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0, 0x32, 0x33, 0x61, + (byte) 0xCA, (byte) 0xBE, 0x22, 0x12, 0x30}) + .findFieldForType(JBBPFieldArrayDouble.class); assertEquals(2, longs.size()); assertEquals(-3.126878492655484E266d, longs.getAsDouble(0), TestUtils.FLOAT_DELTA); assertEquals(7.189183308668011E-67d, longs.getAsDouble(1), TestUtils.FLOAT_DELTA); @@ -1610,7 +1923,10 @@ public void testParse_FixedDoubleArray_BigEndian() throws Exception { @Test public void testParse_FixedDoubleArray_LittleEndian() throws Exception { - final JBBPFieldArrayDouble longs = JBBPParser.prepare("doublej[_];").parse(new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0, 0x32, 0x33, 0x61, (byte) 0xCA, (byte) 0xBE, 0x22, 0x12, 0x30}).findFieldForType(JBBPFieldArrayDouble.class); + final JBBPFieldArrayDouble longs = JBBPParser.prepare(">doublej[_];").parse( + new byte[] {(byte) 0xF7, 0x43, 0x65, 0x10, 0x35, 0x23, 0x67, (byte) 0xA0, 0x32, 0x33, 0x61, + (byte) 0xCA, (byte) 0xBE, 0x22, 0x12, 0x30}) + .findFieldForType(JBBPFieldArrayDouble.class); assertEquals(2, longs.size()); assertEquals(-3.126878492655484E266d, longs.getAsDouble(0), TestUtils.FLOAT_DELTA); assertEquals(7.189183308668011E-67d, longs.getAsDouble(1), TestUtils.FLOAT_DELTA); @@ -1634,7 +1956,10 @@ public void testParse_NonFixedDoubleArray_BigEndian() throws Exception { @Test public void testParse_NonFixedDoubleArray_LittleEndian() throws Exception { - final JBBPFieldArrayDouble longs = JBBPParser.prepare(" JBBPParser.prepare("ubyte len; byte[len-4];").parse(new byte[] {2, 1, 2, 3, 4})); + assertThrows(JBBPParsingException.class, + () -> JBBPParser.prepare("ubyte len; byte[len-4];").parse(new byte[] {2, 1, 2, 3, 4})); } @Test public void testParse_NegativeArrayLength() throws Exception { - assertThrows(JBBPCompilationException.class, () -> JBBPParser.prepare("ubyte len; byte[-2];").parse(new byte[] {2, 1, 2, 3, 4})); + assertThrows(JBBPCompilationException.class, + () -> JBBPParser.prepare("ubyte len; byte[-2];").parse(new byte[] {2, 1, 2, 3, 4})); } @Test public void testParse_ErrorForLessDataThanExpected() throws Exception { - assertThrows(EOFException.class, () -> JBBPParser.prepare("ubyte len; byte[5];").parse(new byte[] {2, 1, 2, 3, 4})); + assertThrows(EOFException.class, + () -> JBBPParser.prepare("ubyte len; byte[5];").parse(new byte[] {2, 1, 2, 3, 4})); } @Test public void testParse_WholeStructStream() throws Exception { - final JBBPFieldArrayStruct array = JBBPParser.prepare("struct [_] {byte;}").parse(new byte[] {1, 2, 3, 4}).findFieldForType(JBBPFieldArrayStruct.class); + final JBBPFieldArrayStruct array = + JBBPParser.prepare("struct [_] {byte;}").parse(new byte[] {1, 2, 3, 4}) + .findFieldForType(JBBPFieldArrayStruct.class); assertEquals(4, array.size()); assertEquals(1, array.getElementAt(0).findFieldForType(JBBPFieldByte.class).getAsInt()); assertEquals(2, array.getElementAt(1).findFieldForType(JBBPFieldByte.class).getAsInt()); @@ -1776,71 +2123,83 @@ public void testParse_WholeStructStream() throws Exception { @Test public void testParse_BitArray_IgnoredForZeroLength() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; bit:4 [len]; ushort;").parse(new byte[] {0x0, 0x01, (byte) 0x02}); + final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; bit:4 [len]; ushort;") + .parse(new byte[] {0x0, 0x01, (byte) 0x02}); assertEquals(0, parsed.findFieldForType(JBBPFieldArrayBit.class).size()); assertEquals(0x0102, parsed.findFieldForType(JBBPFieldUShort.class).getAsInt()); } @Test public void testParse_BoolArray_IgnoredForZeroLength() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; bool [len]; ushort;").parse(new byte[] {0x0, 0x01, (byte) 0x02}); + final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; bool [len]; ushort;") + .parse(new byte[] {0x0, 0x01, (byte) 0x02}); assertEquals(0, parsed.findFieldForType(JBBPFieldArrayBoolean.class).size()); assertEquals(0x0102, parsed.findFieldForType(JBBPFieldUShort.class).getAsInt()); } @Test public void testParse_ByteArray_IgnoredForZeroLength() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; byte [len]; ushort;").parse(new byte[] {0x0, 0x01, (byte) 0x02}); + final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; byte [len]; ushort;") + .parse(new byte[] {0x0, 0x01, (byte) 0x02}); assertEquals(0, parsed.findFieldForType(JBBPFieldArrayByte.class).size()); assertEquals(0x0102, parsed.findFieldForType(JBBPFieldUShort.class).getAsInt()); } @Test public void testParse_UByteArray_IgnoredForZeroLength() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; ubyte [len]; ushort;").parse(new byte[] {0x0, 0x01, (byte) 0x02}); + final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; ubyte [len]; ushort;") + .parse(new byte[] {0x0, 0x01, (byte) 0x02}); assertEquals(0, parsed.findFieldForType(JBBPFieldArrayUByte.class).size()); assertEquals(0x0102, parsed.findFieldForType(JBBPFieldUShort.class).getAsInt()); } @Test public void testParse_ShortArray_IgnoredForZeroLength() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; short [len]; ushort;").parse(new byte[] {0x0, 0x01, (byte) 0x02}); + final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; short [len]; ushort;") + .parse(new byte[] {0x0, 0x01, (byte) 0x02}); assertEquals(0, parsed.findFieldForType(JBBPFieldArrayShort.class).size()); assertEquals(0x0102, parsed.findFieldForType(JBBPFieldUShort.class).getAsInt()); } @Test public void testParse_UShortArray_IgnoredForZeroLength() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; ushort [len]; ushort;").parse(new byte[] {0x0, 0x01, (byte) 0x02}); + final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; ushort [len]; ushort;") + .parse(new byte[] {0x0, 0x01, (byte) 0x02}); assertEquals(0, parsed.findFieldForType(JBBPFieldArrayUShort.class).size()); assertEquals(0x0102, parsed.findFieldForType(JBBPFieldUShort.class).getAsInt()); } @Test public void testParse_IntArray_IgnoredForZeroLength() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; int [len]; ushort;").parse(new byte[] {0x0, 0x01, (byte) 0x02}); + final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; int [len]; ushort;") + .parse(new byte[] {0x0, 0x01, (byte) 0x02}); assertEquals(0, parsed.findFieldForType(JBBPFieldArrayInt.class).size()); assertEquals(0x0102, parsed.findFieldForType(JBBPFieldUShort.class).getAsInt()); } @Test public void testParse_LongArray_IgnoredForZeroLength() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; long [len]; ushort;").parse(new byte[] {0x0, 0x01, (byte) 0x02}); + final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; long [len]; ushort;") + .parse(new byte[] {0x0, 0x01, (byte) 0x02}); assertEquals(0, parsed.findFieldForType(JBBPFieldArrayLong.class).size()); assertEquals(0x0102, parsed.findFieldForType(JBBPFieldUShort.class).getAsInt()); } @Test public void testParse_StructArray_IgnoredForZeroLength() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; sss [len] { byte a; byte b; byte c;} ushort;").parse(new byte[] {0x0, 0x01, (byte) 0x02}); + final JBBPFieldStruct parsed = + JBBPParser.prepare("byte len; sss [len] { byte a; byte b; byte c;} ushort;") + .parse(new byte[] {0x0, 0x01, (byte) 0x02}); assertEquals(0, parsed.findFieldForType(JBBPFieldArrayStruct.class).size()); assertEquals(0x0102, parsed.findFieldForType(JBBPFieldUShort.class).getAsInt()); } @Test public void testParse_StructArray_FixedSize() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("sss [1] { byte a; byte b; byte c;}").parse(new byte[] {0x0, 0x01, (byte) 0x02}); - final JBBPFieldArrayStruct struct = parsed.findFieldForPathAndType("sss", JBBPFieldArrayStruct.class); + final JBBPFieldStruct parsed = JBBPParser.prepare("sss [1] { byte a; byte b; byte c;}") + .parse(new byte[] {0x0, 0x01, (byte) 0x02}); + final JBBPFieldArrayStruct struct = + parsed.findFieldForPathAndType("sss", JBBPFieldArrayStruct.class); assertEquals(1, struct.size()); final JBBPFieldStruct readStruct = struct.getElementAt(0); assertEquals(0, readStruct.findFieldForNameAndType("a", JBBPFieldByte.class).getAsInt()); @@ -1850,8 +2209,10 @@ public void testParse_StructArray_FixedSize() throws Exception { @Test public void testParse_StructArray_WholeStream() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("sss [_] { byte a; byte b; byte c;}").parse(new byte[] {0x0, 0x01, (byte) 0x02}); - final JBBPFieldArrayStruct struct = parsed.findFieldForPathAndType("sss", JBBPFieldArrayStruct.class); + final JBBPFieldStruct parsed = JBBPParser.prepare("sss [_] { byte a; byte b; byte c;}") + .parse(new byte[] {0x0, 0x01, (byte) 0x02}); + final JBBPFieldArrayStruct struct = + parsed.findFieldForPathAndType("sss", JBBPFieldArrayStruct.class); assertEquals(1, struct.size()); final JBBPFieldStruct readStruct = struct.getElementAt(0); assertEquals(0, readStruct.findFieldForNameAndType("a", JBBPFieldByte.class).getAsInt()); @@ -1873,7 +2234,9 @@ public void testParse_EmptyStructArrayInsideStruct_WholeStream() throws Exceptio @Test public void testParse_SkipStructureForZeroItems() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte len; sss [len]{ sss2[10]{ sss3{long;} sss4[45]{ushort; bool [11]; short; bit:4;} byte;}} byte end;").parse(new byte[] {0x00, 0x1F}); + final JBBPFieldStruct parsed = JBBPParser.prepare( + "byte len; sss [len]{ sss2[10]{ sss3{long;} sss4[45]{ushort; bool [11]; short; bit:4;} byte;}} byte end;") + .parse(new byte[] {0x00, 0x1F}); assertEquals(0, parsed.findFieldForPathAndType("len", JBBPFieldByte.class).getAsInt()); assertEquals(0, parsed.findFieldForPathAndType("sss", JBBPFieldArrayStruct.class).size()); assertEquals(0x1F, parsed.findFieldForPathAndType("end", JBBPFieldByte.class).getAsInt()); @@ -1881,46 +2244,63 @@ public void testParse_SkipStructureForZeroItems() throws Exception { @Test public void testParseWithStreamPositionMacros() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("int start; byte [$$] array; int end;").parse(new byte[] {1, 2, 3, 4, 0x1A, 0x1B, 0x1C, 0x1D, 4, 3, 2, 1}); - assertEquals(0x01020304, parsed.findFieldForPathAndType("start", JBBPFieldInt.class).getAsInt()); - assertArrayEquals(new byte[] {0x1A, 0x1B, 0x1C, 0x1D}, parsed.findFieldForPathAndType("array", JBBPFieldArrayByte.class).getArray()); + final JBBPFieldStruct parsed = JBBPParser.prepare("int start; byte [$$] array; int end;") + .parse(new byte[] {1, 2, 3, 4, 0x1A, 0x1B, 0x1C, 0x1D, 4, 3, 2, 1}); + assertEquals(0x01020304, + parsed.findFieldForPathAndType("start", JBBPFieldInt.class).getAsInt()); + assertArrayEquals(new byte[] {0x1A, 0x1B, 0x1C, 0x1D}, + parsed.findFieldForPathAndType("array", JBBPFieldArrayByte.class).getArray()); assertEquals(0x04030201, parsed.findFieldForPathAndType("end", JBBPFieldInt.class).getAsInt()); } @Test public void testParseWithStreamPositionMacrosInExpressions() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("int start; byte [$$-2] array; byte [$$-4] array2; int end;").parse(new byte[] {1, 2, 3, 4, 0x1A, 0x1B, 0x1C, 0x1D, 4, 3, 2, 1}); - assertEquals(0x01020304, parsed.findFieldForPathAndType("start", JBBPFieldInt.class).getAsInt()); - assertArrayEquals(new byte[] {0x1A, 0x1B}, parsed.findFieldForPathAndType("array", JBBPFieldArrayByte.class).getArray()); - assertArrayEquals(new byte[] {0x1C, 0x1D}, parsed.findFieldForPathAndType("array2", JBBPFieldArrayByte.class).getArray()); + final JBBPFieldStruct parsed = + JBBPParser.prepare("int start; byte [$$-2] array; byte [$$-4] array2; int end;") + .parse(new byte[] {1, 2, 3, 4, 0x1A, 0x1B, 0x1C, 0x1D, 4, 3, 2, 1}); + assertEquals(0x01020304, + parsed.findFieldForPathAndType("start", JBBPFieldInt.class).getAsInt()); + assertArrayEquals(new byte[] {0x1A, 0x1B}, + parsed.findFieldForPathAndType("array", JBBPFieldArrayByte.class).getArray()); + assertArrayEquals(new byte[] {0x1C, 0x1D}, + parsed.findFieldForPathAndType("array2", JBBPFieldArrayByte.class).getArray()); assertEquals(0x04030201, parsed.findFieldForPathAndType("end", JBBPFieldInt.class).getAsInt()); } @Test public void testParseManyFieldsWithTheSameName() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte l; a { byte a; b { byte a; c { byte a;}}} byte [a.b.c.a] aa;").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}); + final JBBPFieldStruct parsed = + JBBPParser.prepare("byte l; a { byte a; b { byte a; c { byte a;}}} byte [a.b.c.a] aa;") + .parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}); assertEquals(1, parsed.findFieldForPathAndType("l", JBBPFieldByte.class).getAsInt()); assertEquals(2, parsed.findFieldForPathAndType("a.a", JBBPFieldByte.class).getAsInt()); assertEquals(3, parsed.findFieldForPathAndType("a.b.a", JBBPFieldByte.class).getAsInt()); assertEquals(4, parsed.findFieldForPathAndType("a.b.c.a", JBBPFieldByte.class).getAsInt()); - assertArrayEquals(new byte[] {5, 6, 7, 8}, parsed.findFieldForPathAndType("aa", JBBPFieldArrayByte.class).getArray()); + assertArrayEquals(new byte[] {5, 6, 7, 8}, + parsed.findFieldForPathAndType("aa", JBBPFieldArrayByte.class).getArray()); } @Test public void testParseScopeOfVisibilityOfFieldIfTheSameInStructBefore() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte a; b { byte a;} byte [a] aa;").parse(new byte[] {1, 2, 3}); + final JBBPFieldStruct parsed = + JBBPParser.prepare("byte a; b { byte a;} byte [a] aa;").parse(new byte[] {1, 2, 3}); assertEquals(1, parsed.findFieldForPathAndType("a", JBBPFieldByte.class).getAsInt()); assertEquals(2, parsed.findFieldForPathAndType("b.a", JBBPFieldByte.class).getAsInt()); - assertArrayEquals(new byte[] {3}, parsed.findFieldForPathAndType("aa", JBBPFieldArrayByte.class).getArray()); + assertArrayEquals(new byte[] {3}, + parsed.findFieldForPathAndType("aa", JBBPFieldArrayByte.class).getArray()); } @Test public void testParseScopeOfVisibilityOfFieldInsideStructure() throws Exception { - final JBBPFieldStruct parsed = JBBPParser.prepare("byte a; b { byte a; byte [a] d; } byte [a] aa;").parse(new byte[] {1, 2, 3, 4, 5, 6}); + final JBBPFieldStruct parsed = + JBBPParser.prepare("byte a; b { byte a; byte [a] d; } byte [a] aa;") + .parse(new byte[] {1, 2, 3, 4, 5, 6}); assertEquals(1, parsed.findFieldForPathAndType("a", JBBPFieldByte.class).getAsInt()); assertEquals(2, parsed.findFieldForPathAndType("b.a", JBBPFieldByte.class).getAsInt()); - assertArrayEquals(new byte[] {3, 4}, parsed.findFieldForPathAndType("b.d", JBBPFieldArrayByte.class).getArray()); - assertArrayEquals(new byte[] {5}, parsed.findFieldForPathAndType("aa", JBBPFieldArrayByte.class).getArray()); + assertArrayEquals(new byte[] {3, 4}, + parsed.findFieldForPathAndType("b.d", JBBPFieldArrayByte.class).getArray()); + assertArrayEquals(new byte[] {5}, + parsed.findFieldForPathAndType("aa", JBBPFieldArrayByte.class).getArray()); } @Test @@ -1930,7 +2310,8 @@ public void testParseFixedSizeStructureArray() throws Exception { final JBBPFieldStruct parsed = parser.parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}); assertEquals(0x01020304, parsed.findFieldForPathAndType("val1", JBBPFieldInt.class).getAsInt()); - final JBBPFieldArrayStruct structArray = parsed.findFieldForNameAndType("inner", JBBPFieldArrayStruct.class); + final JBBPFieldArrayStruct structArray = + parsed.findFieldForNameAndType("inner", JBBPFieldArrayStruct.class); assertEquals(2, structArray.size()); } @@ -1938,9 +2319,11 @@ public void testParseFixedSizeStructureArray() throws Exception { @Test public void testParseWithResetCounter() throws Exception { final JBBPParser parser = JBBPParser.prepare("struct[_]{reset$$; byte a; align:3; byte b;}"); - final JBBPFieldStruct parsed = parser.parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}); + final JBBPFieldStruct parsed = + parser.parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}); - final JBBPFieldArrayStruct structArray = parsed.findFieldForNameAndType("struct", JBBPFieldArrayStruct.class); + final JBBPFieldArrayStruct structArray = + parsed.findFieldForNameAndType("struct", JBBPFieldArrayStruct.class); final byte[] etalon = new byte[] {1, 4, 5, 8, 9, 12, 13, 16}; assertEquals(4, structArray.size()); @@ -1965,7 +2348,8 @@ public void testParseResetCounterWithCachedBits() throws Exception { @Test public void testParseArrayWithZeroLengthForResetCounter() throws Exception { - final JBBPParser parser = JBBPParser.prepare("byte; byte [$$] a; reset$$; byte[$$] b; byte [2] c;"); + final JBBPParser parser = + JBBPParser.prepare("byte; byte [$$] a; reset$$; byte[$$] b; byte [2] c;"); final JBBPFieldStruct parsed = parser.parse(new byte[] {1, 2, 3, 4}); final JBBPFieldArrayByte a = parsed.findFieldForNameAndType("a", JBBPFieldArrayByte.class); final JBBPFieldArrayByte b = parsed.findFieldForNameAndType("b", JBBPFieldArrayByte.class); @@ -1984,8 +2368,10 @@ public void testGetFinalStreamByteCounter_Single_NoError() throws Exception { } @Test - public void testGetFinalStreamByteCounter_SequentlyFromTheSameStream_WithEOFAtTheEnd() throws Exception { - final JBBPBitInputStream stream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16})); + public void testGetFinalStreamByteCounter_SequentlyFromTheSameStream_WithEOFAtTheEnd() + throws Exception { + final JBBPBitInputStream stream = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16})); final JBBPParser parser = JBBPParser.prepare("byte [5];"); assertEquals(0L, parser.getFinalStreamByteCounter()); parser.parse(stream); @@ -2004,22 +2390,26 @@ public void testGetFinalStreamByteCounter_SequentlyFromTheSameStream_WithEOFAtTh @Test public void testParse_ErrorForNotAllReadFields() throws Exception { - final JBBPBitInputStream stream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4})); + final JBBPBitInputStream stream = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4})); final JBBPParser parser = JBBPParser.prepare("int a; int b;"); assertThrows(JBBPParsingException.class, () -> parser.parse(stream)); } @Test public void testParse_NegativeExpressonResult_OneFieldAsExpression_FlagOff() throws Exception { - final JBBPBitInputStream stream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {(byte) 0xEF, 1, 2, 3})); + final JBBPBitInputStream stream = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {(byte) 0xEF, 1, 2, 3})); final JBBPParser parser = JBBPParser.prepare("byte len; byte [len] arr;"); assertThrows(JBBPParsingException.class, () -> parser.parse(stream)); } @Test - public void testParse_NegativeExpressonResult_ExpressionWithNegativeResult_FlagOff() throws Exception { - final JBBPBitInputStream stream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {2, 1, 2, 3})); + public void testParse_NegativeExpressonResult_ExpressionWithNegativeResult_FlagOff() + throws Exception { + final JBBPBitInputStream stream = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {2, 1, 2, 3})); final JBBPParser parser = JBBPParser.prepare("byte len; byte [len - 8] arr;"); assertThrows(JBBPParsingException.class, () -> parser.parse(stream)); @@ -2027,17 +2417,22 @@ public void testParse_NegativeExpressonResult_ExpressionWithNegativeResult_FlagO @Test public void testParse_NegativeExpressonResult_OneFieldAsExpression_FlagOn() throws Exception { - final JBBPBitInputStream stream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {(byte) 0xEF, 1, 2, 3})); - final JBBPParser parser = JBBPParser.prepare("byte len; byte [len] arr;", JBBPParser.FLAG_NEGATIVE_EXPRESSION_RESULT_AS_ZERO); + final JBBPBitInputStream stream = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {(byte) 0xEF, 1, 2, 3})); + final JBBPParser parser = JBBPParser + .prepare("byte len; byte [len] arr;", JBBPParser.FLAG_NEGATIVE_EXPRESSION_RESULT_AS_ZERO); final JBBPFieldStruct result = parser.parse(stream); assertEquals((byte) 0xEF, result.findFieldForType(JBBPFieldByte.class).getAsInt()); assertEquals(0, result.findFieldForType(JBBPFieldArrayByte.class).getArray().length); } @Test - public void testParse_NegativeExpressonResult_ExpressionWithNegativResult_FlagOn() throws Exception { - final JBBPBitInputStream stream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {4, 1, 2, 3})); - final JBBPParser parser = JBBPParser.prepare("byte len; byte [len-8] arr;", JBBPParser.FLAG_NEGATIVE_EXPRESSION_RESULT_AS_ZERO); + public void testParse_NegativeExpressonResult_ExpressionWithNegativResult_FlagOn() + throws Exception { + final JBBPBitInputStream stream = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {4, 1, 2, 3})); + final JBBPParser parser = JBBPParser + .prepare("byte len; byte [len-8] arr;", JBBPParser.FLAG_NEGATIVE_EXPRESSION_RESULT_AS_ZERO); final JBBPFieldStruct result = parser.parse(stream); assertEquals(4, result.findFieldForType(JBBPFieldByte.class).getAsInt()); assertEquals(0, result.findFieldForType(JBBPFieldArrayByte.class).getArray().length); @@ -2045,8 +2440,10 @@ public void testParse_NegativeExpressonResult_ExpressionWithNegativResult_FlagOn @Test public void testParse_NoErrorForIgnoreRemainingFieldsFlag() throws Exception { - final JBBPBitInputStream stream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4})); - final JBBPParser parser = JBBPParser.prepare("int a; int b;", JBBPParser.FLAG_SKIP_REMAINING_FIELDS_IF_EOF); + final JBBPBitInputStream stream = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4})); + final JBBPParser parser = + JBBPParser.prepare("int a; int b;", JBBPParser.FLAG_SKIP_REMAINING_FIELDS_IF_EOF); final JBBPFieldStruct result = parser.parse(stream); assertEquals(1, result.getArray().length); assertEquals("a", result.getArray()[0].getFieldName()); @@ -2057,7 +2454,8 @@ public void testParse_NoErrorForIgnoreRemainingFieldsFlag() throws Exception { public void testConvertToSrc_Java_NamedPackage() { final JBBPParser parser = JBBPParser.prepare("byte a;"); - final List src = parser.convertToSrc(TargetSources.JAVA, "some.package.SomeClass"); + final List src = + parser.convertToSrc(TargetSources.JAVA, "some.package.SomeClass"); assertEquals(1, src.size()); assertEquals("byte a;", src.get(0).getMetadata().getProperty("script")); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/TestUtils.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/TestUtils.java index 40eeb645..30e7e88a 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/TestUtils.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/TestUtils.java @@ -44,7 +44,8 @@ public enum TestUtils { * @return value, can be null * @throws Exception it will be thrown if any error */ - public static T getField(final Object instance, final String fieldName, final Class klazz) throws Exception { + public static T getField(final Object instance, final String fieldName, final Class klazz) + throws Exception { final String[] fields = fieldName.split("\\."); Object result = instance; for (final String f : fields) { @@ -64,7 +65,8 @@ public static T getField(final Object instance, final String fieldName, fina * @return value, can be null * @throws Exception it will be thrown if any error */ - public static T getFieldThroughGetters(final Object instance, final String fieldName, final Class klazz) throws Exception { + public static T getFieldThroughGetters(final Object instance, final String fieldName, + final Class klazz) throws Exception { final String[] fields = fieldName.split("\\."); Object result = instance; for (final String f : fields) { @@ -83,8 +85,12 @@ public static T getFieldThroughGetters(final Object instance, final String f * @param chunkCrc chunk crc field value * @param chunkData chunk data, must not be null */ - public static void assertPngChunk(final String etalonName, final int etalonLength, final int chunkType, final int chunkLength, final int chunkCrc, final byte[] chunkData) { - final int chunkEtalonName = (etalonName.charAt(0) << 24) | (etalonName.charAt(1) << 16) | (etalonName.charAt(2) << 8) | etalonName.charAt(3); + public static void assertPngChunk(final String etalonName, final int etalonLength, + final int chunkType, final int chunkLength, final int chunkCrc, + final byte[] chunkData) { + final int chunkEtalonName = + (etalonName.charAt(0) << 24) | (etalonName.charAt(1) << 16) | (etalonName.charAt(2) << 8) | + etalonName.charAt(3); assertEquals(chunkEtalonName, chunkType, "Chunk must be " + etalonName); assertEquals(etalonLength, chunkLength, "Chunk length must be " + etalonLength); @@ -96,8 +102,9 @@ public static void assertPngChunk(final String etalonName, final int etalonLengt crc32.update(etalonName.charAt(3)); if (etalonLength != 0) { - assertEquals(etalonLength, chunkData.length, "Data array " + etalonName + " must be " + etalonLength); - for(final byte b : chunkData) { + assertEquals(etalonLength, chunkData.length, + "Data array " + etalonName + " must be " + etalonLength); + for (final byte b : chunkData) { crc32.update(b & 0xFF); } } @@ -107,6 +114,7 @@ public static void assertPngChunk(final String etalonName, final int etalonLengt } public static String wavInt2Str(final int value) { - return new String(new char[] {(char) (value & 0xFF), (char) ((value >>> 8) & 0xFF), (char) ((value >>> 16) & 0xFF), (char) (value >>> 24)}); + return new String(new char[] {(char) (value & 0xFF), (char) ((value >>> 8) & 0xFF), + (char) ((value >>> 16) & 0xFF), (char) (value >>> 24)}); } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/JBBPCompilerTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/JBBPCompilerTest.java index 4f3ff7f8..67add8bf 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/JBBPCompilerTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/JBBPCompilerTest.java @@ -16,15 +16,21 @@ package com.igormaznitsa.jbbp.compiler; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + + import com.igormaznitsa.jbbp.compiler.tokenizer.JBBPTokenType; import com.igormaznitsa.jbbp.exceptions.JBBPCompilationException; import com.igormaznitsa.jbbp.exceptions.JBBPTokenizerException; import com.igormaznitsa.jbbp.utils.JBBPIntCounter; import com.igormaznitsa.jbbp.utils.JBBPUtils; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.function.Executable; - -import static org.junit.jupiter.api.Assertions.*; public class JBBPCompilerTest { @@ -48,12 +54,17 @@ public void testCompile_AllowedStructInsideStructWhichShouldBeReadTillEnd() thro @Test public void testCompile_ErrorSituationsReadTillEnd() { - assertThrows(JBBPCompilationException.class, () -> JBBPCompiler.compile("ubyte [_]; ubyte [_];")); - assertThrows(JBBPCompilationException.class, () -> JBBPCompiler.compile("ubyte [_]; a {byte;};")); - assertThrows(JBBPCompilationException.class, () -> JBBPCompiler.compile("byte;test [_] {byte;} int error;")); + assertThrows(JBBPCompilationException.class, + () -> JBBPCompiler.compile("ubyte [_]; ubyte [_];")); + assertThrows(JBBPCompilationException.class, + () -> JBBPCompiler.compile("ubyte [_]; a {byte;};")); + assertThrows(JBBPCompilationException.class, + () -> JBBPCompiler.compile("byte;test [_] {byte;} int error;")); assertThrows(JBBPCompilationException.class, () -> JBBPCompiler.compile("ubyte [_]; byte;")); - assertThrows(JBBPCompilationException.class, () -> JBBPCompiler.compile("a [_] { byte a; } b [_] { byte a;}")); - assertThrows(JBBPCompilationException.class, () -> JBBPCompiler.compile("a [_] { b [_] { byte a;}}")); + assertThrows(JBBPCompilationException.class, + () -> JBBPCompiler.compile("a [_] { byte a; } b [_] { byte a;}")); + assertThrows(JBBPCompilationException.class, + () -> JBBPCompiler.compile("a [_] { b [_] { byte a;}}")); } @Test @@ -61,8 +72,10 @@ public void testCompile_StructForWholeStreamAsSecondField() throws Exception { final JBBPCompiledBlock block = JBBPCompiler.compile("byte;test [_] {byte;}"); assertEquals(6, block.getCompiledData().length); assertEquals(JBBPCompiler.CODE_BYTE, block.getCompiledData()[0]); - assertEquals(JBBPCompiler.CODE_STRUCT_START | JBBPCompiler.FLAG_WIDE | JBBPCompiler.FLAG_NAMED, block.getCompiledData()[1] & 0xFF); - assertEquals(JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM, block.getCompiledData()[2] & 0xFF); + assertEquals(JBBPCompiler.CODE_STRUCT_START | JBBPCompiler.FLAG_WIDE | JBBPCompiler.FLAG_NAMED, + block.getCompiledData()[1] & 0xFF); + assertEquals(JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM, + block.getCompiledData()[2] & 0xFF); assertEquals(JBBPCompiler.CODE_BYTE, block.getCompiledData()[3]); assertEquals(JBBPCompiler.CODE_STRUCT_END, block.getCompiledData()[4]); assertEquals(1, block.getCompiledData()[5]); @@ -72,9 +85,12 @@ public void testCompile_StructForWholeStreamAsSecondField() throws Exception { public void testCompile_WholeStreamArrayInsideStructure() throws Exception { final JBBPCompiledBlock block = JBBPCompiler.compile("test {byte [_];}"); assertEquals(5, block.getCompiledData().length); - assertEquals(JBBPCompiler.CODE_STRUCT_START | JBBPCompiler.FLAG_NAMED, block.getCompiledData()[0]); - assertEquals(JBBPCompiler.CODE_BYTE | JBBPCompiler.FLAG_WIDE, block.getCompiledData()[1] & 0xFF); - assertEquals(JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM, block.getCompiledData()[2] & 0xFF); + assertEquals(JBBPCompiler.CODE_STRUCT_START | JBBPCompiler.FLAG_NAMED, + block.getCompiledData()[0]); + assertEquals(JBBPCompiler.CODE_BYTE | JBBPCompiler.FLAG_WIDE, + block.getCompiledData()[1] & 0xFF); + assertEquals(JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM, + block.getCompiledData()[2] & 0xFF); assertEquals(JBBPCompiler.CODE_STRUCT_END, block.getCompiledData()[3]); assertEquals(0, block.getCompiledData()[4]); } @@ -83,9 +99,12 @@ public void testCompile_WholeStreamArrayInsideStructure() throws Exception { public void testCompile_WholeStreamStructureArrayInsideStructure() throws Exception { final JBBPCompiledBlock block = JBBPCompiler.compile("test { whole[_]{ byte;}}"); assertEquals(8, block.getCompiledData().length); - assertEquals(JBBPCompiler.CODE_STRUCT_START | JBBPCompiler.FLAG_NAMED, block.getCompiledData()[0]); - assertEquals(JBBPCompiler.CODE_STRUCT_START | JBBPCompiler.FLAG_NAMED | JBBPCompiler.FLAG_WIDE, block.getCompiledData()[1] & 0xFF); - assertEquals(JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM, block.getCompiledData()[2] & 0xFF); + assertEquals(JBBPCompiler.CODE_STRUCT_START | JBBPCompiler.FLAG_NAMED, + block.getCompiledData()[0]); + assertEquals(JBBPCompiler.CODE_STRUCT_START | JBBPCompiler.FLAG_NAMED | JBBPCompiler.FLAG_WIDE, + block.getCompiledData()[1] & 0xFF); + assertEquals(JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM, + block.getCompiledData()[2] & 0xFF); assertEquals(JBBPCompiler.CODE_BYTE, block.getCompiledData()[3]); assertEquals(JBBPCompiler.CODE_STRUCT_END, block.getCompiledData()[4]); assertEquals(1, block.getCompiledData()[5]); @@ -148,7 +167,8 @@ public void testCompile_ErrorForArraySkipField() throws Exception { @Test public void testCompile_ZeroSkipValueIsAllowed() throws Exception { - assertArrayEquals(new byte[] {JBBPCompiler.CODE_SKIP, 0}, JBBPCompiler.compile("skip:0;").getCompiledData()); + assertArrayEquals(new byte[] {JBBPCompiler.CODE_SKIP, 0}, + JBBPCompiler.compile("skip:0;").getCompiledData()); } @Test @@ -173,7 +193,8 @@ public void testCompile_ArraySize_ExpressionWithAllOperators_NoExceptions() thro } @Test - public void testCompile_ExtraFieldData_ExpressionWithAllOperators_NoExceptions() throws Exception { + public void testCompile_ExtraFieldData_ExpressionWithAllOperators_NoExceptions() + throws Exception { assertNotNull(JBBPCompiler.compile("bit:((1+2-3)*4/(5<<6>>7)>>>3%1&89|22^34-~45) a;")); } @@ -265,7 +286,9 @@ public void testCompile_NonamedVarWithPositiveExtra() throws Exception { @Test public void testCompile_NonamedVarWithNegativeExtra() throws Exception { final byte[] compiled = JBBPCompiler.compile("var:-1;").getCompiledData(); - assertArrayEquals(new byte[] {JBBPCompiler.CODE_VAR, (byte) 0x81, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}, compiled); + assertArrayEquals( + new byte[] {JBBPCompiler.CODE_VAR, (byte) 0x81, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, + (byte) 0xFF}, compiled); } @Test @@ -283,25 +306,33 @@ public void testCompile_NamedVarWithPositiveExtra() throws Exception { @Test public void testCompile_NamedVarWithNegativeExtra() throws Exception { final byte[] compiled = JBBPCompiler.compile("var:-1 VVV;").getCompiledData(); - assertArrayEquals(new byte[] {JBBPCompiler.CODE_VAR | JBBPCompiler.FLAG_NAMED, (byte) 0x81, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}, compiled); + assertArrayEquals( + new byte[] {JBBPCompiler.CODE_VAR | JBBPCompiler.FLAG_NAMED, (byte) 0x81, (byte) 0xFF, + (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}, compiled); } @Test public void testCompile_NamedVarArrayWithoutExtra() throws Exception { final byte[] compiled = JBBPCompiler.compile("var [98] VVV;").getCompiledData(); - assertArrayEquals(new byte[] {JBBPCompiler.CODE_VAR | JBBPCompiler.FLAG_NAMED | JBBPCompiler.FLAG_ARRAY, 98, 0}, compiled); + assertArrayEquals( + new byte[] {JBBPCompiler.CODE_VAR | JBBPCompiler.FLAG_NAMED | JBBPCompiler.FLAG_ARRAY, 98, + 0}, compiled); } @Test public void testCompile_NamedVarArrayWithPositiveExtra() throws Exception { final byte[] compiled = JBBPCompiler.compile("var:12 [98] VVV;").getCompiledData(); - assertArrayEquals(new byte[] {JBBPCompiler.CODE_VAR | JBBPCompiler.FLAG_ARRAY | JBBPCompiler.FLAG_NAMED, 98, 12}, compiled); + assertArrayEquals( + new byte[] {JBBPCompiler.CODE_VAR | JBBPCompiler.FLAG_ARRAY | JBBPCompiler.FLAG_NAMED, 98, + 12}, compiled); } @Test public void testCompile_NamedVarArrayWithNegativeExtra() throws Exception { final byte[] compiled = JBBPCompiler.compile("var:-1 [98] VVV;").getCompiledData(); - assertArrayEquals(new byte[] {JBBPCompiler.CODE_VAR | JBBPCompiler.FLAG_ARRAY | JBBPCompiler.FLAG_NAMED, 98, (byte) 0x81, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}, compiled); + assertArrayEquals( + new byte[] {JBBPCompiler.CODE_VAR | JBBPCompiler.FLAG_ARRAY | JBBPCompiler.FLAG_NAMED, 98, + (byte) 0x81, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}, compiled); } @Test @@ -408,7 +439,8 @@ public void testCompile_SingleNamedIntLittleEndianField() throws Exception { final JBBPCompiledBlock block = JBBPCompiler.compile(" JBBPCompiler.compile("out { int [4] len; some {byte [len] HeLLo;} }")); + assertThrows(JBBPCompilationException.class, + () -> JBBPCompiler.compile("out { int [4] len; some {byte [len] HeLLo;} }")); } @Test public void testCompile_ErrorForFieldInStructArrayAsVarLength() throws Exception { - assertThrows(JBBPCompilationException.class, () -> JBBPCompiler.compile("struct [10] {int [4] len;} some {byte [struct.len] HeLLo;} ")); + assertThrows(JBBPCompilationException.class, + () -> JBBPCompiler.compile("struct [10] {int [4] len;} some {byte [struct.len] HeLLo;} ")); } @Test public void testCompile_ErrorForFieldInStructAsVarLength() throws Exception { - assertThrows(JBBPCompilationException.class, () -> JBBPCompiler.compile("struct [10] {int len;} some {byte [struct.len] HeLLo;} ")); + assertThrows(JBBPCompilationException.class, + () -> JBBPCompiler.compile("struct [10] {int len;} some {byte [struct.len] HeLLo;} ")); } @Test public void testCompile_ErrorForUnknownFieldAsArrayLength() throws Exception { - assertThrows(JBBPCompilationException.class, () -> JBBPCompiler.compile("some {byte [struct.len] HeLLo;} ")); + assertThrows(JBBPCompilationException.class, + () -> JBBPCompiler.compile("some {byte [struct.len] HeLLo;} ")); } @Test @@ -525,8 +566,10 @@ public void testCompile_ArrayWithUndefinedLength() throws Exception { assertEquals(2, compiled.getCompiledData().length); assertNotNull(field); assertEquals(0, field.getFieldOffsetInCompiledBlock()); - assertEquals(JBBPCompiler.CODE_BYTE | JBBPCompiler.FLAG_NAMED | JBBPCompiler.FLAG_WIDE, compiled.getCompiledData()[0] & 0xFF); - assertEquals(JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM, compiled.getCompiledData()[1] & 0xFF); + assertEquals(JBBPCompiler.CODE_BYTE | JBBPCompiler.FLAG_NAMED | JBBPCompiler.FLAG_WIDE, + compiled.getCompiledData()[0] & 0xFF); + assertEquals(JBBPCompiler.EXT_FLAG_EXPRESSION_OR_WHOLESTREAM, + compiled.getCompiledData()[1] & 0xFF); } @Test @@ -538,7 +581,8 @@ public void testCompile_StructFieldWithNameOfExternalField() throws Exception { @Test public void testCompile_FixedStructArray() throws Exception { - final JBBPCompiledBlock compiled = JBBPCompiler.compile("int value; inner [2] { byte a; byte b;}"); + final JBBPCompiledBlock compiled = + JBBPCompiler.compile("int value; inner [2] { byte a; byte b;}"); assertArrayEquals(new byte[] { JBBPCompiler.CODE_INT | JBBPCompiler.FLAG_NAMED, @@ -563,7 +607,8 @@ public void testCompile_ErrorForNonAllowedArguments() throws Exception { assertThrows(JBBPCompilationException.class, () -> JBBPCompiler.compile("reset$$:1;")); assertThrows(JBBPCompilationException.class, () -> JBBPCompiler.compile("reset$$ hello;")); assertThrows(JBBPCompilationException.class, () -> JBBPCompiler.compile("reset$$ [445];")); - assertThrows(JBBPCompilationException.class, () -> JBBPCompiler.compile("reset$$ [445] hello;")); + assertThrows(JBBPCompilationException.class, + () -> JBBPCompiler.compile("reset$$ [445] hello;")); } @Test @@ -573,7 +618,8 @@ public void testCompile_ErrorForResetWithExtraValue() throws Exception { @Test public void testCompile_Reset() throws Exception { - assertArrayEquals(new byte[] {JBBPCompiler.CODE_RESET_COUNTER}, JBBPCompiler.compile("reset$$;").getCompiledData()); + assertArrayEquals(new byte[] {JBBPCompiler.CODE_RESET_COUNTER}, + JBBPCompiler.compile("reset$$;").getCompiledData()); } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJBBPToJavaConverterCompilationTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJBBPToJavaConverterCompilationTest.java index a1042c3b..3f0a77dd 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJBBPToJavaConverterCompilationTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJBBPToJavaConverterCompilationTest.java @@ -67,36 +67,53 @@ private void assertCompilation(final String classSrc) throws Exception { @Test void testVarNamesAsJavaTypes() throws Exception { - final JBBPParser parser = JBBPParser.prepare("ubyte;int integer; int number; int try; int byte; int _byte; int _byte_; int char; int short; int long; int double; int float; int [long+double+char] string;"); - assertCompilation(makeSources(parser, "some multiline text\nto be added into header", true, true, false)); + final JBBPParser parser = JBBPParser.prepare( + "ubyte;int integer; int number; int try; int byte; int _byte; int _byte_; int char; int short; int long; int double; int float; int [long+double+char] string;"); + assertCompilation( + makeSources(parser, "some multiline text\nto be added into header", true, true, false)); } @Test void testExpression() throws Exception { - final JBBPParser parser = JBBPParser.prepare("bit:8 bitf; var somevar; bool bbb; long aaa; ubyte kkk; {{int lrn; {int [(lrn/aaa*1*(2*somevar-4)&$joomla)/(100%9>>bitf)&56|~kkk^78&bbb];}}}"); - assertCompilation(makeSources(parser, "some multiline text\nto be added into header", false, false, false)); - assertCompilation(makeSources(parser, "some multiline text\nto be added into header", true, true, true)); + final JBBPParser parser = JBBPParser.prepare( + "bit:8 bitf; var somevar; bool bbb; long aaa; ubyte kkk; {{int lrn; {int [(lrn/aaa*1*(2*somevar-4)&$joomla)/(100%9>>bitf)&56|~kkk^78&bbb];}}}"); + assertCompilation( + makeSources(parser, "some multiline text\nto be added into header", false, false, false)); + assertCompilation( + makeSources(parser, "some multiline text\nto be added into header", true, true, true)); } @Test void testGenerateBinAnnotation() { - final JBBPParser parser = JBBPParser.prepare("bit:3 someBit; bit:4 [12] bitArray; some {int a; floatj b; doublej[23] darr;}"); - assertFalse(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).build().convert().contains("@Bin")); - assertTrue(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).addBinAnnotations().build().convert().contains("@Bin")); + final JBBPParser parser = JBBPParser + .prepare("bit:3 someBit; bit:4 [12] bitArray; some {int a; floatj b; doublej[23] darr;}"); + assertFalse( + JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).build().convert() + .contains("@Bin")); + assertTrue( + JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).addBinAnnotations() + .build().convert().contains("@Bin")); } @Test void testGenNewInstanceMethod() { - final JBBPParser parser = JBBPParser.prepare("bit:3 someBit; bit:4 [12] bitArray; some {int a; floatj b; doublej[23] darr;}"); - assertFalse(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).build().convert().contains("Object " + JBBPMapper.MAKE_CLASS_INSTANCE_METHOD_NAME)); - assertTrue(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).addNewInstanceMethods().build().convert().contains("Object " + JBBPMapper.MAKE_CLASS_INSTANCE_METHOD_NAME)); + final JBBPParser parser = JBBPParser + .prepare("bit:3 someBit; bit:4 [12] bitArray; some {int a; floatj b; doublej[23] darr;}"); + assertFalse( + JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).build().convert() + .contains("Object " + JBBPMapper.MAKE_CLASS_INSTANCE_METHOD_NAME)); + assertTrue( + JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).addNewInstanceMethods() + .build().convert().contains("Object " + JBBPMapper.MAKE_CLASS_INSTANCE_METHOD_NAME)); } @Test void testForceAbstract() throws Exception { final JBBPParser parser = JBBPParser.prepare("byte a;"); - assertFalse(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).setDoMainClassAbstract(false).build().convert().contains("abstract")); - assertTrue(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).setDoMainClassAbstract(true).build().convert().contains("abstract")); + assertFalse(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME) + .setDoMainClassAbstract(false).build().convert().contains("abstract")); + assertTrue(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME) + .setDoMainClassAbstract(true).build().convert().contains("abstract")); } @Test @@ -110,7 +127,8 @@ void testMakeInternalClassObjects_StaticClasses() throws Exception { .convert(); assertTrue(text.contains("public A makeA(){ this.a = new A(this); return this.a; }")); assertTrue(text.contains("public B makeB(){ this.b = new B(_Root_); return this.b; }")); - assertTrue(text.contains("public C[] makeC(int _Len_){ this.c = new C[_Len_]; for(int i=0;i < _Len_;i++) this.c[i]=new C(_Root_); return this.c; }")); + assertTrue(text.contains( + "public C[] makeC(int _Len_){ this.c = new C[_Len_]; for(int i=0;i < _Len_;i++) this.c[i]=new C(_Root_); return this.c; }")); } @Test @@ -124,7 +142,8 @@ void testMakeInternalClassObjects_NoMakersWithoutGettersSetters() throws Excepti .convert(); assertFalse(text.contains("public A makeA(){ this.a = new A(this); return this.a; }")); assertFalse(text.contains("public B makeB(){ this.b = new B(_Root_); return this.b; }")); - assertFalse(text.contains("public C[] makeC(int _Len_){ this.c = new C[_Len_]; for(int i=0;i < _Len_;i++) this.c[i]=new C(_Root_); return this.c; }")); + assertFalse(text.contains( + "public C[] makeC(int _Len_){ this.c = new C[_Len_]; for(int i=0;i < _Len_;i++) this.c[i]=new C(_Root_); return this.c; }")); } @Test @@ -139,7 +158,8 @@ void testMakeInternalClassObjects_NonStaticClasses() throws Exception { .convert(); assertTrue(text.contains("public A makeA(){ this.a = new A(this); return this.a; }")); assertTrue(text.contains("public B makeB(){ this.b = new B(_Root_); return this.b; }")); - assertTrue(text.contains("public C[] makeC(int _Len_){ this.c = new C[_Len_]; for(int i=0;i < _Len_;i++) this.c[i]=new C(_Root_); return this.c; }")); + assertTrue(text.contains( + "public C[] makeC(int _Len_){ this.c = new C[_Len_]; for(int i=0;i < _Len_;i++) this.c[i]=new C(_Root_); return this.c; }")); } @Test @@ -187,38 +207,52 @@ void testMapSubstructToInterface() throws Exception { @Test void testCustomText() throws Exception { final JBBPParser parser = JBBPParser.prepare("byte a;"); - assertTrue(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).setMainClassCustomText("public void test(){}").build().convert().contains("public void test(){}")); + assertTrue(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME) + .setMainClassCustomText("public void test(){}").build().convert() + .contains("public void test(){}")); } @Test void testSuperclass() throws Exception { final JBBPParser parser = JBBPParser.prepare("byte a;"); - assertTrue(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).setSuperClass("com.igormaznitsa.Super").build().convert().contains("extends com.igormaznitsa.Super ")); + assertTrue(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME) + .setSuperClass("com.igormaznitsa.Super").build().convert() + .contains("extends com.igormaznitsa.Super ")); } @Test void testInterfaces() throws Exception { final JBBPParser parser = JBBPParser.prepare("byte a;"); - assertTrue(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).setMainClassImplements("com.igormaznitsa.InterfaceA", "com.igormaznitsa.InterfaceB").build().convert().contains("implements com.igormaznitsa.InterfaceA,com.igormaznitsa.InterfaceB ")); + assertTrue(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME) + .setMainClassImplements("com.igormaznitsa.InterfaceA", "com.igormaznitsa.InterfaceB") + .build().convert() + .contains("implements com.igormaznitsa.InterfaceA,com.igormaznitsa.InterfaceB ")); } @Test void testClassPackage() throws Exception { final JBBPParser parser = JBBPParser.prepare("byte a;"); - assertFalse(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).build().convert().contains("package ")); - assertFalse(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).setMainClassPackage("").build().convert().contains("package ")); - assertTrue(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).setMainClassPackage("hello.world").build().convert().contains("package hello.world;")); + assertFalse( + JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).build().convert() + .contains("package ")); + assertFalse( + JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).setMainClassPackage("") + .build().convert().contains("package ")); + assertTrue(JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME) + .setMainClassPackage("hello.world").build().convert().contains("package hello.world;")); } @Test void testGettersSetters() throws Exception { final JBBPParser parser = JBBPParser.prepare("byte a;"); - String text = JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).build().convert(); + String text = + JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).build().convert(); assertTrue(text.contains("public byte a;")); assertFalse(text.contains("public void setA(byte value) {")); assertFalse(text.contains("public byte getA() {")); - text = JBBPToJavaConverter.makeBuilder(parser).setAddGettersSetters(true).setMainClassName(CLASS_NAME).build().convert(); + text = JBBPToJavaConverter.makeBuilder(parser).setAddGettersSetters(true) + .setMainClassName(CLASS_NAME).build().convert(); assertFalse(text.contains("public byte a;")); assertTrue(text.contains("protected byte a;")); @@ -228,18 +262,23 @@ void testGettersSetters() throws Exception { @Test void testZ80snap1() throws Exception { - final JBBPParser parser = JBBPParser.prepare("byte reg_a; byte reg_f; assertCompilation(makeSources(parser, null, false, false, false))); - assertThrows(Exception.class, () -> assertCompilation(makeSources(parser, null, true, false, false))); + void testStringFieldAsLength_CompilationErrorForStringFieldInArithmeticException() + throws Exception { + final JBBPParser parser = + JBBPParser.prepare("stringj str; stringj [str] strarr; stringj [_] all;"); + assertThrows(Exception.class, + () -> assertCompilation(makeSources(parser, null, false, false, false))); + assertThrows(Exception.class, + () -> assertCompilation(makeSources(parser, null, true, false, false))); } @Test - void testStringFieldInExpression_CompilationErrorForStringFieldInArithmeticException() throws Exception { - final JBBPParser parser = JBBPParser.prepare("stringj str; byte a; stringj [str+a] strarr; stringj [_] all;"); - assertThrows(Exception.class, () -> assertCompilation(makeSources(parser, null, false, false, false))); - assertThrows(Exception.class, () -> assertCompilation(makeSources(parser, null, true, false, false))); + void testStringFieldInExpression_CompilationErrorForStringFieldInArithmeticException() + throws Exception { + final JBBPParser parser = + JBBPParser.prepare("stringj str; byte a; stringj [str+a] strarr; stringj [_] all;"); + assertThrows(Exception.class, + () -> assertCompilation(makeSources(parser, null, false, false, false))); + assertThrows(Exception.class, + () -> assertCompilation(makeSources(parser, null, true, false, false))); } @Test @@ -372,29 +430,38 @@ void testPngParsing() throws Exception { @Test void testPrimitiveFieldsInExpression() throws Exception { - final JBBPParser parser = JBBPParser.prepare("long lfield; int ifield; byte bfield; ggg {ubyte ubfield; short shfield;} ushort ushfield; bit:4 bitfield; byte [bfield*ggg.shfield<> 3 << 2) >>> 1 + (13 - 1) / 2 + ((11 + 22) * 33 / 44 % 55) - (123 & 345 | 234 ^ ~123) & 255, "(11 * (8 - 7)) % 13 + ( 1234>>3<<2)>>>1 + (13 - 1) / 2 + ((11 + 22) * 33 / 44 % 55) - (123 & 345 | 234 ^ ~123) & 255"); + assertExpression((11 * (8 - 7)) % 13 + (1234 >> 3 << 2) >>> + 1 + (13 - 1) / 2 + ((11 + 22) * 33 / 44 % 55) - (123 & 345 | 234 ^ ~123) & 255, + "(11 * (8 - 7)) % 13 + ( 1234>>3<<2)>>>1 + (13 - 1) / 2 + ((11 + 22) * 33 / 44 % 55) - (123 & 345 | 234 ^ ~123) & 255"); } @Test public void testSynthesidExpression() throws Exception { final Random rnd = new Random(5111975); - final String[] operatorsTwo = new String[] {"-", "+", "*", "/", "%", ">>", ">>>", "<<", "^", "|", "&"}; + final String[] operatorsTwo = + new String[] {"-", "+", "*", "/", "%", ">>", ">>>", "<<", "^", "|", "&"}; final String[] operatorsOne = new String[] {"-", "+", "~"}; int rightCounter = 0; @@ -141,17 +147,21 @@ public void testSynthesidExpression() throws Exception { Object theInstance; final StringBuilder src = new StringBuilder(); try { - theInstance = compileAndMakeInstanceSrc("byte [" + expression + "] array;", " public static int makeExpressionResult(){ return " + expression + ";}", src); + theInstance = compileAndMakeInstanceSrc("byte [" + expression + "] array;", + " public static int makeExpressionResult(){ return " + expression + ";}", src); } catch (Exception ex) { fail("Can't compile : " + expression); return; } try { - final int etalon = (Integer) theInstance.getClass().getMethod("makeExpressionResult").invoke(null); + final int etalon = + (Integer) theInstance.getClass().getMethod("makeExpressionResult").invoke(null); if (etalon > 0 && etalon < 100000) { System.out.println("Testing expression : " + expression); - assertEquals(etalon, getField(callRead(theInstance, new JBBPBitInputStream(UNLIMITED_STREAM)), "array", byte[].class).length, src.toString()); + assertEquals(etalon, + getField(callRead(theInstance, new JBBPBitInputStream(UNLIMITED_STREAM)), "array", + byte[].class).length, src.toString()); rightCounter++; } } catch (InvocationTargetException ex) { diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJavaConverterReadWriteTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJavaConverterReadWriteTest.java index 5e83278c..9e6b92ab 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJavaConverterReadWriteTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJavaConverterReadWriteTest.java @@ -16,6 +16,19 @@ package com.igormaznitsa.jbbp.compiler.conversion; +import static com.igormaznitsa.jbbp.TestUtils.assertPngChunk; +import static com.igormaznitsa.jbbp.TestUtils.getField; +import static com.igormaznitsa.jbbp.TestUtils.getFieldThroughGetters; +import static com.igormaznitsa.jbbp.TestUtils.wavInt2Str; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + + import com.igormaznitsa.jbbp.JBBPCustomFieldTypeProcessor; import com.igormaznitsa.jbbp.JBBPParser; import com.igormaznitsa.jbbp.TestUtils; @@ -30,18 +43,14 @@ import com.igormaznitsa.jbbp.model.JBBPFieldInt; import com.igormaznitsa.jbbp.testaux.AbstractJBBPToJavaConverterTest; import com.igormaznitsa.jbbp.utils.ReflectUtils; -import org.apache.commons.io.IOUtils; -import org.junit.jupiter.api.Test; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; - -import static com.igormaznitsa.jbbp.TestUtils.*; -import static org.junit.jupiter.api.Assertions.*; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; /** * Test reading writing with converted classes from parser. @@ -49,35 +58,12 @@ public class JBBPToJavaConverterReadWriteTest extends AbstractJBBPToJavaConverterTest { private byte[] loadResource(final String name) throws Exception { - try(final InputStream result = this.getClass().getClassLoader().getResourceAsStream("com/igormaznitsa/jbbp/it/" + name)){ + try (final InputStream result = this.getClass().getClassLoader() + .getResourceAsStream("com/igormaznitsa/jbbp/it/" + name)) { return IOUtils.toByteArray(result); } } - public static class TestSuperclass { - public String str; - public String[] strarr; - public float flt; - public float[] fltarr; - public double dbl; - public double[] dblarr; - public char len; - - public class Ins { - public byte[] a; - public byte b; - public byte c; - - public class InsIns { - public byte a; - } - - public InsIns insins; - } - - public Ins[] ins; - } - @Test public void testReadWrite_ExtendsSuperClassAndUseItsFields() throws Exception { final JBBPParser parser = JBBPParser.prepare( @@ -100,9 +86,9 @@ public void testReadWrite_ExtendsSuperClassAndUseItsFields() throws Exception { this.printGeneratedClassText = true; - final Map superclasses = new HashMap<>(); - superclasses.put("ins",TestSuperclass.Ins.class.getCanonicalName()); - superclasses.put("ins.insins",TestSuperclass.Ins.InsIns.class.getCanonicalName()); + final Map superclasses = new HashMap<>(); + superclasses.put("ins", TestSuperclass.Ins.class.getCanonicalName()); + superclasses.put("ins.insins", TestSuperclass.Ins.InsIns.class.getCanonicalName()); final String thePackage = JBBPToJavaConverterReadWriteTest.class.getPackage().getName(); @@ -123,7 +109,7 @@ public void testReadWrite_ExtendsSuperClassAndUseItsFields() throws Exception { final Object instance = ReflectUtils.newInstance(classLoader.loadClass(fullClassName)); assertTrue(instance instanceof TestSuperclass); - final byte [] etalon = new byte[] { + final byte[] etalon = new byte[] { 0, 2, 49, 50, 1, 51, 1, 2, 3, 4, @@ -131,8 +117,8 @@ public void testReadWrite_ExtendsSuperClassAndUseItsFields() throws Exception { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 2, - 1,2, - 3,4,5 + 1, 2, + 3, 4, 5 }; callRead(instance, etalon); @@ -144,10 +130,11 @@ public void testReadWrite_ExtendsSuperClassAndUseItsFields() throws Exception { assertEquals(2.3879393E-38f, parsed.flt); assertArrayEquals(new float[] {6.301941E-36f, 1.661634E-33f}, parsed.fltarr); assertEquals(8.20788039913184E-304d, parsed.dbl); - assertArrayEquals(new double[] {4.0383818836028145E-265d, 1.9074368412237584E-226d}, parsed.dblarr); + assertArrayEquals(new double[] {4.0383818836028145E-265d, 1.9074368412237584E-226d}, + parsed.dblarr); assertEquals(1, parsed.ins.length); - assertArrayEquals(new byte[]{1,2}, parsed.ins[0].a); + assertArrayEquals(new byte[] {1, 2}, parsed.ins[0].a); assertEquals(3, parsed.ins[0].b); assertEquals(4, parsed.ins[0].c); assertEquals(5, parsed.ins[0].insins.a); @@ -160,13 +147,16 @@ public void testReaWrite_StructMappedToInterface_Array_GettersSettersOn() throws final JBBPParser parser = JBBPParser.prepare("z { x { y [_] { byte a;}}}"); final Map interfaceMap = new HashMap<>(); interfaceMap.put("z.x.y", ByteTestInterface.class.getCanonicalName()); - final String text = JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).setMainClassPackage(PACKAGE_NAME).setAddGettersSetters(true).setMapSubClassesInterfaces(interfaceMap).build().convert(); + final String text = JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME) + .setMainClassPackage(PACKAGE_NAME).setAddGettersSetters(true) + .setMapSubClassesInterfaces(interfaceMap).build().convert(); final String fullClassName = PACKAGE_NAME + '.' + CLASS_NAME; final ClassLoader classLoader = saveAndCompile(new JavaClassContent(fullClassName, text)); final Object instance = ReflectUtils.newInstance(classLoader.loadClass(fullClassName)); callRead(instance, new byte[] {0, 1, 2, 3, 4, 5}); - final ByteTestInterface[] data = getFieldThroughGetters(instance, "z.x.y", ByteTestInterface[].class); + final ByteTestInterface[] data = + getFieldThroughGetters(instance, "z.x.y", ByteTestInterface[].class); for (int i = 0; i < 6; i++) { assertEquals(i, data[i].getA()); } @@ -179,13 +169,16 @@ public void testReaWrite_StructMappedToInterface_NotArray_GettersSettersOn() thr final JBBPParser parser = JBBPParser.prepare("z { x { y { byte a;}}}"); final Map interfaceMap = new HashMap<>(); interfaceMap.put("z.x.y", ByteTestInterface.class.getCanonicalName()); - final String text = JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME).setMainClassPackage(PACKAGE_NAME).setAddGettersSetters(true).setMapSubClassesInterfaces(interfaceMap).build().convert(); + final String text = JBBPToJavaConverter.makeBuilder(parser).setMainClassName(CLASS_NAME) + .setMainClassPackage(PACKAGE_NAME).setAddGettersSetters(true) + .setMapSubClassesInterfaces(interfaceMap).build().convert(); final String fullClassName = PACKAGE_NAME + '.' + CLASS_NAME; final ClassLoader classLoader = saveAndCompile(new JavaClassContent(fullClassName, text)); final Object instance = ReflectUtils.newInstance(classLoader.loadClass(fullClassName)); callRead(instance, new byte[] {42}); - final ByteTestInterface data = getFieldThroughGetters(instance, "z.x.y", ByteTestInterface.class); + final ByteTestInterface data = + getFieldThroughGetters(instance, "z.x.y", ByteTestInterface.class); assertEquals(42, data.getA()); assertArrayEquals(new byte[] {42}, callWrite(instance)); @@ -197,7 +190,9 @@ public void testReadWrite_BooleanArrayWholeStream() throws Exception { assertNull(getField(instance, "boolarray", boolean[].class), "by default must be null"); final byte[] etalon = new byte[] {1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1}; callRead(instance, etalon.clone()); - assertArrayEquals(new boolean[] {true, false, true, true, false, true, true, true, false, false, false, true, true, true, true}, getField(instance, "boolarray", boolean[].class)); + assertArrayEquals( + new boolean[] {true, false, true, true, false, true, true, true, false, false, false, true, + true, true, true}, getField(instance, "boolarray", boolean[].class)); assertArrayEquals(etalon, callWrite(instance)); } @@ -221,7 +216,8 @@ public void testReadWite_Float_SingleValue() throws Exception { callRead(instance, etalon.clone()); - assertEquals(2.3879393E-38f, getField(instance, "value", Float.class).floatValue(), TestUtils.FLOAT_DELTA); + assertEquals(2.3879393E-38f, getField(instance, "value", Float.class).floatValue(), + TestUtils.FLOAT_DELTA); assertArrayEquals(etalon, callWrite(instance)); } @@ -234,7 +230,8 @@ public void testReadWite_FloatArrayWholeStream() throws Exception { callRead(instance, etalon.clone()); - assertArrayEquals(new float[] {2.3879393E-38f, 6.301941E-36f, 1.5417845E-33f, 2.6042668E-12f}, getField(instance, "floatarray", float[].class), TestUtils.FLOAT_DELTA); + assertArrayEquals(new float[] {2.3879393E-38f, 6.301941E-36f, 1.5417845E-33f, 2.6042668E-12f}, + getField(instance, "floatarray", float[].class), TestUtils.FLOAT_DELTA); assertArrayEquals(etalon, callWrite(instance)); } @@ -251,7 +248,8 @@ public void testReadWite_String_SingleValue() throws Exception { @Test public void testReadWite_Val_CalculatedLength() throws Exception { - final Object instance = compileAndMakeInstance("ubyte a; ubyte b; val:(a-b) c; val:(c+8) d; byte [d] data;"); + final Object instance = + compileAndMakeInstance("ubyte a; ubyte b; val:(a-b) c; val:(c+8) d; byte [d] data;"); final byte[] etalon = new byte[] {2, 8, 33, 44}; callRead(instance, etalon.clone()); @@ -280,7 +278,8 @@ public void testReadWite_StringArrayWholeStream() throws Exception { callRead(instance, etalon.clone()); - assertArrayEquals(new String[] {"ABC", null, "123"}, getField(instance, "strarray", String[].class)); + assertArrayEquals(new String[] {"ABC", null, "123"}, + getField(instance, "strarray", String[].class)); assertArrayEquals(etalon, callWrite(instance)); } @@ -291,7 +290,8 @@ public void testReadWite_Double_SingleValue() throws Exception { callRead(instance, etalon.clone()); - assertEquals(8.20788039913184E-304d, getField(instance, "value", Double.class).doubleValue(), TestUtils.FLOAT_DELTA); + assertEquals(8.20788039913184E-304d, getField(instance, "value", Double.class).doubleValue(), + TestUtils.FLOAT_DELTA); assertArrayEquals(etalon, callWrite(instance)); } @@ -300,11 +300,15 @@ public void testReadWite_DoubleArrayWholeStream() throws Exception { final Object instance = compileAndMakeInstance("doublej [_] doubleArray;"); assertNull(getField(instance, "doublearray", double[].class), "by default must be null"); - final byte[] etalon = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 22, 33, 44, 55, 66, 77, 3, 5, 9, 11, 33, 12, 10, 45}; + final byte[] etalon = + new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 22, 33, 44, 55, 66, 77, 3, 5, 9, 11, 33, 12, 10, + 45}; callRead(instance, etalon.clone()); - assertArrayEquals(new double[] {8.20788039913184E-304d, 2.494444648262547E-265d, 4.117024896955411E-294d}, getField(instance, "doublearray", double[].class), TestUtils.FLOAT_DELTA); + assertArrayEquals( + new double[] {8.20788039913184E-304d, 2.494444648262547E-265d, 4.117024896955411E-294d}, + getField(instance, "doublearray", double[].class), TestUtils.FLOAT_DELTA); assertArrayEquals(etalon, callWrite(instance)); } @@ -359,7 +363,8 @@ public void testReadWite_DoubleFloatFieldAsCounter() throws Exception { callRead(instance, data.clone()); - assertEquals(3.3d, getField(instance, "len", Double.class).doubleValue(), TestUtils.FLOAT_DELTA); + assertEquals(3.3d, getField(instance, "len", Double.class).doubleValue(), + TestUtils.FLOAT_DELTA); assertArrayEquals(new byte[] {1, 2, 3}, getField(instance, "data", byte[].class)); assertArrayEquals(data, callWrite(instance)); } @@ -373,14 +378,17 @@ public void testReadWite_DoubleFloatFieldAsCounter_Expression() throws Exception callRead(instance, data.clone()); - assertEquals(4.3d, getField(instance, "len", Double.class).doubleValue(), TestUtils.FLOAT_DELTA); + assertEquals(4.3d, getField(instance, "len", Double.class).doubleValue(), + TestUtils.FLOAT_DELTA); assertArrayEquals(new byte[] {1, 2}, getField(instance, "data", byte[].class)); assertArrayEquals(data, callWrite(instance)); } @Test public void testReadWriteWithOptionallyIgnoredStructure() throws Exception { - final Object instance = compileAndMakeInstance(PACKAGE_NAME + '.' + CLASS_NAME, "byte a; optional { byte b; }", JBBPParser.FLAG_SKIP_REMAINING_FIELDS_IF_EOF, null); + final Object instance = + compileAndMakeInstance(PACKAGE_NAME + '.' + CLASS_NAME, "byte a; optional { byte b; }", + JBBPParser.FLAG_SKIP_REMAINING_FIELDS_IF_EOF, null); callRead(instance, new byte[] {1}); assertEquals(1, getField(instance, "a", Byte.class).byteValue()); @@ -391,7 +399,9 @@ public void testReadWriteWithOptionallyIgnoredStructure() throws Exception { @Test public void testReadWriteWithOptionallyIgnoredStructureArray() throws Exception { - final Object instance = compileAndMakeInstance(PACKAGE_NAME + '.' + CLASS_NAME, "byte a; optional [_] { byte b; }", JBBPParser.FLAG_SKIP_REMAINING_FIELDS_IF_EOF, null); + final Object instance = + compileAndMakeInstance(PACKAGE_NAME + '.' + CLASS_NAME, "byte a; optional [_] { byte b; }", + JBBPParser.FLAG_SKIP_REMAINING_FIELDS_IF_EOF, null); callRead(instance, new byte[] {1}); assertEquals(1, getField(instance, "a", Byte.class).byteValue()); @@ -411,7 +421,8 @@ public void testReadWite_PNG() throws Exception { + " int crc;" + "}"); final byte[] pngEtalon = loadResource("picture.png"); - final String[] chunkNames = new String[] {"IHDR", "gAMA", "bKGD", "pHYs", "tIME", "tEXt", "IDAT", "IEND"}; + final String[] chunkNames = + new String[] {"IHDR", "gAMA", "bKGD", "pHYs", "tIME", "tEXt", "IDAT", "IEND"}; final int[] chunkSizes = new int[] {0x0D, 0x04, 0x06, 0x09, 0x07, 0x19, 0x0E5F, 0x00}; callRead(instance, pngEtalon.clone()); @@ -421,7 +432,9 @@ public void testReadWite_PNG() throws Exception { int i = 0; for (final Object chunk : getField(instance, "chunk", Object[].class)) { - assertPngChunk(chunkNames[i], chunkSizes[i], getField(chunk, "type", Integer.class), getField(chunk, "length", Integer.class), getField(chunk, "crc", Integer.class), getField(chunk, "data", byte[].class)); + assertPngChunk(chunkNames[i], chunkSizes[i], getField(chunk, "type", Integer.class), + getField(chunk, "length", Integer.class), getField(chunk, "crc", Integer.class), + getField(chunk, "data", byte[].class)); i++; } @@ -449,16 +462,19 @@ public void testReadWite_WAV() throws Exception { assertEquals(0x45564157, getField(instance, "format", Integer.class).intValue()); final Object[] subchunks = getField(instance, "subchunks", Object[].class); - assertEquals(subchunkNames.length, subchunks.length, "Number of parsed subchunks must be [" + subchunkNames.length + ']'); + assertEquals(subchunkNames.length, subchunks.length, + "Number of parsed subchunks must be [" + subchunkNames.length + ']'); int calculatedSize = 4; int index = 0; for (final Object subchunk : subchunks) { final String strChunkId = subchunkNames[index++]; - assertEquals(4, strChunkId.length(), "WAV subchunk must have 4 char length [" + strChunkId + ']'); + assertEquals(4, strChunkId.length(), + "WAV subchunk must have 4 char length [" + strChunkId + ']'); assertEquals(strChunkId, wavInt2Str(getField(subchunk, "subchunkid", Integer.class))); final int subChunkSize = getField(subchunk, "subchunksize", Integer.class); - assertEquals(subChunkSize, getField(subchunk, "data", byte[].class).length, "Data array must have the same size as described in sub-chunk size field"); + assertEquals(subChunkSize, getField(subchunk, "data", byte[].class).length, + "Data array must have the same size as described in sub-chunk size field"); calculatedSize += subChunkSize + 8 + (subChunkSize & 1); } @@ -538,7 +554,8 @@ public void testReadWrite_TGA_noColormap() throws Exception { callRead(instance, tgaEtalon.clone()); - assertEquals("Truevision(R) Sample Image".length(), getField(instance, "imageid", byte[].class).length); + assertEquals("Truevision(R) Sample Image".length(), + getField(instance, "imageid", byte[].class).length); assertEquals(128, getField(instance, "header.width", Character.class).charValue()); assertEquals(128, getField(instance, "header.height", Character.class).charValue()); assertEquals(8, getField(instance, "header.pixeldepth", Character.class).charValue()); @@ -590,11 +607,15 @@ public void testReadWrite_TGA_hasColormap() throws Exception { @Test public void testReadWrite_Z80v1() throws Exception { - final Object instance = compileAndMakeInstance("byte reg_a; byte reg_f; > 8) & 0xFF; int a = (value >> 16) & 0xFF;" - + " if (byteOrder == JBBPByteOrder.BIG_ENDIAN) {" - + " out.write(a); out.write(b); out.write(c);" - + " } else {" - + " out.write(c); out.write(b); out.write(a);" - + " }" - + " }" - + " public JBBPAbstractField readCustomFieldType(Object sourceStruct, JBBPBitInputStream inStream, JBBPFieldTypeParameterContainer typeParameterContainer, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean readWholeStream, int arraySize) throws IOException{" - + " if (sourceStruct == null) throw new Error(\"Struct must not be null\");" - + " if (readWholeStream || arraySize>=0) {" - + " if (readWholeStream) {" - + " if (extraValue!=3) throw new Error(\"must be 3\");" - + " com.igormaznitsa.jbbp.utils.DynamicIntBuffer buffer = new com.igormaznitsa.jbbp.utils.DynamicIntBuffer();" - + " while(inStream.hasAvailableData()){ buffer.write(readThree(inStream, typeParameterContainer.getByteOrder())); }" - + " return new JBBPFieldArrayInt(nullableNamedFieldInfo, buffer.toIntArray());" - + " } else {" - + " if (extraValue!=2) throw new Error(\"must be 2\");" - + " int [] arra = new int[arraySize];" - + " for (int i=0;i=0 || wholeArray) {" - + " if (wholeArray && extraValue!=3) throw new Error(\"wrong extra\");" - + " if (arraySize>=0 && extraValue!=2) throw new Error(\"wrong extra\");" - + " int [] arra = ((JBBPFieldArrayInt) fieldValue).getArray();" - + " int len = wholeArray ? arra.length : arraySize;" - + " for(int i=0;i> 8) & 0xFF; int a = (value >> 16) & 0xFF;" + + " if (byteOrder == JBBPByteOrder.BIG_ENDIAN) {" + + " out.write(a); out.write(b); out.write(c);" + + " } else {" + + " out.write(c); out.write(b); out.write(a);" + + " }" + + " }" + + + " public JBBPAbstractField readCustomFieldType(Object sourceStruct, JBBPBitInputStream inStream, JBBPFieldTypeParameterContainer typeParameterContainer, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean readWholeStream, int arraySize) throws IOException{" + + " if (sourceStruct == null) throw new Error(\"Struct must not be null\");" + + " if (readWholeStream || arraySize>=0) {" + + " if (readWholeStream) {" + + " if (extraValue!=3) throw new Error(\"must be 3\");" + + + " com.igormaznitsa.jbbp.utils.DynamicIntBuffer buffer = new com.igormaznitsa.jbbp.utils.DynamicIntBuffer();" + + + " while(inStream.hasAvailableData()){ buffer.write(readThree(inStream, typeParameterContainer.getByteOrder())); }" + + + " return new JBBPFieldArrayInt(nullableNamedFieldInfo, buffer.toIntArray());" + + " } else {" + + " if (extraValue!=2) throw new Error(\"must be 2\");" + + " int [] arra = new int[arraySize];" + + + " for (int i=0;i=0 || wholeArray) {" + + " if (wholeArray && extraValue!=3) throw new Error(\"wrong extra\");" + + " if (arraySize>=0 && extraValue!=2) throw new Error(\"wrong extra\");" + + " int [] arra = ((JBBPFieldArrayInt) fieldValue).getArray();" + + " int len = wholeArray ? arra.length : arraySize;" + + + " for(int i=0;i> 8) & 0xFF; int a = (value >> 16) & 0xFF;" - + " if (byteOrder == JBBPByteOrder.BIG_ENDIAN) {" - + " out.write(a); out.write(b); out.write(c);" - + " } else {" - + " out.write(c); out.write(b); out.write(a);" - + " }" - + " }" - + "public JBBPAbstractField readVarField(Object sourceStruct, JBBPBitInputStream inStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) throws IOException{" - + " if (extraValue!=12) throw new Error(\"wrong extra\");" - + " return new JBBPFieldInt(nullableNamedFieldInfo, readThree(inStream, byteOrder));" - + "}" - + "public JBBPAbstractArrayField readVarArray(Object sourceStruct, JBBPBitInputStream inStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean readWholeStream, int arraySize) throws IOException {" - + " if (sourceStruct == null) throw new Error(\"Struct must not be null\");" - + " if (extraValue!=4) throw new Error(\"wrong extra\");" - + " if (readWholeStream) {" - + " com.igormaznitsa.jbbp.utils.DynamicIntBuffer buffer = new com.igormaznitsa.jbbp.utils.DynamicIntBuffer();" - + " while(inStream.hasAvailableData()){ buffer.write(readThree(inStream, byteOrder)); }" - + " return new JBBPFieldArrayInt(nullableNamedFieldInfo, buffer.toIntArray());" - + " } else {" - + " int [] arra = new int[arraySize];" - + " for (int i=0;i array, JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, int arraySizeToWrite) throws IOException{" - + " if (sourceStruct == null) throw new Error(\"Struct must not be null\");" - + " if (extraValue!=4) throw new Error(\"wrong extra\");" - + " int [] arra = ((JBBPFieldArrayInt) array).getArray();" - + " int len = arraySizeToWrite < 0 ? arra.length : arraySizeToWrite;" - + " for(int i=0;i> 8) & 0xFF; int a = (value >> 16) & 0xFF;" + + " if (byteOrder == JBBPByteOrder.BIG_ENDIAN) {" + + " out.write(a); out.write(b); out.write(c);" + + " } else {" + + " out.write(c); out.write(b); out.write(a);" + + " }" + + " }" + + + "public JBBPAbstractField readVarField(Object sourceStruct, JBBPBitInputStream inStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue) throws IOException{" + + " if (extraValue!=12) throw new Error(\"wrong extra\");" + + + " return new JBBPFieldInt(nullableNamedFieldInfo, readThree(inStream, byteOrder));" + + "}" + + + "public JBBPAbstractArrayField readVarArray(Object sourceStruct, JBBPBitInputStream inStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean readWholeStream, int arraySize) throws IOException {" + + " if (sourceStruct == null) throw new Error(\"Struct must not be null\");" + + " if (extraValue!=4) throw new Error(\"wrong extra\");" + + " if (readWholeStream) {" + + + " com.igormaznitsa.jbbp.utils.DynamicIntBuffer buffer = new com.igormaznitsa.jbbp.utils.DynamicIntBuffer();" + + + " while(inStream.hasAvailableData()){ buffer.write(readThree(inStream, byteOrder)); }" + + + " return new JBBPFieldArrayInt(nullableNamedFieldInfo, buffer.toIntArray());" + + " } else {" + + " int [] arra = new int[arraySize];" + + + " for (int i=0;i array, JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, int arraySizeToWrite) throws IOException{" + + " if (sourceStruct == null) throw new Error(\"Struct must not be null\");" + + " if (extraValue!=4) throw new Error(\"wrong extra\");" + + " int [] arra = ((JBBPFieldArrayInt) array).getArray();" + + " int len = arraySizeToWrite < 0 ? arra.length : arraySizeToWrite;" + + " for(int i=0;i callRead(instance, etalon.clone())); @@ -879,7 +943,8 @@ public void testRead_ExpressionResult_NegativeExpression_NegativeResultNotAllowe @Test public void testRead_ExpressionResult_NegativeExpression_NegativeResultAsZero() throws Exception { - final Object instance = compileAndMakeInstance("byte len; byte [len-9] arr;", JBBPParser.FLAG_NEGATIVE_EXPRESSION_RESULT_AS_ZERO); + final Object instance = compileAndMakeInstance("byte len; byte [len-9] arr;", + JBBPParser.FLAG_NEGATIVE_EXPRESSION_RESULT_AS_ZERO); final byte[] etalon = new byte[] {8, 1, 2, 3, 4}; callRead(instance, etalon.clone()); assertEquals(8, getField(instance, "len", Byte.class).byteValue()); @@ -928,11 +993,16 @@ public void testReadWrite_NetPacket() throws Exception { final byte[] netPacketEtalon = loadResource("tcppacket.bin"); - final JBBPBitInputStream inStream = new JBBPBitInputStream(new ByteArrayInputStream(netPacketEtalon)); + final JBBPBitInputStream inStream = + new JBBPBitInputStream(new ByteArrayInputStream(netPacketEtalon)); callRead(ethernetHeader, inStream); - assertArrayEquals(new byte[] {(byte) 0x60, (byte) 0x67, (byte) 0x20, (byte) 0xE1, (byte) 0xF9, (byte) 0xF8}, getField(ethernetHeader, "macdestination", byte[].class), "Destination MAC"); - assertArrayEquals(new byte[] {(byte) 0x00, (byte) 0x26, (byte) 0x44, (byte) 0x74, (byte) 0xFE, (byte) 0x66}, getField(ethernetHeader, "macsource", byte[].class), "Source MAC"); + assertArrayEquals( + new byte[] {(byte) 0x60, (byte) 0x67, (byte) 0x20, (byte) 0xE1, (byte) 0xF9, (byte) 0xF8}, + getField(ethernetHeader, "macdestination", byte[].class), "Destination MAC"); + assertArrayEquals( + new byte[] {(byte) 0x00, (byte) 0x26, (byte) 0x44, (byte) 0x74, (byte) 0xFE, (byte) 0x66}, + getField(ethernetHeader, "macsource", byte[].class), "Source MAC"); final int etherTypeOrLength = getField(ethernetHeader, "ethertypeorlength", Character.class); assertEquals(0x800, etherTypeOrLength, "Ethernet type or length"); @@ -941,26 +1011,36 @@ public void testReadWrite_NetPacket() throws Exception { assertEquals(4, getField(ipHeader, "version", Byte.class).intValue(), "IP Version"); - final int internetHeaderLength = getField(ipHeader, "internetheaderlength", Byte.class).intValue(); + final int internetHeaderLength = + getField(ipHeader, "internetheaderlength", Byte.class).intValue(); assertEquals(5, internetHeaderLength, "Length of the IP header (in 4 byte items)"); - assertEquals(0, getField(ipHeader, "dscp", Byte.class).intValue(), "Differentiated Services Code Point"); - assertEquals(0, getField(ipHeader, "ecn", Byte.class).intValue(), "Explicit Congestion Notification"); + assertEquals(0, getField(ipHeader, "dscp", Byte.class).intValue(), + "Differentiated Services Code Point"); + assertEquals(0, getField(ipHeader, "ecn", Byte.class).intValue(), + "Explicit Congestion Notification"); final int ipTotalPacketLength = getField(ipHeader, "totalpacketlength", Character.class); - assertEquals(159, ipTotalPacketLength, "Entire IP packet size, including header and data, in bytes"); - assertEquals(30810, getField(ipHeader, "identification", Character.class).charValue(), "Identification"); + assertEquals(159, ipTotalPacketLength, + "Entire IP packet size, including header and data, in bytes"); + assertEquals(30810, getField(ipHeader, "identification", Character.class).charValue(), + "Identification"); - final int ipFlagsAndFragmentOffset = getField(ipHeader, "ipflagsandfragmentoffset", Character.class); + final int ipFlagsAndFragmentOffset = + getField(ipHeader, "ipflagsandfragmentoffset", Character.class); assertEquals(0x2, ipFlagsAndFragmentOffset >>> 13, "Extracted IP flags"); assertEquals(0x00, ipFlagsAndFragmentOffset & 0x1FFF, "Extracted Fragment offset"); assertEquals(0x39, getField(ipHeader, "ttl", Character.class).charValue(), "Time To Live"); - assertEquals(0x06, getField(ipHeader, "protocol", Character.class).charValue(), "Protocol (RFC-790)"); - assertEquals(0x7DB6, getField(ipHeader, "headerchecksum", Character.class).charValue(), "IPv4 Header Checksum"); - assertEquals(0xD5C7B393, getField(ipHeader, "sourceaddress", Integer.class).intValue(), "Source IP address"); - assertEquals(0xC0A80145, getField(ipHeader, "destinationaddress", Integer.class).intValue(), "Destination IP address"); + assertEquals(0x06, getField(ipHeader, "protocol", Character.class).charValue(), + "Protocol (RFC-790)"); + assertEquals(0x7DB6, getField(ipHeader, "headerchecksum", Character.class).charValue(), + "IPv4 Header Checksum"); + assertEquals(0xD5C7B393, getField(ipHeader, "sourceaddress", Integer.class).intValue(), + "Source IP address"); + assertEquals(0xC0A80145, getField(ipHeader, "destinationaddress", Integer.class).intValue(), + "Destination IP address"); assertEquals(0, getField(ipHeader, "options", byte[].class).length); @@ -970,7 +1050,8 @@ public void testReadWrite_NetPacket() throws Exception { assertEquals(40018, getField(tcpHeader, "sourceport", Character.class).charValue()); assertEquals(56344, getField(tcpHeader, "destinationport", Character.class).charValue()); assertEquals(0xE0084171, getField(tcpHeader, "sequencenumber", Integer.class).intValue()); - assertEquals(0xAB616F71, getField(tcpHeader, "acknowledgementnumber", Integer.class).intValue()); + assertEquals(0xAB616F71, + getField(tcpHeader, "acknowledgementnumber", Integer.class).intValue()); assertEquals(0, getField(tcpHeader, "fin", Byte.class).intValue()); assertEquals(0, getField(tcpHeader, "syn", Byte.class).intValue()); @@ -991,7 +1072,8 @@ public void testReadWrite_NetPacket() throws Exception { assertEquals(0, getField(tcpHeader, "option", byte[].class).length); - final int payloadDataLength = ipTotalPacketLength - (internetHeaderLength * 4) - (int) inStream.getCounter(); + final int payloadDataLength = + ipTotalPacketLength - (internetHeaderLength * 4) - (int) inStream.getCounter(); final byte[] data = inStream.readByteArray(payloadDataLength); assertEquals(119, data.length); @@ -1016,4 +1098,26 @@ public interface ByteTestInterface { byte getA(); } + public static class TestSuperclass { + public String str; + public String[] strarr; + public float flt; + public float[] fltarr; + public double dbl; + public double[] dblarr; + public char len; + public Ins[] ins; + + public class Ins { + public byte[] a; + public byte b; + public byte c; + public InsIns insins; + + public class InsIns { + public byte a; + } + } + } + } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/ParserToJBBPToJavaClassConverterJBBPFlagsTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/ParserToJBBPToJavaClassConverterJBBPFlagsTest.java index de9d7c85..fe27b911 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/ParserToJBBPToJavaClassConverterJBBPFlagsTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/ParserToJBBPToJavaClassConverterJBBPFlagsTest.java @@ -16,16 +16,16 @@ package com.igormaznitsa.jbbp.compiler.conversion; -import com.igormaznitsa.jbbp.JBBPParser; -import com.igormaznitsa.jbbp.testaux.AbstractJBBPToJavaConverterTest; -import org.junit.jupiter.api.Test; - -import java.io.EOFException; - import static com.igormaznitsa.jbbp.TestUtils.getField; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; + +import com.igormaznitsa.jbbp.JBBPParser; +import com.igormaznitsa.jbbp.testaux.AbstractJBBPToJavaConverterTest; +import java.io.EOFException; +import org.junit.jupiter.api.Test; + /** * Test parser flags for converted sources. */ @@ -41,7 +41,8 @@ public void testFlag_SkipRemainingFieldsIfEOF() throws Exception { } catch (EOFException ex) { } - instance = compileAndMakeInstance("byte a; byte b;", JBBPParser.FLAG_SKIP_REMAINING_FIELDS_IF_EOF); + instance = + compileAndMakeInstance("byte a; byte b;", JBBPParser.FLAG_SKIP_REMAINING_FIELDS_IF_EOF); try { callRead(instance, new byte[] {11}); assertEquals(11, getField(instance, "a", Byte.class).intValue()); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/RandomAutoTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/RandomAutoTest.java index a7d5f3fa..03e0f11e 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/RandomAutoTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/RandomAutoTest.java @@ -1,63 +1,22 @@ package com.igormaznitsa.jbbp.compiler.conversion; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + + import com.igormaznitsa.jbbp.io.JBBPBitNumber; import com.igormaznitsa.jbbp.io.JBBPByteOrder; import com.igormaznitsa.jbbp.testaux.AbstractJBBPToJavaConverterTest; import com.igormaznitsa.jbbp.utils.JBBPDslBuilder; -import org.junit.jupiter.api.Test; - import java.util.ArrayList; import java.util.List; import java.util.Random; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; public class RandomAutoTest extends AbstractJBBPToJavaConverterTest { private final Random RND = new Random(12345); - private static class StructLen { - final int arrayLength; - - int bitLength = 0; - - StructLen() { - this(1); - } - - StructLen(final int arrayLength) { - this.arrayLength = arrayLength; - } - - void add(final int bitLength) { - this.bitLength += bitLength; - } - - int make() { - return this.arrayLength * bitLength; - } - - } - - static class Result { - final String script; - final int bitLength; - final int fieldsNumber; - final int structNumber; - final int booleanDataItemCounter; - final long typeFlags; - - Result(final String script, final int bitLength, final int fieldsNumber, final int structNumber, final int booleanDtaItemCounter, final long typeFlags) { - this.script = script; - this.bitLength = bitLength; - this.fieldsNumber = fieldsNumber; - this.structNumber = structNumber; - this.booleanDataItemCounter = booleanDtaItemCounter; - this.typeFlags = typeFlags; - } - } - int makeArrayLengthNumber() { return RND.nextInt(16) + 1; } @@ -93,8 +52,8 @@ String makeRndName() { String genRandomString(final int length) { final StringBuilder builder = new StringBuilder(length); - for(int i=0;i new JBBPExpressionEvaluator(" 1 334", null, null)); + assertThrows(JBBPCompilationException.class, + () -> new JBBPExpressionEvaluator(" 1 334", null, null)); } @Test public void testExpression_Error_OnlyBrackets() { - assertThrows(JBBPCompilationException.class, () -> new JBBPExpressionEvaluator(" ( ( ( ( ) )) ) ", null, null)); + assertThrows(JBBPCompilationException.class, + () -> new JBBPExpressionEvaluator(" ( ( ( ( ) )) ) ", null, null)); } @Test public void testExpression_Error_NonClosedBracket() { - assertThrows(JBBPCompilationException.class, () -> new JBBPExpressionEvaluator("(34+45 ", null, null)); + assertThrows(JBBPCompilationException.class, + () -> new JBBPExpressionEvaluator("(34+45 ", null, null)); } @Test public void testExpression_Error_NonOpenedBracket() { - assertThrows(JBBPCompilationException.class, () -> new JBBPExpressionEvaluator("34+45) ", null, null)); + assertThrows(JBBPCompilationException.class, + () -> new JBBPExpressionEvaluator("34+45) ", null, null)); } @Test public void testExpression_Error_Spaces() { - assertThrows(JBBPCompilationException.class, () -> new JBBPExpressionEvaluator(" ", null, null)); + assertThrows(JBBPCompilationException.class, + () -> new JBBPExpressionEvaluator(" ", null, null)); } @Test @@ -70,72 +77,86 @@ public void testExpression_Error_Empty() { @Test public void testExpression_Error_OnlyUnaryPlus() { - assertThrows(JBBPCompilationException.class, () -> new JBBPExpressionEvaluator("+", null, null)); + assertThrows(JBBPCompilationException.class, + () -> new JBBPExpressionEvaluator("+", null, null)); } @Test public void testExpression_Error_OnlyUnaryMinus() { - assertThrows(JBBPCompilationException.class, () -> new JBBPExpressionEvaluator("-", null, null)); + assertThrows(JBBPCompilationException.class, + () -> new JBBPExpressionEvaluator("-", null, null)); } @Test public void testExpression_Error_OnlyNot() { - assertThrows(JBBPCompilationException.class, () -> new JBBPExpressionEvaluator("~", null, null)); + assertThrows(JBBPCompilationException.class, + () -> new JBBPExpressionEvaluator("~", null, null)); } @Test public void testExpression_Error_WrongFirstUnaryOperator() { - assertThrows(JBBPCompilationException.class, () -> new JBBPExpressionEvaluator("%345", null, null)); + assertThrows(JBBPCompilationException.class, + () -> new JBBPExpressionEvaluator("%345", null, null)); } @Test public void testExpression_Error_WrongUnaryOperator() { - assertThrows(JBBPCompilationException.class, () -> new JBBPExpressionEvaluator("222%%345", null, null)); + assertThrows(JBBPCompilationException.class, + () -> new JBBPExpressionEvaluator("222%%345", null, null)); } @Test public void testExpression_Error_OnlyNonUnaryOperator() { - assertThrows(JBBPCompilationException.class, () -> new JBBPExpressionEvaluator("*", null, null)); + assertThrows(JBBPCompilationException.class, + () -> new JBBPExpressionEvaluator("*", null, null)); } @Test public void testExpression_Error_MulWithoutSecondArgument() { - assertThrows(JBBPEvalException.class, () -> new JBBPExpressionEvaluator("123*", null, null).eval(null, 0, null, null)); + assertThrows(JBBPEvalException.class, + () -> new JBBPExpressionEvaluator("123*", null, null).eval(null, 0, null, null)); } @Test public void testExpression_Error_SubWithoutSecondArgument() { - assertThrows(JBBPEvalException.class, () -> new JBBPExpressionEvaluator("123-", null, null).eval(null, 0, null, null)); + assertThrows(JBBPEvalException.class, + () -> new JBBPExpressionEvaluator("123-", null, null).eval(null, 0, null, null)); } @Test public void testExpression_Error_AddWithoutSecondArgument() { - assertThrows(JBBPEvalException.class, () -> new JBBPExpressionEvaluator("123+", null, null).eval(null, 0, null, null)); + assertThrows(JBBPEvalException.class, + () -> new JBBPExpressionEvaluator("123+", null, null).eval(null, 0, null, null)); } @Test public void testExpression_Error_ModWithoutSecondArgument() { - assertThrows(JBBPEvalException.class, () -> new JBBPExpressionEvaluator("123%", null, null).eval(null, 0, null, null)); + assertThrows(JBBPEvalException.class, + () -> new JBBPExpressionEvaluator("123%", null, null).eval(null, 0, null, null)); } @Test public void testExpression_Error_DivWithoutSecondArgument() { - assertThrows(JBBPEvalException.class, () -> new JBBPExpressionEvaluator("123/", null, null).eval(null, 0, null, null)); + assertThrows(JBBPEvalException.class, + () -> new JBBPExpressionEvaluator("123/", null, null).eval(null, 0, null, null)); } @Test public void testExpression_Error_AndWithoutSecondArgument() { - assertThrows(JBBPEvalException.class, () -> new JBBPExpressionEvaluator("123&", null, null).eval(null, 0, null, null)); + assertThrows(JBBPEvalException.class, + () -> new JBBPExpressionEvaluator("123&", null, null).eval(null, 0, null, null)); } @Test public void testExpression_Error_OrWithoutSecondArgument() { - assertThrows(JBBPEvalException.class, () -> new JBBPExpressionEvaluator("123|", null, null).eval(null, 0, null, null)); + assertThrows(JBBPEvalException.class, + () -> new JBBPExpressionEvaluator("123|", null, null).eval(null, 0, null, null)); } @Test public void testExpression_Error_XorWithoutSecondArgument() { - assertThrows(JBBPEvalException.class, () -> new JBBPExpressionEvaluator("123^", null, null).eval(null, 0, null, null)); + assertThrows(JBBPEvalException.class, + () -> new JBBPExpressionEvaluator("123^", null, null).eval(null, 0, null, null)); } @Test @@ -163,7 +184,9 @@ public void testExpression_Variable() { JBBPExpressionEvaluator expr = new JBBPExpressionEvaluator("hello", list, compiled); final JBBPNamedNumericFieldMap map = new JBBPNamedNumericFieldMap(); map.putField(new JBBPFieldInt(info, 1234)); - assertEquals(1234, expr.eval(null, 0, JBBPCompiledBlock.prepare().setCompiledData(compiled).setNamedFieldData(list).setSource("no source").build(), map)); + assertEquals(1234, expr.eval(null, 0, + JBBPCompiledBlock.prepare().setCompiledData(compiled).setNamedFieldData(list) + .setSource("no source").build(), map)); } @Test @@ -172,17 +195,24 @@ public void testExpression_ExpressionWithVariable() { final byte[] compiled = new byte[] {JBBPCompiler.CODE_INT | JBBPCompiler.FLAG_NAMED}; final List list = Collections.singletonList(info); - JBBPExpressionEvaluator expr = new JBBPExpressionEvaluator("2*hello*6/4+3*2-11%3&hello-~hello", list, compiled); + JBBPExpressionEvaluator expr = + new JBBPExpressionEvaluator("2*hello*6/4+3*2-11%3&hello-~hello", list, compiled); final JBBPNamedNumericFieldMap map = new JBBPNamedNumericFieldMap(); map.putField(new JBBPFieldInt(info, 8)); - assertEquals(2 * 8 * 6 / 4 + 3 * 2 - 11 % 3 & 8 - ~8, expr.eval(null, 0, JBBPCompiledBlock.prepare().setCompiledData(compiled).setNamedFieldData(list).setSource("no source").build(), map)); + assertEquals(2 * 8 * 6 / 4 + 3 * 2 - 11 % 3 & 8 - ~8, expr.eval(null, 0, + JBBPCompiledBlock.prepare().setCompiledData(compiled).setNamedFieldData(list) + .setSource("no source").build(), map)); } @Test public void testExpression_MustNotThrowStackOverfow() throws Exception { - JBBPExpressionEvaluator expr = new JBBPExpressionEvaluator("1+(2+(3+(4+(5+(6+(7+(8+(9+(10+(11+(12+(13+(14+(15+(16+(17+(18+(19+(20*2)))))))))))))))))))", null, null); + JBBPExpressionEvaluator expr = new JBBPExpressionEvaluator( + "1+(2+(3+(4+(5+(6+(7+(8+(9+(10+(11+(12+(13+(14+(15+(16+(17+(18+(19+(20*2)))))))))))))))))))", + null, null); assertEquals(21, expr.getMaxStackDepth()); - assertEquals(1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + (10 + (11 + (12 + (13 + (14 + (15 + (16 + (17 + (18 + (19 + (20 * 2))))))))))))))))))), expr.eval(null, 0, null, null)); + assertEquals(1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + + (9 + (10 + (11 + (12 + (13 + (14 + (15 + (16 + (17 + (18 + (19 + (20 * 2))))))))))))))))))), + expr.eval(null, 0, null, null)); } @Test @@ -271,7 +301,9 @@ public void testExpression_SingleCharNamedVar_Mul() { assertEquals(2, expr.getMaxStackDepth()); final JBBPNamedNumericFieldMap map = new JBBPNamedNumericFieldMap(); map.putField(new JBBPFieldInt(varA, 123)); - assertEquals(123 * 2, expr.eval(null, 0, JBBPCompiledBlock.prepare().setCompiledData(compiled).setNamedFieldData(list).setSource("no source").build(), map)); + assertEquals(123 * 2, expr.eval(null, 0, + JBBPCompiledBlock.prepare().setCompiledData(compiled).setNamedFieldData(list) + .setSource("no source").build(), map)); } @Test @@ -402,9 +434,11 @@ public void testExpression_TestComplexUnaryInConstantExpression() { @Test public void testExpression_ComplexLogicalWithConstants() { - JBBPExpressionEvaluator expr = new JBBPExpressionEvaluator("~23*-1234&~123/(34+89)|3232%56^~2234", null, null); + JBBPExpressionEvaluator expr = + new JBBPExpressionEvaluator("~23*-1234&~123/(34+89)|3232%56^~2234", null, null); assertEquals(4, expr.getMaxStackDepth()); - assertEquals((~23 * -1234 & ~123 / (34 + 89)) | (3232 % 56 ^ ~2234), expr.eval(null, 0, null, null)); + assertEquals((~23 * -1234 & ~123 / (34 + 89)) | (3232 % 56 ^ ~2234), + expr.eval(null, 0, null, null)); } @Test @@ -416,7 +450,8 @@ public void testExpression_LeftShift() { @Test public void testExpression_LeftShift_ErrorWithoutSecondArgument() { - assertThrows(JBBPEvalException.class, () -> new JBBPExpressionEvaluator("1234<<", null, null).eval(null, 0, null, null)); + assertThrows(JBBPEvalException.class, + () -> new JBBPExpressionEvaluator("1234<<", null, null).eval(null, 0, null, null)); } @Test @@ -428,7 +463,8 @@ public void testExpression_RightShift() { @Test public void testExpression_RightShift_ErrorWithoutSecondArgument() { - assertThrows(JBBPEvalException.class, () -> new JBBPExpressionEvaluator("1234 >>", null, null).eval(null, 0, null, null)); + assertThrows(JBBPEvalException.class, + () -> new JBBPExpressionEvaluator("1234 >>", null, null).eval(null, 0, null, null)); } @Test @@ -447,40 +483,47 @@ public void testExpression_RightSignShiftWithInversion() { @Test public void testExpression_RightSignShift_ErrorWithoutSecondArgument() { - assertThrows(JBBPEvalException.class, () -> new JBBPExpressionEvaluator("1234 >>>", null, null).eval(null, 0, null, null)); + assertThrows(JBBPEvalException.class, + () -> new JBBPExpressionEvaluator("1234 >>>", null, null).eval(null, 0, null, null)); } @Test public void testExpression_ReverseByte() { - JBBPExpressionEvaluator expr = new JBBPExpressionEvaluator("((($v*2050&139536)|($v*32800&558144))*65793>>16)&255", null, null); + JBBPExpressionEvaluator expr = + new JBBPExpressionEvaluator("((($v*2050&139536)|($v*32800&558144))*65793>>16)&255", null, + null); assertEquals(3, expr.getMaxStackDepth()); - assertEquals(JBBPUtils.reverseBitsInByte((byte) 123) & 0xFF, expr.eval(null, 0, null, new JBBPNamedNumericFieldMap((fieldName, numericFieldMap, compiledBlock) -> { - if ("v".equals(fieldName)) { - return 123; - } else { - fail("Unexpected field [" + fieldName + ']'); - return 0; - } - }))); + assertEquals(JBBPUtils.reverseBitsInByte((byte) 123) & 0xFF, expr.eval(null, 0, null, + new JBBPNamedNumericFieldMap((fieldName, numericFieldMap, compiledBlock) -> { + if ("v".equals(fieldName)) { + return 123; + } else { + fail("Unexpected field [" + fieldName + ']'); + return 0; + } + }))); } @Test public void testExpression_CheckExternalField() { final int value = 1234; - final JBBPNamedNumericFieldMap map = new JBBPNamedNumericFieldMap((fieldName, numericFieldMap, compiledBlock) -> { - if (fieldName.equals("value")) { - return value; - } - assertNotNull(numericFieldMap); - assertNotNull(compiledBlock); - fail("Unexpected request for value [" + fieldName + ']'); - return -1; - }); + final JBBPNamedNumericFieldMap map = + new JBBPNamedNumericFieldMap((fieldName, numericFieldMap, compiledBlock) -> { + if (fieldName.equals("value")) { + return value; + } + assertNotNull(numericFieldMap); + assertNotNull(compiledBlock); + fail("Unexpected request for value [" + fieldName + ']'); + return -1; + }); final List list = new ArrayList<>(); final byte[] compiled = new byte[] {0}; - final JBBPCompiledBlock compiledBlock = JBBPCompiledBlock.prepare().setCompiledData(compiled).setSource("none").setNamedFieldData(list).build(); + final JBBPCompiledBlock compiledBlock = + JBBPCompiledBlock.prepare().setCompiledData(compiled).setSource("none") + .setNamedFieldData(list).build(); JBBPExpressionEvaluator expr = new JBBPExpressionEvaluator("123*($value-45/3)", list, compiled); assertEquals(4, expr.getMaxStackDepth()); @@ -496,25 +539,30 @@ public void testExpression_NotAfterMinus() throws Exception { @Test public void testExpression_CheckExternalFieldAndStreamOffset() throws Exception { final int value = 1234; - final JBBPNamedNumericFieldMap map = new JBBPNamedNumericFieldMap((fieldName, numericFieldMap, compiledBlock) -> { - if (fieldName.equals("value")) { - return value; - } - assertNotNull(numericFieldMap); - assertNotNull(compiledBlock); - fail("Unexpected request for value [" + fieldName + ']'); - return -1; - }); + final JBBPNamedNumericFieldMap map = + new JBBPNamedNumericFieldMap((fieldName, numericFieldMap, compiledBlock) -> { + if (fieldName.equals("value")) { + return value; + } + assertNotNull(numericFieldMap); + assertNotNull(compiledBlock); + fail("Unexpected request for value [" + fieldName + ']'); + return -1; + }); final List list = new ArrayList<>(); final byte[] compiled = new byte[] {0}; - final JBBPCompiledBlock compiledBlock = JBBPCompiledBlock.prepare().setCompiledData(compiled).setSource("none").setNamedFieldData(list).build(); + final JBBPCompiledBlock compiledBlock = + JBBPCompiledBlock.prepare().setCompiledData(compiled).setSource("none") + .setNamedFieldData(list).build(); - JBBPExpressionEvaluator expr = new JBBPExpressionEvaluator("123*($value-45/3)*$$", list, compiled); + JBBPExpressionEvaluator expr = + new JBBPExpressionEvaluator("123*($value-45/3)*$$", list, compiled); assertEquals(4, expr.getMaxStackDepth()); - final JBBPBitInputStream inStream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5})); + final JBBPBitInputStream inStream = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5})); inStream.read(); inStream.read(); inStream.read(); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/varlen/JBBPOnlyFieldEvaluatorTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/varlen/JBBPOnlyFieldEvaluatorTest.java index 7b9f0160..b9fe0bd0 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/varlen/JBBPOnlyFieldEvaluatorTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/varlen/JBBPOnlyFieldEvaluatorTest.java @@ -16,19 +16,20 @@ package com.igormaznitsa.jbbp.compiler.varlen; -import com.igormaznitsa.jbbp.JBBPExternalValueProvider; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.fail; + + import com.igormaznitsa.jbbp.JBBPNamedNumericFieldMap; import com.igormaznitsa.jbbp.compiler.JBBPCompiledBlock; import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import com.igormaznitsa.jbbp.io.JBBPBitInputStream; import com.igormaznitsa.jbbp.model.JBBPFieldInt; -import org.junit.jupiter.api.Test; - import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class JBBPOnlyFieldEvaluatorTest { @@ -44,7 +45,9 @@ public void testNumericValue() { list.add(nameInfo); final byte[] compiled = new byte[] {0}; - final JBBPCompiledBlock compiledBlock = JBBPCompiledBlock.prepare().setCompiledData(compiled).setSource("none").setNamedFieldData(list).build(); + final JBBPCompiledBlock compiledBlock = + JBBPCompiledBlock.prepare().setCompiledData(compiled).setSource("none") + .setNamedFieldData(list).build(); JBBPOnlyFieldEvaluator expr = new JBBPOnlyFieldEvaluator(null, 0); assertEquals(value, expr.eval(null, 0, compiledBlock, map)); @@ -53,20 +56,23 @@ public void testNumericValue() { @Test public void testExternalValue() { final int value = 1234; - final JBBPNamedNumericFieldMap map = new JBBPNamedNumericFieldMap((fieldName, numericFieldMap, compiledBlock) -> { - if (fieldName.equals("value")) { - return value; - } - assertNotNull(numericFieldMap); - assertNotNull(compiledBlock); - fail("Unexpected request for value [" + fieldName + ']'); - return -1; - }); + final JBBPNamedNumericFieldMap map = + new JBBPNamedNumericFieldMap((fieldName, numericFieldMap, compiledBlock) -> { + if (fieldName.equals("value")) { + return value; + } + assertNotNull(numericFieldMap); + assertNotNull(compiledBlock); + fail("Unexpected request for value [" + fieldName + ']'); + return -1; + }); final List list = new ArrayList<>(); final byte[] compiled = new byte[] {0}; - final JBBPCompiledBlock compiledBlock = JBBPCompiledBlock.prepare().setCompiledData(compiled).setSource("none").setNamedFieldData(list).build(); + final JBBPCompiledBlock compiledBlock = + JBBPCompiledBlock.prepare().setCompiledData(compiled).setSource("none") + .setNamedFieldData(list).build(); JBBPOnlyFieldEvaluator expr = new JBBPOnlyFieldEvaluator("value", -1); assertEquals(value, expr.eval(null, 0, compiledBlock, map)); @@ -75,20 +81,23 @@ public void testExternalValue() { @Test public void testExternalValueNamedAsFirstCharDollar() { final int value = 1234; - final JBBPNamedNumericFieldMap map = new JBBPNamedNumericFieldMap((fieldName, numericFieldMap, compiledBlock) -> { - if (fieldName.equals("$value")) { - return value; - } - assertNotNull(numericFieldMap); - assertNotNull(compiledBlock); - fail("Unexpected request for value [" + fieldName + ']'); - return -1; - }); + final JBBPNamedNumericFieldMap map = + new JBBPNamedNumericFieldMap((fieldName, numericFieldMap, compiledBlock) -> { + if (fieldName.equals("$value")) { + return value; + } + assertNotNull(numericFieldMap); + assertNotNull(compiledBlock); + fail("Unexpected request for value [" + fieldName + ']'); + return -1; + }); final List list = new ArrayList<>(); final byte[] compiled = new byte[] {0}; - final JBBPCompiledBlock compiledBlock = JBBPCompiledBlock.prepare().setCompiledData(compiled).setSource("none").setNamedFieldData(list).build(); + final JBBPCompiledBlock compiledBlock = + JBBPCompiledBlock.prepare().setCompiledData(compiled).setSource("none") + .setNamedFieldData(list).build(); JBBPOnlyFieldEvaluator expr = new JBBPOnlyFieldEvaluator("$value", -1); assertEquals(value, expr.eval(null, 0, compiledBlock, map)); @@ -99,11 +108,14 @@ public void testCounterOfStreamAsParameter() throws Exception { final List list = new ArrayList<>(); final byte[] compiled = new byte[] {0}; - final JBBPCompiledBlock compiledBlock = JBBPCompiledBlock.prepare().setCompiledData(compiled).setSource("none").setNamedFieldData(list).build(); + final JBBPCompiledBlock compiledBlock = + JBBPCompiledBlock.prepare().setCompiledData(compiled).setSource("none") + .setNamedFieldData(list).build(); JBBPOnlyFieldEvaluator expr = new JBBPOnlyFieldEvaluator("$", -1); - final JBBPBitInputStream inStream = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5})); + final JBBPBitInputStream inStream = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5})); inStream.read(); inStream.read(); inStream.read(); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/exceptions/JBBPMapperExceptionTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/exceptions/JBBPMapperExceptionTest.java index d250dcb6..c9c7385a 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/exceptions/JBBPMapperExceptionTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/exceptions/JBBPMapperExceptionTest.java @@ -16,17 +16,20 @@ package com.igormaznitsa.jbbp.exceptions; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + + import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import com.igormaznitsa.jbbp.model.JBBPAbstractField; import com.igormaznitsa.jbbp.model.JBBPFieldByte; -import org.junit.jupiter.api.Test; - import java.lang.reflect.Field; - -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class JBBPMapperExceptionTest { - private final JBBPAbstractField field = new JBBPFieldByte(new JBBPNamedFieldInfo("test.test", "test", 0), (byte) 1); + private final JBBPAbstractField field = + new JBBPFieldByte(new JBBPNamedFieldInfo("test.test", "test", 0), (byte) 1); private final Exception cause = new Exception(); private final String message = "Message"; @@ -37,7 +40,8 @@ public void testConstructorAndGetters() throws Exception { assertNotNull(clazzField); - final JBBPMapperException ex = new JBBPMapperException(this.message, this.field, clazz, clazzField, this.cause); + final JBBPMapperException ex = + new JBBPMapperException(this.message, this.field, clazz, clazzField, this.cause); assertSame(this.message, ex.getMessage()); assertSame(this.field, ex.getField()); assertSame(clazz, ex.getMappingClass()); @@ -49,7 +53,8 @@ public void testToString() throws Exception { final Class clazz = Integer.class; final Field clazzField = Integer.class.getDeclaredFields()[0]; assertNotNull(clazzField); - final JBBPMapperException ex = new JBBPMapperException(this.message, this.field, clazz, clazzField, this.cause); + final JBBPMapperException ex = + new JBBPMapperException(this.message, this.field, clazz, clazzField, this.cause); assertTrue(ex.toString().contains(clazzField.toString())); } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/io/BitIOCommonTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/io/BitIOCommonTest.java index ca030c18..8b5c9394 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/io/BitIOCommonTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/io/BitIOCommonTest.java @@ -16,13 +16,13 @@ package com.igormaznitsa.jbbp.io; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.Random; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; public class BitIOCommonTest { @@ -51,15 +51,17 @@ public void testWriteReadString() throws Exception { final byte[] writtenBig = buffBig.toByteArray(); final byte[] writtenLittl = buffLittl.toByteArray(); - final String restoredBig = new JBBPBitInputStream(new ByteArrayInputStream(writtenBig)).readString(JBBPByteOrder.BIG_ENDIAN); - final String restoredLittl = new JBBPBitInputStream(new ByteArrayInputStream(writtenLittl)).readString(JBBPByteOrder.LITTLE_ENDIAN); + final String restoredBig = new JBBPBitInputStream(new ByteArrayInputStream(writtenBig)) + .readString(JBBPByteOrder.BIG_ENDIAN); + final String restoredLittl = new JBBPBitInputStream(new ByteArrayInputStream(writtenLittl)) + .readString(JBBPByteOrder.LITTLE_ENDIAN); assertEquals(text, restoredBig, "Iteration#" + i); assertEquals(text, restoredLittl, "Iteration#" + i); - buffer.append((char)('A' + rnd.nextInt(11))); - buffer.append((char)('Б' + rnd.nextInt(22))); + buffer.append((char) ('A' + rnd.nextInt(11))); + buffer.append((char) ('Б' + rnd.nextInt(22))); } } @@ -90,7 +92,8 @@ public void testWriteRead() throws Exception { out.close(); - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(buff.toByteArray())); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(buff.toByteArray())); for (int i = 0; i < LEN; i++) { assertEquals(array[i] & 0xFF, in.readBits(JBBPBitNumber.decode(len[i])), "Index i=" + i); } @@ -129,7 +132,8 @@ public void testWriteRead_MSB0() throws Exception { out.close(); - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(buff.toByteArray()), JBBPBitOrder.MSB0); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(buff.toByteArray()), JBBPBitOrder.MSB0); for (int i = 0; i < LEN; i++) { assertEquals(array[i] & 0xFF, in.readBits(JBBPBitNumber.decode(len[i])), "Index i=" + i); } @@ -154,7 +158,8 @@ public void testWriteRead_NotFullByteAsLSB0AndReadAsMSB0() throws Exception { out.writeBits(0, JBBPBitNumber.BITS_1); out.flush(); - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(buffer.toByteArray()), JBBPBitOrder.MSB0); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(buffer.toByteArray()), JBBPBitOrder.MSB0); assertEquals(0, in.readBits(JBBPBitNumber.BITS_1)); assertEquals(0, in.readBits(JBBPBitNumber.BITS_1)); assertEquals(0, in.readBits(JBBPBitNumber.BITS_1)); @@ -195,7 +200,8 @@ public void testWriteRead_LSB0() throws Exception { out.close(); - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(buff.toByteArray()), JBBPBitOrder.LSB0); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(buff.toByteArray()), JBBPBitOrder.LSB0); for (int i = 0; i < LEN; i++) { assertEquals(array[i] & 0xFF, in.readBits(JBBPBitNumber.decode(len[i])), "Index i=" + i); } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPBitInputStreamTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPBitInputStreamTest.java index 4ea7a7d2..c5170ddc 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPBitInputStreamTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPBitInputStreamTest.java @@ -33,8 +33,10 @@ public class JBBPBitInputStreamTest { - private static final String TEST_BYTES = "01001100_01110000_11110000_01111100_00001111_11000000_01100111_00000000_10011111"; - private static final String TEST_BYTES_EXTRABIT = "0 01001100_01110000_11110000_01111100_00001111_11000000_01100111_00000000_10011111"; + private static final String TEST_BYTES = + "01001100_01110000_11110000_01111100_00001111_11000000_01100111_00000000_10011111"; + private static final String TEST_BYTES_EXTRABIT = + "0 01001100_01110000_11110000_01111100_00001111_11000000_01100111_00000000_10011111"; private static byte[] intArrayToByteArray(final int... array) { final byte[] bytearray = new byte[array.length]; @@ -52,27 +54,32 @@ private static JBBPBitInputStream asInputStream(final int... array) { } private static JBBPBitInputStream asInputStreamMSB0(final int... array) { - return new JBBPBitInputStream(new ByteArrayInputStream(intArrayToByteArray(array)), JBBPBitOrder.MSB0); + return new JBBPBitInputStream(new ByteArrayInputStream(intArrayToByteArray(array)), + JBBPBitOrder.MSB0); } @Test public void testReadUnsignedShort_EOFforEmpty_BigEndian_EOFException() throws Exception { - assertThrows(EOFException.class, () -> asInputStream().readUnsignedShort(JBBPByteOrder.BIG_ENDIAN)); + assertThrows(EOFException.class, + () -> asInputStream().readUnsignedShort(JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadUnsignedShort_EOFforEmpty_LittleEndian_EOFException() throws Exception { - assertThrows(EOFException.class, () -> asInputStream().readUnsignedShort(JBBPByteOrder.LITTLE_ENDIAN)); + assertThrows(EOFException.class, + () -> asInputStream().readUnsignedShort(JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadUnsignedShort_EOFforOneByte_BigEndian_EOFException() throws Exception { - assertThrows(EOFException.class, () -> asInputStream((byte) 1).readUnsignedShort(JBBPByteOrder.BIG_ENDIAN)); + assertThrows(EOFException.class, + () -> asInputStream((byte) 1).readUnsignedShort(JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadUnsignedShort_EOFforOneByte_LittleEndian_EOFException() throws Exception { - assertThrows(EOFException.class, () -> asInputStream((byte) 1).readUnsignedShort(JBBPByteOrder.LITTLE_ENDIAN)); + assertThrows(EOFException.class, + () -> asInputStream((byte) 1).readUnsignedShort(JBBPByteOrder.LITTLE_ENDIAN)); } @Test @@ -92,62 +99,79 @@ public void testReadUnsignedShort_LittleEndian() throws Exception { @Test public void testReadUnsignedShort_LittleEndian_MSB0() throws Exception { - assertEquals(0x2C48, asInputStreamMSB0(0x12, 0x34).readUnsignedShort(JBBPByteOrder.LITTLE_ENDIAN)); + assertEquals(0x2C48, + asInputStreamMSB0(0x12, 0x34).readUnsignedShort(JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadInt_BigEndian() throws Exception { - assertEquals(0x12345678, asInputStream(0x12, 0x34, 0x56, 0x78).readInt(JBBPByteOrder.BIG_ENDIAN)); + assertEquals(0x12345678, + asInputStream(0x12, 0x34, 0x56, 0x78).readInt(JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadInt_BigEndian_EOF() throws Exception { - assertThrows(EOFException.class, () -> asInputStream(0x12, 0x34, 0x56).readInt(JBBPByteOrder.BIG_ENDIAN)); + assertThrows(EOFException.class, + () -> asInputStream(0x12, 0x34, 0x56).readInt(JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadInt_BigEndian_MSB0() throws Exception { - assertEquals(0x482C6A1E, asInputStreamMSB0(0x12, 0x34, 0x56, 0x78).readInt(JBBPByteOrder.BIG_ENDIAN)); + assertEquals(0x482C6A1E, + asInputStreamMSB0(0x12, 0x34, 0x56, 0x78).readInt(JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadStringArray_BigEndan_FixedSize() throws Exception { - assertArrayEquals(new String[] {null, "", "ABC"}, asInputStream(0xFF, 0x00, 3, 65, 66, 67, 0, 0).readStringArray(3, JBBPByteOrder.BIG_ENDIAN)); + assertArrayEquals(new String[] {null, "", "ABC"}, asInputStream(0xFF, 0x00, 3, 65, 66, 67, 0, 0) + .readStringArray(3, JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadStringArray_ErrorForEOF() { - assertThrows(IOException.class, () -> asInputStream(0xFF, 0x00, 3, 65, 66, 67, 0, 0).readStringArray(8, JBBPByteOrder.BIG_ENDIAN)); - assertThrows(IOException.class, () -> asInputStream().readStringArray(8, JBBPByteOrder.BIG_ENDIAN)); - assertThrows(IOException.class, () -> asInputStream().readStringArray(8, JBBPByteOrder.LITTLE_ENDIAN)); - assertThrows(IOException.class, () -> asInputStream(0xFF, 0x00, 3, 65, 66, 67, 0, 0).readStringArray(8, JBBPByteOrder.LITTLE_ENDIAN)); + assertThrows(IOException.class, () -> asInputStream(0xFF, 0x00, 3, 65, 66, 67, 0, 0) + .readStringArray(8, JBBPByteOrder.BIG_ENDIAN)); + assertThrows(IOException.class, + () -> asInputStream().readStringArray(8, JBBPByteOrder.BIG_ENDIAN)); + assertThrows(IOException.class, + () -> asInputStream().readStringArray(8, JBBPByteOrder.LITTLE_ENDIAN)); + assertThrows(IOException.class, () -> asInputStream(0xFF, 0x00, 3, 65, 66, 67, 0, 0) + .readStringArray(8, JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadStringArray_ErrorForWrongPrefix() { - assertThrows(IOException.class, () -> asInputStream(0x80, 0x00, 3, 65, 66, 67, 0, 0).readStringArray(3, JBBPByteOrder.BIG_ENDIAN)); - assertThrows(IOException.class, () -> asInputStream(0x91, 0x00, 3, 65, 66, 67, 0, 0).readStringArray(3, JBBPByteOrder.LITTLE_ENDIAN)); + assertThrows(IOException.class, () -> asInputStream(0x80, 0x00, 3, 65, 66, 67, 0, 0) + .readStringArray(3, JBBPByteOrder.BIG_ENDIAN)); + assertThrows(IOException.class, () -> asInputStream(0x91, 0x00, 3, 65, 66, 67, 0, 0) + .readStringArray(3, JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadStringArray_LittleEndan_FixedSize() throws Exception { - assertArrayEquals(new String[] {null, "", "ABC"}, asInputStream(0xFF, 0x00, 3, 65, 66, 67, 0, 0).readStringArray(3, JBBPByteOrder.LITTLE_ENDIAN)); + assertArrayEquals(new String[] {null, "", "ABC"}, asInputStream(0xFF, 0x00, 3, 65, 66, 67, 0, 0) + .readStringArray(3, JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadStringArray_WholeStream_ResultEmptyArray() throws Exception { - assertArrayEquals(new String[0], asInputStream().readStringArray(-1, JBBPByteOrder.LITTLE_ENDIAN)); + assertArrayEquals(new String[0], + asInputStream().readStringArray(-1, JBBPByteOrder.LITTLE_ENDIAN)); assertArrayEquals(new String[0], asInputStream().readStringArray(-1, JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadStringArray_BigEndan_WholeStream() throws Exception { - assertArrayEquals(new String[] {null, "", "ABC", "", ""}, asInputStream(0xFF, 0x00, 3, 65, 66, 67, 0, 0).readStringArray(-1, JBBPByteOrder.BIG_ENDIAN)); + assertArrayEquals(new String[] {null, "", "ABC", "", ""}, + asInputStream(0xFF, 0x00, 3, 65, 66, 67, 0, 0) + .readStringArray(-1, JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadStringArray_LittleEndan_WholeStream() throws Exception { - assertArrayEquals(new String[] {null, "", "ABC", "", ""}, asInputStream(0xFF, 0x00, 3, 65, 66, 67, 0, 0).readStringArray(-1, JBBPByteOrder.LITTLE_ENDIAN)); + assertArrayEquals(new String[] {null, "", "ABC", "", ""}, + asInputStream(0xFF, 0x00, 3, 65, 66, 67, 0, 0) + .readStringArray(-1, JBBPByteOrder.LITTLE_ENDIAN)); } @Test @@ -167,7 +191,8 @@ public void testReadString_BigEndan_ShortString() throws Exception { @Test public void testReadString_BigEndan_Msb0_ShortString() throws Exception { - assertEquals("zzzz", asInputStreamMSB0(0x20, '^', '^', '^', '^').readString(JBBPByteOrder.BIG_ENDIAN)); + assertEquals("zzzz", + asInputStreamMSB0(0x20, '^', '^', '^', '^').readString(JBBPByteOrder.BIG_ENDIAN)); } @Test @@ -187,102 +212,127 @@ public void testReadString_LittleEndian_ShortString() throws Exception { @Test public void testReadFloat_BigEndian_MSB0() throws Exception { - assertEquals(176552.47f, asInputStreamMSB0(0x12, 0x34, 0x56, 0x78).readFloat(JBBPByteOrder.BIG_ENDIAN), TestUtils.FLOAT_DELTA); + assertEquals(176552.47f, + asInputStreamMSB0(0x12, 0x34, 0x56, 0x78).readFloat(JBBPByteOrder.BIG_ENDIAN), + TestUtils.FLOAT_DELTA); } @Test public void testReadInt_BigEndian_MSB0_EOF() throws Exception { - assertThrows(EOFException.class, () -> asInputStreamMSB0(0x12, 0x34, 0x56).readInt(JBBPByteOrder.BIG_ENDIAN)); + assertThrows(EOFException.class, + () -> asInputStreamMSB0(0x12, 0x34, 0x56).readInt(JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadFloat_BigEndian_MSB0_EOF() throws Exception { - assertThrows(EOFException.class, () -> asInputStreamMSB0(0x12, 0x34, 0x56).readFloat(JBBPByteOrder.BIG_ENDIAN)); + assertThrows(EOFException.class, + () -> asInputStreamMSB0(0x12, 0x34, 0x56).readFloat(JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadInt_LittleEndian() throws Exception { - assertEquals(0x78563412, asInputStream(0x12, 0x34, 0x56, 0x78).readInt(JBBPByteOrder.LITTLE_ENDIAN)); + assertEquals(0x78563412, + asInputStream(0x12, 0x34, 0x56, 0x78).readInt(JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadFloat_LittleEndian() throws Exception { - assertEquals(1.7378244E34f, asInputStream(0x12, 0x34, 0x56, 0x78).readFloat(JBBPByteOrder.LITTLE_ENDIAN), TestUtils.FLOAT_DELTA); + assertEquals(1.7378244E34f, + asInputStream(0x12, 0x34, 0x56, 0x78).readFloat(JBBPByteOrder.LITTLE_ENDIAN), + TestUtils.FLOAT_DELTA); } @Test public void testReadInt_LittleEndian_EOF() throws Exception { - assertThrows(EOFException.class, () -> asInputStream(0x12, 0x34, 0x56).readInt(JBBPByteOrder.LITTLE_ENDIAN)); + assertThrows(EOFException.class, + () -> asInputStream(0x12, 0x34, 0x56).readInt(JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadFloat_LittleEndian_EOF() throws Exception { - assertThrows(EOFException.class, () -> asInputStream(0x12, 0x34, 0x56).readFloat(JBBPByteOrder.LITTLE_ENDIAN)); + assertThrows(EOFException.class, + () -> asInputStream(0x12, 0x34, 0x56).readFloat(JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadInt_LittleEndian_MSB0() throws Exception { - assertEquals(0x1E6A2C48, asInputStreamMSB0(0x12, 0x34, 0x56, 0x78).readInt(JBBPByteOrder.LITTLE_ENDIAN)); + assertEquals(0x1E6A2C48, + asInputStreamMSB0(0x12, 0x34, 0x56, 0x78).readInt(JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadFloat_LittleEndian_MSB0() throws Exception { - assertEquals(1.2397014E-20f, asInputStreamMSB0(0x12, 0x34, 0x56, 0x78).readFloat(JBBPByteOrder.LITTLE_ENDIAN), TestUtils.FLOAT_DELTA); + assertEquals(1.2397014E-20f, + asInputStreamMSB0(0x12, 0x34, 0x56, 0x78).readFloat(JBBPByteOrder.LITTLE_ENDIAN), + TestUtils.FLOAT_DELTA); } @Test public void testReadInt_LittleEndian_MSB0_EOF() throws Exception { - assertThrows(EOFException.class, () -> asInputStreamMSB0(0x12, 0x34, 0x56).readInt(JBBPByteOrder.LITTLE_ENDIAN)); + assertThrows(EOFException.class, + () -> asInputStreamMSB0(0x12, 0x34, 0x56).readInt(JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadFloat_LittleEndian_MSB0_EOF() throws Exception { - assertThrows(EOFException.class, () -> asInputStreamMSB0(0x12, 0x34, 0x56).readFloat(JBBPByteOrder.LITTLE_ENDIAN)); + assertThrows(EOFException.class, + () -> asInputStreamMSB0(0x12, 0x34, 0x56).readFloat(JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadLong_BigEndian() throws Exception { - assertEquals(0x12345678AABBCCDDL, asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC, 0xDD).readLong(JBBPByteOrder.BIG_ENDIAN)); + assertEquals(0x12345678AABBCCDDL, asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC, 0xDD) + .readLong(JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadDouble_BigEndian() throws Exception { - assertEquals(5.626349538661693E-221d, asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC, 0xDD).readDouble(JBBPByteOrder.BIG_ENDIAN), TestUtils.FLOAT_DELTA); + assertEquals(5.626349538661693E-221d, + asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC, 0xDD) + .readDouble(JBBPByteOrder.BIG_ENDIAN), TestUtils.FLOAT_DELTA); } @Test public void testReadLong_BigEndian_EOF() throws Exception { - assertThrows(EOFException.class, () -> asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC).readLong(JBBPByteOrder.BIG_ENDIAN)); + assertThrows(EOFException.class, () -> asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC) + .readLong(JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadDouble_BigEndian_EOF() throws Exception { - assertThrows(EOFException.class, () -> asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC).readDouble(JBBPByteOrder.BIG_ENDIAN)); + assertThrows(EOFException.class, () -> asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC) + .readDouble(JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadLong_LittleEndian() throws Exception { - assertEquals(0xDDCCBBAA78563412L, asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC, 0xDD).readLong(JBBPByteOrder.LITTLE_ENDIAN)); + assertEquals(0xDDCCBBAA78563412L, asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC, 0xDD) + .readLong(JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadDouble_LittleEndian() throws Exception { - assertEquals(-7.00761088740633E143d, asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC, 0xDD).readDouble(JBBPByteOrder.LITTLE_ENDIAN), TestUtils.FLOAT_DELTA); + assertEquals(-7.00761088740633E143d, + asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC, 0xDD) + .readDouble(JBBPByteOrder.LITTLE_ENDIAN), TestUtils.FLOAT_DELTA); } @Test public void testReadLong_LittleEndian_EOF() throws Exception { - assertThrows(EOFException.class, () -> asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC).readLong(JBBPByteOrder.LITTLE_ENDIAN)); + assertThrows(EOFException.class, () -> asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC) + .readLong(JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadDouble_LittleEndian_EOF() throws Exception { - assertThrows(EOFException.class, () -> asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC).readDouble(JBBPByteOrder.LITTLE_ENDIAN)); + assertThrows(EOFException.class, () -> asInputStream(0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC) + .readDouble(JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testRead9bit() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {(byte) 0xDA, 1})); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {(byte) 0xDA, 1})); assertEquals(0xA, in.readBits(JBBPBitNumber.BITS_4)); assertEquals(0x1D, in.readBits(JBBPBitNumber.BITS_5)); @@ -302,7 +352,8 @@ public void testRead9bit_MSB0() throws Exception { @Test public void testGetBitBuffer() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {(byte) 0xAA})); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {(byte) 0xAA})); assertEquals(0, in.getBitBuffer()); assertEquals(0xA, in.readBits(JBBPBitNumber.BITS_4)); assertEquals(0xA, in.getBitBuffer()); @@ -409,7 +460,8 @@ public void testReadStream_AsBits() throws IOException { @Test public void testReadStream_BitByBit() throws IOException { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {0x01})); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {0x01})); assertEquals(1, in.readBits(JBBPBitNumber.BITS_1)); assertEquals(0, in.getCounter()); assertEquals(0, in.readBits(JBBPBitNumber.BITS_1)); @@ -425,7 +477,8 @@ public void testReadStream_BitByBit() throws IOException { @Test public void testReadStream_7bits_Default() throws IOException { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils.str2bin("11011100", JBBPBitOrder.MSB0))); + final JBBPBitInputStream in = new JBBPBitInputStream( + new ByteArrayInputStream(JBBPUtils.str2bin("11011100", JBBPBitOrder.MSB0))); assertEquals(0x3B, in.readBits(JBBPBitNumber.BITS_7)); assertEquals(0, in.getCounter()); } @@ -486,7 +539,8 @@ public void testReadStream_AsPartOfArray() throws IOException { public void testReadStream_AsPartOfArray_MSB0() throws IOException { final byte[] testarray = JBBPUtils.str2bin(TEST_BYTES, JBBPBitOrder.MSB0); - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(testarray), JBBPBitOrder.MSB0); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(testarray), JBBPBitOrder.MSB0); final byte[] buff = new byte[27]; assertEquals(5, in.read(buff, 9, 5)); @@ -511,7 +565,8 @@ public void testReadStream_AsPartOfArray_MSB0() throws IOException { public void testReadStream_AsPartOfArray_1bitOffset() throws IOException { final byte[] testarray = JBBPUtils.str2bin(TEST_BYTES, JBBPBitOrder.MSB0); - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils.str2bin(TEST_BYTES_EXTRABIT, JBBPBitOrder.MSB0))); + final JBBPBitInputStream in = new JBBPBitInputStream( + new ByteArrayInputStream(JBBPUtils.str2bin(TEST_BYTES_EXTRABIT, JBBPBitOrder.MSB0))); assertEquals(0, in.readBits(JBBPBitNumber.BITS_1)); @@ -536,7 +591,8 @@ public void testReadStream_AsPartOfArray_1bitOffset() throws IOException { @Test public void testMarkForReadBits() throws IOException { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils.str2bin("10010110_00101000_10101010", JBBPBitOrder.MSB0))); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + JBBPUtils.str2bin("10010110_00101000_10101010", JBBPBitOrder.MSB0))); assertEquals(0x9, in.readBits(JBBPBitNumber.BITS_4)); assertEquals(0x6, in.readBits(JBBPBitNumber.BITS_6)); @@ -560,7 +616,8 @@ public void testMarkForReadBits() throws IOException { @Test public void testReadBits_ExceptionForWrongArgument() throws Exception { - final JBBPBitInputStream inLe = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils.str2bin(TEST_BYTES, JBBPBitOrder.LSB0))); + final JBBPBitInputStream inLe = new JBBPBitInputStream( + new ByteArrayInputStream(JBBPUtils.str2bin(TEST_BYTES, JBBPBitOrder.LSB0))); try { inLe.readBits(JBBPBitNumber.decode(0)); @@ -586,7 +643,9 @@ public void testReadBits_ExceptionForWrongArgument() throws Exception { @Test public void testSkipBytes() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils.str2bin("01010101_01010101_01010101_00011000_01010101_01010101_00000001", JBBPBitOrder.MSB0))); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils + .str2bin("01010101_01010101_01010101_00011000_01010101_01010101_00000001", + JBBPBitOrder.MSB0))); assertEquals(3, in.skip(3)); assertEquals(0x18, in.read()); @@ -597,7 +656,9 @@ public void testSkipBytes() throws Exception { @Test public void testAlignBytes() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils.str2bin("01010101_01010101_01011101_00011000_01010101_01010101_00000001", JBBPBitOrder.MSB0))); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils + .str2bin("01010101_01010101_01011101_00011000_01010101_01010101_00000001", + JBBPBitOrder.MSB0))); assertEquals(0xAA, in.read()); in.align(3); @@ -616,7 +677,9 @@ public void testAlignBytes() throws Exception { @Test public void testRead_WithoutOffset() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils.str2bin("01010111_01010111_01010111_00011000_01010101_01100011_00000001", JBBPBitOrder.MSB0))); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils + .str2bin("01010111_01010111_01010111_00011000_01010101_01100011_00000001", + JBBPBitOrder.MSB0))); assertEquals(0xEA, in.read()); assertEquals(0xEA, in.read()); @@ -630,7 +693,9 @@ public void testRead_WithoutOffset() throws Exception { @Test public void testRead_1bitOffset() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils.str2bin("1 01010111_01010111_01010111_00011000_01010111_01100011_00101101", JBBPBitOrder.MSB0))); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils + .str2bin("1 01010111_01010111_01010111_00011000_01010111_01100011_00101101", + JBBPBitOrder.MSB0))); assertEquals(1, in.readBits(JBBPBitNumber.BITS_1)); @@ -647,7 +712,9 @@ public void testRead_1bitOffset() throws Exception { @Test public void testSkipBytes_1bitOffset() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils.str2bin("0 01010101_01010101_01010101 00011000_01010101_010110110_0000001", JBBPBitOrder.MSB0))); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils + .str2bin("0 01010101_01010101_01010101 00011000_01010101_010110110_0000001", + JBBPBitOrder.MSB0))); assertEquals(0, in.readBits(JBBPBitNumber.BITS_1)); @@ -677,8 +744,10 @@ public void testSkipBytes_1bitOffset() throws Exception { @Test public void testReadArray_Bits_WholeStream() throws Exception { - JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils.str2bin("00101001_11001011_10111110", JBBPBitOrder.LSB0))); - assertArrayEquals(new byte[] {1, 2, 2, 0, 3, 2, 0, 3, 2, 3, 3, 2}, in.readBitsArray(-1, JBBPBitNumber.BITS_2)); + JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + JBBPUtils.str2bin("00101001_11001011_10111110", JBBPBitOrder.LSB0))); + assertArrayEquals(new byte[] {1, 2, 2, 0, 3, 2, 0, 3, 2, 3, 3, 2}, + in.readBitsArray(-1, JBBPBitNumber.BITS_2)); assertEquals(3, in.getCounter()); final Random rnd = new Random(1234); @@ -711,21 +780,24 @@ public void testReadArray_Bits_WholeStream() throws Exception { @Test public void testReadArray_Bits_ThreeItems() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils.str2bin("00101001_11001011_10111110", JBBPBitOrder.LSB0))); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + JBBPUtils.str2bin("00101001_11001011_10111110", JBBPBitOrder.LSB0))); assertArrayEquals(new byte[] {1, 2, 2}, in.readBitsArray(3, JBBPBitNumber.BITS_2)); } @Test public void testReadArray_Bits_EOF() throws Exception { assertThrows(EOFException.class, () -> { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(JBBPUtils.str2bin("00101001_11001011_10111110", JBBPBitOrder.LSB0))); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + JBBPUtils.str2bin("00101001_11001011_10111110", JBBPBitOrder.LSB0))); in.readBitsArray(58, JBBPBitNumber.BITS_2); }); } @Test public void testReadArray_Bytes_WholeStream() throws Exception { - JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); + JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 0}, in.readByteArray(-1)); assertEquals(8, in.getCounter()); @@ -758,34 +830,40 @@ public void testReadArray_Bytes_WholeStream() throws Exception { @Test public void testReadArray_Bytes_ThreeItems() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); assertArrayEquals(new byte[] {1, 2, 3,}, in.readByteArray(3)); } @Test public void testReadArray_Bytes_BIG_ENDIAN_ThreeItems() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); assertArrayEquals(new byte[] {1, 2, 3,}, in.readByteArray(3, JBBPByteOrder.BIG_ENDIAN)); } @Test public void testReadArray_Bytes_LITTLE_ENDIAN_ThreeItems() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); assertArrayEquals(new byte[] {3, 2, 1,}, in.readByteArray(3, JBBPByteOrder.LITTLE_ENDIAN)); } @Test public void testReadArray_Bytes_EOF() throws Exception { assertThrows(EOFException.class, () -> { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); in.readByteArray(259); }); } @Test public void testReadArray_Short_WholeStream() throws Exception { - JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); - assertArrayEquals(new short[] {0x0102, 0x0304, 0x0506, 0x0700}, in.readShortArray(-1, JBBPByteOrder.BIG_ENDIAN)); + JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); + assertArrayEquals(new short[] {0x0102, 0x0304, 0x0506, 0x0700}, + in.readShortArray(-1, JBBPByteOrder.BIG_ENDIAN)); assertEquals(8, in.getCounter()); final Random rnd = new Random(1234); @@ -821,8 +899,10 @@ public void testReadArray_Short_WholeStream() throws Exception { @Test public void testReadArray_UShort_WholeStream() throws Exception { - JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); - assertArrayEquals(new char[] {0x0102, 0x0304, 0x0506, 0x0700}, in.readUShortArray(-1, JBBPByteOrder.BIG_ENDIAN)); + JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); + assertArrayEquals(new char[] {0x0102, 0x0304, 0x0506, 0x0700}, + in.readUShortArray(-1, JBBPByteOrder.BIG_ENDIAN)); assertEquals(8, in.getCounter()); final Random rnd = new Random(1234); @@ -858,14 +938,16 @@ public void testReadArray_UShort_WholeStream() throws Exception { @Test public void testReadArray_Short_TwoItems() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); assertArrayEquals(new short[] {0x0102, 0x0304}, in.readShortArray(2, JBBPByteOrder.BIG_ENDIAN)); assertEquals(4, in.getCounter()); } @Test public void testReadArray_UShort_TwoItems() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); assertArrayEquals(new char[] {0x0102, 0x0304}, in.readUShortArray(2, JBBPByteOrder.BIG_ENDIAN)); assertEquals(4, in.getCounter()); } @@ -873,15 +955,18 @@ public void testReadArray_UShort_TwoItems() throws Exception { @Test public void testReadArray_Short_EOF() throws Exception { assertThrows(EOFException.class, () -> { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0})); in.readShortArray(259, JBBPByteOrder.BIG_ENDIAN); }); } @Test public void testReadArray_Int_WholeStream() throws Exception { - JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01})); - assertArrayEquals(new int[] {0x01020304, 0x05060700, 0xFECABE01}, in.readIntArray(-1, JBBPByteOrder.BIG_ENDIAN)); + JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01})); + assertArrayEquals(new int[] {0x01020304, 0x05060700, 0xFECABE01}, + in.readIntArray(-1, JBBPByteOrder.BIG_ENDIAN)); assertEquals(12, in.getCounter()); final Random rnd = new Random(1234); @@ -897,7 +982,9 @@ public void testReadArray_Int_WholeStream() throws Exception { for (int i = 0; i < read.length; i++) { final int val = read[i]; final int j = i * 4; - assertEquals(val, ((buff[j] << 24) | ((buff[j + 1] & 0xFF) << 16) | ((buff[j + 2] & 0xFF) << 8) | (buff[j + 3] & 0xFF))); + assertEquals(val, + ((buff[j] << 24) | ((buff[j + 1] & 0xFF) << 16) | ((buff[j + 2] & 0xFF) << 8) | + (buff[j + 3] & 0xFF))); } final byte[] big = new byte[JBBPBitInputStream.INITIAL_ARRAY_BUFFER_SIZE * 128]; @@ -911,14 +998,17 @@ public void testReadArray_Int_WholeStream() throws Exception { for (int i = 0; i < readbig.length; i++) { final int val = readbig[i]; final int j = i * 4; - assertEquals(val, ((big[j] << 24) | ((big[j + 1] & 0xFF) << 16) | ((big[j + 2] & 0xFF) << 8) | (big[j + 3] & 0xFF))); + assertEquals(val, ((big[j] << 24) | ((big[j + 1] & 0xFF) << 16) | ((big[j + 2] & 0xFF) << 8) | + (big[j + 3] & 0xFF))); } } @Test public void testReadArray_Float_WholeStream() throws Exception { - JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01})); - assertArrayEquals(new float[] {2.3879393E-38f, 6.3019354E-36f, -1.3474531E38f}, in.readFloatArray(-1, JBBPByteOrder.BIG_ENDIAN), TestUtils.FLOAT_DELTA); + JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01})); + assertArrayEquals(new float[] {2.3879393E-38f, 6.3019354E-36f, -1.3474531E38f}, + in.readFloatArray(-1, JBBPByteOrder.BIG_ENDIAN), TestUtils.FLOAT_DELTA); assertEquals(12, in.getCounter()); final Random rnd = new Random(1234); @@ -934,7 +1024,9 @@ public void testReadArray_Float_WholeStream() throws Exception { for (int i = 0; i < read.length; i++) { final float val = read[i]; final int j = i * 4; - assertEquals(val, Float.intBitsToFloat((buff[j] << 24) | ((buff[j + 1] & 0xFF) << 16) | ((buff[j + 2] & 0xFF) << 8) | (buff[j + 3] & 0xFF)), TestUtils.FLOAT_DELTA); + assertEquals(val, Float.intBitsToFloat( + (buff[j] << 24) | ((buff[j + 1] & 0xFF) << 16) | ((buff[j + 2] & 0xFF) << 8) | + (buff[j + 3] & 0xFF)), TestUtils.FLOAT_DELTA); } final byte[] big = new byte[JBBPBitInputStream.INITIAL_ARRAY_BUFFER_SIZE * 128]; @@ -948,28 +1040,35 @@ public void testReadArray_Float_WholeStream() throws Exception { for (int i = 0; i < readbig.length; i++) { final float val = readbig[i]; final int j = i * 4; - assertEquals(val, Float.intBitsToFloat((big[j] << 24) | ((big[j + 1] & 0xFF) << 16) | ((big[j + 2] & 0xFF) << 8) | (big[j + 3] & 0xFF)), TestUtils.FLOAT_DELTA); + assertEquals(val, Float.intBitsToFloat( + (big[j] << 24) | ((big[j + 1] & 0xFF) << 16) | ((big[j + 2] & 0xFF) << 8) | + (big[j + 3] & 0xFF)), TestUtils.FLOAT_DELTA); } } @Test public void testReadArray_Int_TwoItems() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01})); - assertArrayEquals(new int[] {0x01020304, 0x05060700}, in.readIntArray(2, JBBPByteOrder.BIG_ENDIAN)); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01})); + assertArrayEquals(new int[] {0x01020304, 0x05060700}, + in.readIntArray(2, JBBPByteOrder.BIG_ENDIAN)); assertEquals(8, in.getCounter()); } @Test public void testReadArray_Float_TwoItems() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01})); - assertArrayEquals(new float[] {2.3879393E-38f, 6.3019354E-36f}, in.readFloatArray(2, JBBPByteOrder.BIG_ENDIAN), TestUtils.FLOAT_DELTA); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01})); + assertArrayEquals(new float[] {2.3879393E-38f, 6.3019354E-36f}, + in.readFloatArray(2, JBBPByteOrder.BIG_ENDIAN), TestUtils.FLOAT_DELTA); assertEquals(8, in.getCounter()); } @Test public void testReadArray_Int_EOF() throws Exception { assertThrows(EOFException.class, () -> { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01})); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01})); in.readIntArray(259, JBBPByteOrder.BIG_ENDIAN); }); } @@ -977,15 +1076,19 @@ public void testReadArray_Int_EOF() throws Exception { @Test public void testReadArray_DoubleInt_EOF() throws Exception { assertThrows(EOFException.class, () -> { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01})); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01})); in.readFloatArray(259, JBBPByteOrder.BIG_ENDIAN); }); } @Test public void testReadArray_Long_WholeStream() throws Exception { - JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); - assertArrayEquals(new long[] {0x0102030405060700L, 0xFECABE0102030405L, 0x0607080901020304L}, in.readLongArray(-1, JBBPByteOrder.BIG_ENDIAN)); + JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, + 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); + assertArrayEquals(new long[] {0x0102030405060700L, 0xFECABE0102030405L, 0x0607080901020304L}, + in.readLongArray(-1, JBBPByteOrder.BIG_ENDIAN)); assertEquals(24, in.getCounter()); final Random rnd = new Random(1234); @@ -1001,7 +1104,10 @@ public void testReadArray_Long_WholeStream() throws Exception { for (int i = 0; i < read.length; i++) { final long val = read[i]; final int j = i * 8; - assertEquals(val, (((long) buff[j] << 56) | (((long) buff[j + 1] & 0xFFL) << 48) | (((long) buff[j + 2] & 0xFFL) << 40) | (((long) buff[j + 3] & 0xFFL) << 32) | (((long) buff[j + 4] & 0xFFL) << 24) | (((long) buff[j + 5] & 0xFFL) << 16) | (((long) buff[j + 6] & 0xFFL) << 8) | ((long) buff[j + 7] & 0xFF))); + assertEquals(val, (((long) buff[j] << 56) | (((long) buff[j + 1] & 0xFFL) << 48) | + (((long) buff[j + 2] & 0xFFL) << 40) | (((long) buff[j + 3] & 0xFFL) << 32) | + (((long) buff[j + 4] & 0xFFL) << 24) | (((long) buff[j + 5] & 0xFFL) << 16) | + (((long) buff[j + 6] & 0xFFL) << 8) | ((long) buff[j + 7] & 0xFF))); } final byte[] big = new byte[JBBPBitInputStream.INITIAL_ARRAY_BUFFER_SIZE * 128]; @@ -1015,14 +1121,21 @@ public void testReadArray_Long_WholeStream() throws Exception { for (int i = 0; i < readbig.length; i++) { final long val = readbig[i]; final int j = i * 8; - assertEquals(val, (((long) big[j] << 56) | (((long) big[j + 1] & 0xFFL) << 48) | (((long) big[j + 2] & 0xFFL) << 40) | (((long) big[j + 3] & 0xFFL) << 32) | (((long) big[j + 4] & 0xFFL) << 24) | (((long) big[j + 5] & 0xFFL) << 16) | (((long) big[j + 6] & 0xFFL) << 8) | ((long) big[j + 7] & 0xFF))); + assertEquals(val, (((long) big[j] << 56) | (((long) big[j + 1] & 0xFFL) << 48) | + (((long) big[j + 2] & 0xFFL) << 40) | (((long) big[j + 3] & 0xFFL) << 32) | + (((long) big[j + 4] & 0xFFL) << 24) | (((long) big[j + 5] & 0xFFL) << 16) | + (((long) big[j + 6] & 0xFFL) << 8) | ((long) big[j + 7] & 0xFF))); } } @Test public void testReadArray_Double_WholeStream() throws Exception { - JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); - assertArrayEquals(new double[] {8.207880399131826E-304d, -5.730900111929792E302d, 1.268802825418157E-279d}, in.readDoubleArray(-1, JBBPByteOrder.BIG_ENDIAN), TestUtils.FLOAT_DELTA); + JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, + 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); + assertArrayEquals( + new double[] {8.207880399131826E-304d, -5.730900111929792E302d, 1.268802825418157E-279d}, + in.readDoubleArray(-1, JBBPByteOrder.BIG_ENDIAN), TestUtils.FLOAT_DELTA); assertEquals(24, in.getCounter()); final Random rnd = new Random(1234); @@ -1038,7 +1151,12 @@ public void testReadArray_Double_WholeStream() throws Exception { for (int i = 0; i < read.length; i++) { final double val = read[i]; final int j = i * 8; - assertEquals(val, Double.longBitsToDouble(((long) buff[j] << 56) | (((long) buff[j + 1] & 0xFFL) << 48) | (((long) buff[j + 2] & 0xFFL) << 40) | (((long) buff[j + 3] & 0xFFL) << 32) | (((long) buff[j + 4] & 0xFFL) << 24) | (((long) buff[j + 5] & 0xFFL) << 16) | (((long) buff[j + 6] & 0xFFL) << 8) | ((long) buff[j + 7] & 0xFF)), TestUtils.FLOAT_DELTA); + assertEquals(val, Double.longBitsToDouble( + ((long) buff[j] << 56) | (((long) buff[j + 1] & 0xFFL) << 48) | + (((long) buff[j + 2] & 0xFFL) << 40) | (((long) buff[j + 3] & 0xFFL) << 32) | + (((long) buff[j + 4] & 0xFFL) << 24) | (((long) buff[j + 5] & 0xFFL) << 16) | + (((long) buff[j + 6] & 0xFFL) << 8) | ((long) buff[j + 7] & 0xFF)), + TestUtils.FLOAT_DELTA); } final byte[] big = new byte[JBBPBitInputStream.INITIAL_ARRAY_BUFFER_SIZE * 128]; @@ -1052,28 +1170,41 @@ public void testReadArray_Double_WholeStream() throws Exception { for (int i = 0; i < readbig.length; i++) { final double val = readbig[i]; final int j = i * 8; - assertEquals(val, Double.longBitsToDouble(((long) big[j] << 56) | (((long) big[j + 1] & 0xFFL) << 48) | (((long) big[j + 2] & 0xFFL) << 40) | (((long) big[j + 3] & 0xFFL) << 32) | (((long) big[j + 4] & 0xFFL) << 24) | (((long) big[j + 5] & 0xFFL) << 16) | (((long) big[j + 6] & 0xFFL) << 8) | ((long) big[j + 7] & 0xFF)), TestUtils.FLOAT_DELTA); + assertEquals(val, Double.longBitsToDouble( + ((long) big[j] << 56) | (((long) big[j + 1] & 0xFFL) << 48) | + (((long) big[j + 2] & 0xFFL) << 40) | (((long) big[j + 3] & 0xFFL) << 32) | + (((long) big[j + 4] & 0xFFL) << 24) | (((long) big[j + 5] & 0xFFL) << 16) | + (((long) big[j + 6] & 0xFFL) << 8) | ((long) big[j + 7] & 0xFF)), + TestUtils.FLOAT_DELTA); } } @Test public void testReadArray_Long_TwoItems() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); - assertArrayEquals(new long[] {0x0102030405060700L, 0xFECABE0102030405L}, in.readLongArray(2, JBBPByteOrder.BIG_ENDIAN)); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, + 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); + assertArrayEquals(new long[] {0x0102030405060700L, 0xFECABE0102030405L}, + in.readLongArray(2, JBBPByteOrder.BIG_ENDIAN)); assertEquals(16, in.getCounter()); } @Test public void testReadArray_Double_TwoItems() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); - assertArrayEquals(new double[] {8.207880399131826E-304d, -5.730900111929792E302d}, in.readDoubleArray(2, JBBPByteOrder.BIG_ENDIAN), TestUtils.FLOAT_DELTA); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, + 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); + assertArrayEquals(new double[] {8.207880399131826E-304d, -5.730900111929792E302d}, + in.readDoubleArray(2, JBBPByteOrder.BIG_ENDIAN), TestUtils.FLOAT_DELTA); assertEquals(16, in.getCounter()); } @Test public void testReadArray_Long_EOF() throws Exception { assertThrows(EOFException.class, () -> { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, + 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); in.readLongArray(259, JBBPByteOrder.BIG_ENDIAN); }); } @@ -1081,14 +1212,18 @@ public void testReadArray_Long_EOF() throws Exception { @Test public void testReadArray_Double_EOF() throws Exception { assertThrows(EOFException.class, () -> { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, + 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); in.readDoubleArray(259, JBBPByteOrder.BIG_ENDIAN); }); } @Test public void testResetCounter_ForStartOfStream() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, + 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); in.resetCounter(); assertEquals(1, in.readByte()); assertEquals(1, in.getCounter()); @@ -1096,7 +1231,9 @@ public void testResetCounter_ForStartOfStream() throws Exception { @Test public void testResetCounter_ForCachedBits() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 0, (byte) 0xFE, (byte) 0xCA, (byte) 0xBE, (byte) 0x01, 2, + 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4})); assertEquals(1, in.readBits(JBBPBitNumber.BITS_3)); assertEquals(0, in.getCounter()); assertTrue(in.getBufferedBitsNumber() != 0); @@ -1134,7 +1271,8 @@ public void testReadBooleanArray_WholeStream() throws Exception { @Test public void testReadNotFullByteArrayAfterBitReading() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {(byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0xDD})); + final JBBPBitInputStream in = new JBBPBitInputStream( + new ByteArrayInputStream(new byte[] {(byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0xDD})); assertEquals(0x2, in.readBits(JBBPBitNumber.BITS_4)); assertEquals(0, in.getCounter()); @@ -1142,12 +1280,15 @@ public void testReadNotFullByteArrayAfterBitReading() throws Exception { final int read = in.read(readarray, 0, readarray.length); assertEquals(4, read); assertEquals(4, in.getCounter()); - assertArrayEquals(new byte[] {(byte) 0x41, (byte) 0x63, (byte) 0xD5, (byte) 0x0D, 0, 0}, readarray); + assertArrayEquals(new byte[] {(byte) 0x41, (byte) 0x63, (byte) 0xD5, (byte) 0x0D, 0, 0}, + readarray); } @Test public void testReadNotFullByteArrayAfterBitReading_MSB0() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {(byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0xDD}), JBBPBitOrder.MSB0); + final JBBPBitInputStream in = new JBBPBitInputStream( + new ByteArrayInputStream(new byte[] {(byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0xDD}), + JBBPBitOrder.MSB0); assertEquals(0x8, in.readBits(JBBPBitNumber.BITS_4)); final byte[] readarray = new byte[6]; @@ -1156,12 +1297,14 @@ public void testReadNotFullByteArrayAfterBitReading_MSB0() throws Exception { assertEquals(4, read); assertEquals(4, in.getCounter()); - assertArrayEquals(new byte[] {(byte) 0xC4, (byte) 0xA2, (byte) 0xB6, (byte) 0x0B, 0, 0}, readarray); + assertArrayEquals(new byte[] {(byte) 0xC4, (byte) 0xA2, (byte) 0xB6, (byte) 0x0B, 0, 0}, + readarray); } @Test public void testCheckThatCounterResetDoesntResetFullBitBuffer() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 0x7F})); + final JBBPBitInputStream in = + new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 0x7F})); assertEquals(0, in.getBufferedBitsNumber()); assertTrue(in.hasAvailableData()); assertEquals(0, in.getCounter()); @@ -1182,7 +1325,8 @@ public void testCheckThatCounterResetDoesntResetFullBitBuffer() throws Exception @Test public void testByteCounterWithHasAvailableData() throws Exception { - final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16})); + final JBBPBitInputStream in = new JBBPBitInputStream(new ByteArrayInputStream( + new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16})); assertTrue(in.hasAvailableData()); assertEquals(0, in.getCounter()); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPBitOutputStreamTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPBitOutputStreamTest.java index 57e2a6b0..4de46a5d 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPBitOutputStreamTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPBitOutputStreamTest.java @@ -16,20 +16,23 @@ package com.igormaznitsa.jbbp.io; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + + import com.igormaznitsa.jbbp.utils.JBBPUtils; import com.igormaznitsa.jbbp.utils.SpecialTestUtils; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.function.Executable; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Random; - -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class JBBPBitOutputStreamTest { - private static byte[] writeString(final JBBPByteOrder order, final String str) throws IOException { + private static byte[] writeString(final JBBPByteOrder order, final String str) + throws IOException { final ByteArrayOutputStream bos = new ByteArrayOutputStream(); final JBBPBitOutputStream out = new JBBPBitOutputStream(bos); out.writeString(str, order); @@ -37,7 +40,8 @@ private static byte[] writeString(final JBBPByteOrder order, final String str) t return bos.toByteArray(); } - private static byte[] writeStrings(final JBBPByteOrder order, final String... array) throws IOException { + private static byte[] writeStrings(final JBBPByteOrder order, final String... array) + throws IOException { final ByteArrayOutputStream bos = new ByteArrayOutputStream(); final JBBPBitOutputStream out = new JBBPBitOutputStream(bos); out.writeStringArray(array, order); @@ -255,7 +259,8 @@ public void testWriteFloat_BigEndian() throws Exception { assertEquals(4, out.getCounter()); out.flush(); assertEquals(4, out.getCounter()); - assertArrayEquals(new byte[] {(byte) 65, (byte) 19, (byte) -64, (byte) -125}, outBiuffer.toByteArray()); + assertArrayEquals(new byte[] {(byte) 65, (byte) 19, (byte) -64, (byte) -125}, + outBiuffer.toByteArray()); } @Test @@ -279,17 +284,20 @@ public void testWriteFloat_LittleEndian() throws Exception { assertEquals(4, out.getCounter()); out.flush(); assertEquals(4, out.getCounter()); - assertArrayEquals(new byte[] {(byte) -125, (byte) -64, (byte) 19, (byte) 65}, outBiuffer.toByteArray()); + assertArrayEquals(new byte[] {(byte) -125, (byte) -64, (byte) 19, (byte) 65}, + outBiuffer.toByteArray()); } @Test public void testWriteStringArray_BigEndian() throws Exception { - assertArrayEquals(new byte[] {(byte) 0xFF, 0, 0x03, 65, 66, 67}, writeStrings(JBBPByteOrder.BIG_ENDIAN, null, "", "ABC")); + assertArrayEquals(new byte[] {(byte) 0xFF, 0, 0x03, 65, 66, 67}, + writeStrings(JBBPByteOrder.BIG_ENDIAN, null, "", "ABC")); } @Test public void testWriteStringArray_LittleEndian() throws Exception { - assertArrayEquals(new byte[] {(byte) 0xFF, 0, 0x03, 65, 66, 67}, writeStrings(JBBPByteOrder.LITTLE_ENDIAN, null, "", "ABC")); + assertArrayEquals(new byte[] {(byte) 0xFF, 0, 0x03, 65, 66, 67}, + writeStrings(JBBPByteOrder.LITTLE_ENDIAN, null, "", "ABC")); } @Test @@ -319,7 +327,8 @@ public void testWriteString_LittleEndian_Empty() throws Exception { @Test public void testWriteString_LittleEndian_ShortString() throws Exception { - assertArrayEquals(new byte[] {0x03, 65, 66, 67}, writeString(JBBPByteOrder.LITTLE_ENDIAN, "ABC")); + assertArrayEquals(new byte[] {0x03, 65, 66, 67}, + writeString(JBBPByteOrder.LITTLE_ENDIAN, "ABC")); } @Test @@ -331,7 +340,9 @@ public void testWriteLong_BigEndian() throws Exception { assertEquals(8, out.getCounter()); out.flush(); assertEquals(8, out.getCounter()); - assertArrayEquals(new byte[] {0x12, 0x34, 0x56, 0x78, (byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD}, outBiuffer.toByteArray()); + assertArrayEquals( + new byte[] {0x12, 0x34, 0x56, 0x78, (byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD}, + outBiuffer.toByteArray()); } @Test @@ -343,7 +354,9 @@ public void testWriteDouble_BigEndian() throws Exception { assertEquals(8, out.getCounter()); out.flush(); assertEquals(8, out.getCounter()); - assertArrayEquals(new byte[] {(byte) 63, (byte) -15, (byte) -7, (byte) -83, (byte) -47, (byte) -86, (byte) 35, (byte) 64}, outBiuffer.toByteArray()); + assertArrayEquals( + new byte[] {(byte) 63, (byte) -15, (byte) -7, (byte) -83, (byte) -47, (byte) -86, (byte) 35, + (byte) 64}, outBiuffer.toByteArray()); } @Test @@ -355,7 +368,9 @@ public void testWriteLong_LittleEndian() throws Exception { assertEquals(8, out.getCounter()); out.flush(); assertEquals(8, out.getCounter()); - assertArrayEquals(new byte[] {(byte) 0xDD, (byte) 0xCC, (byte) 0XBB, (byte) 0xAA, 0x78, 0x56, 0x34, 0x12}, outBiuffer.toByteArray()); + assertArrayEquals( + new byte[] {(byte) 0xDD, (byte) 0xCC, (byte) 0XBB, (byte) 0xAA, 0x78, 0x56, 0x34, 0x12}, + outBiuffer.toByteArray()); } @Test @@ -367,7 +382,9 @@ public void testWriteDouble_LittleEndian() throws Exception { assertEquals(8, out.getCounter()); out.flush(); assertEquals(8, out.getCounter()); - assertArrayEquals(new byte[] {(byte) 58, (byte) 93, (byte) -77, (byte) -24, (byte) 95, (byte) 88, (byte) 55, (byte) -64}, outBiuffer.toByteArray()); + assertArrayEquals( + new byte[] {(byte) 58, (byte) 93, (byte) -77, (byte) -24, (byte) 95, (byte) 88, (byte) 55, + (byte) -64}, outBiuffer.toByteArray()); } @Test @@ -396,8 +413,11 @@ public void testWriteArrayPartlyWithOffset1Bit() throws Exception { assertEquals(0, out.getCounter()); - final byte[] ORIG_ARRAY = JBBPUtils.str2bin("10101001 01100100 10000101 01000010 10010100 10010010 00100100 10001010", JBBPBitOrder.MSB0); - final byte[] ARRAY_1BIT_OFFSET = JBBPUtils.str2bin("1 10000101 01000010 10010100 10010010 00100100", JBBPBitOrder.MSB0); + final byte[] ORIG_ARRAY = JBBPUtils + .str2bin("10101001 01100100 10000101 01000010 10010100 10010010 00100100 10001010", + JBBPBitOrder.MSB0); + final byte[] ARRAY_1BIT_OFFSET = + JBBPUtils.str2bin("1 10000101 01000010 10010100 10010010 00100100", JBBPBitOrder.MSB0); out.writeBits(1, JBBPBitNumber.BITS_1); assertEquals(0, out.getCounter()); @@ -449,17 +469,23 @@ public void testGetBitBuffer() throws Exception { @Test public void testWriteBit_ErrorForZeroSize() throws Exception { - assertThrows(IllegalArgumentException.class, () -> new JBBPBitOutputStream(new ByteArrayOutputStream()).writeBits(4, JBBPBitNumber.decode(0))); + assertThrows(IllegalArgumentException.class, + () -> new JBBPBitOutputStream(new ByteArrayOutputStream()) + .writeBits(4, JBBPBitNumber.decode(0))); } @Test public void testWriteBit_ErrorForNegativeSize() throws Exception { - assertThrows(IllegalArgumentException.class, () -> new JBBPBitOutputStream(new ByteArrayOutputStream()).writeBits(4, JBBPBitNumber.decode(-1))); + assertThrows(IllegalArgumentException.class, + () -> new JBBPBitOutputStream(new ByteArrayOutputStream()) + .writeBits(4, JBBPBitNumber.decode(-1))); } @Test public void testWriteBit_ErrorForTooBigSize() throws Exception { - assertThrows(IllegalArgumentException.class, () -> new JBBPBitOutputStream(new ByteArrayOutputStream()).writeBits(4, JBBPBitNumber.decode(9))); + assertThrows(IllegalArgumentException.class, + () -> new JBBPBitOutputStream(new ByteArrayOutputStream()) + .writeBits(4, JBBPBitNumber.decode(9))); } @Test @@ -467,8 +493,12 @@ public void testWriteWholeArrayWith1Bit() throws Exception { final ByteArrayOutputStream buff = new ByteArrayOutputStream(); final JBBPBitOutputStream out = new JBBPBitOutputStream(buff); - final byte[] ORIG_ARRAY = JBBPUtils.str2bin("10101001 01100100 10000101 01000010 10010100 10010010 00100100 10001010", JBBPBitOrder.MSB0); - final byte[] ORIG_ARRAY_1BIT_OFFSET = JBBPUtils.str2bin("1 10101001 01100100 10000101 01000010 10010100 10010010 00100100 10001010", JBBPBitOrder.MSB0); + final byte[] ORIG_ARRAY = JBBPUtils + .str2bin("10101001 01100100 10000101 01000010 10010100 10010010 00100100 10001010", + JBBPBitOrder.MSB0); + final byte[] ORIG_ARRAY_1BIT_OFFSET = JBBPUtils + .str2bin("1 10101001 01100100 10000101 01000010 10010100 10010010 00100100 10001010", + JBBPBitOrder.MSB0); out.writeBits(1, JBBPBitNumber.BITS_1); out.write(ORIG_ARRAY); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPOutTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPOutTest.java index 2d2a79d9..26ae4ab6 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPOutTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPOutTest.java @@ -48,36 +48,54 @@ public void testString() throws Exception { assertArrayEquals(new byte[] {0}, BeginBin().String("").End().toByteArray()); assertArrayEquals(new byte[] {3, 65, 66, 67}, BeginBin().String("ABC").End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0xFF}, BeginBin(JBBPBitOrder.LSB0).String(null).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0xFF}, + BeginBin(JBBPBitOrder.LSB0).String(null).End().toByteArray()); assertArrayEquals(new byte[] {0}, BeginBin(JBBPBitOrder.LSB0).String("").End().toByteArray()); - assertArrayEquals(new byte[] {3, 65, 66, 67}, BeginBin(JBBPBitOrder.LSB0).String("ABC").End().toByteArray()); + assertArrayEquals(new byte[] {3, 65, 66, 67}, + BeginBin(JBBPBitOrder.LSB0).String("ABC").End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0xFF}, BeginBin(JBBPBitOrder.MSB0).String(null).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0xFF}, + BeginBin(JBBPBitOrder.MSB0).String(null).End().toByteArray()); assertArrayEquals(new byte[] {0}, BeginBin(JBBPBitOrder.MSB0).String("").End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0xc0, (byte) 0x82, (byte) 0x42, (byte) 0xC2}, BeginBin(JBBPBitOrder.MSB0).String("ABC").End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0xc0, (byte) 0x82, (byte) 0x42, (byte) 0xC2}, + BeginBin(JBBPBitOrder.MSB0).String("ABC").End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0xFF}, BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).String(null).End().toByteArray()); - assertArrayEquals(new byte[] {0}, BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).String("").End().toByteArray()); - assertArrayEquals(new byte[] {3, 65, 66, 67}, BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).String("ABC").End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0xFF}, + BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).String(null).End().toByteArray()); + assertArrayEquals(new byte[] {0}, + BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).String("").End().toByteArray()); + assertArrayEquals(new byte[] {3, 65, 66, 67}, + BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).String("ABC").End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0xFF}, BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).String(null).End().toByteArray()); - assertArrayEquals(new byte[] {0}, BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).String("").End().toByteArray()); - assertArrayEquals(new byte[] {3, 65, 66, 67}, BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).String("ABC").End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0xFF}, + BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).String(null).End().toByteArray()); + assertArrayEquals(new byte[] {0}, + BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).String("").End().toByteArray()); + assertArrayEquals(new byte[] {3, 65, 66, 67}, + BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).String("ABC").End().toByteArray()); } @Test public void testStrings() throws Exception { - assertArrayEquals(new byte[] {(byte)0x03, 65, 66, 67, (byte)0x00, (byte)0xFF, 3, 48, 49, 50}, BeginBin().Strings("ABC", "", null, "012").End().toByteArray()); - assertArrayEquals(new byte[] {(byte)0x03, 65, 66, 67, (byte)0x00, (byte)0xFF, 3, 48, 49, 50}, BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Strings("ABC", "", null, "012").End().toByteArray()); - assertArrayEquals(new byte[] {(byte)0x03, 65, 66, 67, (byte)0x00, (byte)0xFF, 3, 48, 49, 50}, BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Strings("ABC", "", null, "012").End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x03, 65, 66, 67, (byte) 0x00, (byte) 0xFF, 3, 48, 49, 50}, + BeginBin().Strings("ABC", "", null, "012").End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x03, 65, 66, 67, (byte) 0x00, (byte) 0xFF, 3, 48, 49, 50}, + BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Strings("ABC", "", null, "012").End() + .toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x03, 65, 66, 67, (byte) 0x00, (byte) 0xFF, 3, 48, 49, 50}, + BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Strings("ABC", "", null, "012").End() + .toByteArray()); } @Test public void testBeginBin() throws Exception { assertArrayEquals(new byte[] {1}, BeginBin().Byte(1).End().toByteArray()); - assertArrayEquals(new byte[] {0x02, 0x01}, BeginBin(JBBPByteOrder.LITTLE_ENDIAN).Short(0x0102).End().toByteArray()); - assertArrayEquals(new byte[] {0x40, (byte) 0x80}, BeginBin(JBBPByteOrder.LITTLE_ENDIAN, JBBPBitOrder.MSB0).Short(0x0102).End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0x80}, BeginBin(JBBPBitOrder.MSB0).Byte(1).End().toByteArray()); + assertArrayEquals(new byte[] {0x02, 0x01}, + BeginBin(JBBPByteOrder.LITTLE_ENDIAN).Short(0x0102).End().toByteArray()); + assertArrayEquals(new byte[] {0x40, (byte) 0x80}, + BeginBin(JBBPByteOrder.LITTLE_ENDIAN, JBBPBitOrder.MSB0).Short(0x0102).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x80}, + BeginBin(JBBPBitOrder.MSB0).Byte(1).End().toByteArray()); assertArrayEquals(new byte[] {(byte) 0x80}, BeginBin(1).Byte(0x80).End().toByteArray()); final ByteArrayOutputStream buffer1 = new ByteArrayOutputStream(); @@ -90,9 +108,12 @@ public void testBeginBin() throws Exception { @Test public void testSkip() throws Exception { - assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0xFF}, BeginBin().Bit(1).Skip(0).Byte(0xFF).End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0x01, 0x00, (byte) 0xFF}, BeginBin().Bit(1).Skip(1).Byte(0xFF).End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0x01, 0x00, 0x00, (byte) 0xFF}, BeginBin().Bit(1).Skip(2).Byte(0xFF).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0xFF}, + BeginBin().Bit(1).Skip(0).Byte(0xFF).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x01, 0x00, (byte) 0xFF}, + BeginBin().Bit(1).Skip(1).Byte(0xFF).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x01, 0x00, 0x00, (byte) 0xFF}, + BeginBin().Bit(1).Skip(2).Byte(0xFF).End().toByteArray()); } @Test @@ -102,12 +123,14 @@ public void testSkip_ErrorForNegativeValue() throws Exception { @Test public void testAlign() throws Exception { - assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0xFF}, BeginBin().Bit(1).Align().Byte(0xFF).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0xFF}, + BeginBin().Bit(1).Align().Byte(0xFF).End().toByteArray()); } @Test public void testResetCounter() throws Exception { - assertArrayEquals(new byte[] {1, 2, 0, 0, (byte) 0xFF}, BeginBin().Byte(1).ResetCounter().Byte(2).Align(3).Byte(0xFF).End().toByteArray()); + assertArrayEquals(new byte[] {1, 2, 0, 0, (byte) 0xFF}, + BeginBin().Byte(1).ResetCounter().Byte(2).Align(3).Byte(0xFF).End().toByteArray()); } @Test @@ -138,20 +161,36 @@ public void testGetByteCounter() throws Exception { @Test public void testAlignWithArgument() throws Exception { assertEquals(0, BeginBin().Align(2).End().toByteArray().length); - assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0xFF}, BeginBin().Bit(1).Align(1).Byte(0xFF).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0xFF}, + BeginBin().Bit(1).Align(1).Byte(0xFF).End().toByteArray()); assertArrayEquals(new byte[] {(byte) 0xFF}, BeginBin().Align(3).Byte(0xFF).End().toByteArray()); - assertArrayEquals(new byte[] {0x01, (byte) 0xFF}, BeginBin().Bit(1).Align(1).Byte(0xFF).End().toByteArray()); - assertArrayEquals(new byte[] {0x01, 0x00, (byte) 0xFF}, BeginBin().Bit(1).Align(2).Byte(0xFF).End().toByteArray()); - assertArrayEquals(new byte[] {0x01, 0x00, 0x00, 0x00, (byte) 0xFF}, BeginBin().Bit(1).Align(4).Byte(0xFF).End().toByteArray()); - assertArrayEquals(new byte[] {0x01, 0x02, 0x00, 0x00, (byte) 0xFF}, BeginBin().Byte(1, 2).Align(4).Byte(0xFF).End().toByteArray()); - assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x00, 0x00, (byte) 0xFF}, BeginBin().Byte(1, 2, 3).Align(5).Byte(0xFF).End().toByteArray()); - assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x00, (byte) 0xFF}, BeginBin().Byte(1, 2, 3, 4).Align(5).Byte(0xFF).End().toByteArray()); - assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, (byte) 0xFF}, BeginBin().Byte(1, 2, 3, 4, 5).Align(5).Byte(0xFF).End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0x01, 0x00, 0x02, 0x00, (byte) 0x03}, BeginBin().Align(2).Byte(1).Align(2).Byte(2).Align(2).Byte(3).End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0xF1, 0x00, (byte) 0x01, 0x00, 0x02, 0x00, (byte) 0x03}, BeginBin().Byte(0xF1).Align(2).Byte(1).Align(2).Byte(2).Align(2).Byte(3).End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0xF1, 0x00, 0x00, (byte) 0x01, 0x00, 0x00, 0x02, 0x00, 00, (byte) 0x03}, BeginBin().Byte(0xF1).Align(3).Byte(1).Align(3).Byte(2).Align(3).Byte(3).End().toByteArray()); - assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x00, (byte) 0xF1}, BeginBin().Int(0x01020304).Align(5).Byte(0xF1).End().toByteArray()); - assertArrayEquals(new byte[] {0x01, 0x00, 0x00, 0x00, 0x00, (byte) 0xF1}, BeginBin().Bit(1).Align(5).Byte(0xF1).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, (byte) 0xFF}, + BeginBin().Bit(1).Align(1).Byte(0xFF).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x00, (byte) 0xFF}, + BeginBin().Bit(1).Align(2).Byte(0xFF).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x00, 0x00, 0x00, (byte) 0xFF}, + BeginBin().Bit(1).Align(4).Byte(0xFF).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x02, 0x00, 0x00, (byte) 0xFF}, + BeginBin().Byte(1, 2).Align(4).Byte(0xFF).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x00, 0x00, (byte) 0xFF}, + BeginBin().Byte(1, 2, 3).Align(5).Byte(0xFF).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x00, (byte) 0xFF}, + BeginBin().Byte(1, 2, 3, 4).Align(5).Byte(0xFF).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, (byte) 0xFF}, + BeginBin().Byte(1, 2, 3, 4, 5).Align(5).Byte(0xFF).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x01, 0x00, 0x02, 0x00, (byte) 0x03}, + BeginBin().Align(2).Byte(1).Align(2).Byte(2).Align(2).Byte(3).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0xF1, 0x00, (byte) 0x01, 0x00, 0x02, 0x00, (byte) 0x03}, + BeginBin().Byte(0xF1).Align(2).Byte(1).Align(2).Byte(2).Align(2).Byte(3).End() + .toByteArray()); + assertArrayEquals( + new byte[] {(byte) 0xF1, 0x00, 0x00, (byte) 0x01, 0x00, 0x00, 0x02, 0x00, 00, (byte) 0x03}, + BeginBin().Byte(0xF1).Align(3).Byte(1).Align(3).Byte(2).Align(3).Byte(3).End() + .toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x00, (byte) 0xF1}, + BeginBin().Int(0x01020304).Align(5).Byte(0xF1).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x00, 0x00, 0x00, 0x00, (byte) 0xF1}, + BeginBin().Bit(1).Align(5).Byte(0xF1).End().toByteArray()); } @Test @@ -166,32 +205,39 @@ public void testByte() throws Exception { @Test public void testByteArrayAsInts() throws Exception { - assertArrayEquals(new byte[] {1, 3, 0, 2, 4, 1, 3, 7}, BeginBin().Byte(1, 3, 0, 2, 4, 1, 3, 7).End().toByteArray()); + assertArrayEquals(new byte[] {1, 3, 0, 2, 4, 1, 3, 7}, + BeginBin().Byte(1, 3, 0, 2, 4, 1, 3, 7).End().toByteArray()); } @Test public void testByteArrayAsByteArray() throws Exception { - assertArrayEquals(new byte[] {1, 3, 0, 2, 4, 1, 3, 7}, BeginBin().Byte(new byte[] {1, 3, 0, 2, 4, 1, 3, 7}).End().toByteArray()); + assertArrayEquals(new byte[] {1, 3, 0, 2, 4, 1, 3, 7}, + BeginBin().Byte(new byte[] {1, 3, 0, 2, 4, 1, 3, 7}).End().toByteArray()); } @Test public void testByteArrayAsString() throws Exception { - assertArrayEquals(new byte[] {(byte) 'a', (byte) 'b', (byte) 'c'}, BeginBin().Byte("abc").End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 'a', (byte) 'b', (byte) 'c'}, + BeginBin().Byte("abc").End().toByteArray()); } @Test public void testByteArrayAsString_RussianChars() throws Exception { - assertArrayEquals(new byte[] {(byte) 0x20, (byte) 0x43, (byte) 0x41}, BeginBin().Byte("Рус").End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x20, (byte) 0x43, (byte) 0x41}, + BeginBin().Byte("Рус").End().toByteArray()); } @Test public void testUtf8_OnlyLatinChars() throws Exception { - assertArrayEquals(new byte[] {(byte) 'a', (byte) 'b', (byte) 'c'}, BeginBin().Utf8("abc").End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 'a', (byte) 'b', (byte) 'c'}, + BeginBin().Utf8("abc").End().toByteArray()); } @Test public void testUtf8_RussianChars() throws Exception { - assertArrayEquals(new byte[] {(byte) 0xD0, (byte) 0xA0, (byte) 0xD1, (byte) 0x83, (byte) 0xD1, (byte) 0x81}, BeginBin().Utf8("Рус").End().toByteArray()); + assertArrayEquals( + new byte[] {(byte) 0xD0, (byte) 0xA0, (byte) 0xD1, (byte) 0x83, (byte) 0xD1, (byte) 0x81}, + BeginBin().Utf8("Рус").End().toByteArray()); } @Test @@ -201,45 +247,57 @@ public void testBit() throws Exception { @Test public void testBit_MSB0() throws Exception { - assertArrayEquals(new byte[] {(byte) 0x80}, BeginBin(JBBPByteOrder.BIG_ENDIAN, JBBPBitOrder.MSB0).Bit(1).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x80}, + BeginBin(JBBPByteOrder.BIG_ENDIAN, JBBPBitOrder.MSB0).Bit(1).End().toByteArray()); } @Test public void testBit_LSB0() throws Exception { - assertArrayEquals(new byte[] {(byte) 0x01}, BeginBin(JBBPByteOrder.BIG_ENDIAN, JBBPBitOrder.LSB0).Bit(1).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x01}, + BeginBin(JBBPByteOrder.BIG_ENDIAN, JBBPBitOrder.LSB0).Bit(1).End().toByteArray()); } @Test public void testBits_Int() throws Exception { - assertArrayEquals(new byte[] {0xD}, BeginBin().Bits(JBBPBitNumber.BITS_4, 0xFD).End().toByteArray()); + assertArrayEquals(new byte[] {0xD}, + BeginBin().Bits(JBBPBitNumber.BITS_4, 0xFD).End().toByteArray()); } @Test public void testBits_IntArray() throws Exception { - assertArrayEquals(new byte[] {(byte) 0xED}, BeginBin().Bits(JBBPBitNumber.BITS_4, 0xFD, 0xFE).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0xED}, + BeginBin().Bits(JBBPBitNumber.BITS_4, 0xFD, 0xFE).End().toByteArray()); } @Test public void testBits_ByteArray() throws Exception { - assertArrayEquals(new byte[] {(byte) 0xED}, BeginBin().Bits(JBBPBitNumber.BITS_4, new byte[] {(byte) 0xFD, (byte) 0x8E}).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0xED}, + BeginBin().Bits(JBBPBitNumber.BITS_4, new byte[] {(byte) 0xFD, (byte) 0x8E}).End() + .toByteArray()); } @Test public void testBitArrayAsInts() throws Exception { - assertArrayEquals(new byte[] {(byte) 0xE3}, BeginBin().Bit(1, 3, 0, 2, 4, 1, 3, 7).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0xE3}, + BeginBin().Bit(1, 3, 0, 2, 4, 1, 3, 7).End().toByteArray()); assertArrayEquals(new byte[] {(byte) 0x0B}, BeginBin().Bit(1, 3, 0, 7).End().toByteArray()); } @Test public void testBitArrayAsBytes() throws Exception { - assertArrayEquals(new byte[] {(byte) 0xE3}, BeginBin().Bit(new byte[] {(byte) 1, (byte) 3, (byte) 0, (byte) 2, (byte) 4, (byte) 1, (byte) 3, (byte) 7}).End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0x0B}, BeginBin().Bit(new byte[] {(byte) 1, (byte) 3, (byte) 0, (byte) 7}).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0xE3}, BeginBin().Bit( + new byte[] {(byte) 1, (byte) 3, (byte) 0, (byte) 2, (byte) 4, (byte) 1, (byte) 3, (byte) 7}) + .End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x0B}, + BeginBin().Bit(new byte[] {(byte) 1, (byte) 3, (byte) 0, (byte) 7}).End().toByteArray()); } @Test public void testBitArrayAsBooleans() throws Exception { - assertArrayEquals(new byte[] {(byte) 0xE3}, BeginBin().Bit(true, true, false, false, false, true, true, true).End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0x0B}, BeginBin().Bit(true, true, false, true).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0xE3}, + BeginBin().Bit(true, true, false, false, false, true, true, true).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x0B}, + BeginBin().Bit(true, true, false, true).End().toByteArray()); } @Test @@ -249,7 +307,8 @@ public void testShort() throws Exception { @Test public void testShort_BigEndian() throws Exception { - assertArrayEquals(new byte[] {0x01, 0x02}, BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Short(0x0102).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x02}, + BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Short(0x0102).End().toByteArray()); } @Test @@ -259,112 +318,147 @@ public void testShort_String_NPEForNullString() throws Exception { @Test public void testShort_String_BigEndian() throws Exception { - assertArrayEquals(JBBPUtils.str2UnicodeByteArray(JBBPByteOrder.BIG_ENDIAN, "Hello"), BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Short("Hello").End().toByteArray()); + assertArrayEquals(JBBPUtils.str2UnicodeByteArray(JBBPByteOrder.BIG_ENDIAN, "Hello"), + BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Short("Hello").End().toByteArray()); } @Test public void testShort_String_LittleEndian() throws Exception { - assertArrayEquals(JBBPUtils.str2UnicodeByteArray(JBBPByteOrder.LITTLE_ENDIAN, "Hello"), BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Short("Hello").End().toByteArray()); + assertArrayEquals(JBBPUtils.str2UnicodeByteArray(JBBPByteOrder.LITTLE_ENDIAN, "Hello"), + BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Short("Hello").End().toByteArray()); } @Test public void testShort_LittleEndian() throws Exception { - assertArrayEquals(new byte[] {0x02, 0x01}, BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Short(0x0102).End().toByteArray()); + assertArrayEquals(new byte[] {0x02, 0x01}, + BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Short(0x0102).End().toByteArray()); } @Test public void testShortArray_AsIntegers() throws Exception { - assertArrayEquals(new byte[] {1, 2, 3, 4}, BeginBin().Short(0x0102, 0x0304).End().toByteArray()); + assertArrayEquals(new byte[] {1, 2, 3, 4}, + BeginBin().Short(0x0102, 0x0304).End().toByteArray()); } @Test public void testShortArray_AsIntegers_BigEndian() throws Exception { - assertArrayEquals(new byte[] {1, 2, 3, 4}, BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Short(0x0102, 0x0304).End().toByteArray()); + assertArrayEquals(new byte[] {1, 2, 3, 4}, + BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Short(0x0102, 0x0304).End().toByteArray()); } @Test public void testShortArray_AsChars_BigEndian() throws Exception { - assertArrayEquals(new byte[] {1, 2, 3, 4}, BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Short(new char[] {0x0102, 0x0304}).End().toByteArray()); + assertArrayEquals(new byte[] {1, 2, 3, 4}, + BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Short(new char[] {0x0102, 0x0304}).End() + .toByteArray()); } @Test public void testShortArray_AsIntegers_LittleEndian() throws Exception { - assertArrayEquals(new byte[] {2, 1, 4, 3}, BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Short(0x0102, 0x0304).End().toByteArray()); + assertArrayEquals(new byte[] {2, 1, 4, 3}, + BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Short(0x0102, 0x0304).End() + .toByteArray()); } @Test public void testShortArray_AsShorts() throws Exception { - assertArrayEquals(new byte[] {1, 2, 3, 4}, BeginBin().Short(new short[] {(short) 0x0102, (short) 0x0304}).End().toByteArray()); + assertArrayEquals(new byte[] {1, 2, 3, 4}, + BeginBin().Short(new short[] {(short) 0x0102, (short) 0x0304}).End().toByteArray()); } @Test public void testShortArray_AsShortArray() throws Exception { - assertArrayEquals(new byte[] {1, 2, 3, 4}, BeginBin().Short(new short[] {(short) 0x0102, (short) 0x0304}).End().toByteArray()); + assertArrayEquals(new byte[] {1, 2, 3, 4}, + BeginBin().Short(new short[] {(short) 0x0102, (short) 0x0304}).End().toByteArray()); } @Test public void testInt() throws Exception { - assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04}, BeginBin().Int(0x01020304).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04}, + BeginBin().Int(0x01020304).End().toByteArray()); } @Test public void testIntArray() throws Exception { - assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, BeginBin().Int(0x01020304, 0x05060708).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + BeginBin().Int(0x01020304, 0x05060708).End().toByteArray()); } @Test public void testInt_BigEndian() throws Exception { - assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04}, BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Int(0x01020304).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04}, + BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Int(0x01020304).End().toByteArray()); } @Test public void testInt_LittleEndian() throws Exception { - assertArrayEquals(new byte[] {0x04, 0x03, 0x02, 0x01}, BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Int(0x01020304).End().toByteArray()); + assertArrayEquals(new byte[] {0x04, 0x03, 0x02, 0x01}, + BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Int(0x01020304).End().toByteArray()); } @Test public void testFloat_BigEndian() throws Exception { final int flt = Float.floatToIntBits(Float.MAX_VALUE); - assertArrayEquals(new byte[] {(byte) (flt >>> 24), (byte) (flt >>> 16), (byte) (flt >>> 8), (byte) flt}, BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Float(Float.MAX_VALUE).End().toByteArray()); + assertArrayEquals( + new byte[] {(byte) (flt >>> 24), (byte) (flt >>> 16), (byte) (flt >>> 8), (byte) flt}, + BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Float(Float.MAX_VALUE).End().toByteArray()); } @Test public void testFloat_LittleEndian() throws Exception { final int flt = Float.floatToIntBits(Float.MAX_VALUE); - assertArrayEquals(new byte[] {(byte) flt, (byte) (flt >>> 8), (byte) (flt >>> 16), (byte) (flt >>> 24)}, BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Float(Float.MAX_VALUE).End().toByteArray()); + assertArrayEquals( + new byte[] {(byte) flt, (byte) (flt >>> 8), (byte) (flt >>> 16), (byte) (flt >>> 24)}, + BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Float(Float.MAX_VALUE).End() + .toByteArray()); } @Test public void testLong() throws Exception { - assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, BeginBin().Long(0x0102030405060708L).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + BeginBin().Long(0x0102030405060708L).End().toByteArray()); } @Test public void testLongArray() throws Exception { - assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}, BeginBin().Long(0x0102030405060708L, 0x1112131415161718L).End().toByteArray()); + assertArrayEquals( + new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18}, + BeginBin().Long(0x0102030405060708L, 0x1112131415161718L).End().toByteArray()); } @Test public void testLong_BigEndian() throws Exception { - assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Long(0x0102030405060708L).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Long(0x0102030405060708L).End() + .toByteArray()); } @Test public void testLong_LittleEndian() throws Exception { - assertArrayEquals(new byte[] {0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01}, BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Long(0x0102030405060708L).End().toByteArray()); + assertArrayEquals(new byte[] {0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01}, + BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Long(0x0102030405060708L).End() + .toByteArray()); } @Test public void testDouble_BigEndian() throws Exception { final long dbl = Double.doubleToLongBits(Double.MAX_VALUE); - final byte[] array = BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Double(Double.MAX_VALUE).End().toByteArray(); - assertArrayEquals(new byte[] {(byte) (dbl >>> 56), (byte) (dbl >>> 48), (byte) (dbl >>> 40), (byte) (dbl >>> 32), (byte) (dbl >>> 24), (byte) (dbl >>> 16), (byte) (dbl >>> 8), (byte) dbl}, array); + final byte[] array = + BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).Double(Double.MAX_VALUE).End().toByteArray(); + assertArrayEquals(new byte[] {(byte) (dbl >>> 56), (byte) (dbl >>> 48), (byte) (dbl >>> 40), + (byte) (dbl >>> 32), (byte) (dbl >>> 24), (byte) (dbl >>> 16), (byte) (dbl >>> 8), + (byte) dbl}, array); } @Test public void testDouble_LittleEndian() throws Exception { final long dbl = Double.doubleToLongBits(Double.MAX_VALUE); - assertArrayEquals(new byte[] {(byte) dbl, (byte) (dbl >>> 8), (byte) (dbl >>> 16), (byte) (dbl >>> 24), (byte) (dbl >>> 32), (byte) (dbl >>> 40), (byte) (dbl >>> 48), (byte) (dbl >>> 56)}, BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Double(Double.MAX_VALUE).End().toByteArray()); + assertArrayEquals( + new byte[] {(byte) dbl, (byte) (dbl >>> 8), (byte) (dbl >>> 16), (byte) (dbl >>> 24), + (byte) (dbl >>> 32), (byte) (dbl >>> 40), (byte) (dbl >>> 48), (byte) (dbl >>> 56)}, + BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Double(Double.MAX_VALUE).End() + .toByteArray()); } @Test @@ -559,7 +653,8 @@ public void testExceptionForBitOrderConfilctInCaseOfUsageBitOutputStream() throw final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); final JBBPBitOutputStream bitstream = new JBBPBitOutputStream(buffer, JBBPBitOrder.LSB0); - assertThrows(IllegalArgumentException.class, () -> BeginBin(bitstream, JBBPByteOrder.BIG_ENDIAN, JBBPBitOrder.MSB0)); + assertThrows(IllegalArgumentException.class, + () -> BeginBin(bitstream, JBBPByteOrder.BIG_ENDIAN, JBBPBitOrder.MSB0)); } @Test @@ -581,8 +676,10 @@ public void testComplexWriting_1() throws Exception { assertEquals(47, array.length); assertArrayEquals(new byte[] { (byte) 0x55, 5, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 1, 0, 1, 1, - (byte) 0xAB, (byte) 0xCD, (byte) 0xEF, 0x23, (byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE, - 0x12, 0x34, 0x56, 0x78, (byte) 0x9A, (byte) 0xBC, (byte) 0xDE, (byte) 0xF1, 0x21, 0x23, 0x56, 0x23, (byte) 0x90, (byte) 0x91, (byte) 0xAB, 0x32, + (byte) 0xAB, (byte) 0xCD, (byte) 0xEF, 0x23, (byte) 0xCA, (byte) 0xFE, (byte) 0xBA, + (byte) 0xBE, + 0x12, 0x34, 0x56, 0x78, (byte) 0x9A, (byte) 0xBC, (byte) 0xDE, (byte) 0xF1, 0x21, 0x23, + 0x56, 0x23, (byte) 0x90, (byte) 0x91, (byte) 0xAB, 0x32, 0x4A, 0x46, 0x49, 0x46, (byte) 0x20, (byte) 0x43, (byte) 0x41 }, array); @@ -621,7 +718,8 @@ class Test { Bin(new Test(0x12, 0x13)). End().toByteArray(); - assertArrayEquals(new byte[] {(byte) 0xCC, (byte) 0xDD, (byte) 0xAA, (byte) 0x12, (byte) 0x13}, array); + assertArrayEquals(new byte[] {(byte) 0xCC, (byte) 0xDD, (byte) 0xAA, (byte) 0x12, (byte) 0x13}, + array); } @Test @@ -732,28 +830,35 @@ class Test { this.c = c; } } - assertArrayEquals(new byte[] {1, (byte) 0x40, 3}, BeginBin().Bin(new Test((byte) 1, (byte) 2, (byte) 3)).End().toByteArray()); + assertArrayEquals(new byte[] {1, (byte) 0x40, 3}, + BeginBin().Bin(new Test((byte) 1, (byte) 2, (byte) 3)).End().toByteArray()); } @Test public void testBin_Byte_StringAsByteArray() throws Exception { assertArrayEquals(new byte[0], BeginBin().Byte("", JBBPBitOrder.LSB0).End().toByteArray()); assertArrayEquals(new byte[0], BeginBin().Byte("", JBBPBitOrder.MSB0).End().toByteArray()); - assertArrayEquals(new byte[] {65, 66, 67, 68}, BeginBin().Byte("ABCD", JBBPBitOrder.LSB0).End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 130, 66, (byte) 194, 34}, BeginBin().Byte("ABCD", JBBPBitOrder.MSB0).End().toByteArray()); + assertArrayEquals(new byte[] {65, 66, 67, 68}, + BeginBin().Byte("ABCD", JBBPBitOrder.LSB0).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 130, 66, (byte) 194, 34}, + BeginBin().Byte("ABCD", JBBPBitOrder.MSB0).End().toByteArray()); } @Test public void testBin_Byte_StringAsShortArray() throws Exception { assertArrayEquals(new byte[0], BeginBin().Short("", JBBPBitOrder.LSB0).End().toByteArray()); assertArrayEquals(new byte[0], BeginBin().Short("", JBBPBitOrder.MSB0).End().toByteArray()); - assertArrayEquals(new byte[] {0x04, 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, 0x14}, BeginBin().Short("АБВГД", JBBPBitOrder.LSB0).End().toByteArray()); - assertArrayEquals(new byte[] {0x08, 0x20, (byte) 0x88, 0x20, (byte) 0x48, 0x20, (byte) 0xC8, 0x20, (byte) 0x28, 0x20}, BeginBin().Short("АБВГД", JBBPBitOrder.MSB0).End().toByteArray()); + assertArrayEquals(new byte[] {0x04, 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, 0x14}, + BeginBin().Short("АБВГД", JBBPBitOrder.LSB0).End().toByteArray()); + assertArrayEquals( + new byte[] {0x08, 0x20, (byte) 0x88, 0x20, (byte) 0x48, 0x20, (byte) 0xC8, 0x20, + (byte) 0x28, 0x20}, BeginBin().Short("АБВГД", JBBPBitOrder.MSB0).End().toByteArray()); } @Test public void testBin_StaticField() throws Exception { - assertArrayEquals(new byte[] {1, (byte) 0x40, 3}, BeginBin().Bin(new TestWithStaticField((byte) 1, (byte) 2, (byte) 3)).End().toByteArray()); + assertArrayEquals(new byte[] {1, (byte) 0x40, 3}, + BeginBin().Bin(new TestWithStaticField((byte) 1, (byte) 2, (byte) 3)).End().toByteArray()); } @Test @@ -773,7 +878,8 @@ class Test { this.c = c; } } - assertArrayEquals(new byte[] {1, (byte) 0x80, 0}, BeginBin().Bin(new Test(true, true, false)).End().toByteArray()); + assertArrayEquals(new byte[] {1, (byte) 0x80, 0}, + BeginBin().Bin(new Test(true, true, false)).End().toByteArray()); } @Test @@ -806,22 +912,31 @@ class Internal { } } - final byte[] defaultOrder = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).BinForceByteOrder(new DefaultByteOrder()).End().toByteArray(); + final byte[] defaultOrder = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN) + .BinForceByteOrder(new DefaultByteOrder()).End().toByteArray(); assertArrayEquals(new byte[] {4, 3, 2, 1}, defaultOrder); - final byte[] bigEndianOrder = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).BinForceByteOrder(new BigEndianByteOrder()).End().toByteArray(); + final byte[] bigEndianOrder = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN) + .BinForceByteOrder(new BigEndianByteOrder()).End().toByteArray(); assertArrayEquals(new byte[] {4, 3, 2, 1}, bigEndianOrder); - final byte[] littleEndianOrder = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).BinForceByteOrder(new LittleEndianByteOrder()).End().toByteArray(); + final byte[] littleEndianOrder = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN) + .BinForceByteOrder(new LittleEndianByteOrder()).End().toByteArray(); assertArrayEquals(new byte[] {1, 2, 3, 4}, littleEndianOrder); - final byte[] littleEndianOrderWithStruct = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN).BinForceByteOrder(new LittleEndianByteOrderWithStructure()).End().toByteArray(); + final byte[] littleEndianOrderWithStruct = + JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.BIG_ENDIAN) + .BinForceByteOrder(new LittleEndianByteOrderWithStructure()).End().toByteArray(); assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}, littleEndianOrderWithStruct); - final byte[] littleEndianOrderWithStructBin = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).Bin(new LittleEndianByteOrderWithStructure()).End().toByteArray(); + final byte[] littleEndianOrderWithStructBin = + JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN) + .Bin(new LittleEndianByteOrderWithStructure()).End().toByteArray(); assertArrayEquals(new byte[] {4, 3, 2, 1, 5, 6, 7, 8}, littleEndianOrderWithStructBin); - final byte[] littleEndianOrderWithStructLe = JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN).BinForceByteOrder(new LittleEndianByteOrderWithStructure()).End().toByteArray(); + final byte[] littleEndianOrderWithStructLe = + JBBPOut.BeginBin().ByteOrder(JBBPByteOrder.LITTLE_ENDIAN) + .BinForceByteOrder(new LittleEndianByteOrderWithStructure()).End().toByteArray(); assertArrayEquals(new byte[] {4, 3, 2, 1, 8, 7, 6, 5}, littleEndianOrderWithStructLe); } @@ -842,7 +957,8 @@ class Test { this.c = c; } } - assertArrayEquals(new byte[] {(byte) 0x55, 0x0C}, BeginBin().Bin(new Test((byte) 0x05, (byte) 0x0A, (byte) 0x0C)).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0x55, 0x0C}, + BeginBin().Bin(new Test((byte) 0x05, (byte) 0x0A, (byte) 0x0C)).End().toByteArray()); } @Test @@ -852,19 +968,30 @@ class Test { byte a = (byte) 0b10101010; } - assertArrayEquals(new byte[] {(byte) 0b00001010}, BeginBin().Bin(new Test(), null, null).End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0b10101010}, BeginBin().Bin(new Test(), new BinAnnotationWrapper().setBitNumber(JBBPBitNumber.BITS_8), null).End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0b00000101}, BeginBin().Bin(new Test(), new BinAnnotationWrapper().setBitOrder(JBBPBitOrder.MSB0), null).End().toByteArray()); - assertArrayEquals(new byte[] {(byte) 0b10101010}, BeginBin().Bin(new Test(), new BinAnnotationWrapper().setType(BinType.BYTE), null).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0b00001010}, + BeginBin().Bin(new Test(), null, null).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0b10101010}, BeginBin() + .Bin(new Test(), new BinAnnotationWrapper().setBitNumber(JBBPBitNumber.BITS_8), null).End() + .toByteArray()); + assertArrayEquals(new byte[] {(byte) 0b00000101}, + BeginBin().Bin(new Test(), new BinAnnotationWrapper().setBitOrder(JBBPBitOrder.MSB0), null) + .End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 0b10101010}, + BeginBin().Bin(new Test(), new BinAnnotationWrapper().setType(BinType.BYTE), null).End() + .toByteArray()); final JBBPCustomFieldWriter customFieldWriter = new JBBPCustomFieldWriter() { @Override - public void writeCustomField(JBBPOut context, JBBPBitOutputStream outStream, Object instanceToSave, Field instanceCustomField, Bin fieldAnnotation, Object value) throws IOException { + public void writeCustomField(JBBPOut context, JBBPBitOutputStream outStream, + Object instanceToSave, Field instanceCustomField, + Bin fieldAnnotation, Object value) throws IOException { outStream.write(123); } }; - assertArrayEquals(new byte[] {(byte) 123}, BeginBin().Bin(new Test(), new BinAnnotationWrapper().setCustom(true), customFieldWriter).End().toByteArray()); + assertArrayEquals(new byte[] {(byte) 123}, + BeginBin().Bin(new Test(), new BinAnnotationWrapper().setCustom(true), customFieldWriter) + .End().toByteArray()); } @Test @@ -885,7 +1012,9 @@ class Test { } } - assertArrayEquals(new byte[] {0x01, 0x02, 0x20, (byte) 0xC0, 0x05, 0x06}, BeginBin().Bin(new Test((short) 0x0102, (short) 0x0304, (short) 0x0506)).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x02, 0x20, (byte) 0xC0, 0x05, 0x06}, + BeginBin().Bin(new Test((short) 0x0102, (short) 0x0304, (short) 0x0506)).End() + .toByteArray()); } @Test @@ -906,7 +1035,8 @@ class Test { } } - assertArrayEquals(new byte[] {0x01, 0x02, 0x20, (byte) 0xC0, 0x05, 0x06}, BeginBin().Bin(new Test((char) 0x0102, (char) 0x0304, (char) 0x0506)).End().toByteArray()); + assertArrayEquals(new byte[] {0x01, 0x02, 0x20, (byte) 0xC0, 0x05, 0x06}, + BeginBin().Bin(new Test((char) 0x0102, (char) 0x0304, (char) 0x0506)).End().toByteArray()); } @Test @@ -927,7 +1057,10 @@ class Test { } } - assertArrayEquals(new byte[] {(byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD, (byte) 0x22, (byte) 0xCC, (byte) 0x44, (byte) 0x88, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD, (byte) 0xEE}, BeginBin().Bin(new Test(0xAABBCCDD, 0x11223344, 0xBBCCDDEE)).End().toByteArray()); + assertArrayEquals( + new byte[] {(byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD, (byte) 0x22, (byte) 0xCC, + (byte) 0x44, (byte) 0x88, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD, (byte) 0xEE}, + BeginBin().Bin(new Test(0xAABBCCDD, 0x11223344, 0xBBCCDDEE)).End().toByteArray()); } @Test @@ -950,7 +1083,8 @@ class Test { assertArrayEquals(JBBPUtils.concat( JBBPUtils.splitInteger(Float.floatToIntBits(0.456f), false, null), - JBBPUtils.splitInteger((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(8.1123f)), false, null), + JBBPUtils.splitInteger((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(8.1123f)), false, + null), JBBPUtils.splitInteger(Float.floatToIntBits(56.123f), false, null) ), BeginBin().Bin(new Test(0.456f, 8.1123f, 56.123f)).End().toByteArray()); } @@ -977,7 +1111,8 @@ class Test { JBBPUtils.splitLong(0xFFAABBCCDD001122L, false, null), JBBPUtils.splitLong(JBBPFieldLong.reverseBits(0x0102030405060708L), false, null), JBBPUtils.splitLong(0x11223344556677AAL, false, null) - ), BeginBin().Bin(new Test(0xFFAABBCCDD001122L, 0x0102030405060708L, 0x11223344556677AAL)).End().toByteArray()); + ), BeginBin().Bin(new Test(0xFFAABBCCDD001122L, 0x0102030405060708L, 0x11223344556677AAL)).End() + .toByteArray()); } @Test @@ -1000,7 +1135,9 @@ class Test { assertArrayEquals(JBBPUtils.concat( JBBPUtils.splitLong(Double.doubleToLongBits(34350.456d), false, null), - JBBPUtils.splitLong(JBBPFieldLong.reverseBits(Double.doubleToLongBits(8829374.1123d)), false, null), + JBBPUtils + .splitLong(JBBPFieldLong.reverseBits(Double.doubleToLongBits(8829374.1123d)), false, + null), JBBPUtils.splitLong(Double.doubleToLongBits(3256.123d), false, null) ), BeginBin().Bin(new Test(34350.456d, 8829374.1123d, 3256.123d)).End().toByteArray()); } @@ -1036,7 +1173,9 @@ class Test { } } - assertArrayEquals(new byte[] {1, 3, 4, 2}, BeginBin().Bin(new Test((byte) 1, (byte) 2, new Inside((byte) 3, (byte) 4))).End().toByteArray()); + assertArrayEquals(new byte[] {1, 3, 4, 2}, + BeginBin().Bin(new Test((byte) 1, (byte) 2, new Inside((byte) 3, (byte) 4))).End() + .toByteArray()); } @Test @@ -1057,7 +1196,8 @@ class Test { } } assertArrayEquals(new byte[] {(byte) 0xAA, (byte) 0x21, (byte) 0x43, (byte) 0x6A, (byte) 0x0E}, - BeginBin().Bin(new Test((byte) 0xAA, new byte[] {1, 2, 3, 4}, new byte[] {5, 6, 7})).End().toByteArray()); + BeginBin().Bin(new Test((byte) 0xAA, new byte[] {1, 2, 3, 4}, new byte[] {5, 6, 7})).End() + .toByteArray()); } @Test @@ -1074,7 +1214,8 @@ class Test { this.lsbarray = lsbarray; } } - assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0xA0, (byte) 0x60, (byte) 0xE0}, + assertArrayEquals( + new byte[] {(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0xA0, (byte) 0x60, (byte) 0xE0}, BeginBin().Bin(new Test(new byte[] {1, 2, 3}, new byte[] {5, 6, 7})).End().toByteArray()); } @@ -1093,7 +1234,9 @@ class Test { } } assertArrayEquals(new byte[] {0x01, 0x00, 0x01, (byte) 0x80, 0x00, (byte) 0x80}, - BeginBin().Bin(new Test(new boolean[] {true, false, true}, new boolean[] {true, false, true})).End().toByteArray()); + BeginBin() + .Bin(new Test(new boolean[] {true, false, true}, new boolean[] {true, false, true})) + .End().toByteArray()); } @Test @@ -1147,8 +1290,12 @@ class Test { this.lsbarray = lsbarray; } } - assertArrayEquals(new byte[] {(byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0xA0, (byte) 0x60, (byte) 0x60, (byte) 0xE0, (byte) 0xE0, (byte) 0x00}, - BeginBin().Bin(new Test(new short[] {0x0101, 0x0102, 0x0103}, new short[] {0x0605, 0x0706, 0x0007})).End().toByteArray()); + assertArrayEquals( + new byte[] {(byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x03, + (byte) 0xA0, (byte) 0x60, (byte) 0x60, (byte) 0xE0, (byte) 0xE0, (byte) 0x00}, + BeginBin().Bin( + new Test(new short[] {0x0101, 0x0102, 0x0103}, new short[] {0x0605, 0x0706, 0x0007})) + .End().toByteArray()); } @Test @@ -1165,7 +1312,9 @@ class Test { this.lsbarray = lsbarray; } } - assertArrayEquals(new byte[] {(byte) 0x04, (byte) 0x1F, (byte) 0x04, (byte) 0x20, (byte) 0x18, (byte) 0x20, (byte) 0x48, (byte) 0x20}, + assertArrayEquals( + new byte[] {(byte) 0x04, (byte) 0x1F, (byte) 0x04, (byte) 0x20, (byte) 0x18, (byte) 0x20, + (byte) 0x48, (byte) 0x20}, BeginBin().Bin(new Test("ПР", "ИВ")).End().toByteArray()); } @@ -1183,9 +1332,12 @@ class Test { this.lsbarray = lsbarray; } } - assertArrayEquals(new byte[] {(byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, (byte) 0x77, (byte) 0x88, + assertArrayEquals( + new byte[] {(byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, + (byte) 0x77, (byte) 0x88, (byte) 0x48, (byte) 0xF7, (byte) 0xB3, (byte) 0xD5}, - BeginBin().Bin(new Test(new int[] {0x11223344, 0x55667788}, new int[] {0xABCDEF12})).End().toByteArray()); + BeginBin().Bin(new Test(new int[] {0x11223344, 0x55667788}, new int[] {0xABCDEF12})).End() + .toByteArray()); } @Test @@ -1203,11 +1355,18 @@ class Test { } } assertArrayEquals(JBBPUtils.concat( - JBBPUtils.splitInteger(Float.floatToIntBits(23.4546f), false, null), JBBPUtils.splitInteger(Float.floatToIntBits(123.32f), false, null), - JBBPUtils.splitInteger((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(11.98872f)), false, null), - JBBPUtils.splitInteger((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(-234.322f)), false, null) + JBBPUtils.splitInteger(Float.floatToIntBits(23.4546f), false, null), + JBBPUtils.splitInteger(Float.floatToIntBits(123.32f), false, null), + JBBPUtils + .splitInteger((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(11.98872f)), false, + null), + JBBPUtils + .splitInteger((int) JBBPFieldInt.reverseBits(Float.floatToIntBits(-234.322f)), false, + null) ), - BeginBin().Bin(new Test(new float[] {23.4546f, 123.32f}, new float[] {11.98872f, -234.322f})).End().toByteArray()); + BeginBin() + .Bin(new Test(new float[] {23.4546f, 123.32f}, new float[] {11.98872f, -234.322f})) + .End().toByteArray()); } @Test @@ -1225,11 +1384,13 @@ class Test { } } assertArrayEquals(JBBPUtils.concat( - JBBPUtils.splitLong(0x1122334455667788L, false, null), JBBPUtils.splitLong(0xAABBCCDDEEFF1122L, false, null), + JBBPUtils.splitLong(0x1122334455667788L, false, null), + JBBPUtils.splitLong(0xAABBCCDDEEFF1122L, false, null), JBBPUtils.splitLong(JBBPFieldLong.reverseBits(0x0102030405060708L), false, null), JBBPUtils.splitLong(JBBPFieldLong.reverseBits(0xCAFEBABE12345334L), false, null) ), - BeginBin().Bin(new Test(new long[] {0x1122334455667788L, 0xAABBCCDDEEFF1122L}, new long[] {0x0102030405060708L, 0xCAFEBABE12345334L})).End().toByteArray()); + BeginBin().Bin(new Test(new long[] {0x1122334455667788L, 0xAABBCCDDEEFF1122L}, + new long[] {0x0102030405060708L, 0xCAFEBABE12345334L})).End().toByteArray()); } @Test @@ -1260,7 +1421,9 @@ class Test { } } assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, - BeginBin().Bin(new Test((byte) 0x01, new Inner[] {new Inner((byte) 0x02, (byte) 0x03), new Inner((byte) 0x04, (byte) 0x05), new Inner((byte) 0x06, (byte) 0x07)})).End().toByteArray()); + BeginBin().Bin(new Test((byte) 0x01, + new Inner[] {new Inner((byte) 0x02, (byte) 0x03), new Inner((byte) 0x04, (byte) 0x05), + new Inner((byte) 0x06, (byte) 0x07)})).End().toByteArray()); } @@ -1297,7 +1460,8 @@ class Test { } } - assertThrows(JBBPIllegalArgumentException.class, () -> BeginBin().Bin(new Test((byte) 12, (byte) 24))); + assertThrows(JBBPIllegalArgumentException.class, + () -> BeginBin().Bin(new Test((byte) 12, (byte) 24))); } @@ -1315,17 +1479,18 @@ class Test { } } - assertArrayEquals(new byte[] {1, 2, 3}, BeginBin().Bin(new Test((byte) 1, (byte) 0), (context, outStream, instanceToSave, instanceCustomField, fieldAnnotation, value) -> { - assertNotNull(context); - assertNotNull(outStream); - assertNotNull(instanceToSave); - assertNotNull(instanceCustomField); - assertNotNull(fieldAnnotation); - assertEquals("b", instanceCustomField.getName()); - assertTrue(instanceToSave.getClass() == instanceCustomField.getDeclaringClass()); - - context.Byte(2, 3); - }).End().toByteArray()); + assertArrayEquals(new byte[] {1, 2, 3}, BeginBin().Bin(new Test((byte) 1, (byte) 0), + (context, outStream, instanceToSave, instanceCustomField, fieldAnnotation, value) -> { + assertNotNull(context); + assertNotNull(outStream); + assertNotNull(instanceToSave); + assertNotNull(instanceCustomField); + assertNotNull(fieldAnnotation); + assertEquals("b", instanceCustomField.getName()); + assertTrue(instanceToSave.getClass() == instanceCustomField.getDeclaringClass()); + + context.Byte(2, 3); + }).End().toByteArray()); } @Bin diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/AbstractParserIntegrationTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/AbstractParserIntegrationTest.java index 20ca17ea..62559ea4 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/AbstractParserIntegrationTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/AbstractParserIntegrationTest.java @@ -16,33 +16,34 @@ package com.igormaznitsa.jbbp.it; -import com.igormaznitsa.jbbp.io.JBBPBitInputStream; -import org.apache.commons.io.IOUtils; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.igormaznitsa.jbbp.io.JBBPBitInputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; - -import static org.junit.jupiter.api.Assertions.*; +import org.apache.commons.io.IOUtils; public abstract class AbstractParserIntegrationTest { + public static String normalizeEol(final String text) { + return text + .replace("\r\n", "\n") + .replace("\n\r", "\n") + .replace("\r", ""); + } + public void assertFileContent(final String fileName, final String content) throws Exception { final String fileText; - try(InputStream inStream = this.getResourceAsInputStream(fileName)) { + try (InputStream inStream = this.getResourceAsInputStream(fileName)) { fileText = IOUtils.toString(inStream, StandardCharsets.UTF_8); } assertEquals(normalizeEol(fileText), normalizeEol(content), "File content must be equals"); } - public static String normalizeEol(final String text) { - return text - .replace("\r\n","\n") - .replace("\n\r","\n") - .replace("\r",""); - } - public InputStream getResourceAsInputStream(final String resourceName) { final InputStream result = this.getClass().getResourceAsStream(resourceName); if (result == null) { @@ -52,8 +53,9 @@ public InputStream getResourceAsInputStream(final String resourceName) { } public void assertResource(final String resourceName, final byte[] content) throws Exception { - try(InputStream in = this.getResourceAsInputStream(resourceName)) { - assertArrayEquals(new JBBPBitInputStream(in).readByteArray(-1), content, "Content of '" + resourceName + "'"); + try (InputStream in = this.getResourceAsInputStream(resourceName)) { + assertArrayEquals(new JBBPBitInputStream(in).readByteArray(-1), content, + "Content of '" + resourceName + "'"); } } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java index fb9b6a2d..1c09dbe2 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/BasedOnQuestionsAndCasesTest.java @@ -472,26 +472,26 @@ class BKlazz { JBBPParser parser = JBBPParser.prepare("byte [$alen] a; byte [$blen] b; byte [$clen] c;"); - BKlazz parsed = parser.parse(new byte[] {1,2,3}, null, new JBBPExternalValueProvider() { + BKlazz parsed = parser.parse(new byte[] {1, 2, 3}, null, new JBBPExternalValueProvider() { @Override public int provideArraySize(String fieldName, JBBPNamedNumericFieldMap numericFieldMap, JBBPCompiledBlock compiledBlock) { - if ("alen".equals(fieldName)) { - return 0; - } else if ("blen".equals(fieldName)) { - return 3; - } else if ("clen".equals(fieldName)) { - return 0; - } else { - throw new IllegalArgumentException("Unknown name: " + fieldName); - } + if ("alen".equals(fieldName)) { + return 0; + } else if ("blen".equals(fieldName)) { + return 3; + } else if ("clen".equals(fieldName)) { + return 0; + } else { + throw new IllegalArgumentException("Unknown name: " + fieldName); + } } }).mapTo(new BKlazz()); assertArrayEquals(new byte[0], parsed.a); - assertArrayEquals(new byte[]{1,2,3}, parsed.b); + assertArrayEquals(new byte[] {1, 2, 3}, parsed.b); assertArrayEquals(new byte[0], parsed.c); } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/ClassParsingTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/ClassParsingTest.java index 55093fe2..18075bb3 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/ClassParsingTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/ClassParsingTest.java @@ -16,6 +16,11 @@ package com.igormaznitsa.jbbp.it; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + + import com.igormaznitsa.jbbp.JBBPNamedNumericFieldMap; import com.igormaznitsa.jbbp.JBBPParser; import com.igormaznitsa.jbbp.JBBPVarFieldProcessor; @@ -27,13 +32,10 @@ import com.igormaznitsa.jbbp.model.JBBPAbstractField; import com.igormaznitsa.jbbp.model.JBBPFieldArrayByte; import com.igormaznitsa.jbbp.utils.JBBPUtils; -import org.junit.jupiter.api.Test; - import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; - -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class ClassParsingTest extends AbstractParserIntegrationTest { @@ -88,7 +90,8 @@ public class ClassParsingTest extends AbstractParserIntegrationTest { + "ushort minor_version;" + "ushort major_version;" + "ushort constant_pool_count;" - + "constant_pool_item [constant_pool_count - 1] { var [1] cp_item; //we can make any array size because the field will be processed by a custom processor\n }" + + + "constant_pool_item [constant_pool_count - 1] { var [1] cp_item; //we can make any array size because the field will be processed by a custom processor\n }" + "ushort access_flags;" + "ushort this_class;" + "ushort super_class;" @@ -131,7 +134,10 @@ private JBBPVarFieldProcessor getVarFieldProcessor() { return new JBBPVarFieldProcessor() { @Override - public JBBPAbstractArrayField readVarArray(final JBBPBitInputStream inStream, final int arraySize, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { + public JBBPAbstractArrayField readVarArray( + final JBBPBitInputStream inStream, final int arraySize, + final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { if ("cp_item".equals(fieldName.getFieldName())) { final int tagItem = inStream.readByte(); final JBBPFieldArrayByte result; @@ -139,7 +145,9 @@ public JBBPAbstractArrayField readVarArray(final JB case CONSTANT_Class: case CONSTANT_String: case CONSTANT_MethodType: { - result = new JBBPFieldArrayByte(fieldName, new byte[] {(byte) tagItem, (byte) inStream.readByte(), (byte) inStream.readByte()}); + result = new JBBPFieldArrayByte(fieldName, + new byte[] {(byte) tagItem, (byte) inStream.readByte(), + (byte) inStream.readByte()}); } break; case CONSTANT_InterfaceMethodref: @@ -148,12 +156,20 @@ public JBBPAbstractArrayField readVarArray(final JB case CONSTANT_Float: case CONSTANT_Integer: case CONSTANT_NameAndType: { - result = new JBBPFieldArrayByte(fieldName, new byte[] {(byte) tagItem, (byte) inStream.readByte(), (byte) inStream.readByte(), (byte) inStream.readByte(), (byte) inStream.readByte()}); + result = new JBBPFieldArrayByte(fieldName, + new byte[] {(byte) tagItem, (byte) inStream.readByte(), + (byte) inStream.readByte(), (byte) inStream.readByte(), + (byte) inStream.readByte()}); } break; case CONSTANT_Double: case CONSTANT_Long: { - result = new JBBPFieldArrayByte(fieldName, new byte[] {(byte) tagItem, (byte) inStream.readByte(), (byte) inStream.readByte(), (byte) inStream.readByte(), (byte) inStream.readByte(), (byte) inStream.readByte(), (byte) inStream.readByte(), (byte) inStream.readByte(), (byte) inStream.readByte()}); + result = new JBBPFieldArrayByte(fieldName, + new byte[] {(byte) tagItem, (byte) inStream.readByte(), + (byte) inStream.readByte(), (byte) inStream.readByte(), + (byte) inStream.readByte(), (byte) inStream.readByte(), + (byte) inStream.readByte(), (byte) inStream.readByte(), + (byte) inStream.readByte()}); } break; case CONSTANT_Utf8: { @@ -171,7 +187,9 @@ public JBBPAbstractArrayField readVarArray(final JB break; case CONSTANT_MethodHandle: case CONSTANT_InvokeDynamic: { - result = new JBBPFieldArrayByte(fieldName, new byte[] {(byte) tagItem, (byte) inStream.readByte(), (byte) inStream.readByte(), (byte) inStream.readByte()}); + result = new JBBPFieldArrayByte(fieldName, + new byte[] {(byte) tagItem, (byte) inStream.readByte(), + (byte) inStream.readByte(), (byte) inStream.readByte()}); } break; default: { @@ -186,20 +204,26 @@ public JBBPAbstractArrayField readVarArray(final JB } @Override - public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException { + public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, + final JBBPNamedFieldInfo fieldName, + final int extraValue, final JBBPByteOrder byteOrder, + final JBBPNamedNumericFieldMap numericFieldMap) + throws IOException { fail("Must not be called"); return null; } }; } - private String extractClassNameFromConstantPool(final ClassFile klazz, final int classInfoIndex) throws Exception { + private String extractClassNameFromConstantPool(final ClassFile klazz, final int classInfoIndex) + throws Exception { final byte[] constantClassInfo = klazz.constant_pool_item[classInfoIndex - 1].cp_item; final int utf8Index = (constantClassInfo[1] << 8) | (constantClassInfo[2] & 0xFF); return extractUtf8FromConstantPool(klazz, utf8Index); } - private String extractUtf8FromConstantPool(final ClassFile klazz, final int utf8Index) throws Exception { + private String extractUtf8FromConstantPool(final ClassFile klazz, final int utf8Index) + throws Exception { final byte[] utf8data = klazz.constant_pool_item[utf8Index - 1].cp_item; return new String(utf8data, 3, utf8data.length - 3, StandardCharsets.UTF_8); } @@ -214,7 +238,9 @@ private void assertAttribute(final ClassFile klass, final AttributeInfo attr) th fail("Disallowed attribute '" + attrName + '\''); } - private void assertClass(final ClassFile klazz, final int majorVersion, final String className, final String superclass, final int interfaces, final int fields, final int methods) throws Exception { + private void assertClass(final ClassFile klazz, final int majorVersion, final String className, + final String superclass, final int interfaces, final int fields, + final int methods) throws Exception { assertEquals(0xCAFEBABE, klazz.magic); assertEquals(0, klazz.minor_version); assertEquals(majorVersion, klazz.major_version); @@ -252,7 +278,8 @@ private void assertClass(final ClassFile klazz, final int majorVersion, final St public void testParseClassFile_TestClass() throws Exception { final InputStream in = getResourceAsInputStream("test.clazz"); try { - final ClassFile klazz = classParser.parse(in, getVarFieldProcessor(), null).mapTo(new ClassFile()); + final ClassFile klazz = + classParser.parse(in, getVarFieldProcessor(), null).mapTo(new ClassFile()); assertClass(klazz, FORMAT_J2SE7, "Test", "java/lang/Object", 0, 2, 4); assertEquals(831, classParser.getFinalStreamByteCounter()); } finally { @@ -264,8 +291,10 @@ public void testParseClassFile_TestClass() throws Exception { public void testParseClassFile_HexEngineClass() throws Exception { final InputStream in = getResourceAsInputStream("hexengine.clazz"); try { - final ClassFile klazz = classParser.parse(in, getVarFieldProcessor(), null).mapTo(new ClassFile()); - assertClass(klazz, FORMAT_J2SE5, "com/igormaznitsa/jhexed/engine/HexEngine", "java/lang/Object", 0, 22, 44); + final ClassFile klazz = + classParser.parse(in, getVarFieldProcessor(), null).mapTo(new ClassFile()); + assertClass(klazz, FORMAT_J2SE5, "com/igormaznitsa/jhexed/engine/HexEngine", + "java/lang/Object", 0, 22, 44); assertEquals(21364, classParser.getFinalStreamByteCounter()); } finally { JBBPUtils.closeQuietly(in); @@ -299,7 +328,7 @@ public static class AttributeInfo { } @Bin - public static class ClassFile { + public static class ClassFile { int magic; char minor_version; char major_version; diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/ConvertToJSONTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/ConvertToJSONTest.java index 75e7d17b..b2269820 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/ConvertToJSONTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/ConvertToJSONTest.java @@ -16,6 +16,9 @@ package com.igormaznitsa.jbbp.it; +import static org.junit.jupiter.api.Assertions.assertTrue; + + import com.igormaznitsa.jbbp.JBBPParser; import com.igormaznitsa.jbbp.model.JBBPAbstractArrayField; import com.igormaznitsa.jbbp.model.JBBPAbstractField; @@ -37,15 +40,12 @@ import com.igormaznitsa.jbbp.model.JBBPFieldStruct; import com.igormaznitsa.jbbp.model.JBBPFieldUByte; import com.igormaznitsa.jbbp.model.JBBPFieldUShort; +import java.io.InputStream; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.JSONStyle; import org.junit.jupiter.api.Test; -import java.io.InputStream; - -import static org.junit.jupiter.api.Assertions.assertTrue; - public class ConvertToJSONTest extends AbstractParserIntegrationTest { public static JSONObject convertToJSon(final JSONObject jsn, final JBBPAbstractField field) { @@ -135,14 +135,14 @@ public void testConvertToJSON() throws Exception { try (InputStream pngStream = getResourceAsInputStream("picture.png")) { final JBBPParser pngParser = JBBPParser.prepare( - "long header;" - + "// chunks\n" - + "chunk [_]{" - + " int length; " - + " int type; " - + " byte[length] data; " - + " int crc;" - + "}" + "long header;" + + "// chunks\n" + + "chunk [_]{" + + " int length; " + + " int type; " + + " byte[length] data; " + + " int crc;" + + "}" ); final JSONObject json = convertToJSon(null, pngParser.parse(pngStream)); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/CustomThreeByteIntegerTypeTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/CustomThreeByteIntegerTypeTest.java index e433dc85..ac17a9bb 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/CustomThreeByteIntegerTypeTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/CustomThreeByteIntegerTypeTest.java @@ -16,6 +16,11 @@ package com.igormaznitsa.jbbp.it; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + + import com.igormaznitsa.jbbp.JBBPCustomFieldTypeProcessor; import com.igormaznitsa.jbbp.JBBPParser; import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; @@ -29,14 +34,10 @@ import com.igormaznitsa.jbbp.model.JBBPFieldArrayInt; import com.igormaznitsa.jbbp.model.JBBPFieldInt; import com.igormaznitsa.jbbp.model.JBBPFieldStruct; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.function.Executable; - import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Arrays; - -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; /** * Example of three byte integer custom type processor to parse unsigned integer values represented by three bytes in data stream. @@ -46,24 +47,32 @@ public class CustomThreeByteIntegerTypeTest extends AbstractParserIntegrationTes @Test public void testCustomFieldAsAnonymousSingleField() throws Exception { final JBBPParser parser = JBBPParser.prepare("int24;", new Int24CustomTypeProcessor()); - assertEquals(5, parser.parse(new byte[] {0, 0, 5}).findFieldForType(JBBPFieldInt.class).getAsInt()); + assertEquals(5, + parser.parse(new byte[] {0, 0, 5}).findFieldForType(JBBPFieldInt.class).getAsInt()); } @Test public void testReadThreeByteInteger_AnonymousArray() throws Exception { final JBBPParser parser = JBBPParser.prepare("int24 [_];", new Int24CustomTypeProcessor()); - assertArrayEquals(new int[] {0x010203, 0x040506, 0x070809}, parser.parse(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}).findFieldForType(JBBPFieldArrayInt.class).getArray()); + assertArrayEquals(new int[] {0x010203, 0x040506, 0x070809}, + parser.parse(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}) + .findFieldForType(JBBPFieldArrayInt.class).getArray()); } @Test public void testReadThreeByte_NamedCustomFieldAsArrayLength() throws Exception { - final JBBPParser parser = JBBPParser.prepare("int24 value; byte [value];", new Int24CustomTypeProcessor()); - assertEquals(5, parser.parse(new byte[] {0, 0, 5, 1, 2, 3, 4, 5}).findFieldForType(JBBPFieldArrayByte.class).size()); + final JBBPParser parser = + JBBPParser.prepare("int24 value; byte [value];", new Int24CustomTypeProcessor()); + assertEquals(5, + parser.parse(new byte[] {0, 0, 5, 1, 2, 3, 4, 5}).findFieldForType(JBBPFieldArrayByte.class) + .size()); } @Test public void testReadThreeByteInteger_NamedCustomFieldInExpression() throws Exception { - final JBBPParser parser = JBBPParser.prepare("int24 value1; int24 value2; byte [value1+value2];", new Int24CustomTypeProcessor()); + final JBBPParser parser = JBBPParser + .prepare("int24 value1; int24 value2; byte [value1+value2];", + new Int24CustomTypeProcessor()); final JBBPFieldStruct struct = parser.parse(new byte[] {0, 0, 2, 0, 0, 3, 1, 2, 3, 4, 5}); assertEquals(5, struct.findFieldForType(JBBPFieldArrayByte.class).size()); assertEquals(2, struct.findFieldForNameAndType("value1", JBBPFieldInt.class).getAsInt()); @@ -73,11 +82,20 @@ public void testReadThreeByteInteger_NamedCustomFieldInExpression() throws Excep @Test public void testReadThreeByteInteger_OneValue() throws Exception { final JBBPParser parser = JBBPParser.prepare("int24 value;", new Int24CustomTypeProcessor()); - final JBBPParser inverseparser = JBBPParser.prepare(">> 8); } @@ -147,14 +174,21 @@ public String[] getCustomFieldTypes() { } @Override - public boolean isAllowed(final JBBPFieldTypeParameterContainer fieldType, final String fieldName, final int extraData, final boolean isArray) { + public boolean isAllowed(final JBBPFieldTypeParameterContainer fieldType, + final String fieldName, final int extraData, final boolean isArray) { return extraData == 0; } @Override - public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in, final JBBPBitOrder bitOrder, final int parserFlags, final JBBPFieldTypeParameterContainer customTypeFieldInfo, final JBBPNamedFieldInfo fieldName, final int extraData, final boolean readWholeStream, final int arrayLength) throws IOException { + public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in, + final JBBPBitOrder bitOrder, final int parserFlags, + final JBBPFieldTypeParameterContainer customTypeFieldInfo, + final JBBPNamedFieldInfo fieldName, + final int extraData, final boolean readWholeStream, + final int arrayLength) throws IOException { if (arrayLength < 0) { - return new JBBPFieldInt(fieldName, readThreeBytesAsInt(in, customTypeFieldInfo.getByteOrder(), bitOrder)); + return new JBBPFieldInt(fieldName, + readThreeBytesAsInt(in, customTypeFieldInfo.getByteOrder(), bitOrder)); } else { if (readWholeStream) { final IntBuffer intBuffer = new IntBuffer(1024); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/NetPacketParsingTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/NetPacketParsingTest.java index 4dca2c5e..2ff98ba0 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/NetPacketParsingTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/NetPacketParsingTest.java @@ -43,7 +43,8 @@ public class NetPacketParsingTest extends AbstractParserIntegrationTest { @Test public void testParsingTCPFrameInsideNetworkFrame() throws Exception { - final JBBPBitInputStream netPacketStream = new JBBPBitInputStream(getResourceAsInputStream("tcppacket.bin")); + final JBBPBitInputStream netPacketStream = + new JBBPBitInputStream(getResourceAsInputStream("tcppacket.bin")); try { // Ethernet header Ethernet II @@ -67,7 +68,8 @@ public void testParsingTCPFrameInsideNetworkFrame() throws Exception { + "ushort HeaderChecksum;" + "int SourceAddress;" + "int DestinationAddress;" - + "byte [((InternetHeaderLength-5)*4)*((((InternetHeaderLength-5)&16)^16)>>4)] Options;" + + + "byte [((InternetHeaderLength-5)*4)*((((InternetHeaderLength-5)&16)^16)>>4)] Options;" ); // TCP header @@ -95,16 +97,26 @@ public void testParsingTCPFrameInsideNetworkFrame() throws Exception { // Check Ethernet header - final JBBPFieldStruct parsedEthernetHeader = ethernetParserHeaderWithout802_1QTag.parse(netPacketStream); - assertArrayEquals(new byte[] {(byte) 0x60, (byte) 0x67, (byte) 0x20, (byte) 0xE1, (byte) 0xF9, (byte) 0xF8}, parsedEthernetHeader.findFieldForNameAndType("MacDestination", JBBPFieldArrayByte.class).getArray(), "Destination MAC"); - assertArrayEquals(new byte[] {(byte) 0x00, (byte) 0x26, (byte) 0x44, (byte) 0x74, (byte) 0xFE, (byte) 0x66}, parsedEthernetHeader.findFieldForNameAndType("MacSource", JBBPFieldArrayByte.class).getArray(), "Source MAC"); - - final int etherTypeOrLength = parsedEthernetHeader.findFieldForNameAndType("EtherTypeOrLength", JBBPFieldUShort.class).getAsInt(); + final JBBPFieldStruct parsedEthernetHeader = + ethernetParserHeaderWithout802_1QTag.parse(netPacketStream); + assertArrayEquals( + new byte[] {(byte) 0x60, (byte) 0x67, (byte) 0x20, (byte) 0xE1, (byte) 0xF9, (byte) 0xF8}, + parsedEthernetHeader.findFieldForNameAndType("MacDestination", JBBPFieldArrayByte.class) + .getArray(), "Destination MAC"); + assertArrayEquals( + new byte[] {(byte) 0x00, (byte) 0x26, (byte) 0x44, (byte) 0x74, (byte) 0xFE, (byte) 0x66}, + parsedEthernetHeader.findFieldForNameAndType("MacSource", JBBPFieldArrayByte.class) + .getArray(), "Source MAC"); + + final int etherTypeOrLength = + parsedEthernetHeader.findFieldForNameAndType("EtherTypeOrLength", JBBPFieldUShort.class) + .getAsInt(); assertEquals(0x800, etherTypeOrLength, "Ethernet type or length"); if (etherTypeOrLength > 1500) { // list of protocols http://standards-oui.ieee.org/ethertype/eth.txt - System.out.println("Ethernet type is : 0x" + Integer.toHexString(etherTypeOrLength).toUpperCase()); + System.out.println( + "Ethernet type is : 0x" + Integer.toHexString(etherTypeOrLength).toUpperCase()); } else { System.out.println("Payload length : " + etherTypeOrLength); } @@ -114,39 +126,69 @@ public void testParsingTCPFrameInsideNetworkFrame() throws Exception { netPacketStream.resetCounter(); final JBBPFieldStruct parsedIPHeader = ipParserHeaderWithoutOptions.parse(netPacketStream); - assertEquals(4, parsedIPHeader.findFieldForNameAndType("Version", JBBPFieldBit.class).getAsInt(), "IP Version"); + assertEquals(4, + parsedIPHeader.findFieldForNameAndType("Version", JBBPFieldBit.class).getAsInt(), + "IP Version"); - final int internetHeaderLength = parsedIPHeader.findFieldForNameAndType("InternetHeaderLength", JBBPFieldBit.class).getAsInt(); + final int internetHeaderLength = + parsedIPHeader.findFieldForNameAndType("InternetHeaderLength", JBBPFieldBit.class) + .getAsInt(); assertEquals(5, internetHeaderLength, "Length of the IP header (in 4 byte items)"); - assertEquals(0, parsedIPHeader.findFieldForNameAndType("DSCP", JBBPFieldBit.class).getAsInt(), "Differentiated Services Code Point"); - assertEquals(0, parsedIPHeader.findFieldForNameAndType("ECN", JBBPFieldBit.class).getAsInt(), "Explicit Congestion Notification"); + assertEquals(0, parsedIPHeader.findFieldForNameAndType("DSCP", JBBPFieldBit.class).getAsInt(), + "Differentiated Services Code Point"); + assertEquals(0, parsedIPHeader.findFieldForNameAndType("ECN", JBBPFieldBit.class).getAsInt(), + "Explicit Congestion Notification"); - final int ipTotalPacketLength = parsedIPHeader.findFieldForNameAndType("TotalPacketLength", JBBPFieldUShort.class).getAsInt(); + final int ipTotalPacketLength = + parsedIPHeader.findFieldForNameAndType("TotalPacketLength", JBBPFieldUShort.class) + .getAsInt(); - assertEquals(159, ipTotalPacketLength, "Entire IP packet size, including header and data, in bytes"); - assertEquals(30810, parsedIPHeader.findFieldForNameAndType("Identification", JBBPFieldUShort.class).getAsInt(), "Identification"); + assertEquals(159, ipTotalPacketLength, + "Entire IP packet size, including header and data, in bytes"); + assertEquals(30810, + parsedIPHeader.findFieldForNameAndType("Identification", JBBPFieldUShort.class) + .getAsInt(), "Identification"); - final int ipFlagsAndFragmentOffset = parsedIPHeader.findFieldForNameAndType("IPFlagsAndFragmentOffset", JBBPFieldUShort.class).getAsInt(); + final int ipFlagsAndFragmentOffset = + parsedIPHeader.findFieldForNameAndType("IPFlagsAndFragmentOffset", JBBPFieldUShort.class) + .getAsInt(); assertEquals(0x2, ipFlagsAndFragmentOffset >>> 13, "Extracted IP flags"); assertEquals(0x00, ipFlagsAndFragmentOffset & 0x1FFF, "Extracted Fragment offset"); - assertEquals(0x39, parsedIPHeader.findFieldForNameAndType("TTL", JBBPFieldUByte.class).getAsInt(), "Time To Live"); - assertEquals(0x06, parsedIPHeader.findFieldForNameAndType("Protocol", JBBPFieldUByte.class).getAsInt(), "Protocol (RFC-790)"); - assertEquals(0x7DB6, parsedIPHeader.findFieldForNameAndType("HeaderChecksum", JBBPFieldUShort.class).getAsInt(), "IPv4 Header Checksum"); - assertEquals(0xD5C7B393, parsedIPHeader.findFieldForNameAndType("SourceAddress", JBBPFieldInt.class).getAsInt(), "Source IP address"); - assertEquals(0xC0A80145, parsedIPHeader.findFieldForNameAndType("DestinationAddress", JBBPFieldInt.class).getAsInt(), "Destination IP address"); - - assertEquals(0, parsedIPHeader.findFieldForNameAndType("Options", JBBPFieldArrayByte.class).getArray().length); + assertEquals(0x39, + parsedIPHeader.findFieldForNameAndType("TTL", JBBPFieldUByte.class).getAsInt(), + "Time To Live"); + assertEquals(0x06, + parsedIPHeader.findFieldForNameAndType("Protocol", JBBPFieldUByte.class).getAsInt(), + "Protocol (RFC-790)"); + assertEquals(0x7DB6, + parsedIPHeader.findFieldForNameAndType("HeaderChecksum", JBBPFieldUShort.class) + .getAsInt(), "IPv4 Header Checksum"); + assertEquals(0xD5C7B393, + parsedIPHeader.findFieldForNameAndType("SourceAddress", JBBPFieldInt.class).getAsInt(), + "Source IP address"); + assertEquals(0xC0A80145, + parsedIPHeader.findFieldForNameAndType("DestinationAddress", JBBPFieldInt.class) + .getAsInt(), "Destination IP address"); + + assertEquals(0, parsedIPHeader.findFieldForNameAndType("Options", JBBPFieldArrayByte.class) + .getArray().length); // Check TCP header netPacketStream.resetCounter(); final JBBPFieldStruct parsedTcpHeader = tcpHeader.parse(netPacketStream); - assertEquals(40018, parsedTcpHeader.findFieldForNameAndType("SourcePort", JBBPFieldUShort.class).getAsInt()); - assertEquals(56344, parsedTcpHeader.findFieldForNameAndType("DestinationPort", JBBPFieldUShort.class).getAsInt()); - assertEquals(0xE0084171, parsedTcpHeader.findFieldForNameAndType("SequenceNumber", JBBPFieldInt.class).getAsInt()); - assertEquals(0xAB616F71, parsedTcpHeader.findFieldForNameAndType("AcknowledgementNumber", JBBPFieldInt.class).getAsInt()); + assertEquals(40018, + parsedTcpHeader.findFieldForNameAndType("SourcePort", JBBPFieldUShort.class).getAsInt()); + assertEquals(56344, + parsedTcpHeader.findFieldForNameAndType("DestinationPort", JBBPFieldUShort.class) + .getAsInt()); + assertEquals(0xE0084171, + parsedTcpHeader.findFieldForNameAndType("SequenceNumber", JBBPFieldInt.class).getAsInt()); + assertEquals(0xAB616F71, + parsedTcpHeader.findFieldForNameAndType("AcknowledgementNumber", JBBPFieldInt.class) + .getAsInt()); assertFalse(parsedTcpHeader.findFieldForNameAndType("FIN", JBBPFieldBit.class).getAsBool()); assertFalse(parsedTcpHeader.findFieldForNameAndType("SYN", JBBPFieldBit.class).getAsBool()); @@ -154,25 +196,36 @@ public void testParsingTCPFrameInsideNetworkFrame() throws Exception { assertTrue(parsedTcpHeader.findFieldForNameAndType("PSH", JBBPFieldBit.class).getAsBool()); assertTrue(parsedTcpHeader.findFieldForNameAndType("ACK", JBBPFieldBit.class).getAsBool()); assertFalse(parsedTcpHeader.findFieldForNameAndType("URG", JBBPFieldBit.class).getAsBool()); - assertFalse(parsedTcpHeader.findFieldForNameAndType("ECNECHO", JBBPFieldBit.class).getAsBool()); + assertFalse( + parsedTcpHeader.findFieldForNameAndType("ECNECHO", JBBPFieldBit.class).getAsBool()); assertFalse(parsedTcpHeader.findFieldForNameAndType("CWR", JBBPFieldBit.class).getAsBool()); assertFalse(parsedTcpHeader.findFieldForNameAndType("NONCE", JBBPFieldBit.class).getAsBool()); - assertFalse(parsedTcpHeader.findFieldForNameAndType("RESERVED", JBBPFieldBit.class).getAsBool()); + assertFalse( + parsedTcpHeader.findFieldForNameAndType("RESERVED", JBBPFieldBit.class).getAsBool()); - assertEquals(5, parsedTcpHeader.findFieldForNameAndType("HLEN", JBBPFieldBit.class).getAsInt()); + assertEquals(5, + parsedTcpHeader.findFieldForNameAndType("HLEN", JBBPFieldBit.class).getAsInt()); - assertEquals(40880, parsedTcpHeader.findFieldForNameAndType("WindowSize", JBBPFieldUShort.class).getAsInt()); - assertEquals(0x8BB6, parsedTcpHeader.findFieldForNameAndType("TCPCheckSum", JBBPFieldUShort.class).getAsInt()); - assertEquals(0, parsedTcpHeader.findFieldForNameAndType("UrgentPointer", JBBPFieldUShort.class).getAsInt()); + assertEquals(40880, + parsedTcpHeader.findFieldForNameAndType("WindowSize", JBBPFieldUShort.class).getAsInt()); + assertEquals(0x8BB6, + parsedTcpHeader.findFieldForNameAndType("TCPCheckSum", JBBPFieldUShort.class).getAsInt()); + assertEquals(0, + parsedTcpHeader.findFieldForNameAndType("UrgentPointer", JBBPFieldUShort.class) + .getAsInt()); - assertEquals(0, parsedTcpHeader.findFieldForNameAndType("Option", JBBPFieldArrayByte.class).size()); + assertEquals(0, + parsedTcpHeader.findFieldForNameAndType("Option", JBBPFieldArrayByte.class).size()); // extract data - final int payloadDataLength = ipTotalPacketLength - (internetHeaderLength * 4) - (int) netPacketStream.getCounter(); + final int payloadDataLength = + ipTotalPacketLength - (internetHeaderLength * 4) - (int) netPacketStream.getCounter(); final byte[] data = netPacketStream.readByteArray(payloadDataLength); assertEquals(119, data.length); - System.out.println(new JBBPTextWriter(new StringWriter()).Comment("Payload data extracted from the TCP part").Byte(data).BR().toString()); + System.out.println( + new JBBPTextWriter(new StringWriter()).Comment("Payload data extracted from the TCP part") + .Byte(data).BR().toString()); final byte[] restOfFrame = netPacketStream.readByteArray(-1); assertEquals(0, restOfFrame.length); @@ -198,9 +251,11 @@ final class Parsed { int dataLength; } - final byte[] testArray = new byte[] {0x23, 0x21, (byte) 0x90, 0x23, 0x21, 0x22, 0x12, 0x00, (byte) 0xAA}; + 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;") + final Parsed parsed = JBBPParser.prepare( + "byte begin; bit:4 version; bit:4 returnType; byte [5] productCode; ushort dataLength;") .parse(testArray) .mapTo(new Parsed()); @@ -229,9 +284,15 @@ final class Parsed { byte[] data; } - final byte[] testArray = new byte[] {0x04, (byte) 0x89, 0x00, 0x35, 0x00, 0x2C, (byte) 0xAB, (byte) 0xB4, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x70, 0x6F, 0x70, 0x64, 0x02, 0x69, 0x78, 0x06, 0x6E, 0x65, 0x74, 0x63, 0x6F, 0x6D, 0x03, 0x63, 0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01}; + final byte[] testArray = + new byte[] {0x04, (byte) 0x89, 0x00, 0x35, 0x00, 0x2C, (byte) 0xAB, (byte) 0xB4, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x70, 0x6F, 0x70, + 0x64, 0x02, 0x69, 0x78, 0x06, 0x6E, 0x65, 0x74, 0x63, 0x6F, 0x6D, 0x03, 0x63, 0x6F, + 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01}; - final Parsed parsed = JBBPParser.prepare("ushort source; ushort destination; ushort length; ushort checksum; byte [length-8] data;").parse(testArray).mapTo(new Parsed()); + final Parsed parsed = JBBPParser.prepare( + "ushort source; ushort destination; ushort length; ushort checksum; byte [length-8] data;") + .parse(testArray).mapTo(new Parsed()); assertEquals(0x0489, parsed.source); assertEquals(0x0035, parsed.destination); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/PNGParsingTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/PNGParsingTest.java index 47a3197f..2a9727c7 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/PNGParsingTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/PNGParsingTest.java @@ -36,11 +36,15 @@ public class PNGParsingTest extends AbstractParserIntegrationTest { - private static void assertChunk(final String name, final int length, final JBBPFieldStruct chunk) { - final int chunkName = (name.charAt(0) << 24) | (name.charAt(1) << 16) | (name.charAt(2) << 8) | name.charAt(3); + private static void assertChunk(final String name, final int length, + final JBBPFieldStruct chunk) { + final int chunkName = + (name.charAt(0) << 24) | (name.charAt(1) << 16) | (name.charAt(2) << 8) | name.charAt(3); - assertEquals(chunkName, chunk.findFieldForNameAndType("type", JBBPFieldInt.class).getAsInt(), "Chunk must be " + name); - assertEquals(length, chunk.findFieldForNameAndType("length", JBBPFieldInt.class).getAsInt(), "Chunk length must be " + length); + assertEquals(chunkName, chunk.findFieldForNameAndType("type", JBBPFieldInt.class).getAsInt(), + "Chunk must be " + name); + assertEquals(length, chunk.findFieldForNameAndType("length", JBBPFieldInt.class).getAsInt(), + "Chunk length must be " + length); final PureJavaCrc32 crc32 = new PureJavaCrc32(); crc32.update(name.charAt(0)); @@ -57,7 +61,8 @@ private static void assertChunk(final String name, final int length, final JBBPF } final int crc = (int) crc32.getValue(); - assertEquals(crc, chunk.findLastFieldForType(JBBPFieldInt.class).getAsInt(), "CRC32 for " + name + " must be " + crc); + assertEquals(crc, chunk.findLastFieldForType(JBBPFieldInt.class).getAsInt(), + "CRC32 for " + name + " must be " + crc); } @@ -106,13 +111,15 @@ Chunk makeChunk() { assertEquals(0x89504E470D0A1A0AL, png.hEAder); - final String[] chunkNames = new String[] {"IHDR", "gAMA", "bKGD", "pHYs", "tIME", "tEXt", "IDAT", "IEND"}; + final String[] chunkNames = + new String[] {"IHDR", "gAMA", "bKGD", "pHYs", "tIME", "tEXt", "IDAT", "IEND"}; final int[] chunkSizes = new int[] {0x0D, 0x04, 0x06, 0x09, 0x07, 0x19, 0x0E5F, 0x00}; assertEquals(chunkNames.length, png.chuNK.length); for (int i = 0; i < png.chuNK.length; i++) { - assertPngChunk(chunkNames[i], chunkSizes[i], png.chuNK[i].type, png.chuNK[i].length, png.chuNK[i].crc, png.chuNK[i].data); + assertPngChunk(chunkNames[i], chunkSizes[i], png.chuNK[i].type, png.chuNK[i].length, + png.chuNK[i].crc, png.chuNK[i].data); } assertEquals(3847, pngParser.getFinalStreamByteCounter()); @@ -140,11 +147,14 @@ public void testPngParsing() throws Exception { final JBBPFieldStruct result = pngParser.parse(pngStream); - assertEquals(0x89504E470D0A1A0AL, result.findFieldForNameAndType("header", JBBPFieldLong.class).getAsLong()); + assertEquals(0x89504E470D0A1A0AL, + result.findFieldForNameAndType("header", JBBPFieldLong.class).getAsLong()); - final JBBPFieldArrayStruct chunks = result.findFieldForNameAndType("chunk", JBBPFieldArrayStruct.class); + final JBBPFieldArrayStruct chunks = + result.findFieldForNameAndType("chunk", JBBPFieldArrayStruct.class); - final String[] chunkNames = new String[] {"IHDR", "gAMA", "bKGD", "pHYs", "tIME", "tEXt", "IDAT", "IEND"}; + final String[] chunkNames = + new String[] {"IHDR", "gAMA", "bKGD", "pHYs", "tIME", "tEXt", "IDAT", "IEND"}; final int[] chunkSizes = new int[] {0x0D, 0x04, 0x06, 0x09, 0x07, 0x19, 0x0E5F, 0x00}; assertEquals(chunkNames.length, chunks.size()); @@ -175,19 +185,24 @@ public void testPngParsing_WithExternalValue() throws Exception { + "}" ); - final JBBPFieldStruct result = pngParser.parse(pngStream, null, (fieldName, numericFieldMap, compiledBlock) -> { - if ("value".equals(fieldName)) { - return numericFieldMap.findFieldForPathAndType("chunk.length", JBBPFieldInt.class).getAsInt(); - } - fail("Unexpected variable '" + fieldName + '\''); - return -1; - }); + final JBBPFieldStruct result = + pngParser.parse(pngStream, null, (fieldName, numericFieldMap, compiledBlock) -> { + if ("value".equals(fieldName)) { + return numericFieldMap.findFieldForPathAndType("chunk.length", JBBPFieldInt.class) + .getAsInt(); + } + fail("Unexpected variable '" + fieldName + '\''); + return -1; + }); - assertEquals(0x89504E470D0A1A0AL, result.findFieldForNameAndType("header", JBBPFieldLong.class).getAsLong()); + assertEquals(0x89504E470D0A1A0AL, + result.findFieldForNameAndType("header", JBBPFieldLong.class).getAsLong()); - final JBBPFieldArrayStruct chunks = result.findFieldForNameAndType("chunk", JBBPFieldArrayStruct.class); + final JBBPFieldArrayStruct chunks = + result.findFieldForNameAndType("chunk", JBBPFieldArrayStruct.class); - final String[] chunkNames = new String[] {"IHDR", "gAMA", "bKGD", "pHYs", "tIME", "tEXt", "IDAT", "IEND"}; + final String[] chunkNames = + new String[] {"IHDR", "gAMA", "bKGD", "pHYs", "tIME", "tEXt", "IDAT", "IEND"}; final int[] chunkSizes = new int[] {0x0D, 0x04, 0x06, 0x09, 0x07, 0x19, 0x0E5F, 0x00}; assertEquals(chunkNames.length, chunks.size()); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/PackedBCDCustomFieldTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/PackedBCDCustomFieldTest.java index f46ddfa5..e720feb1 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/PackedBCDCustomFieldTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/PackedBCDCustomFieldTest.java @@ -16,6 +16,10 @@ package com.igormaznitsa.jbbp.it; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + + import com.igormaznitsa.jbbp.JBBPCustomFieldTypeProcessor; import com.igormaznitsa.jbbp.JBBPParser; import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; @@ -28,19 +32,15 @@ import com.igormaznitsa.jbbp.model.JBBPFieldArrayLong; import com.igormaznitsa.jbbp.model.JBBPFieldLong; import com.igormaznitsa.jbbp.model.JBBPFieldStruct; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.function.Executable; - import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.Test; public class PackedBCDCustomFieldTest implements JBBPCustomFieldTypeProcessor { private static final String[] types = new String[] {"bcd", "sbcd"}; - public static long readValueFromPackedDecimal(final JBBPBitInputStream in, final int len, final boolean signed) throws IOException { + public static long readValueFromPackedDecimal(final JBBPBitInputStream in, final int len, + final boolean signed) throws IOException { final byte[] data = in.readByteArray(len); StringBuilder digitStr = new StringBuilder(); @@ -68,9 +68,11 @@ public String[] getCustomFieldTypes() { } @Override - public boolean isAllowed(final JBBPFieldTypeParameterContainer fieldType, final String fieldName, final int extraData, final boolean isArray) { + public boolean isAllowed(final JBBPFieldTypeParameterContainer fieldType, final String fieldName, + final int extraData, final boolean isArray) { if (fieldType.getByteOrder() == JBBPByteOrder.LITTLE_ENDIAN) { - System.err.println("Packed Decimal does not support little endian...using big endian instead"); + System.err + .println("Packed Decimal does not support little endian...using big endian instead"); return false; } @@ -78,7 +80,12 @@ public boolean isAllowed(final JBBPFieldTypeParameterContainer fieldType, final } @Override - public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in, final JBBPBitOrder bitOrder, final int parserFlags, final JBBPFieldTypeParameterContainer customTypeFieldInfo, JBBPNamedFieldInfo fieldName, int extraData, boolean readWholeStream, int arrayLength) throws IOException { + public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in, + final JBBPBitOrder bitOrder, final int parserFlags, + final JBBPFieldTypeParameterContainer customTypeFieldInfo, + JBBPNamedFieldInfo fieldName, int extraData, + boolean readWholeStream, int arrayLength) + throws IOException { final boolean signed = "sbcd".equals(customTypeFieldInfo.getTypeName()); if (readWholeStream) { @@ -111,7 +118,8 @@ public void testParse_SingleDefaultNonamedPackedDecimal_BigEndian() throws Excep } @Test - public void testParse_SingleDefaultNonamedPackedDecimal_LittleEndian_Exception() throws Exception { + public void testParse_SingleDefaultNonamedPackedDecimal_LittleEndian_Exception() + throws Exception { final PackedBCDCustomFieldTest theInstance = this; assertThrows(JBBPCompilationException.class, () -> JBBPParser.prepare(" 10000); System.out.println(text); } @Test public void testParseAndSave_ThroughDslBuilder() throws Exception { - final JBBPParser parser = JBBPParser.prepare(JBBPDslBuilder.Begin().AnnotatedClass(SNA.class).End()); + final JBBPParser parser = + JBBPParser.prepare(JBBPDslBuilder.Begin().AnnotatedClass(SNA.class).End()); final InputStream in = getResourceAsInputStream("zexall.sna"); @@ -100,7 +103,8 @@ public void testParseAndSave_ThroughDslBuilder() throws Exception { JBBPUtils.closeQuietly(in); } - final SNA mapped = parsed.findFieldForNameAndType("SNA", JBBPFieldStruct.class).mapTo(new SNA()); + final SNA mapped = + parsed.findFieldForNameAndType("SNA", JBBPFieldStruct.class).mapTo(new SNA()); assertResource("zexall.sna", JBBPOut.BeginBin().Bin(mapped).End().toByteArray()); } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/TAP_ParsingTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/TAP_ParsingTest.java index a1c804bc..164f8ec8 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/TAP_ParsingTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/TAP_ParsingTest.java @@ -16,24 +16,26 @@ package com.igormaznitsa.jbbp.it; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + + import com.igormaznitsa.jbbp.JBBPParser; import com.igormaznitsa.jbbp.io.JBBPByteOrder; import com.igormaznitsa.jbbp.io.JBBPOut; import com.igormaznitsa.jbbp.mapper.Bin; import com.igormaznitsa.jbbp.mapper.BinType; import com.igormaznitsa.jbbp.utils.JBBPUtils; -import org.junit.jupiter.api.Test; - import java.io.IOException; import java.io.InputStream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.Test; public class TAP_ParsingTest extends AbstractParserIntegrationTest { - public static final JBBPParser HEADER_PARSER = JBBPParser.prepare("byte type; byte [10] name; { - if (aClass == Tap.class) return new Tap(); - throw new Error("Unexpected class: "+aClass); + if (aClass == Tap.class) { + return new Tap(); + } + throw new Error("Unexpected class: " + aClass); }); assertEquals(89410, TAP_FILE_PARSER.getFinalStreamByteCounter()); @@ -116,12 +120,14 @@ static class Header extends TapData { @Override public String toString() { - return "HEADER: " + name + " (length=" + length + ", param1=" + param1 + ", param2=" + param2 + ')'; + return "HEADER: " + name + " (length=" + length + ", param1=" + param1 + ", param2=" + + param2 + ')'; } @Override void save(final JBBPOut ctx) throws IOException { - ctx.Short(19).Byte(0, type).ResetCounter().Byte(name).Align(10).Short(length).Short(param1).Short(param2).Byte(check); + ctx.Short(19).Byte(0, type).ResetCounter().Byte(name).Align(10).Short(length).Short(param1) + .Short(param2).Byte(check); } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/TGAParsingTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/TGAParsingTest.java index 89936ac6..82605ee8 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/TGAParsingTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/TGAParsingTest.java @@ -16,6 +16,9 @@ package com.igormaznitsa.jbbp.it; +import static org.junit.jupiter.api.Assertions.assertEquals; + + import com.igormaznitsa.jbbp.JBBPParser; import com.igormaznitsa.jbbp.model.JBBPFieldArrayByte; import com.igormaznitsa.jbbp.model.JBBPFieldArrayStruct; @@ -24,11 +27,8 @@ import com.igormaznitsa.jbbp.model.JBBPFieldUByte; import com.igormaznitsa.jbbp.model.JBBPFieldUShort; import com.igormaznitsa.jbbp.utils.JBBPUtils; -import org.junit.jupiter.api.Test; - import java.io.InputStream; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; public class TGAParsingTest extends AbstractParserIntegrationTest { @@ -58,8 +58,11 @@ public class TGAParsingTest extends AbstractParserIntegrationTest { "byte [_] ImageData;" ); - private void assertTgaFile(final JBBPFieldStruct parsedTga, final String imageId, final int width, final int height, final int pixelDepth, final int colorTableItems, final int imageDataSize) { - final JBBPFieldArrayByte imageIdArray = parsedTga.findFieldForNameAndType("ImageID", JBBPFieldArrayByte.class); + private void assertTgaFile(final JBBPFieldStruct parsedTga, final String imageId, final int width, + final int height, final int pixelDepth, final int colorTableItems, + final int imageDataSize) { + final JBBPFieldArrayByte imageIdArray = + parsedTga.findFieldForNameAndType("ImageID", JBBPFieldArrayByte.class); if (imageId == null || imageId.length() == 0) { assertEquals(0, imageIdArray.size()); } else { @@ -69,11 +72,16 @@ private void assertTgaFile(final JBBPFieldStruct parsedTga, final String imageId } } - assertEquals(width, parsedTga.findFieldForPathAndType("header.Width", JBBPFieldUShort.class).getAsInt()); - assertEquals(height, parsedTga.findFieldForPathAndType("header.Height", JBBPFieldUShort.class).getAsInt()); - assertEquals(pixelDepth, parsedTga.findFieldForPathAndType("header.PixelDepth", JBBPFieldUByte.class).getAsInt()); - assertEquals(colorTableItems, parsedTga.findFieldForNameAndType("ColorMap", JBBPFieldArrayStruct.class).size()); - assertEquals(imageDataSize, parsedTga.findFieldForNameAndType("ImageData", JBBPFieldArrayByte.class).size()); + assertEquals(width, + parsedTga.findFieldForPathAndType("header.Width", JBBPFieldUShort.class).getAsInt()); + assertEquals(height, + parsedTga.findFieldForPathAndType("header.Height", JBBPFieldUShort.class).getAsInt()); + assertEquals(pixelDepth, + parsedTga.findFieldForPathAndType("header.PixelDepth", JBBPFieldUByte.class).getAsInt()); + assertEquals(colorTableItems, + parsedTga.findFieldForNameAndType("ColorMap", JBBPFieldArrayStruct.class).size()); + assertEquals(imageDataSize, + parsedTga.findFieldForNameAndType("ImageData", JBBPFieldArrayByte.class).size()); } @Test @@ -104,8 +112,10 @@ public void testTgaParsing_Logo() throws Exception { try { final JBBPFieldStruct result = TGAParser.parse(tgaStream); assertTgaFile(result, "", 319, 165, 32, 0, 116944); - assertEquals(0, result.findFieldForPathAndType("Header.XOffset", JBBPFieldShort.class).getAsInt()); - assertEquals(165, result.findFieldForPathAndType("Header.YOffset", JBBPFieldShort.class).getAsInt()); + assertEquals(0, + result.findFieldForPathAndType("Header.XOffset", JBBPFieldShort.class).getAsInt()); + assertEquals(165, + result.findFieldForPathAndType("Header.YOffset", JBBPFieldShort.class).getAsInt()); } finally { JBBPUtils.closeQuietly(tgaStream); } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/WAVParsingTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/WAVParsingTest.java index ad009c9f..a1e047d4 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/WAVParsingTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/WAVParsingTest.java @@ -16,17 +16,17 @@ package com.igormaznitsa.jbbp.it; +import static org.junit.jupiter.api.Assertions.assertEquals; + + import com.igormaznitsa.jbbp.JBBPParser; import com.igormaznitsa.jbbp.model.JBBPFieldArrayByte; import com.igormaznitsa.jbbp.model.JBBPFieldArrayStruct; import com.igormaznitsa.jbbp.model.JBBPFieldInt; import com.igormaznitsa.jbbp.model.JBBPFieldStruct; import com.igormaznitsa.jbbp.utils.JBBPUtils; -import org.junit.jupiter.api.Test; - import java.io.InputStream; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; public class WAVParsingTest extends AbstractParserIntegrationTest { @@ -43,29 +43,40 @@ public class WAVParsingTest extends AbstractParserIntegrationTest { ); private static String wavInt2Str(final int value) { - return new String(new char[] {(char) (value & 0xFF), (char) ((value >>> 8) & 0xFF), (char) ((value >>> 16) & 0xFF), (char) (value >>> 24)}); + return new String(new char[] {(char) (value & 0xFF), (char) ((value >>> 8) & 0xFF), + (char) ((value >>> 16) & 0xFF), (char) (value >>> 24)}); } private static void assertWavChunks(final JBBPFieldStruct parsedWav, final String... chunks) { - assertEquals(0x46464952, parsedWav.findFieldForNameAndType("ChunkID", JBBPFieldInt.class).getAsInt()); - assertEquals(0x45564157, parsedWav.findFieldForNameAndType("Format", JBBPFieldInt.class).getAsInt()); + assertEquals(0x46464952, + parsedWav.findFieldForNameAndType("ChunkID", JBBPFieldInt.class).getAsInt()); + assertEquals(0x45564157, + parsedWav.findFieldForNameAndType("Format", JBBPFieldInt.class).getAsInt()); int calculatedSize = 4; int index = 0; - assertEquals(chunks.length, parsedWav.findFieldForNameAndType("SubChunks", JBBPFieldArrayStruct.class).size(), "Number of parsed subchunks must be [" + chunks.length + ']'); + assertEquals(chunks.length, + parsedWav.findFieldForNameAndType("SubChunks", JBBPFieldArrayStruct.class).size(), + "Number of parsed subchunks must be [" + chunks.length + ']'); - for (final JBBPFieldStruct subchunk : parsedWav.findFieldForNameAndType("SubChunks", JBBPFieldArrayStruct.class)) { + for (final JBBPFieldStruct subchunk : parsedWav + .findFieldForNameAndType("SubChunks", JBBPFieldArrayStruct.class)) { final String strChunkId = chunks[index++]; - assertEquals(4, strChunkId.length(), "WAV subchunk must have 4 char length [" + strChunkId + ']'); - assertEquals(strChunkId, wavInt2Str(subchunk.findFieldForNameAndType("SubChunkID", JBBPFieldInt.class).getAsInt())); - final int subChunkSize = subchunk.findFieldForNameAndType("SubChunkSize", JBBPFieldInt.class).getAsInt(); - assertEquals(subChunkSize, subchunk.findFieldForNameAndType("data", JBBPFieldArrayByte.class).size()); + assertEquals(4, strChunkId.length(), + "WAV subchunk must have 4 char length [" + strChunkId + ']'); + assertEquals(strChunkId, wavInt2Str( + subchunk.findFieldForNameAndType("SubChunkID", JBBPFieldInt.class).getAsInt())); + final int subChunkSize = + subchunk.findFieldForNameAndType("SubChunkSize", JBBPFieldInt.class).getAsInt(); + assertEquals(subChunkSize, + subchunk.findFieldForNameAndType("data", JBBPFieldArrayByte.class).size()); calculatedSize += subChunkSize + 8 + (subChunkSize & 1); } - assertEquals(calculatedSize, parsedWav.findFieldForNameAndType("ChunkSize", JBBPFieldInt.class).getAsInt()); + assertEquals(calculatedSize, + parsedWav.findFieldForNameAndType("ChunkSize", JBBPFieldInt.class).getAsInt()); } @Test diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/Z80_v1_ParsingTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/Z80_v1_ParsingTest.java index 96a6e488..3c033237 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/it/Z80_v1_ParsingTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/it/Z80_v1_ParsingTest.java @@ -54,20 +54,14 @@ public class Z80_v1_ParsingTest extends AbstractParserIntegrationTest { private static final JBBPParser z80Parser = JBBPParser.prepare( "byte reg_a; byte reg_f; , Object> INSTANTIATOR = aClass -> { if (aClass == Flags.class) { return new Flags(); @@ -78,6 +72,28 @@ public void testRLEEncoding() throws Exception { return null; }; + @Test + public void testRLEEncoding() throws Exception { + assertArrayEquals(new byte[] {(byte) 0xED, (byte) 0xED, 1, 2, 3}, JBBPOut.BeginBin() + .Var(new RLEDataEncoder(), 0, new byte[] {(byte) 0xED, (byte) 0xED, 1, 2, 3}).End() + .toByteArray()); + assertArrayEquals( + new byte[] {(byte) 0xED, (byte) 0xED, 2, (byte) 0xED, 1, 2, 3, 0x00, (byte) 0xED, + (byte) 0xED, 0x00}, JBBPOut.BeginBin() + .Var(new RLEDataEncoder(), 1, new byte[] {(byte) 0xED, (byte) 0xED, 1, 2, 3}).End() + .toByteArray()); + assertArrayEquals( + new byte[] {(byte) 0xED, 0x00, (byte) 0xED, (byte) 0xED, 0x05, 0x00, 0x00, (byte) 0xED, + (byte) 0xED, 0x00}, + JBBPOut.BeginBin().Var(new RLEDataEncoder(), 1, new byte[] {(byte) 0xED, 0, 0, 0, 0, 0, 0}) + .End().toByteArray()); + assertArrayEquals( + new byte[] {(byte) 0xED, (byte) 0xED, 8, 5, 1, 2, 3, 0x00, (byte) 0xED, (byte) 0xED, 0x00}, + JBBPOut.BeginBin() + .Var(new RLEDataEncoder(), 1, new byte[] {5, 5, 5, 5, 5, 5, 5, 5, 1, 2, 3}).End() + .toByteArray()); + } + @Test public void testParseAndWriteTestZ80WithoutCheckOfFields() throws Exception { assertParseAndPackBack("test1.z80", 16059); @@ -86,7 +102,8 @@ public void testParseAndWriteTestZ80WithoutCheckOfFields() throws Exception { assertParseAndPackBack("test4.z80", 9946); } - private Z80Snapshot assertParseAndPackBack(final String name, final long etalonLen) throws Exception { + private Z80Snapshot assertParseAndPackBack(final String name, final long etalonLen) + throws Exception { final Z80Snapshot z80sn; final InputStream resource = getResourceAsInputStream(name); @@ -128,19 +145,21 @@ private Z80Snapshot assertParseAndPackBack(final String name, final long etalonL public void testParseAndWriteTestZ80WithCheckOfFields() throws Exception { final Z80Snapshot z80sn = assertParseAndPackBack("test.z80", 12429); - final String text = new JBBPTextWriter().ByteOrder(LITTLE_ENDIAN).SetMaxValuesPerLine(32).AddExtras(new JBBPTextWriterExtraAdapter() { - - @Override - public String doConvertCustomField(JBBPTextWriter context, Object obj, Field field, Bin annotation) throws IOException { - try { - final byte[] data = (byte[]) field.get(obj); - return "byte array length [" + data.length + ']'; - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } + final String text = new JBBPTextWriter().ByteOrder(LITTLE_ENDIAN).SetMaxValuesPerLine(32) + .AddExtras(new JBBPTextWriterExtraAdapter() { + + @Override + public String doConvertCustomField(JBBPTextWriter context, Object obj, Field field, + Bin annotation) throws IOException { + try { + final byte[] data = (byte[]) field.get(obj); + return "byte array length [" + data.length + ']'; + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } - }).Bin(z80sn).Close().toString(); + }).Bin(z80sn).Close().toString(); assertTrue(text.contains("byte array length [49152]")); System.out.println(text); @@ -197,7 +216,8 @@ public void testParseAndPackThrowMapping() throws Exception { JBBPUtils.closeQuietly(in); } - final byte[] saved = JBBPOut.BeginBin(LITTLE_ENDIAN).Bin(parsed, new DataProcessor()).End().toByteArray(); + final byte[] saved = + JBBPOut.BeginBin(LITTLE_ENDIAN).Bin(parsed, new DataProcessor()).End().toByteArray(); assertResource("test.z80", saved); } @@ -205,7 +225,8 @@ public void testParseAndPackThrowMapping() throws Exception { private static class RLEDataEncoder implements JBBPOutVarProcessor { @Override - public boolean processVarOut(final JBBPOut context, final JBBPBitOutputStream outStream, final Object... args) throws IOException { + public boolean processVarOut(final JBBPOut context, final JBBPBitOutputStream outStream, + final Object... args) throws IOException { final byte[] unpackedData = (byte[]) args[1]; if (((Number) args[0]).intValue() == 0) { context.Byte(unpackedData); @@ -263,14 +284,18 @@ public boolean processVarOut(final JBBPOut context, final JBBPBitOutputStream ou } } - private static class DataProcessor implements JBBPMapperCustomFieldProcessor, JBBPCustomFieldWriter { + private static class DataProcessor + implements JBBPMapperCustomFieldProcessor, JBBPCustomFieldWriter { @Override - public Object prepareObjectForMapping(JBBPFieldStruct parsedBlock, Bin annotation, Field field) { + public Object prepareObjectForMapping(JBBPFieldStruct parsedBlock, Bin annotation, + Field field) { if (field.getName().equals("data")) { - final byte[] data = parsedBlock.findFieldForNameAndType("data", JBBPFieldArrayByte.class).getArray(); + final byte[] data = + parsedBlock.findFieldForNameAndType("data", JBBPFieldArrayByte.class).getArray(); - if (parsedBlock.findFieldForPathAndType("flags.compressed", JBBPFieldBit.class).getAsBool()) { + if (parsedBlock.findFieldForPathAndType("flags.compressed", JBBPFieldBit.class) + .getAsBool()) { // RLE compressed final ByteArrayOutputStream baos = new ByteArrayOutputStream(data.length << 1); int i = 0; @@ -314,7 +339,9 @@ public Object prepareObjectForMapping(JBBPFieldStruct parsedBlock, Bin annotatio } @Override - public void writeCustomField(final JBBPOut context, final JBBPBitOutputStream out, final Object instanceForSaving, final Field instanceCustomField, final Bin fieldAnnotation, final Object value) throws IOException { + public void writeCustomField(final JBBPOut context, final JBBPBitOutputStream out, + final Object instanceForSaving, final Field instanceCustomField, + final Bin fieldAnnotation, final Object value) throws IOException { try { final byte[] array = (byte[]) instanceCustomField.get(instanceForSaving); new RLEDataEncoder().processVarOut(context, out, 1, array); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/mapper/BinTypeTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/mapper/BinTypeTest.java index a56a8a07..0ba163cf 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/mapper/BinTypeTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/mapper/BinTypeTest.java @@ -16,14 +16,13 @@ package com.igormaznitsa.jbbp.mapper; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.function.Executable; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + import java.math.BigInteger; import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.Test; public class BinTypeTest { diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/mapper/JBBPMapperTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/mapper/JBBPMapperTest.java index dc77d35d..20d7e99f 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/mapper/JBBPMapperTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/mapper/JBBPMapperTest.java @@ -41,7 +41,9 @@ public class JBBPMapperTest { @Test void testMakeNewInstanceInLocalThroughDefaultConstructors() throws Exception { - final StaticTopNoInstanceMethod result = JBBPParser.prepare("levelOne { levelTwos[_]{byte a;}}").parse(new byte[] {1, 2, 3}).mapTo(new StaticTopNoInstanceMethod()); + final StaticTopNoInstanceMethod result = + JBBPParser.prepare("levelOne { levelTwos[_]{byte a;}}").parse(new byte[] {1, 2, 3}) + .mapTo(new StaticTopNoInstanceMethod()); assertNotNull(result.levelOne); assertNotNull(result.levelOne.levelTwos); @@ -50,7 +52,9 @@ void testMakeNewInstanceInLocalThroughDefaultConstructors() throws Exception { @Test void testMakeNewInstanceInLocalStaticClasses() throws Exception { - final StaticTop result = JBBPParser.prepare("levelOne { levelTwos[_]{byte a;}}").parse(new byte[] {1, 2, 3}).mapTo(new StaticTop()); + final StaticTop result = + JBBPParser.prepare("levelOne { levelTwos[_]{byte a;}}").parse(new byte[] {1, 2, 3}) + .mapTo(new StaticTop()); assertNotNull(result.levelOne); assertNotNull(result.levelOne.levelTwos); @@ -88,7 +92,9 @@ class LevelTwo { } } - final Top result = JBBPParser.prepare("levelOne { levelTwos[_]{byte a;}}").parse(new byte[] {1, 2, 3}).mapTo(new Top()); + final Top result = + JBBPParser.prepare("levelOne { levelTwos[_]{byte a;}}").parse(new byte[] {1, 2, 3}) + .mapTo(new Top()); assertNotNull(result.levelOne); assertNotNull(result.levelOne.levelTwos); @@ -101,7 +107,8 @@ class Mapped { @Bin byte a; } - assertEquals(3, JBBPParser.prepare("byte a; some{struc {byte a;}}").parse(new byte[] {1, 3}).mapTo("some.struc", new Mapped()).a); + assertEquals(3, JBBPParser.prepare("byte a; some{struc {byte a;}}").parse(new byte[] {1, 3}) + .mapTo("some.struc", new Mapped()).a); } @Test @@ -110,7 +117,8 @@ class Mapped { @Bin byte a; } - assertEquals(3, JBBPMapper.map(JBBPParser.prepare("byte a;").parse(new byte[] {3}), new Mapped()).a); + assertEquals(3, + JBBPMapper.map(JBBPParser.prepare("byte a;").parse(new byte[] {3}), new Mapped()).a); } @Test @@ -128,7 +136,8 @@ class Mapped { @Bin short a; } - assertEquals(0x0304, JBBPParser.prepare("short a;").parse(new byte[] {3, 4}).mapTo(new Mapped()).a); + assertEquals(0x0304, + JBBPParser.prepare("short a;").parse(new byte[] {3, 4}).mapTo(new Mapped()).a); } @Test @@ -141,7 +150,9 @@ class Mapped { @Bin boolean c; } - final Mapped mapped = JBBPParser.prepare("bool a; bool b; bool c;").parse(new byte[] {23, 0, 12}).mapTo(new Mapped()); + final Mapped mapped = + JBBPParser.prepare("bool a; bool b; bool c;").parse(new byte[] {23, 0, 12}) + .mapTo(new Mapped()); assertTrue(mapped.a); assertFalse(mapped.b); assertTrue(mapped.c); @@ -155,7 +166,9 @@ class Mapped { @Bin String b; } - final Mapped mapped = JBBPParser.prepare("stringj a; stringj b;").parse(new byte[] {3, 65, 66, 67, 2, 68, 69}).mapTo(new Mapped()); + final Mapped mapped = + JBBPParser.prepare("stringj a; stringj b;").parse(new byte[] {3, 65, 66, 67, 2, 68, 69}) + .mapTo(new Mapped()); assertEquals("ABC", mapped.a); assertEquals("DE", mapped.b); } @@ -166,13 +179,16 @@ class Mapped { @Bin String[] a; } - final Mapped mapped = JBBPParser.prepare("stringj [_] a;").parse(new byte[] {3, 65, 66, 67, 2, 68, 69}).mapTo(new Mapped()); + final Mapped mapped = + JBBPParser.prepare("stringj [_] a;").parse(new byte[] {3, 65, 66, 67, 2, 68, 69}) + .mapTo(new Mapped()); assertArrayEquals(new String[] {"ABC", "DE"}, mapped.a); } @Test void testMap_IgnoreStaticField() throws Exception { - final MappedWithStaticField mapped = JBBPParser.prepare("int a;").parse(new byte[] {1, 2, 3, 4}).mapTo(new MappedWithStaticField()); + final MappedWithStaticField mapped = JBBPParser.prepare("int a;").parse(new byte[] {1, 2, 3, 4}) + .mapTo(new MappedWithStaticField()); assertEquals(0x01020304, mapped.a); assertEquals(111, MappedWithStaticField.ignored); } @@ -187,7 +203,9 @@ class Mapped { @Bin(type = BinType.BIT) byte c; } - final Mapped mapped = JBBPParser.prepare("bit:3 a; bit:2 b; bit:3 c; ").parse(new byte[] {(byte) 0xDD}).mapTo(new Mapped()); + final Mapped mapped = + JBBPParser.prepare("bit:3 a; bit:2 b; bit:3 c; ").parse(new byte[] {(byte) 0xDD}) + .mapTo(new Mapped()); assertEquals(5, mapped.a); assertEquals(3, mapped.b); assertEquals(6, mapped.c); @@ -199,7 +217,8 @@ class Mapped { @Bin int a; } - assertEquals(0x01020304, JBBPParser.prepare("int a;").parse(new byte[] {1, 2, 3, 4}).mapTo(new Mapped()).a); + assertEquals(0x01020304, + JBBPParser.prepare("int a;").parse(new byte[] {1, 2, 3, 4}).mapTo(new Mapped()).a); } @Test @@ -209,10 +228,14 @@ class Mapped { float a; } - final byte[] max = JBBPOut.BeginBin().Int(Float.floatToIntBits(Float.MAX_VALUE)).End().toByteArray(); - assertEquals(Float.MAX_VALUE, JBBPParser.prepare("int a;").parse(max).mapTo(new Mapped()).a, 0.005d); - final byte[] min = JBBPOut.BeginBin().Int(Float.floatToIntBits(Float.MIN_VALUE)).End().toByteArray(); - assertEquals(Float.MIN_VALUE, JBBPParser.prepare("int a;").parse(min).mapTo(new Mapped()).a, 0.005d); + final byte[] max = + JBBPOut.BeginBin().Int(Float.floatToIntBits(Float.MAX_VALUE)).End().toByteArray(); + assertEquals(Float.MAX_VALUE, JBBPParser.prepare("int a;").parse(max).mapTo(new Mapped()).a, + 0.005d); + final byte[] min = + JBBPOut.BeginBin().Int(Float.floatToIntBits(Float.MIN_VALUE)).End().toByteArray(); + assertEquals(Float.MIN_VALUE, JBBPParser.prepare("int a;").parse(min).mapTo(new Mapped()).a, + 0.005d); } @Test @@ -222,7 +245,8 @@ class Mapped { float[] a; } - final byte[] max = JBBPOut.BeginBin().Float(Float.MAX_VALUE, Float.MIN_VALUE).End().toByteArray(); + final byte[] max = + JBBPOut.BeginBin().Float(Float.MAX_VALUE, Float.MIN_VALUE).End().toByteArray(); final Mapped result = JBBPParser.prepare("int [_] a;").parse(max).mapTo(new Mapped()); assertEquals(2, result.a.length); assertEquals(Float.MAX_VALUE, result.a[0], TestUtils.FLOAT_DELTA); @@ -237,7 +261,8 @@ class Mapped { double[] a; } - final byte[] max = JBBPOut.BeginBin().Double(Double.MAX_VALUE, Double.MIN_VALUE).End().toByteArray(); + final byte[] max = + JBBPOut.BeginBin().Double(Double.MAX_VALUE, Double.MIN_VALUE).End().toByteArray(); final Mapped result = JBBPParser.prepare("long [_] a;").parse(max).mapTo(new Mapped()); assertEquals(2, result.a.length); assertEquals(Double.MAX_VALUE, result.a[0], TestUtils.FLOAT_DELTA); @@ -252,7 +277,8 @@ class Mapped { } final byte[] max = JBBPOut.BeginBin().Float(-1.234567f).End().toByteArray(); - assertEquals(-1.234567f, JBBPParser.prepare("floatj a;").parse(max).mapTo(new Mapped()).a, TestUtils.FLOAT_DELTA); + assertEquals(-1.234567f, JBBPParser.prepare("floatj a;").parse(max).mapTo(new Mapped()).a, + TestUtils.FLOAT_DELTA); } @Test @@ -263,7 +289,9 @@ class Mapped { } final byte[] max = JBBPOut.BeginBin().Float(-1.234567f, 1.234567f).End().toByteArray(); - assertArrayEquals(new float[] {-1.234567f, 1.234567f}, JBBPParser.prepare("floatj [_] a;").parse(max).mapTo(new Mapped()).a, TestUtils.FLOAT_DELTA); + assertArrayEquals(new float[] {-1.234567f, 1.234567f}, + JBBPParser.prepare("floatj [_] a;").parse(max).mapTo(new Mapped()).a, + TestUtils.FLOAT_DELTA); } @Test @@ -273,10 +301,14 @@ class Mapped { double a; } - final byte[] max = JBBPOut.BeginBin().Long(Double.doubleToLongBits(Double.MAX_VALUE)).End().toByteArray(); - assertEquals(Double.MAX_VALUE, JBBPParser.prepare("long a;").parse(max).mapTo(new Mapped()).a, TestUtils.FLOAT_DELTA); - final byte[] min = JBBPOut.BeginBin().Long(Double.doubleToLongBits(Double.MIN_VALUE)).End().toByteArray(); - assertEquals(Double.MIN_VALUE, JBBPParser.prepare("long a;").parse(min).mapTo(new Mapped()).a, TestUtils.FLOAT_DELTA); + final byte[] max = + JBBPOut.BeginBin().Long(Double.doubleToLongBits(Double.MAX_VALUE)).End().toByteArray(); + assertEquals(Double.MAX_VALUE, JBBPParser.prepare("long a;").parse(max).mapTo(new Mapped()).a, + TestUtils.FLOAT_DELTA); + final byte[] min = + JBBPOut.BeginBin().Long(Double.doubleToLongBits(Double.MIN_VALUE)).End().toByteArray(); + assertEquals(Double.MIN_VALUE, JBBPParser.prepare("long a;").parse(min).mapTo(new Mapped()).a, + TestUtils.FLOAT_DELTA); } @Test @@ -287,7 +319,8 @@ class Mapped { } final byte[] max = JBBPOut.BeginBin().Double(-1.2345678912345d).End().toByteArray(); - assertEquals(-1.2345678912345d, JBBPParser.prepare("doublej a;").parse(max).mapTo(new Mapped()).a, TestUtils.FLOAT_DELTA); + assertEquals(-1.2345678912345d, + JBBPParser.prepare("doublej a;").parse(max).mapTo(new Mapped()).a, TestUtils.FLOAT_DELTA); } @Test @@ -298,7 +331,9 @@ class Mapped { } final byte[] max = JBBPOut.BeginBin().Double(-1.2345678912345d, 45.3334d).End().toByteArray(); - assertArrayEquals(new double[] {-1.2345678912345d, 45.3334d}, JBBPParser.prepare("doublej [_] a;").parse(max).mapTo(new Mapped()).a, TestUtils.FLOAT_DELTA); + assertArrayEquals(new double[] {-1.2345678912345d, 45.3334d}, + JBBPParser.prepare("doublej [_] a;").parse(max).mapTo(new Mapped()).a, + TestUtils.FLOAT_DELTA); } @Test @@ -307,7 +342,9 @@ class Mapped { @Bin long a; } - assertEquals(0x0102030405060708L, JBBPParser.prepare("long a;").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}).mapTo(new Mapped()).a); + assertEquals(0x0102030405060708L, + JBBPParser.prepare("long a;").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}) + .mapTo(new Mapped()).a); } @Test @@ -316,7 +353,8 @@ class Mapped { @Bin(type = BinType.UBYTE) int a; } - assertEquals(0xFE, JBBPParser.prepare("ubyte a;").parse(new byte[] {(byte) 0xFE}).mapTo(new Mapped()).a); + assertEquals(0xFE, + JBBPParser.prepare("ubyte a;").parse(new byte[] {(byte) 0xFE}).mapTo(new Mapped()).a); } @Test @@ -325,7 +363,8 @@ class Mapped { @Bin char a; } - assertEquals(0x0102, JBBPParser.prepare("ushort a;").parse(new byte[] {1, 2}).mapTo(new Mapped()).a); + assertEquals(0x0102, + JBBPParser.prepare("ushort a;").parse(new byte[] {1, 2}).mapTo(new Mapped()).a); } @Test @@ -334,7 +373,8 @@ class Mapped { @Bin byte[] a; } - assertArrayEquals(new byte[] {1, 2, 3, 4}, JBBPParser.prepare("byte [_] a;").parse(new byte[] {1, 2, 3, 4}).mapTo(new Mapped()).a); + assertArrayEquals(new byte[] {1, 2, 3, 4}, + JBBPParser.prepare("byte [_] a;").parse(new byte[] {1, 2, 3, 4}).mapTo(new Mapped()).a); } @Test @@ -343,7 +383,9 @@ class Mapped { @Bin(type = BinType.UBYTE_ARRAY) String a; } - assertEquals("JFIF", JBBPParser.prepare("ubyte [_] a;").parse(new byte[] {(byte) 0x4A, (byte) 0x46, (byte) 0x49, (byte) 0x46}).mapTo(new Mapped()).a); + assertEquals("JFIF", JBBPParser.prepare("ubyte [_] a;") + .parse(new byte[] {(byte) 0x4A, (byte) 0x46, (byte) 0x49, (byte) 0x46}) + .mapTo(new Mapped()).a); } @Test @@ -352,7 +394,10 @@ class Mapped { @Bin(type = BinType.BIT_ARRAY) String a; } - assertEquals(new String(new char[] {0xA, 0x4, 0x6, 0x4, 0x9, 0x4, 0x6, 0x4}), JBBPParser.prepare("bit:4 [_] a;").parse(new byte[] {(byte) 0x4A, (byte) 0x46, (byte) 0x49, (byte) 0x46}).mapTo(new Mapped()).a); + assertEquals(new String(new char[] {0xA, 0x4, 0x6, 0x4, 0x9, 0x4, 0x6, 0x4}), + JBBPParser.prepare("bit:4 [_] a;") + .parse(new byte[] {(byte) 0x4A, (byte) 0x46, (byte) 0x49, (byte) 0x46}) + .mapTo(new Mapped()).a); } @Test @@ -361,7 +406,9 @@ class Mapped { @Bin(type = BinType.BIT_ARRAY) String a; } - assertEquals(new String(new char[] {0xFF, 0xED, 0x01, 0x36}), JBBPParser.prepare("bit:8 [_] a;").parse(new byte[] {(byte) 0xFF, (byte) 0xED, (byte) 0x01, (byte) 0x36}).mapTo(new Mapped()).a); + assertEquals(new String(new char[] {0xFF, 0xED, 0x01, 0x36}), JBBPParser.prepare("bit:8 [_] a;") + .parse(new byte[] {(byte) 0xFF, (byte) 0xED, (byte) 0x01, (byte) 0x36}) + .mapTo(new Mapped()).a); } @Test @@ -370,7 +417,9 @@ class Mapped { @Bin(type = BinType.BYTE_ARRAY) String a; } - assertEquals("JFIF", JBBPParser.prepare("byte [_] a;").parse(new byte[] {(byte) 0x4A, (byte) 0x46, (byte) 0x49, (byte) 0x46}).mapTo(new Mapped()).a); + assertEquals("JFIF", JBBPParser.prepare("byte [_] a;") + .parse(new byte[] {(byte) 0x4A, (byte) 0x46, (byte) 0x49, (byte) 0x46}) + .mapTo(new Mapped()).a); } @Test @@ -379,7 +428,9 @@ class Mapped { @Bin(type = BinType.SHORT_ARRAY) String a; } - assertEquals("JFIF", JBBPParser.prepare("short [_] a;").parse(new byte[] {0, (byte) 0x4A, 0, (byte) 0x46, 0, (byte) 0x49, 0, (byte) 0x46}).mapTo(new Mapped()).a); + assertEquals("JFIF", JBBPParser.prepare("short [_] a;") + .parse(new byte[] {0, (byte) 0x4A, 0, (byte) 0x46, 0, (byte) 0x49, 0, (byte) 0x46}) + .mapTo(new Mapped()).a); } @Test @@ -388,7 +439,9 @@ class Mapped { @Bin(type = BinType.INT_ARRAY) String a; } - assertThrows(JBBPMapperException.class, () -> JBBPParser.prepare("int [_] a;").parse(new byte[] {0, (byte) 0x4A, 0, (byte) 0x46, 0, (byte) 0x49, 0, (byte) 0x46}).mapTo(new Mapped())); + assertThrows(JBBPMapperException.class, () -> JBBPParser.prepare("int [_] a;") + .parse(new byte[] {0, (byte) 0x4A, 0, (byte) 0x46, 0, (byte) 0x49, 0, (byte) 0x46}) + .mapTo(new Mapped())); } @Test @@ -397,7 +450,9 @@ class Mapped { @Bin(type = BinType.USHORT_ARRAY) String a; } - assertEquals("JFIF", JBBPParser.prepare("ushort [_] a;").parse(new byte[] {0, (byte) 0x4A, 0, (byte) 0x46, 0, (byte) 0x49, 0, (byte) 0x46}).mapTo(new Mapped()).a); + assertEquals("JFIF", JBBPParser.prepare("ushort [_] a;") + .parse(new byte[] {0, (byte) 0x4A, 0, (byte) 0x46, 0, (byte) 0x49, 0, (byte) 0x46}) + .mapTo(new Mapped()).a); } @Test @@ -406,7 +461,8 @@ class Mapped { @Bin(type = BinType.BIT_ARRAY) byte[] a; } - assertArrayEquals(new byte[] {2, 0, 3, 2}, JBBPParser.prepare("bit:2 [_] a;").parse(new byte[] {(byte) 0xB2}).mapTo(new Mapped()).a); + assertArrayEquals(new byte[] {2, 0, 3, 2}, + JBBPParser.prepare("bit:2 [_] a;").parse(new byte[] {(byte) 0xB2}).mapTo(new Mapped()).a); } @Test @@ -415,7 +471,8 @@ class Mapped { @Bin short[] a; } - assertArrayEquals(new short[] {0x0102, 0x0304}, JBBPParser.prepare("short [_] a;").parse(new byte[] {1, 2, 3, 4}).mapTo(new Mapped()).a); + assertArrayEquals(new short[] {0x0102, 0x0304}, + JBBPParser.prepare("short [_] a;").parse(new byte[] {1, 2, 3, 4}).mapTo(new Mapped()).a); } @Test @@ -424,7 +481,8 @@ class Mapped { @Bin boolean[] a; } - final Mapped mapped = JBBPParser.prepare("bool [_] a;").parse(new byte[] {1, 0, 0, 4, 8, 0}).mapTo(new Mapped()); + final Mapped mapped = + JBBPParser.prepare("bool [_] a;").parse(new byte[] {1, 0, 0, 4, 8, 0}).mapTo(new Mapped()); assertEquals(6, mapped.a.length); assertTrue(mapped.a[0]); assertFalse(mapped.a[1]); @@ -440,7 +498,8 @@ class Mapped { @Bin char[] a; } - assertArrayEquals(new char[] {0x0102, 0x0304}, JBBPParser.prepare("ushort [_] a;").parse(new byte[] {1, 2, 3, 4}).mapTo(new Mapped()).a); + assertArrayEquals(new char[] {0x0102, 0x0304}, + JBBPParser.prepare("ushort [_] a;").parse(new byte[] {1, 2, 3, 4}).mapTo(new Mapped()).a); } @Test @@ -449,7 +508,9 @@ class Mapped { @Bin int[] a; } - assertArrayEquals(new int[] {0x01020304, 0x05060708}, JBBPParser.prepare("int [_] a;").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}).mapTo(new Mapped()).a); + assertArrayEquals(new int[] {0x01020304, 0x05060708}, + JBBPParser.prepare("int [_] a;").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}) + .mapTo(new Mapped()).a); } @Test @@ -466,12 +527,14 @@ class Mapped { @Bin Inside a; } - final Mapped mapped = JBBPParser.prepare("byte b; a{ int a; }").parse(new byte[] {1, 2, 3, 4, 5}).mapTo(new Mapped(), aClass -> { - if (aClass == Inside.class) { - return new Inside(); - } - return null; - }); + final Mapped mapped = + JBBPParser.prepare("byte b; a{ int a; }").parse(new byte[] {1, 2, 3, 4, 5}) + .mapTo(new Mapped(), aClass -> { + if (aClass == Inside.class) { + return new Inside(); + } + return null; + }); assertEquals(0x02030405, mapped.a.a); } @@ -488,12 +551,14 @@ class Mapped { @Bin Inside[] a; } - final Mapped mapped = JBBPParser.prepare("byte b; a [_]{ int a; }").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}).mapTo(new Mapped(), aClass -> { - if (aClass == Inside.class) { - return new Inside(); - } - return null; - }); + final Mapped mapped = + JBBPParser.prepare("byte b; a [_]{ int a; }").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}) + .mapTo(new Mapped(), aClass -> { + if (aClass == Inside.class) { + return new Inside(); + } + return null; + }); assertEquals(2, mapped.a.length); assertEquals(0x02030405, mapped.a[0].a); assertEquals(0x06070809, mapped.a[1].a); @@ -505,7 +570,10 @@ class Mapped { @Bin long[] a; } - assertArrayEquals(new long[] {0x0102030405060708L, 0x1112131415161718L}, JBBPParser.prepare("long [_] a;").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}).mapTo(new Mapped()).a); + assertArrayEquals(new long[] {0x0102030405060708L, 0x1112131415161718L}, + JBBPParser.prepare("long [_] a;").parse( + new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}) + .mapTo(new Mapped()).a); } @Test @@ -514,7 +582,9 @@ class Mapped { @Bin(name = "test", type = BinType.STRUCT) long a; } - assertThrows(JBBPMapperException.class, () -> JBBPParser.prepare("test { byte [_] a;}").parse(new byte[] {1, 2, 3, 4}).mapTo(new Mapped())); + assertThrows(JBBPMapperException.class, + () -> JBBPParser.prepare("test { byte [_] a;}").parse(new byte[] {1, 2, 3, 4}) + .mapTo(new Mapped())); } @Test @@ -523,7 +593,8 @@ class Mapped { @Bin long a; } - final Mapped mapped = JBBPParser.prepare("byte f; test { inside {long a;} }").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}).mapTo("test.inside", new Mapped()); + final Mapped mapped = JBBPParser.prepare("byte f; test { inside {long a;} }") + .parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}).mapTo("test.inside", new Mapped()); assertEquals(0x0203040506070809L, mapped.a); } @@ -534,17 +605,23 @@ class Mapped { long a; } - assertThrows(JBBPMapperException.class, () -> JBBPParser.prepare("byte f; test { inside {long a;} }").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}).mapTo("f", new Mapped())); + assertThrows(JBBPMapperException.class, + () -> JBBPParser.prepare("byte f; test { inside {long a;} }") + .parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}).mapTo("f", new Mapped())); } @Test void testMap_privateFieldInPackagelevelClass() { - assertThrows(JBBPMapperException.class, () -> JBBPParser.prepare("int field;").parse(new byte[] {1, 2, 3, 4}).mapTo(new ClassWithPrivateFields())); + assertThrows(JBBPMapperException.class, + () -> JBBPParser.prepare("int field;").parse(new byte[] {1, 2, 3, 4}) + .mapTo(new ClassWithPrivateFields())); } @Test void testMap_privateFieldWithSetterInPackagelevelClass() throws Exception { - final ClassWithPrivateFieldsAndSetterGetter instance = JBBPParser.prepare("int field;").parse(new byte[] {1, 2, 3, 4}).mapTo(new ClassWithPrivateFieldsAndSetterGetter()); + final ClassWithPrivateFieldsAndSetterGetter instance = + JBBPParser.prepare("int field;").parse(new byte[] {1, 2, 3, 4}) + .mapTo(new ClassWithPrivateFieldsAndSetterGetter()); assertEquals(0x1020304, instance.getField()); } @@ -559,7 +636,8 @@ public void testMap_classWithGettersSettersAndGenerator() throws Exception { assertEquals(3, instance.getI().getC()); assertEquals(4, instance.getI().getIi().getD()); - assertArrayEquals(new byte[] {1, 2, 3, 4}, JBBPOut.BeginBin().Bin(instance).End().toByteArray()); + assertArrayEquals(new byte[] {1, 2, 3, 4}, + JBBPOut.BeginBin().Bin(instance).End().toByteArray()); } @Test @@ -574,15 +652,20 @@ final class Mapped { int c; } - final Mapped mapped = JBBPParser.prepare("int a; int b; int c;").parse(new byte[] {1, 2, 3, 4, 0x4A, 0x46, 0x49, 0x46, 5, 6, 7, 8}).mapTo(new Mapped(), (parsedBlock, annotation, field) -> { - if ("b".equals(field.getName()) && "TEST_TEXT".equals(annotation.paramExpr())) { - final int bvalue = parsedBlock.findFieldForNameAndType("b", JBBPFieldInt.class).getAsInt(); - return String.valueOf((char) ((bvalue >>> 24) & 0xFF)) + (char) ((bvalue >>> 16) & 0xFF) + (char) ((bvalue >>> 8) & 0xFF) + (char) (bvalue & 0xFF); - } else { - fail("Unexpected state" + field); - return null; - } - }); + final Mapped mapped = JBBPParser.prepare("int a; int b; int c;") + .parse(new byte[] {1, 2, 3, 4, 0x4A, 0x46, 0x49, 0x46, 5, 6, 7, 8}) + .mapTo(new Mapped(), (parsedBlock, annotation, field) -> { + if ("b".equals(field.getName()) && "TEST_TEXT".equals(annotation.paramExpr())) { + final int bvalue = + parsedBlock.findFieldForNameAndType("b", JBBPFieldInt.class).getAsInt(); + return String.valueOf((char) ((bvalue >>> 24) & 0xFF)) + + (char) ((bvalue >>> 16) & 0xFF) + (char) ((bvalue >>> 8) & 0xFF) + + (char) (bvalue & 0xFF); + } else { + fail("Unexpected state" + field); + return null; + } + }); assertEquals(0x01020304, mapped.a); assertEquals("JFIF", mapped.b); @@ -602,15 +685,20 @@ final class Mapped { final Mapped mapped = new Mapped(); - final Mapped result = JBBPParser.prepare("int a; int b; int c;").parse(new byte[] {1, 2, 3, 4, 0x4A, 0x46, 0x49, 0x46, 5, 6, 7, 8}).mapTo(mapped, (parsedBlock, annotation, field) -> { - if ("b".equals(field.getName()) && "TEST_TEXT".equals(annotation.paramExpr())) { - final int bvalue = parsedBlock.findFieldForNameAndType("b", JBBPFieldInt.class).getAsInt(); - return String.valueOf((char) ((bvalue >>> 24) & 0xFF)) + (char) ((bvalue >>> 16) & 0xFF) + (char) ((bvalue >>> 8) & 0xFF) + (char) (bvalue & 0xFF); - } else { - fail("Unexpected state" + field); - return null; - } - }); + final Mapped result = JBBPParser.prepare("int a; int b; int c;") + .parse(new byte[] {1, 2, 3, 4, 0x4A, 0x46, 0x49, 0x46, 5, 6, 7, 8}) + .mapTo(mapped, (parsedBlock, annotation, field) -> { + if ("b".equals(field.getName()) && "TEST_TEXT".equals(annotation.paramExpr())) { + final int bvalue = + parsedBlock.findFieldForNameAndType("b", JBBPFieldInt.class).getAsInt(); + return String.valueOf((char) ((bvalue >>> 24) & 0xFF)) + + (char) ((bvalue >>> 16) & 0xFF) + (char) ((bvalue >>> 8) & 0xFF) + + (char) (bvalue & 0xFF); + } else { + fail("Unexpected state" + field); + return null; + } + }); assertSame(mapped, result); @@ -629,7 +717,9 @@ final class Parsed { String c; } - final Parsed parsed = JBBPParser.prepare("int a; int b; byte [_] c;").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd'}).mapTo(new Parsed()); + final Parsed parsed = JBBPParser.prepare("int a; int b; byte [_] c;") + .parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd'}) + .mapTo(new Parsed()); assertEquals(0x01020304, parsed.a); assertEquals(0x05060708, parsed.b); assertEquals("abcd", parsed.c); @@ -659,7 +749,8 @@ final class Inner { final Outer oldouter = new Outer(); final Outer.Inner inner = oldouter.inner; - final Outer newouter = JBBPParser.prepare("int value; inner{ byte a; byte b;}").parse(new byte[] {1, 2, 3, 4, 5, 6}).mapTo(oldouter); + final Outer newouter = JBBPParser.prepare("int value; inner{ byte a; byte b;}") + .parse(new byte[] {1, 2, 3, 4, 5, 6}).mapTo(oldouter); assertSame(oldouter, newouter); assertSame(inner, newouter.inner); @@ -696,7 +787,8 @@ final class Inner { final Outer.Inner inner0 = oldouter.inner[0]; final Outer.Inner inner1 = oldouter.inner[1]; - final Outer newouter = JBBPParser.prepare("int value; inner [2] { byte a; byte b;}").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}).mapTo(oldouter); + final Outer newouter = JBBPParser.prepare("int value; inner [2] { byte a; byte b;}") + .parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}).mapTo(oldouter); assertSame(oldouter, newouter); assertSame(inner, newouter.inner); @@ -740,12 +832,13 @@ final class Inner { assertNull(inner[0]); assertNull(inner[1]); - final Outer newouter = JBBPParser.prepare("int value; inner [2] { byte a; byte b;}").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}).mapTo(oldouter, aClass -> { - if (aClass == Outer.Inner.class) { - return oldouter.makeInner(); - } - return null; - }); + final Outer newouter = JBBPParser.prepare("int value; inner [2] { byte a; byte b;}") + .parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}).mapTo(oldouter, aClass -> { + if (aClass == Outer.Inner.class) { + return oldouter.makeInner(); + } + return null; + }); assertSame(oldouter, newouter); assertSame(inner, newouter.inner); @@ -778,7 +871,9 @@ final class Inner { } } - assertThrows(JBBPMapperException.class, () -> JBBPParser.prepare("int value; inner [2] { byte a; byte b;}").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}).mapTo(new Outer())); + assertThrows(JBBPMapperException.class, + () -> JBBPParser.prepare("int value; inner [2] { byte a; byte b;}") + .parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}).mapTo(new Outer())); } @Test @@ -794,7 +889,9 @@ class Successor extends Ancestor { int b; } - final Successor successor = JBBPParser.prepare("int a; int b;").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}).mapTo(new Successor()); + final Successor successor = + JBBPParser.prepare("int a; int b;").parse(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}) + .mapTo(new Successor()); assertEquals(0x01020304, successor.a); assertEquals(0x05060708, successor.b); @@ -810,7 +907,9 @@ class Parsed { String str; } - final Parsed parsed = JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;").parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}).mapTo(new Parsed()); + final Parsed parsed = JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;") + .parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}) + .mapTo(new Parsed()); assertEquals(0x05, parsed.num); assertEquals("abc", parsed.str); } @@ -825,7 +924,10 @@ class Parsed { String str; } - assertThrows(JBBPMapperException.class, () -> JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;").parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}).mapTo(new Parsed())); + assertThrows(JBBPMapperException.class, + () -> JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;") + .parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}) + .mapTo(new Parsed())); } @Test @@ -838,7 +940,10 @@ class Parsed { String str; } - assertThrows(JBBPMapperException.class, () -> JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;").parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}).mapTo(new Parsed())); + assertThrows(JBBPMapperException.class, + () -> JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;") + .parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}) + .mapTo(new Parsed())); } @Test @@ -851,7 +956,10 @@ class Parsed { String str; } - assertThrows(JBBPMapperException.class, () -> JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;").parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}).mapTo(new Parsed())); + assertThrows(JBBPMapperException.class, + () -> JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;") + .parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}) + .mapTo(new Parsed())); } @Test @@ -863,7 +971,10 @@ class Parsed { byte str; } - assertThrows(JBBPMapperException.class, () -> JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;").parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}).mapTo(new Parsed())); + assertThrows(JBBPMapperException.class, + () -> JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;") + .parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}) + .mapTo(new Parsed())); } @Test @@ -877,7 +988,9 @@ class Parsed { transient String ignored; } - final Parsed parsed = JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;").parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}).mapTo(new Parsed()); + final Parsed parsed = JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;") + .parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}) + .mapTo(new Parsed()); assertEquals(0x05, parsed.num); assertEquals("abc", parsed.str); } @@ -894,7 +1007,10 @@ class Parsed { transient String trans; } - final Parsed parsed = JBBPParser.prepare("int start; struct { byte a; byte [3] b; byte [3] c; } byte end;").parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', 9}).mapTo(new Parsed()); + final Parsed parsed = + JBBPParser.prepare("int start; struct { byte a; byte [3] b; byte [3] c; } byte end;").parse( + new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', + (byte) 'f', 9}).mapTo(new Parsed()); assertEquals(0x05, parsed.num); assertEquals("abc", parsed.str); assertEquals("def", parsed.trans); @@ -911,7 +1027,9 @@ class Parsed { String ignored; } - final Parsed parsed = JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;").parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}).mapTo(new Parsed()); + final Parsed parsed = JBBPParser.prepare("int start; struct { byte a; byte [3] b; } int end;") + .parse(new byte[] {1, 2, 3, 4, 5, (byte) 'a', (byte) 'b', (byte) 'c', 6, 7, 8, 9}) + .mapTo(new Parsed()); assertEquals(0x05, parsed.num); assertEquals("abc", parsed.str); } @@ -944,10 +1062,12 @@ class Parsed { final byte[] array = new byte[1024]; rnd.nextBytes(array); - final Parsed parsed = JBBPParser.prepare("struct [_] { byte a; byte b; }").parse(new ByteArrayInputStream(array)).mapTo(new Parsed(null), aClass -> { - fail("Must not be called"); - return null; - }); + final Parsed parsed = + JBBPParser.prepare("struct [_] { byte a; byte b; }").parse(new ByteArrayInputStream(array)) + .mapTo(new Parsed(null), aClass -> { + fail("Must not be called"); + return null; + }); assertNull(parsed.struct); } @@ -957,17 +1077,22 @@ class Parsed { @Bin(bitNumber = JBBPBitNumber.BITS_5) byte field; } - final Parsed parsed = JBBPParser.prepare("int fieldint; bit:5 field;").parse(new byte[] {1, 2, 3, 4, 0x35}).mapTo(new Parsed()); + final Parsed parsed = + JBBPParser.prepare("int fieldint; bit:5 field;").parse(new byte[] {1, 2, 3, 4, 0x35}) + .mapTo(new Parsed()); assertEquals(0x15, parsed.field); } @Test - void testMap_FieldWithDefinedBitNumberToBitField_FieldPresentedWithDifferentBitNumber() throws Exception { + void testMap_FieldWithDefinedBitNumberToBitField_FieldPresentedWithDifferentBitNumber() + throws Exception { class Parsed { @Bin(bitNumber = JBBPBitNumber.BITS_5) byte field; } - assertThrows(JBBPMapperException.class, () -> JBBPParser.prepare("int fieldint; bit:6 field;").parse(new byte[] {1, 2, 3, 4, 0x35}).mapTo(new Parsed())); + assertThrows(JBBPMapperException.class, + () -> JBBPParser.prepare("int fieldint; bit:6 field;").parse(new byte[] {1, 2, 3, 4, 0x35}) + .mapTo(new Parsed())); } @Test @@ -977,7 +1102,9 @@ class Parsed { byte[] field; } - final Parsed parsed = JBBPParser.prepare("int fieldint; bit:4 [2] field;").parse(new byte[] {1, 2, 3, 4, 0x35}).mapTo(new Parsed()); + final Parsed parsed = + JBBPParser.prepare("int fieldint; bit:4 [2] field;").parse(new byte[] {1, 2, 3, 4, 0x35}) + .mapTo(new Parsed()); assertArrayEquals(new byte[] {5, 3}, parsed.field); } @@ -987,18 +1114,23 @@ class Parsed { @Bin(type = BinType.INT_ARRAY, bitNumber = JBBPBitNumber.BITS_4) int[] field; } - final Parsed parsed = JBBPParser.prepare("int fieldint; int [2] field;").parse(new byte[] {1, 2, 3, 4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0A, 0x0B, 0x0C}).mapTo(new Parsed()); + final Parsed parsed = JBBPParser.prepare("int fieldint; int [2] field;") + .parse(new byte[] {1, 2, 3, 4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0A, 0x0B, 0x0C}) + .mapTo(new Parsed()); assertArrayEquals(new int[] {0x05060708, 0x090A0B0C}, parsed.field); } @Test - void testMap_ArrayFieldWithDefinedBitNumberToArrayBitField_FieldPresentedWithDifferentBitNumber() throws Exception { + void testMap_ArrayFieldWithDefinedBitNumberToArrayBitField_FieldPresentedWithDifferentBitNumber() + throws Exception { class Parsed { @Bin(bitNumber = JBBPBitNumber.BITS_4) byte field; } - assertThrows(JBBPMapperException.class, () -> JBBPParser.prepare("int fieldint; bit:3 [2] field;").parse(new byte[] {1, 2, 3, 4, 0x35}).mapTo(new Parsed())); + assertThrows(JBBPMapperException.class, + () -> JBBPParser.prepare("int fieldint; bit:3 [2] field;") + .parse(new byte[] {1, 2, 3, 4, 0x35}).mapTo(new Parsed())); } @Test @@ -1011,7 +1143,10 @@ class Parsed { int b; } - final Parsed parsed = JBBPParser.prepare("int a; int b;", JBBPParser.FLAG_SKIP_REMAINING_FIELDS_IF_EOF).parse(new byte[] {1, 2, 3, 4}).mapTo(new Parsed(), JBBPMapper.FLAG_IGNORE_MISSING_VALUES); + final Parsed parsed = + JBBPParser.prepare("int a; int b;", JBBPParser.FLAG_SKIP_REMAINING_FIELDS_IF_EOF) + .parse(new byte[] {1, 2, 3, 4}) + .mapTo(new Parsed(), JBBPMapper.FLAG_IGNORE_MISSING_VALUES); assertEquals(0x01020304, parsed.a); assertEquals(0, parsed.b); } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayBitTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayBitTest.java index 4984adcf..19318fe7 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayBitTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayBitTest.java @@ -16,22 +16,29 @@ package com.igormaznitsa.jbbp.model; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; + + import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import com.igormaznitsa.jbbp.io.JBBPBitNumber; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.function.Executable; - import java.io.Serializable; - -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class JBBPFieldArrayBitTest { private final byte[] array = new byte[] {(byte) -1, 0, 1, 2, 3}; - private final JBBPFieldArrayBit test = new JBBPFieldArrayBit(new JBBPNamedFieldInfo("test.field", "field", 999), array, JBBPBitNumber.BITS_1); + private final JBBPFieldArrayBit test = + new JBBPFieldArrayBit(new JBBPNamedFieldInfo("test.field", "field", 999), array, + JBBPBitNumber.BITS_1); @Test public void testConstructor_NPEForNullBitNumber() { - assertThrows(NullPointerException.class, () -> new JBBPFieldArrayBit(new JBBPNamedFieldInfo("test.field", "field", 999), new byte[] {(byte) -1, 0, 1, 2, 3}, null)); + assertThrows(NullPointerException.class, + () -> new JBBPFieldArrayBit(new JBBPNamedFieldInfo("test.field", "field", 999), + new byte[] {(byte) -1, 0, 1, 2, 3}, null)); } @Test @@ -102,7 +109,9 @@ public void testIterable() { public void testGetValueArrayAsObject() { final byte[] array = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - final JBBPFieldArrayBit test = new JBBPFieldArrayBit(new JBBPNamedFieldInfo("test.field", "field", 999), array, JBBPBitNumber.BITS_4); + final JBBPFieldArrayBit test = + new JBBPFieldArrayBit(new JBBPNamedFieldInfo("test.field", "field", 999), array, + JBBPBitNumber.BITS_4); assertArrayEquals(array, (byte[]) test.getValueArrayAsObject(false)); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayBooleanTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayBooleanTest.java index e5ffaa69..4b0c1b5e 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayBooleanTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayBooleanTest.java @@ -16,17 +16,21 @@ package com.igormaznitsa.jbbp.model; -import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; -import java.io.Serializable; -import static org.junit.jupiter.api.Assertions.*; +import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; +import java.io.Serializable; +import org.junit.jupiter.api.Test; public class JBBPFieldArrayBooleanTest { private final boolean[] array = new boolean[] {true, false, true, true, false}; - private final JBBPFieldArrayBoolean test = new JBBPFieldArrayBoolean(new JBBPNamedFieldInfo("test.field", "field", 999), array); + private final JBBPFieldArrayBoolean test = + new JBBPFieldArrayBoolean(new JBBPNamedFieldInfo("test.field", "field", 999), array); @Test public void testNameAndOffset() { diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayByteTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayByteTest.java index d4ae7374..a6e75d72 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayByteTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayByteTest.java @@ -16,16 +16,20 @@ package com.igormaznitsa.jbbp.model; -import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; -import java.io.Serializable; -import static org.junit.jupiter.api.Assertions.*; +import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; +import java.io.Serializable; +import org.junit.jupiter.api.Test; public class JBBPFieldArrayByteTest { private final byte[] array = new byte[] {(byte) -1, 0, 1, 2, 3}; - private final JBBPFieldArrayByte test = new JBBPFieldArrayByte(new JBBPNamedFieldInfo("test.field", "field", 999), array); + private final JBBPFieldArrayByte test = + new JBBPFieldArrayByte(new JBBPNamedFieldInfo("test.field", "field", 999), array); @Test public void testNameAndOffset() { diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayIntTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayIntTest.java index 96f929ed..8981b44f 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayIntTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayIntTest.java @@ -16,16 +16,20 @@ package com.igormaznitsa.jbbp.model; -import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; -import java.io.Serializable; -import static org.junit.jupiter.api.Assertions.*; +import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; +import java.io.Serializable; +import org.junit.jupiter.api.Test; public class JBBPFieldArrayIntTest { private final int[] array = new int[] {-278349, 12223423, 0, -2, 3}; - private final JBBPFieldArrayInt test = new JBBPFieldArrayInt(new JBBPNamedFieldInfo("test.field", "field", 999), array); + private final JBBPFieldArrayInt test = + new JBBPFieldArrayInt(new JBBPNamedFieldInfo("test.field", "field", 999), array); @Test public void testNameAndOffset() { diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayLongTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayLongTest.java index 9520aa60..f9e806df 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayLongTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayLongTest.java @@ -16,16 +16,21 @@ package com.igormaznitsa.jbbp.model; -import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; -import java.io.Serializable; -import static org.junit.jupiter.api.Assertions.*; +import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; +import java.io.Serializable; +import org.junit.jupiter.api.Test; public class JBBPFieldArrayLongTest { - private final long[] array = new long[] {-278349872364L, 12223423987439324L, 0L, -2782346872343L, 37238468273412L}; - private final JBBPFieldArrayLong test = new JBBPFieldArrayLong(new JBBPNamedFieldInfo("test.field", "field", 999), array); + private final long[] array = + new long[] {-278349872364L, 12223423987439324L, 0L, -2782346872343L, 37238468273412L}; + private final JBBPFieldArrayLong test = + new JBBPFieldArrayLong(new JBBPNamedFieldInfo("test.field", "field", 999), array); @Test public void testNameAndOffset() { @@ -42,7 +47,9 @@ public void testSize() { @Test public void testGetArray() { - assertArrayEquals(new long[] {-278349872364L, 12223423987439324L, 0L, -2782346872343L, 37238468273412L}, test.getArray()); + assertArrayEquals( + new long[] {-278349872364L, 12223423987439324L, 0L, -2782346872343L, 37238468273412L}, + test.getArray()); } @Test @@ -55,7 +62,9 @@ public void testGetAsBool() { @Test public void testGetAsInt() { - final int[] etalon = new int[] {(int) -278349872364L, (int) 12223423987439324L, (int) 0L, (int) -2782346872343L, (int) 37238468273412L}; + final int[] etalon = + new int[] {(int) -278349872364L, (int) 12223423987439324L, (int) 0L, (int) -2782346872343L, + (int) 37238468273412L}; for (int i = 0; i < etalon.length; i++) { assertEquals(etalon[i], test.getAsInt(i)); } @@ -63,7 +72,8 @@ public void testGetAsInt() { @Test public void testGetAsLong() { - final long[] etalon = new long[] {-278349872364L, 12223423987439324L, 0L, -2782346872343L, 37238468273412L}; + final long[] etalon = + new long[] {-278349872364L, 12223423987439324L, 0L, -2782346872343L, 37238468273412L}; for (int i = 0; i < etalon.length; i++) { assertEquals(etalon[i], test.getAsLong(i)); } @@ -71,7 +81,8 @@ public void testGetAsLong() { @Test public void testGetElementAt() { - final long[] etalon = new long[] {-278349872364L, 12223423987439324L, 0L, -2782346872343L, 37238468273412L}; + final long[] etalon = + new long[] {-278349872364L, 12223423987439324L, 0L, -2782346872343L, 37238468273412L}; final Serializable payload = new FakePayload(); test.setPayload(payload); for (int i = 0; i < etalon.length; i++) { @@ -84,7 +95,8 @@ public void testGetElementAt() { @Test public void testIterable() { - final long[] etalon = new long[] {-278349872364L, 12223423987439324L, 0L, -2782346872343L, 37238468273412L}; + final long[] etalon = + new long[] {-278349872364L, 12223423987439324L, 0L, -2782346872343L, 37238468273412L}; int index = 0; for (final JBBPFieldLong f : test) { assertEquals(etalon[index++], f.getAsLong()); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayShortTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayShortTest.java index 71fa28ec..414b7c81 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayShortTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayShortTest.java @@ -16,17 +16,21 @@ package com.igormaznitsa.jbbp.model; -import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; -import java.io.Serializable; -import static org.junit.jupiter.api.Assertions.*; +import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; +import java.io.Serializable; +import org.junit.jupiter.api.Test; public class JBBPFieldArrayShortTest { private final short[] array = new short[] {(short) -27834, 23423, 0, -2, 3}; - private final JBBPFieldArrayShort test = new JBBPFieldArrayShort(new JBBPNamedFieldInfo("test.field", "field", 999), array); + private final JBBPFieldArrayShort test = + new JBBPFieldArrayShort(new JBBPNamedFieldInfo("test.field", "field", 999), array); @Test public void testNameAndOffset() { diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayStringTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayStringTest.java index bad4ec66..399d4562 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayStringTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayStringTest.java @@ -1,15 +1,19 @@ package com.igormaznitsa.jbbp.model; -import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; -import java.io.Serializable; -import static org.junit.jupiter.api.Assertions.*; +import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; +import java.io.Serializable; +import org.junit.jupiter.api.Test; public class JBBPFieldArrayStringTest { - private final String [] array = new String[] {"012",null,"ABC"}; - private final JBBPFieldArrayString test = new JBBPFieldArrayString(new JBBPNamedFieldInfo("test.field", "field", 999), array); + private final String[] array = new String[] {"012", null, "ABC"}; + private final JBBPFieldArrayString test = + new JBBPFieldArrayString(new JBBPNamedFieldInfo("test.field", "field", 999), array); @Test public void testNameAndOffset() { @@ -26,12 +30,12 @@ public void testSize() { @Test public void testGetArray() { - assertArrayEquals(new String[] {"012",null,"ABC"}, test.getArray()); + assertArrayEquals(new String[] {"012", null, "ABC"}, test.getArray()); } @Test public void testGetElementAt() { - final String[] etalon = new String[] {"012",null,"ABC"}; + final String[] etalon = new String[] {"012", null, "ABC"}; final Serializable payload = new FakePayload(); test.setPayload(payload); for (int i = 0; i < etalon.length; i++) { @@ -43,7 +47,7 @@ public void testGetElementAt() { @Test public void testIterable() { - final String[] etalon = new String[] {"012",null,"ABC"}; + final String[] etalon = new String[] {"012", null, "ABC"}; int index = 0; for (final JBBPFieldString f : test) { assertEquals(etalon[index++], f.getAsString()); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayStructTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayStructTest.java index d5f1381b..c758b8f3 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayStructTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayStructTest.java @@ -16,11 +16,15 @@ package com.igormaznitsa.jbbp.model; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; + + import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - public class JBBPFieldArrayStructTest { private final JBBPFieldArrayStruct test = new JBBPFieldArrayStruct( diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayUByteTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayUByteTest.java index 3d46cbf5..2aad908d 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayUByteTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayUByteTest.java @@ -16,16 +16,20 @@ package com.igormaznitsa.jbbp.model; -import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; -import java.io.Serializable; -import static org.junit.jupiter.api.Assertions.*; +import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; +import java.io.Serializable; +import org.junit.jupiter.api.Test; public class JBBPFieldArrayUByteTest { private final byte[] array = new byte[] {(byte) -1, 0, 1, 2, 3}; - private final JBBPFieldArrayUByte test = new JBBPFieldArrayUByte(new JBBPNamedFieldInfo("test.field", "field", 999), array); + private final JBBPFieldArrayUByte test = + new JBBPFieldArrayUByte(new JBBPNamedFieldInfo("test.field", "field", 999), array); @Test public void testNameAndOffset() { diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayUShortTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayUShortTest.java index acb3cee9..cd99c992 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayUShortTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldArrayUShortTest.java @@ -16,16 +16,21 @@ package com.igormaznitsa.jbbp.model; -import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; -import java.io.Serializable; -import static org.junit.jupiter.api.Assertions.*; +import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; +import java.io.Serializable; +import org.junit.jupiter.api.Test; public class JBBPFieldArrayUShortTest { - private final JBBPFieldArrayUShort test = new JBBPFieldArrayUShort(new JBBPNamedFieldInfo("test.field", "field", 999), new short[] {(short) -27834, 23423, 0, -2, 3}); + private final JBBPFieldArrayUShort test = + new JBBPFieldArrayUShort(new JBBPNamedFieldInfo("test.field", "field", 999), + new short[] {(short) -27834, 23423, 0, -2, 3}); @Test public void testNameAndOffset() { diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldBitTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldBitTest.java index 38e89bfe..24df0831 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldBitTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldBitTest.java @@ -16,23 +16,29 @@ package com.igormaznitsa.jbbp.model; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + + import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import com.igormaznitsa.jbbp.io.JBBPBitNumber; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.function.Executable; - -import static org.junit.jupiter.api.Assertions.*; public class JBBPFieldBitTest { @Test public void testConstructor_NPEForNullBitNumber() { - assertThrows(NullPointerException.class, () -> new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 123, null)); + assertThrows(NullPointerException.class, + () -> new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 123, null)); } @Test public void testNameField() { - final JBBPFieldBit field = new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 123, JBBPBitNumber.BITS_4); + final JBBPFieldBit field = + new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 123, + JBBPBitNumber.BITS_4); final JBBPNamedFieldInfo namedField = field.getNameInfo(); assertEquals("test.field", namedField.getFieldPath()); assertEquals("field", namedField.getFieldName()); @@ -42,33 +48,46 @@ public void testNameField() { @Test public void testgetAsBool_True() { - assertTrue(new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 123, JBBPBitNumber.BITS_1).getAsBool()); + assertTrue(new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 123, + JBBPBitNumber.BITS_1).getAsBool()); } @Test public void testgetAsBool_False() { - assertFalse(new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 0, JBBPBitNumber.BITS_1).getAsBool()); + assertFalse(new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 0, + JBBPBitNumber.BITS_1).getAsBool()); } @Test public void testgetAsInt() { - assertEquals(12, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 12, JBBPBitNumber.BITS_3).getAsInt()); - assertEquals(-12 & 0xFF, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), -12, JBBPBitNumber.BITS_4).getAsInt()); + assertEquals(12, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 12, + JBBPBitNumber.BITS_3).getAsInt()); + assertEquals(-12 & 0xFF, + new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), -12, + JBBPBitNumber.BITS_4).getAsInt()); } @Test public void testgetAsLong() { - assertEquals(12L, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 12, JBBPBitNumber.BITS_6).getAsLong()); - assertEquals(-12L & 0xFFL, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), -12, JBBPBitNumber.BITS_5).getAsLong()); + assertEquals(12L, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 12, + JBBPBitNumber.BITS_6).getAsLong()); + assertEquals(-12L & 0xFFL, + new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), -12, + JBBPBitNumber.BITS_5).getAsLong()); } @Test public void testGetAsInvertedBitOrder() { - assertEquals(1L, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 7, JBBPBitNumber.BITS_1).getAsInvertedBitOrder()); - assertEquals(4L, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 1, JBBPBitNumber.BITS_3).getAsInvertedBitOrder()); - assertEquals(0xF0L, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 0xF, JBBPBitNumber.BITS_8).getAsInvertedBitOrder()); - assertEquals(0x8FL, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 0xFF1, JBBPBitNumber.BITS_8).getAsInvertedBitOrder()); - assertEquals(0x8L, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 0xFF1, JBBPBitNumber.BITS_4).getAsInvertedBitOrder()); + assertEquals(1L, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 7, + JBBPBitNumber.BITS_1).getAsInvertedBitOrder()); + assertEquals(4L, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 1, + JBBPBitNumber.BITS_3).getAsInvertedBitOrder()); + assertEquals(0xF0L, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 0xF, + JBBPBitNumber.BITS_8).getAsInvertedBitOrder()); + assertEquals(0x8FL, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 0xFF1, + JBBPBitNumber.BITS_8).getAsInvertedBitOrder()); + assertEquals(0x8L, new JBBPFieldBit(new JBBPNamedFieldInfo("test.field", "field", 123), 0xFF1, + JBBPBitNumber.BITS_4).getAsInvertedBitOrder()); } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldBooleanTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldBooleanTest.java index 497e19fb..1f933791 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldBooleanTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldBooleanTest.java @@ -16,16 +16,20 @@ package com.igormaznitsa.jbbp.model; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + + import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - public class JBBPFieldBooleanTest { @Test public void testNameField() { - final JBBPFieldBoolean field = new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), true); + final JBBPFieldBoolean field = + new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), true); final JBBPNamedFieldInfo namedField = field.getNameInfo(); assertEquals("test.field", namedField.getFieldPath()); assertEquals("field", namedField.getFieldName()); @@ -34,30 +38,38 @@ public void testNameField() { @Test public void testgetAsBool_True() { - assertTrue(new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), true).getAsBool()); + assertTrue( + new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), true).getAsBool()); } @Test public void testgetAsBool_False() { - assertFalse(new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), false).getAsBool()); + assertFalse(new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), false) + .getAsBool()); } @Test public void testgetAsInt() { - assertEquals(1, new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), true).getAsInt()); - assertEquals(0, new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), false).getAsInt()); + assertEquals(1, + new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), true).getAsInt()); + assertEquals(0, + new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), false).getAsInt()); } @Test public void testgetAsLong() { - assertEquals(1L, new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), true).getAsLong()); - assertEquals(0L, new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), false).getAsLong()); + assertEquals(1L, + new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), true).getAsLong()); + assertEquals(0L, new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), false) + .getAsLong()); } @Test public void testGetAsInvertedBitOrder() { - assertEquals(0L, new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), false).getAsInvertedBitOrder()); - assertEquals(1L, new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), true).getAsInvertedBitOrder()); + assertEquals(0L, new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), false) + .getAsInvertedBitOrder()); + assertEquals(1L, new JBBPFieldBoolean(new JBBPNamedFieldInfo("test.field", "field", 123), true) + .getAsInvertedBitOrder()); } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldByteTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldByteTest.java index f74cfa64..4c59a477 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldByteTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldByteTest.java @@ -16,16 +16,20 @@ package com.igormaznitsa.jbbp.model; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + + import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - public class JBBPFieldByteTest { @Test public void testNameField() { - final JBBPFieldByte field = new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 123); + final JBBPFieldByte field = + new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 123); final JBBPNamedFieldInfo namedField = field.getNameInfo(); assertEquals("test.field", namedField.getFieldPath()); assertEquals("field", namedField.getFieldName()); @@ -34,31 +38,47 @@ public void testNameField() { @Test public void testgetAsBool_True() { - assertTrue(new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 123).getAsBool()); + assertTrue(new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 123) + .getAsBool()); } @Test public void testgetAsBool_False() { - assertFalse(new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 0).getAsBool()); + assertFalse(new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 0) + .getAsBool()); } @Test public void testgetAsInt() { - assertEquals(12, new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 12).getAsInt()); - assertEquals(-12, new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) -12).getAsInt()); + assertEquals(12, + new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 12) + .getAsInt()); + assertEquals(-12, + new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) -12) + .getAsInt()); } @Test public void testgetAsLong() { - assertEquals(12L, new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 12).getAsLong()); - assertEquals(-12L, new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) -12).getAsLong()); + assertEquals(12L, + new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 12) + .getAsLong()); + assertEquals(-12L, + new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) -12) + .getAsLong()); } @Test public void testGetAsInvertedBitOrder() { - assertEquals(0xFFFFFFFFFFFFFF80L, new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 1).getAsInvertedBitOrder()); - assertEquals(0xFFFFFFFFFFFFFFE0L, new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 7).getAsInvertedBitOrder()); - assertEquals(0x0FL, new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 0xF0).getAsInvertedBitOrder()); + assertEquals(0xFFFFFFFFFFFFFF80L, + new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 1) + .getAsInvertedBitOrder()); + assertEquals(0xFFFFFFFFFFFFFFE0L, + new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 7) + .getAsInvertedBitOrder()); + assertEquals(0x0FL, + new JBBPFieldByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 0xF0) + .getAsInvertedBitOrder()); } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldIntTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldIntTest.java index 3d88a66c..79cae952 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldIntTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldIntTest.java @@ -16,16 +16,20 @@ package com.igormaznitsa.jbbp.model; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + + import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - public class JBBPFieldIntTest { @Test public void testNameField() { - final JBBPFieldInt field = new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 123456); + final JBBPFieldInt field = + new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 123456); final JBBPNamedFieldInfo namedField = field.getNameInfo(); assertEquals("test.field", namedField.getFieldPath()); assertEquals("field", namedField.getFieldName()); @@ -34,32 +38,44 @@ public void testNameField() { @Test public void testgetAsBool_True() { - assertTrue(new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 32423).getAsBool()); + assertTrue( + new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 32423).getAsBool()); } @Test public void testgetAsBool_False() { - assertFalse(new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 0).getAsBool()); + assertFalse( + new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 0).getAsBool()); } @Test public void testgetAsInt() { - assertEquals(234324, new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 234324).getAsInt()); - assertEquals(-234324, new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), -234324).getAsInt()); + assertEquals(234324, + new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 234324).getAsInt()); + assertEquals(-234324, + new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), -234324).getAsInt()); } @Test public void testgetAsLong() { - assertEquals(234324L, new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 234324).getAsLong()); - assertEquals(-234324L, new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), -234324).getAsLong()); + assertEquals(234324L, + new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 234324).getAsLong()); + assertEquals(-234324L, + new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), -234324).getAsLong()); } @Test public void testGetAsInvertedBitOrder() { - assertEquals(0x0000000020C04080L, new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 0x01020304).getAsInvertedBitOrder()); - assertEquals(0x000000007FFFFFFFL, new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 0xFFFFFFFE).getAsInvertedBitOrder()); - assertEquals(0xFFFFFFFF80000000L, new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 0x00000001).getAsInvertedBitOrder()); + assertEquals(0x0000000020C04080L, + new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 0x01020304) + .getAsInvertedBitOrder()); + assertEquals(0x000000007FFFFFFFL, + new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 0xFFFFFFFE) + .getAsInvertedBitOrder()); + assertEquals(0xFFFFFFFF80000000L, + new JBBPFieldInt(new JBBPNamedFieldInfo("test.field", "field", 123), 0x00000001) + .getAsInvertedBitOrder()); } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldLongTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldLongTest.java index c0b86930..34df7ebb 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldLongTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldLongTest.java @@ -16,16 +16,20 @@ package com.igormaznitsa.jbbp.model; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + + import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - public class JBBPFieldLongTest { @Test public void testNameField() { - final JBBPFieldLong field = new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), 123456L); + final JBBPFieldLong field = + new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), 123456L); final JBBPNamedFieldInfo namedField = field.getNameInfo(); assertEquals("test.field", namedField.getFieldPath()); assertEquals("field", namedField.getFieldName()); @@ -34,29 +38,41 @@ public void testNameField() { @Test public void testgetAsBool_True() { - assertTrue(new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), 32423L).getAsBool()); + assertTrue( + new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), 32423L).getAsBool()); } @Test public void testgetAsBool_False() { - assertFalse(new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), 0L).getAsBool()); + assertFalse( + new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), 0L).getAsBool()); } @Test public void testgetAsInt() { - assertEquals((int) 23432498237439L, new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), 23432498237439L).getAsInt()); - assertEquals((int) -2343249987234L, new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), -2343249987234L).getAsInt()); + assertEquals((int) 23432498237439L, + new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), 23432498237439L) + .getAsInt()); + assertEquals((int) -2343249987234L, + new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), -2343249987234L) + .getAsInt()); } @Test public void testgetAsLong() { - assertEquals(23432498237439L, new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), 23432498237439L).getAsLong()); - assertEquals(-2343249987234L, new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), -2343249987234L).getAsLong()); + assertEquals(23432498237439L, + new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), 23432498237439L) + .getAsLong()); + assertEquals(-2343249987234L, + new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), -2343249987234L) + .getAsLong()); } @Test public void testGetAsInvertedBitOrder() { - assertEquals(0x10E060A020C04080L, new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), 0x0102030405060708L).getAsInvertedBitOrder()); + assertEquals(0x10E060A020C04080L, + new JBBPFieldLong(new JBBPNamedFieldInfo("test.field", "field", 123), 0x0102030405060708L) + .getAsInvertedBitOrder()); } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldShortTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldShortTest.java index 5cddf8a2..e3b6b14d 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldShortTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldShortTest.java @@ -16,16 +16,20 @@ package com.igormaznitsa.jbbp.model; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + + import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - public class JBBPFieldShortTest { @Test public void testNameField() { - final JBBPFieldShort field = new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 23456); + final JBBPFieldShort field = + new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 23456); final JBBPNamedFieldInfo namedField = field.getNameInfo(); assertEquals("test.field", namedField.getFieldPath()); assertEquals("field", namedField.getFieldName()); @@ -34,31 +38,47 @@ public void testNameField() { @Test public void testgetAsBool_True() { - assertTrue(new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 32423).getAsBool()); + assertTrue(new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 32423) + .getAsBool()); } @Test public void testgetAsBool_False() { - assertFalse(new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0).getAsBool()); + assertFalse(new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0) + .getAsBool()); } @Test public void testgetAsInt() { - assertEquals(23432, new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 23432).getAsInt()); - assertEquals(-23432, new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) -23432).getAsInt()); + assertEquals(23432, + new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 23432) + .getAsInt()); + assertEquals(-23432, + new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) -23432) + .getAsInt()); } @Test public void testgetAsLong() { - assertEquals(23432L, new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 23432).getAsLong()); - assertEquals(-23432L, new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) -23432).getAsLong()); + assertEquals(23432L, + new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 23432) + .getAsLong()); + assertEquals(-23432L, + new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) -23432) + .getAsLong()); } @Test public void testGetAsInvertedBitOrder() { - assertEquals(0xFFFFFFFFFFFF8000L, new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0x1).getAsInvertedBitOrder()); - assertEquals(0x0L, new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0x0).getAsInvertedBitOrder()); - assertEquals(0x0000000000004080L, new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0x0102).getAsInvertedBitOrder()); + assertEquals(0xFFFFFFFFFFFF8000L, + new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0x1) + .getAsInvertedBitOrder()); + assertEquals(0x0L, + new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0x0) + .getAsInvertedBitOrder()); + assertEquals(0x0000000000004080L, + new JBBPFieldShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0x0102) + .getAsInvertedBitOrder()); } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldStringTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldStringTest.java index 7a7e0f67..f38978af 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldStringTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldStringTest.java @@ -1,16 +1,18 @@ package com.igormaznitsa.jbbp.model; -import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; + +import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; +import org.junit.jupiter.api.Test; + public class JBBPFieldStringTest { @Test public void testNameField() { - final JBBPFieldString field = new JBBPFieldString(new JBBPNamedFieldInfo("test.field", "field", 123), "Huzzaa"); + final JBBPFieldString field = + new JBBPFieldString(new JBBPNamedFieldInfo("test.field", "field", 123), "Huzzaa"); final JBBPNamedFieldInfo namedField = field.getNameInfo(); assertEquals("test.field", namedField.getFieldPath()); assertEquals("field", namedField.getFieldName()); @@ -30,13 +32,15 @@ public void testReverseBits_Text() { @Test public void testGetAsString_NotNull() { - final JBBPFieldString field = new JBBPFieldString(new JBBPNamedFieldInfo("test.field", "field", 123), "Huzzaa"); + final JBBPFieldString field = + new JBBPFieldString(new JBBPNamedFieldInfo("test.field", "field", 123), "Huzzaa"); assertEquals("Huzzaa", field.getAsString()); } @Test public void testGetAsString_Null() { - final JBBPFieldString field = new JBBPFieldString(new JBBPNamedFieldInfo("test.field", "field", 123), null); + final JBBPFieldString field = + new JBBPFieldString(new JBBPNamedFieldInfo("test.field", "field", 123), null); assertNull(field.getAsString()); } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldStructTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldStructTest.java index c236e718..92b047f4 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldStructTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldStructTest.java @@ -16,6 +16,16 @@ package com.igormaznitsa.jbbp.model; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + + import com.igormaznitsa.jbbp.JBBPParser; import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import com.igormaznitsa.jbbp.exceptions.JBBPFinderException; @@ -24,20 +34,23 @@ import com.igormaznitsa.jbbp.utils.JBBPUtils; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - public class JBBPFieldStructTest { @Test public void testConstructor_Fields() { - final JBBPFieldStruct struct = new JBBPFieldStruct(null, new JBBPAbstractField[] {new JBBPFieldByte(null, (byte) 123), new JBBPFieldByte(null, (byte) -123)}); + final JBBPFieldStruct struct = new JBBPFieldStruct(null, + new JBBPAbstractField[] {new JBBPFieldByte(null, (byte) 123), + new JBBPFieldByte(null, (byte) -123)}); assertNull(struct.getNameInfo()); assertEquals(2, struct.getArray().length); } @Test public void testConstructor_Name_Fields() { - final JBBPFieldStruct struct = new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), new JBBPAbstractField[] {new JBBPFieldByte(null, (byte) 123), new JBBPFieldByte(null, (byte) -123)}); + final JBBPFieldStruct struct = + new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), + new JBBPAbstractField[] {new JBBPFieldByte(null, (byte) 123), + new JBBPFieldByte(null, (byte) -123)}); assertNotNull(struct.getNameInfo()); assertEquals("test.struct", struct.getNameInfo().getFieldPath()); assertEquals("struct", struct.getNameInfo().getFieldName()); @@ -47,7 +60,10 @@ public void testConstructor_Name_Fields() { @Test public void testConstructor_Name_ListOfFields() { - final JBBPFieldStruct struct = new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), JBBPUtils.fieldsAsList(new JBBPFieldByte(null, (byte) 123), new JBBPFieldByte(null, (byte) -123))); + final JBBPFieldStruct struct = + new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), JBBPUtils + .fieldsAsList(new JBBPFieldByte(null, (byte) 123), + new JBBPFieldByte(null, (byte) -123))); assertNotNull(struct.getNameInfo()); assertEquals("test.struct", struct.getNameInfo().getFieldPath()); assertEquals("struct", struct.getNameInfo().getFieldName()); @@ -57,11 +73,16 @@ public void testConstructor_Name_ListOfFields() { @Test public void testFindFieldForName() { - final JBBPFieldByte field1 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); - final JBBPFieldInt field2 = new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); - final JBBPFieldByte field3 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); - - final JBBPFieldStruct struct = new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), new JBBPAbstractField[] {field1, field2, field3}); + final JBBPFieldByte field1 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); + final JBBPFieldInt field2 = + new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); + final JBBPFieldByte field3 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); + + final JBBPFieldStruct struct = + new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), + new JBBPAbstractField[] {field1, field2, field3}); assertSame(field1, struct.findFieldForName("field1")); assertSame(field2, struct.findFieldForName("field2")); assertSame(field3, struct.findFieldForName("field3")); @@ -70,11 +91,16 @@ public void testFindFieldForName() { @Test public void testFindFieldForNameAndType() { - final JBBPFieldByte field1 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); - final JBBPFieldInt field2 = new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); - final JBBPFieldByte field3 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); - - final JBBPFieldStruct struct = new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), new JBBPAbstractField[] {field1, field2, field3}); + final JBBPFieldByte field1 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); + final JBBPFieldInt field2 = + new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); + final JBBPFieldByte field3 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); + + final JBBPFieldStruct struct = + new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), + new JBBPAbstractField[] {field1, field2, field3}); assertSame(field2, struct.findFieldForNameAndType("field2", JBBPFieldInt.class)); assertNull(struct.findFieldForNameAndType("field2", JBBPFieldByte.class)); assertNull(struct.findFieldForNameAndType("field1", JBBPFieldInt.class)); @@ -82,11 +108,16 @@ public void testFindFieldForNameAndType() { @Test public void testFindFieldForPathAndType() { - final JBBPFieldByte field1 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); - final JBBPFieldInt field2 = new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); - final JBBPFieldByte field3 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); - - final JBBPFieldStruct struct = new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), new JBBPAbstractField[] {field1, field2, field3}); + final JBBPFieldByte field1 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); + final JBBPFieldInt field2 = + new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); + final JBBPFieldByte field3 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); + + final JBBPFieldStruct struct = + new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), + new JBBPAbstractField[] {field1, field2, field3}); assertSame(field2, struct.findFieldForPathAndType("struct.field2", JBBPFieldInt.class)); assertNull(struct.findFieldForPathAndType("field2", JBBPFieldByte.class)); assertNull(struct.findFieldForPathAndType("field1", JBBPFieldInt.class)); @@ -94,9 +125,15 @@ public void testFindFieldForPathAndType() { @Test public void testFindFieldForPath() { - final JBBPFieldByte field = new JBBPFieldByte(new JBBPNamedFieldInfo("struct1.struct2.field3", "field3", 2048), (byte) 78); - final JBBPFieldStruct struct2 = new JBBPFieldStruct(new JBBPNamedFieldInfo("struct1.struct2", "struct2", 1024), new JBBPAbstractField[] {field}); - final JBBPFieldStruct struct1 = new JBBPFieldStruct(new JBBPNamedFieldInfo("struct1", "struct1", 1024), new JBBPAbstractField[] {struct2}); + final JBBPFieldByte field = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct1.struct2.field3", "field3", 2048), + (byte) 78); + final JBBPFieldStruct struct2 = + new JBBPFieldStruct(new JBBPNamedFieldInfo("struct1.struct2", "struct2", 1024), + new JBBPAbstractField[] {field}); + final JBBPFieldStruct struct1 = + new JBBPFieldStruct(new JBBPNamedFieldInfo("struct1", "struct1", 1024), + new JBBPAbstractField[] {struct2}); try { struct1.findFieldForPath(null); @@ -119,11 +156,16 @@ public void testFindFieldForPath() { @Test public void testFindFieldForType() { - final JBBPFieldByte field1 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); - final JBBPFieldInt field2 = new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); - final JBBPFieldByte field3 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); - - final JBBPFieldStruct struct = new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), new JBBPAbstractField[] {field1, field2, field3}); + final JBBPFieldByte field1 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); + final JBBPFieldInt field2 = + new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); + final JBBPFieldByte field3 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); + + final JBBPFieldStruct struct = + new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), + new JBBPAbstractField[] {field1, field2, field3}); try { struct.findFieldForType(JBBPFieldByte.class); fail("Must throw JBBPTooManyFieldsFoundException"); @@ -136,11 +178,16 @@ public void testFindFieldForType() { @Test public void testFindFirstFieldForType() { - final JBBPFieldByte field1 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); - final JBBPFieldInt field2 = new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); - final JBBPFieldByte field3 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); + final JBBPFieldByte field1 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); + final JBBPFieldInt field2 = + new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); + final JBBPFieldByte field3 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); - final JBBPFieldStruct struct = new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), new JBBPAbstractField[] {field1, field2, field3}); + final JBBPFieldStruct struct = + new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), + new JBBPAbstractField[] {field1, field2, field3}); assertSame(field1, struct.findFirstFieldForType(JBBPFieldByte.class)); assertSame(field2, struct.findFirstFieldForType(JBBPFieldInt.class)); @@ -149,11 +196,16 @@ public void testFindFirstFieldForType() { @Test public void testFindLastFieldForType() { - final JBBPFieldByte field1 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); - final JBBPFieldInt field2 = new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); - final JBBPFieldByte field3 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); + final JBBPFieldByte field1 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); + final JBBPFieldInt field2 = + new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); + final JBBPFieldByte field3 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); - final JBBPFieldStruct struct = new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), new JBBPAbstractField[] {field1, field2, field3}); + final JBBPFieldStruct struct = + new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), + new JBBPAbstractField[] {field1, field2, field3}); assertSame(field3, struct.findLastFieldForType(JBBPFieldByte.class)); assertSame(field2, struct.findLastFieldForType(JBBPFieldInt.class)); @@ -162,11 +214,16 @@ public void testFindLastFieldForType() { @Test public void testPathExists() { - final JBBPFieldByte field1 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); - final JBBPFieldInt field2 = new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); - final JBBPFieldByte field3 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); + final JBBPFieldByte field1 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); + final JBBPFieldInt field2 = + new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); + final JBBPFieldByte field3 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); - final JBBPFieldStruct struct = new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), new JBBPAbstractField[] {field1, field2, field3}); + final JBBPFieldStruct struct = + new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), + new JBBPAbstractField[] {field1, field2, field3}); assertTrue(struct.pathExists("struct.field1")); assertFalse(struct.pathExists("field1")); @@ -175,11 +232,16 @@ public void testPathExists() { @Test public void testNameExists() { - final JBBPFieldByte field1 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); - final JBBPFieldInt field2 = new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); - final JBBPFieldByte field3 = new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); + final JBBPFieldByte field1 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field1", "field1", 1024), (byte) 23); + final JBBPFieldInt field2 = + new JBBPFieldInt(new JBBPNamedFieldInfo("struct.field2", "field2", 1960), 23432); + final JBBPFieldByte field3 = + new JBBPFieldByte(new JBBPNamedFieldInfo("struct.field3", "field3", 2048), (byte) 78); - final JBBPFieldStruct struct = new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), new JBBPAbstractField[] {field1, field2, field3}); + final JBBPFieldStruct struct = + new JBBPFieldStruct(new JBBPNamedFieldInfo("test.struct", "struct", 999), + new JBBPAbstractField[] {field1, field2, field3}); assertFalse(struct.nameExists("struct.field1")); assertTrue(struct.nameExists("field1")); @@ -189,7 +251,9 @@ public void testNameExists() { @Test public void testMapTo_Class() throws Exception { - final ClassTestMapToClass mapped = JBBPParser.prepare("byte a; byte b; byte c;").parse(new byte[] {1, 2, 3}).mapTo(new ClassTestMapToClass()); + final ClassTestMapToClass mapped = + JBBPParser.prepare("byte a; byte b; byte c;").parse(new byte[] {1, 2, 3}) + .mapTo(new ClassTestMapToClass()); assertEquals(1, mapped.a); assertEquals(2, mapped.b); @@ -199,7 +263,8 @@ public void testMapTo_Class() throws Exception { @Test public void testMapTo_Object() throws Exception { final ClassTestMapToClass mapped = new ClassTestMapToClass(); - assertSame(mapped, JBBPParser.prepare("byte a; byte b; byte c;").parse(new byte[] {1, 2, 3}).mapTo(mapped)); + assertSame(mapped, + JBBPParser.prepare("byte a; byte b; byte c;").parse(new byte[] {1, 2, 3}).mapTo(mapped)); assertEquals(1, mapped.a); assertEquals(2, mapped.b); @@ -208,12 +273,15 @@ public void testMapTo_Object() throws Exception { @Test public void testInterStructFieldReferences() throws Exception { - final JBBPParser parser = JBBPParser.prepare("header {ubyte sections; ubyte datalen;} sections [header.sections]{byte[header.datalen] data;}"); + final JBBPParser parser = JBBPParser.prepare( + "header {ubyte sections; ubyte datalen;} sections [header.sections]{byte[header.datalen] data;}"); - final JBBPFieldArrayStruct sections = parser.parse(new byte[] {3, 2, 1, 2, 3, 4, 5, 6}).findFieldForNameAndType("sections", JBBPFieldArrayStruct.class); + final JBBPFieldArrayStruct sections = parser.parse(new byte[] {3, 2, 1, 2, 3, 4, 5, 6}) + .findFieldForNameAndType("sections", JBBPFieldArrayStruct.class); assertEquals(3, sections.size()); for (int i = 0; i < 3; i++) { - JBBPFieldArrayByte data = sections.getElementAt(i).findFieldForNameAndType("data", JBBPFieldArrayByte.class); + JBBPFieldArrayByte data = + sections.getElementAt(i).findFieldForNameAndType("data", JBBPFieldArrayByte.class); final int base = i * 2; assertArrayEquals(new byte[] {(byte) (base + 1), (byte) (base + 2)}, data.getArray()); } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldUByteTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldUByteTest.java index 9aa4ffec..38edb868 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldUByteTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldUByteTest.java @@ -16,15 +16,19 @@ package com.igormaznitsa.jbbp.model; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + + import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - public class JBBPFieldUByteTest { @Test public void testNameField() { - final JBBPFieldUByte field = new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 10); + final JBBPFieldUByte field = + new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 10); final JBBPNamedFieldInfo namedField = field.getNameInfo(); assertEquals("test.field", namedField.getFieldPath()); assertEquals("field", namedField.getFieldName()); @@ -33,30 +37,46 @@ public void testNameField() { @Test public void testgetAsBool_True() { - assertTrue(new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 123).getAsBool()); + assertTrue(new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 123) + .getAsBool()); } @Test public void testgetAsBool_False() { - assertFalse(new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 0).getAsBool()); + assertFalse(new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 0) + .getAsBool()); } @Test public void testgetAsInt() { - assertEquals(12, new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 12).getAsInt()); - assertEquals(-12 & 0xFF, new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) -12).getAsInt()); + assertEquals(12, + new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 12) + .getAsInt()); + assertEquals(-12 & 0xFF, + new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) -12) + .getAsInt()); } @Test public void testgetAsLong() { - assertEquals(12L, new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 12).getAsLong()); - assertEquals(-12L & 0xFFL, new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) -12).getAsLong()); + assertEquals(12L, + new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 12) + .getAsLong()); + assertEquals(-12L & 0xFFL, + new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) -12) + .getAsLong()); } @Test public void testGetAsInvertedBitOrder() { - assertEquals(0x0000000000000080L, new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 1).getAsInvertedBitOrder()); - assertEquals(0x00000000000000E0L, new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 7).getAsInvertedBitOrder()); - assertEquals(0x0FL, new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 0xF0).getAsInvertedBitOrder()); + assertEquals(0x0000000000000080L, + new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 1) + .getAsInvertedBitOrder()); + assertEquals(0x00000000000000E0L, + new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 7) + .getAsInvertedBitOrder()); + assertEquals(0x0FL, + new JBBPFieldUByte(new JBBPNamedFieldInfo("test.field", "field", 123), (byte) 0xF0) + .getAsInvertedBitOrder()); } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldUShortTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldUShortTest.java index 9c451aaf..8aa10b3a 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldUShortTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/model/JBBPFieldUShortTest.java @@ -16,16 +16,21 @@ package com.igormaznitsa.jbbp.model; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + + import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - public class JBBPFieldUShortTest { @Test public void testNameField() { - final JBBPFieldUShort field = new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 23456); + final JBBPFieldUShort field = + new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 23456); final JBBPNamedFieldInfo namedField = field.getNameInfo(); assertEquals("test.field", namedField.getFieldPath()); assertEquals("field", namedField.getFieldName()); @@ -34,37 +39,55 @@ public void testNameField() { @Test public void testgetAsBool_True() { - assertTrue(new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 32423).getAsBool()); + assertTrue( + new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 32423) + .getAsBool()); } @Test public void testgetAsBool_False() { - assertFalse(new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0).getAsBool()); + assertFalse(new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0) + .getAsBool()); } @Test public void testgetAsInt() { - assertEquals(23432, new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 23432).getAsInt()); - assertEquals(-23432 & 0xFFFF, new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) -23432).getAsInt()); + assertEquals(23432, + new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 23432) + .getAsInt()); + assertEquals(-23432 & 0xFFFF, + new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) -23432) + .getAsInt()); } @Test public void testgetAsLong() { - assertEquals(23432L, new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 23432).getAsLong()); - assertEquals(-23432L & 0xFFFFL, new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) -23432).getAsLong()); + assertEquals(23432L, + new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 23432) + .getAsLong()); + assertEquals(-23432L & 0xFFFFL, + new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) -23432) + .getAsLong()); } @Test public void testGetAsInvertedBitOrder() { - assertEquals(0x0000000000008000L, new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0x1).getAsInvertedBitOrder()); - assertEquals(0x0L, new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0x0).getAsInvertedBitOrder()); - assertEquals(0x0000000000004080L, new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0x0102).getAsInvertedBitOrder()); + assertEquals(0x0000000000008000L, + new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0x1) + .getAsInvertedBitOrder()); + assertEquals(0x0L, + new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0x0) + .getAsInvertedBitOrder()); + assertEquals(0x0000000000004080L, + new JBBPFieldUShort(new JBBPNamedFieldInfo("test.field", "field", 123), (short) 0x0102) + .getAsInvertedBitOrder()); } @Test public void testGetValueArrayAsObject() { final short[] array = new short[] {(short) -27834, 23423, 0, -2, 3}; - final JBBPFieldArrayUShort test = new JBBPFieldArrayUShort(new JBBPNamedFieldInfo("test.field", "field", 999), array); + final JBBPFieldArrayUShort test = + new JBBPFieldArrayUShort(new JBBPNamedFieldInfo("test.field", "field", 999), array); assertArrayEquals(array, (short[]) test.getValueArrayAsObject(false)); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/testaux/AbstractJBBPToJavaConverterTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/testaux/AbstractJBBPToJavaConverterTest.java index b6a511bb..cf60b118 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/testaux/AbstractJBBPToJavaConverterTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/testaux/AbstractJBBPToJavaConverterTest.java @@ -93,7 +93,8 @@ protected Object callRead(final Object instance, final byte[] array) throws Exce } } - protected Object callRead(final Object instance, final JBBPBitInputStream inStream) throws Exception { + protected Object callRead(final Object instance, final JBBPBitInputStream inStream) + throws Exception { try { instance.getClass().getMethod("read", JBBPBitInputStream.class).invoke(instance, inStream); return instance; @@ -122,16 +123,22 @@ protected byte[] callWrite(final Object instance) throws Exception { } } - protected void callWrite(final Object instance, final JBBPBitOutputStream outStream) throws Exception { + protected void callWrite(final Object instance, final JBBPBitOutputStream outStream) + throws Exception { instance.getClass().getMethod("write", JBBPBitOutputStream.class).invoke(instance, outStream); } - protected Object compileAndMakeInstanceSrc(final String script, final String classCustomText, final StringBuilder srcBuffer) throws Exception { - final String classBody = JBBPToJavaConverter.makeBuilder(JBBPParser.prepare(script)).setMainClassName(CLASS_NAME).setMainClassPackage(PACKAGE_NAME).setMainClassCustomText(classCustomText).build().convert(); + protected Object compileAndMakeInstanceSrc(final String script, final String classCustomText, + final StringBuilder srcBuffer) throws Exception { + final String classBody = + JBBPToJavaConverter.makeBuilder(JBBPParser.prepare(script)).setMainClassName(CLASS_NAME) + .setMainClassPackage(PACKAGE_NAME).setMainClassCustomText(classCustomText).build() + .convert(); if (srcBuffer != null) { srcBuffer.append(classBody); } - final ClassLoader cloader = saveAndCompile(new JavaClassContent(PACKAGE_NAME + '.' + CLASS_NAME, classBody)); + final ClassLoader cloader = + saveAndCompile(new JavaClassContent(PACKAGE_NAME + '.' + CLASS_NAME, classBody)); return ReflectUtils.newInstance(cloader.loadClass(PACKAGE_NAME + '.' + CLASS_NAME)); } @@ -139,17 +146,27 @@ protected Object compileAndMakeInstance(final String script) throws Exception { return this.compileAndMakeInstance(PACKAGE_NAME + '.' + CLASS_NAME, script, null); } - protected Object compileAndMakeInstance(final String script, final int parserFlags) throws Exception { + protected Object compileAndMakeInstance(final String script, final int parserFlags) + throws Exception { return this.compileAndMakeInstance(PACKAGE_NAME + '.' + CLASS_NAME, script, parserFlags, null); } - protected Object compileAndMakeInstance(final String instanceClassName, final String script, final JBBPCustomFieldTypeProcessor customFieldProcessor, final JavaClassContent... extraClasses) throws Exception { - return this.compileAndMakeInstance(instanceClassName, script, 0, customFieldProcessor, extraClasses); + protected Object compileAndMakeInstance(final String instanceClassName, final String script, + final JBBPCustomFieldTypeProcessor customFieldProcessor, + final JavaClassContent... extraClasses) throws Exception { + return this + .compileAndMakeInstance(instanceClassName, script, 0, customFieldProcessor, extraClasses); } - protected Object compileAndMakeInstance(final String instanceClassName, final String script, final int parserFlags, final JBBPCustomFieldTypeProcessor customFieldProcessor, final JavaClassContent... extraClasses) throws Exception { + protected Object compileAndMakeInstance(final String instanceClassName, final String script, + final int parserFlags, + final JBBPCustomFieldTypeProcessor customFieldProcessor, + final JavaClassContent... extraClasses) throws Exception { final List klazzes = new ArrayList<>(Arrays.asList(extraClasses)); - final JavaClassContent klazzContent = new JavaClassContent(PACKAGE_NAME + '.' + CLASS_NAME, JBBPParser.prepare(script, JBBPBitOrder.LSB0, customFieldProcessor, parserFlags).convertToSrc(TargetSources.JAVA, PACKAGE_NAME + "." + CLASS_NAME).get(0).getResult().values().iterator().next()); + final JavaClassContent klazzContent = new JavaClassContent(PACKAGE_NAME + '.' + CLASS_NAME, + JBBPParser.prepare(script, JBBPBitOrder.LSB0, customFieldProcessor, parserFlags) + .convertToSrc(TargetSources.JAVA, PACKAGE_NAME + "." + CLASS_NAME).get(0).getResult() + .values().iterator().next()); if (this.printGeneratedClassText) { System.out.println(klazzContent.classText); } @@ -162,7 +179,8 @@ public ClassLoader saveAndCompile(final JavaClassContent... klasses) throws IOEx return this.saveAndCompile(null, klasses); } - public ClassLoader saveAndCompile(final ClassLoader classLoader, final JavaClassContent... klasses) throws IOException { + public ClassLoader saveAndCompile(final ClassLoader classLoader, + final JavaClassContent... klasses) throws IOException { final File folder = tempFolder.newFolder(); final List classFiles = new ArrayList<>(); @@ -180,12 +198,15 @@ public ClassLoader saveAndCompile(final ClassLoader classLoader, final JavaClass final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); final DiagnosticCollector diagnostics = new DiagnosticCollector<>(); - final StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null); - final Iterable compilationUnits = fileManager.getJavaFileObjectsFromFiles(classFiles); + final StandardJavaFileManager fileManager = + compiler.getStandardFileManager(diagnostics, null, null); + final Iterable compilationUnits = + fileManager.getJavaFileObjectsFromFiles(classFiles); if (!compiler.getTask(null, fileManager, null, null, null, compilationUnits).call()) { for (final Diagnostic diagnostic : diagnostics.getDiagnostics()) { - System.err.format("Error on line %d in %s%n", diagnostic.getLineNumber(), diagnostic.getSource()); + System.err + .format("Error on line %d in %s%n", diagnostic.getLineNumber(), diagnostic.getSource()); } for (final File f : classFiles) { @@ -197,7 +218,8 @@ public ClassLoader saveAndCompile(final ClassLoader classLoader, final JavaClass throw new IOException("Error during compilation"); } - return classLoader == null ? new URLClassLoader(new URL[] {folder.toURI().toURL()}) : classLoader; + return classLoader == null ? new URLClassLoader(new URL[] {folder.toURI().toURL()}) : + classLoader; } protected static class TemporaryFolder { @@ -234,7 +256,8 @@ public File newFolder() { result.deleteOnExit(); return result; } catch (IOException ex) { - throw new Error("Can't make new sub-folder in temp folder : " + this.folder.getAbsolutePath(), ex); + throw new Error( + "Can't make new sub-folder in temp folder : " + this.folder.getAbsolutePath(), ex); } } diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/DynamicIntBuffer.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/DynamicIntBuffer.java index bd4de782..4a047238 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/DynamicIntBuffer.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/DynamicIntBuffer.java @@ -17,7 +17,6 @@ package com.igormaznitsa.jbbp.utils; import com.igormaznitsa.jbbp.compiler.conversion.JBBPToJavaConverterReadWriteTest; - import java.util.Arrays; /** diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPCustomFieldTypeProcessorAggregatorTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPCustomFieldTypeProcessorAggregatorTest.java index 3d20aa9e..4ba6fcbf 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPCustomFieldTypeProcessorAggregatorTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPCustomFieldTypeProcessorAggregatorTest.java @@ -16,6 +16,12 @@ package com.igormaznitsa.jbbp.utils; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + + import com.igormaznitsa.jbbp.JBBPCustomFieldTypeProcessor; import com.igormaznitsa.jbbp.JBBPParser; import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo; @@ -24,15 +30,11 @@ import com.igormaznitsa.jbbp.io.JBBPBitOrder; import com.igormaznitsa.jbbp.model.JBBPAbstractField; import com.igormaznitsa.jbbp.model.JBBPFieldByte; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.function.Executable; - import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class JBBPCustomFieldTypeProcessorAggregatorTest { @@ -47,13 +49,21 @@ public String[] getCustomFieldTypes() { } @Override - public boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, int extraData, boolean isArray) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, + int extraData, boolean isArray) { + throw new UnsupportedOperationException( + "Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override - public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, int parserFlags, JBBPFieldTypeParameterContainer customTypeFieldInfo, JBBPNamedFieldInfo fieldName, int extraData, boolean readWholeStream, int arrayLength) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, + int parserFlags, + JBBPFieldTypeParameterContainer customTypeFieldInfo, + JBBPNamedFieldInfo fieldName, int extraData, + boolean readWholeStream, int arrayLength) + throws IOException { + throw new UnsupportedOperationException( + "Not supported yet."); //To change body of generated methods, choose Tools | Templates. } }; @@ -65,13 +75,21 @@ public String[] getCustomFieldTypes() { } @Override - public boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, int extraData, boolean isArray) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, + int extraData, boolean isArray) { + throw new UnsupportedOperationException( + "Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override - public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, int parserFlags, JBBPFieldTypeParameterContainer customTypeFieldInfo, JBBPNamedFieldInfo fieldName, int extraData, boolean readWholeStream, int arrayLength) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, + int parserFlags, + JBBPFieldTypeParameterContainer customTypeFieldInfo, + JBBPNamedFieldInfo fieldName, int extraData, + boolean readWholeStream, int arrayLength) + throws IOException { + throw new UnsupportedOperationException( + "Not supported yet."); //To change body of generated methods, choose Tools | Templates. } }; @@ -89,13 +107,21 @@ public String[] getCustomFieldTypes() { } @Override - public boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, int extraData, boolean isArray) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, + int extraData, boolean isArray) { + throw new UnsupportedOperationException( + "Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override - public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, int parserFlags, JBBPFieldTypeParameterContainer customTypeFieldInfo, JBBPNamedFieldInfo fieldName, int extraData, boolean readWholeStream, int arrayLength) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, + int parserFlags, + JBBPFieldTypeParameterContainer customTypeFieldInfo, + JBBPNamedFieldInfo fieldName, int extraData, + boolean readWholeStream, int arrayLength) + throws IOException { + throw new UnsupportedOperationException( + "Not supported yet."); //To change body of generated methods, choose Tools | Templates. } }; @@ -107,17 +133,26 @@ public String[] getCustomFieldTypes() { } @Override - public boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, int extraData, boolean isArray) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, + int extraData, boolean isArray) { + throw new UnsupportedOperationException( + "Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override - public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, int parserFlags, JBBPFieldTypeParameterContainer customTypeFieldInfo, JBBPNamedFieldInfo fieldName, int extraData, boolean readWholeStream, int arrayLength) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, + int parserFlags, + JBBPFieldTypeParameterContainer customTypeFieldInfo, + JBBPNamedFieldInfo fieldName, int extraData, + boolean readWholeStream, int arrayLength) + throws IOException { + throw new UnsupportedOperationException( + "Not supported yet."); //To change body of generated methods, choose Tools | Templates. } }; - final List types = Arrays.asList(new JBBPCustomFieldTypeProcessorAggregator(proc1, proc2).getCustomFieldTypes()); + final List types = Arrays + .asList(new JBBPCustomFieldTypeProcessorAggregator(proc1, proc2).getCustomFieldTypes()); assertEquals(6, types.size()); assertTrue(types.contains("type1")); @@ -142,13 +177,19 @@ public String[] getCustomFieldTypes() { } @Override - public boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, int extraData, boolean isArray) { + public boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, + int extraData, boolean isArray) { allowed.add(new Record(fieldType.getTypeName(), this)); return true; } @Override - public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, int parserFlags, JBBPFieldTypeParameterContainer customTypeFieldInfo, JBBPNamedFieldInfo fieldName, int extraData, boolean readWholeStream, int arrayLength) throws IOException { + public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, + int parserFlags, + JBBPFieldTypeParameterContainer customTypeFieldInfo, + JBBPNamedFieldInfo fieldName, int extraData, + boolean readWholeStream, int arrayLength) + throws IOException { read.add(new Record(customTypeFieldInfo.getTypeName(), this)); return new JBBPFieldByte(fieldName, (byte) in.readByte()); } @@ -162,19 +203,27 @@ public String[] getCustomFieldTypes() { } @Override - public boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, int extraData, boolean isArray) { + public boolean isAllowed(JBBPFieldTypeParameterContainer fieldType, String fieldName, + int extraData, boolean isArray) { allowed.add(new Record(fieldType.getTypeName(), this)); return true; } @Override - public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, int parserFlags, JBBPFieldTypeParameterContainer customTypeFieldInfo, JBBPNamedFieldInfo fieldName, int extraData, boolean readWholeStream, int arrayLength) throws IOException { + public JBBPAbstractField readCustomFieldType(JBBPBitInputStream in, JBBPBitOrder bitOrder, + int parserFlags, + JBBPFieldTypeParameterContainer customTypeFieldInfo, + JBBPNamedFieldInfo fieldName, int extraData, + boolean readWholeStream, int arrayLength) + throws IOException { read.add(new Record(customTypeFieldInfo.getTypeName(), this)); return new JBBPFieldByte(fieldName, (byte) in.readByte()); } }; - final JBBPParser parser = JBBPParser.prepare("type1; type2; type3; type4; type5; type6;", JBBPBitOrder.LSB0, new JBBPCustomFieldTypeProcessorAggregator(proc1, proc2), 0); + final JBBPParser parser = JBBPParser + .prepare("type1; type2; type3; type4; type5; type6;", JBBPBitOrder.LSB0, + new JBBPCustomFieldTypeProcessorAggregator(proc1, proc2), 0); assertEquals(6, allowed.size()); diff --git a/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPDslBuilderTest.java b/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPDslBuilderTest.java index 1029ad3c..fd2c4199 100644 --- a/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPDslBuilderTest.java +++ b/jbbp/src/test/java/com/igormaznitsa/jbbp/utils/JBBPDslBuilderTest.java @@ -59,7 +59,8 @@ public void testCheckForDuplicatedNameInSameStructure() { final JBBPDslBuilder builder2 = JBBPDslBuilder.Begin().Int("test"); assertThrows(IllegalArgumentException.class, () -> builder2.Struct("test")); - final JBBPDslBuilder builder3 = JBBPDslBuilder.Begin().Struct("test").Int("a").CloseStruct().Bool("b"); + final JBBPDslBuilder builder3 = + JBBPDslBuilder.Begin().Struct("test").Int("a").CloseStruct().Bool("b"); assertThrows(IllegalArgumentException.class, () -> builder3.Struct("test")); } @@ -67,19 +68,23 @@ public void testCheckForDuplicatedNameInSameStructure() { @Test public void testCheckForDuplicatedNameInDifferentStructures() { JBBPDslBuilder.Begin().Int("test").Struct().Bool("test").CloseStruct().End(); - JBBPDslBuilder.Begin().Int("test").Struct().Int("test").Struct().Bool("test").CloseStruct().CloseStruct().End(); - JBBPDslBuilder.Begin().Struct().Int("test").Struct().Bool("test").CloseStruct().CloseStruct().Int("test").End(); + JBBPDslBuilder.Begin().Int("test").Struct().Int("test").Struct().Bool("test").CloseStruct() + .CloseStruct().End(); + JBBPDslBuilder.Begin().Struct().Int("test").Struct().Bool("test").CloseStruct().CloseStruct() + .Int("test").End(); JBBPDslBuilder.Begin().Struct("test").Int("test").CloseStruct().End(); } @Test public void testNonFormatted() { - assertEquals("bool test;{int field1;}", Begin().Bool("test").Struct().Int("field1").CloseStruct().End(false)); + assertEquals("bool test;{int field1;}", + Begin().Bool("test").Struct().Int("field1").CloseStruct().End(false)); } @Test public void testFormatted() { - assertEquals("bool test;\n{\n\tint field1;\n}\n", Begin().Bool("test").Struct().Int("field1").CloseStruct().End(true)); + assertEquals("bool test;\n{\n\tint field1;\n}\n", + Begin().Bool("test").Struct().Int("field1").CloseStruct().End(true)); } @Test @@ -103,9 +108,12 @@ public void testComment() { assertEquals("// Test\n", Begin().Comment("Test").End()); assertEquals("// //\n// Test\n", Begin().Comment("//").Comment("Test").End()); assertEquals("// Test\n// Test2\n", Begin().Comment("Test").Comment("Test2").End()); - assertEquals("int a;// Test\n// Test2\n", Begin().Int("a").Comment("Test").Comment("Test2").End()); - assertEquals("int a;\n// Test\n// Test2\n", Begin().Int("a").NewLineComment("Test").NewLineComment("Test2").End()); - assertEquals("int a;hello{// hello\n}// end hello\n", Begin().Int("a").Struct("hello").Comment("hello").CloseStruct().Comment("end hello").End()); + assertEquals("int a;// Test\n// Test2\n", + Begin().Int("a").Comment("Test").Comment("Test2").End()); + assertEquals("int a;\n// Test\n// Test2\n", + Begin().Int("a").NewLineComment("Test").NewLineComment("Test2").End()); + assertEquals("int a;hello{// hello\n}// end hello\n", + Begin().Int("a").Struct("hello").Comment("hello").CloseStruct().Comment("end hello").End()); } @Test @@ -125,7 +133,8 @@ public void testType_CustomArray() { assertEquals("some[1234] lupus;", Begin().CustomArray("some", "lupus", 1234).End()); assertEquals("some[a+1234] lupus;", Begin().CustomArray("some", "lupus", "a+1234").End()); assertEquals("some:(c/2)[_] huzzaa;", Begin().CustomArray("some", "huzzaa", -1, "c/2").End()); - assertEquals("some:(c/2)[a+b] huzzaa;", Begin().CustomArray("some", "huzzaa", "a+b", "c/2").End()); + assertEquals("some:(c/2)[a+b] huzzaa;", + Begin().CustomArray("some", "huzzaa", "a+b", "c/2").End()); } @Test @@ -368,13 +377,15 @@ public void testStructArray() { @Test public void testStruct_CloseStruct() { - assertEquals("{{{}}}", Begin().Struct().Struct().Struct().CloseStruct().CloseStruct().CloseStruct().End()); + assertEquals("{{{}}}", + Begin().Struct().Struct().Struct().CloseStruct().CloseStruct().CloseStruct().End()); assertEquals("{\n" + - "\t{\n" + - "\t\t{\n" + - "\t\t}\n" + - "\t}\n" + - "}\n", Begin().Struct().Struct().Struct().CloseStruct().CloseStruct().CloseStruct().End(true)); + "\t{\n" + + "\t\t{\n" + + "\t\t}\n" + + "\t}\n" + + "}\n", + Begin().Struct().Struct().Struct().CloseStruct().CloseStruct().CloseStruct().End(true)); assertThrows(IllegalStateException.class, () -> Begin().CloseStruct()); } @@ -419,7 +430,8 @@ class Internal { } } - assertEquals("Test{int a;,0x02", makeWriter().Byte(1).Str("Hello", "World", null).Byte(2).Close().toString()); + assertEquals(".0x01,Hello,World,,0x02", + makeWriter().Byte(1).Str("Hello", "World", null).Byte(2).Close().toString()); } @Test @@ -615,7 +643,8 @@ public void testAppend() throws Exception { @Test public void testSetValuePrefixPostfix() throws Exception { - assertEquals(".0x01,$02^", makeWriter().Byte(1).SetValuePrefix("$").SetValuePostfix("^").Byte(2).Close().toString()); + assertEquals(".0x01,$02^", + makeWriter().Byte(1).SetValuePrefix("$").SetValuePostfix("^").Byte(2).Close().toString()); } @Test @@ -640,7 +669,8 @@ public void testPrintNumericValueByExtras() throws Exception { final JBBPTextWriter writer = makeWriter(); writer.AddExtras(new JBBPTextWriterExtraAdapter() { @Override - public String doConvertObjToStr(JBBPTextWriter context, int id, Object obj) throws IOException { + public String doConvertObjToStr(JBBPTextWriter context, int id, Object obj) + throws IOException { assertEquals(234, id); return "obj" + obj; } @@ -677,9 +707,11 @@ public String doConvertByteToStr(JBBPTextWriter context, int value) throws IOExc }); - writer.SetValuePrefix("").Byte(1).Short(2).Int(3).Long(4).Obj(234, "Str").Float(Float.MIN_VALUE).Double(Double.MAX_VALUE); + writer.SetValuePrefix("").Byte(1).Short(2).Int(3).Long(4).Obj(234, "Str").Float(Float.MIN_VALUE) + .Double(Double.MAX_VALUE); - assertEquals(".byte1,short2,int3,long4,objStr,float1.4E-45,double1.7976931348623157E308", writer.Close().toString()); + assertEquals(".byte1,short2,int3,long4,objStr,float1.4E-45,double1.7976931348623157E308", + writer.Close().toString()); } @Test @@ -756,7 +788,9 @@ class Png { } final Png png = pngParser.parse(pngStream).mapTo(new Png(), aClass -> { - if (aClass == Chunk.class) return new Chunk(); + if (aClass == Chunk.class) { + return new Chunk(); + } return null; }); @@ -775,7 +809,8 @@ 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;"); + final JBBPParser parser = + JBBPParser.prepare("floatj f; doublej d; floatj [2] fa; doublej [2] da;"); class Klazz { @@ -816,7 +851,8 @@ public void testBin_ParsedPng_NonMappedRawStruct() throws Exception { + "}" ); - final String text = makeWriter().SetMaxValuesPerLine(16).Bin(pngParser.parse(pngStream)).Close().toString(); + final String text = + makeWriter().SetMaxValuesPerLine(16).Bin(pngParser.parse(pngStream)).Close().toString(); System.out.println(text); assertFileContent("testwriterbin2b.txt", text); } finally { @@ -826,10 +862,16 @@ public void testBin_ParsedPng_NonMappedRawStruct() throws Exception { @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(); + 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); } @@ -837,19 +879,23 @@ public void testBin_AllEasyTypes_NonMappedRawStruct() throws Exception { @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" + + final String text = + makeWriter().SetMaxValuesPerLine(16).Bin(parser.parse(new byte[0])).Close().toString(); + assertEquals( "~--------------------------------------------------------------------------------\n" + - " .0x0000007B; int a\n" + - "~--------------------------------------------------------------------------------\n" + - "; End {} \n" + - "~--------------------------------------------------------------------------------\n", text); + "; Start {} \n" + + "~--------------------------------------------------------------------------------\n" + + " .0x0000007B; int a\n" + + "~--------------------------------------------------------------------------------\n" + + "; End {} \n" + + "~--------------------------------------------------------------------------------\n", + text); } @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 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, @@ -858,7 +904,8 @@ public void testBin_AllEasyTypes_Anonymous_NonMappedRawStruct() throws Exception 3, 65, 66, 67 }; - final String text = makeWriter().SetMaxValuesPerLine(16).Bin(parser.parse(testArray)).Close().toString(); + final String text = + makeWriter().SetMaxValuesPerLine(16).Bin(parser.parse(testArray)).Close().toString(); System.out.println(text); assertFileContent("txtwrtrjbbpobj2.txt", text); } @@ -872,7 +919,8 @@ public void testBin_StringFieldAndStringArray() throws Exception { 3, 71, 72, 73 }; - final String text = makeWriter().SetMaxValuesPerLine(16).Bin(parser.parse(testArray)).Close().toString(); + final String text = + makeWriter().SetMaxValuesPerLine(16).Bin(parser.parse(testArray)).Close().toString(); System.out.println(text); assertFileContent("txtwrtrjbbpobj3.txt", text); } @@ -880,9 +928,14 @@ public void testBin_StringFieldAndStringArray() throws Exception { @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(); + 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); } @@ -896,7 +949,8 @@ class Parsed { 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 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); @@ -919,19 +973,23 @@ class TestClass { writer.AddExtras(new JBBPTextWriterExtraAdapter() { @Override - public String doConvertObjToStr(JBBPTextWriter context, int id, Object obj) throws IOException { + public String doConvertObjToStr(JBBPTextWriter context, int id, Object obj) + throws IOException { fail("Must not be called"); return null; } @Override - public String doConvertCustomField(final JBBPTextWriter context, final Object obj, final Field field, final Bin annotation) throws IOException { + public String doConvertCustomField(final JBBPTextWriter context, final Object obj, + final Field field, final Bin annotation) + throws IOException { return "test" + field.getName(); } }); - final String text = writer.SetHR("~", 3, '-').SetValuePrefix("").Bin(new TestClass()).Close().toString(); + final String text = + writer.SetHR("~", 3, '-').SetValuePrefix("").Bin(new TestClass()).Close().toString(); System.out.println(text); assertFileContent("testwriterbin3.txt", text); } @@ -951,20 +1009,24 @@ class TestClass { writer.AddExtras(new JBBPTextWriterExtraAdapter() { @Override - public String doConvertObjToStr(JBBPTextWriter context, int id, Object obj) throws IOException { + public String doConvertObjToStr(JBBPTextWriter context, int id, Object obj) + throws IOException { fail("Must not be called"); return null; } @Override - public String doConvertCustomField(JBBPTextWriter context, Object obj, Field field, Bin annotation) throws IOException { - context.HR().Str(field.getType().isArray() ? "See on array" : "Error").Comment("Line one", "Line two").HR(); + public String doConvertCustomField(JBBPTextWriter context, Object obj, Field field, + Bin annotation) throws IOException { + context.HR().Str(field.getType().isArray() ? "See on array" : "Error") + .Comment("Line one", "Line two").HR(); return null; } }); - final String text = writer.SetHR("~", 3, '-').SetValuePrefix("").Bin(new TestClass()).Close().toString(); + final String text = + writer.SetHR("~", 3, '-').SetValuePrefix("").Bin(new TestClass()).Close().toString(); System.out.println(text); assertFileContent("testwriterbin4.txt", text); } diff --git a/jbbp/src/test/jmh/com/igormaznitsa/jbbp/benchmarks/JBBP_Benchmark.java b/jbbp/src/test/jmh/com/igormaznitsa/jbbp/benchmarks/JBBP_Benchmark.java index 91908231..82ed5c4b 100644 --- a/jbbp/src/test/jmh/com/igormaznitsa/jbbp/benchmarks/JBBP_Benchmark.java +++ b/jbbp/src/test/jmh/com/igormaznitsa/jbbp/benchmarks/JBBP_Benchmark.java @@ -32,7 +32,8 @@ */ public class JBBP_Benchmark { - private static final JBBPParser parser = JBBPParser.prepare("ubyte value; data [(value>>1)*(value+3)]{ bit:3 a; bit:3 b; bit:2 c; skip:1; }"); + private static final JBBPParser parser = JBBPParser + .prepare("ubyte value; data [(value>>1)*(value+3)]{ bit:3 a; bit:3 b; bit:2 c; skip:1; }"); private static final Random RND = new Random(12345); diff --git a/logo.svg b/logo.svg index 88966259..6ed51689 100644 --- a/logo.svg +++ b/logo.svg @@ -25,13223 +25,13244 @@ inkscape:export-ydpi="671.93872">image/svg+xml + + + + + + + + + + + + + - + + + + + + + + + + + + + + Date: Sun, 3 Jan 2021 15:27:50 +0200 Subject: [PATCH 021/131] release 2.0.3 --- README.md | 13 +++++-------- changelog.txt | 2 +- jbbp-plugins/jbbp-gradle/build.gradle | 4 ++-- jbbp-plugins/jbbp-gradle/pom.xml | 2 +- .../jbbp-maven/jbbp-maven-plugin-tests/pom.xml | 2 +- jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml | 2 +- jbbp-plugins/jbbp-maven/pom.xml | 2 +- jbbp-plugins/jbbp-plugin-common/pom.xml | 2 +- jbbp-plugins/pom.xml | 4 ++-- jbbp/pom.xml | 2 +- .../jbbp/exceptions/JBBPTokenizerException.java | 2 +- .../java/com/igormaznitsa/jbbp/utils/JBBPUtils.java | 2 +- pom.xml | 4 ++-- 13 files changed, 20 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 24451ccc..39099a05 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![JBBP Logo](https://github.com/raydac/java-binary-block-parser/blob/master/logo.png) [![License Apache 2.0](https://img.shields.io/badge/license-Apache%20License%202.0-green.svg)](http://www.apache.org/licenses/LICENSE-2.0) -[![Maven central](https://maven-badges.herokuapp.com/maven-central/com.igormaznitsa/jbbp/badge.svg)](http://search.maven.org/#artifactdetails|com.igormaznitsa|jbbp|2.0.2|jar) +[![Maven central](https://maven-badges.herokuapp.com/maven-central/com.igormaznitsa/jbbp/badge.svg)](http://search.maven.org/#artifactdetails|com.igormaznitsa|jbbp|2.0.3|jar) [![Java 1.8+](https://img.shields.io/badge/java-1.8%2b-green.svg)](http://www.oracle.com/technetwork/java/javase/downloads/index.html) [![Android 3.0+](https://img.shields.io/badge/android-3.0%2b-green.svg)](http://developer.android.com/sdk/index.html) [![PayPal donation](https://img.shields.io/badge/donation-PayPal-cyan.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=AHWJHJFBAWGL2) @@ -17,7 +17,7 @@ that for Java. So I developed the JBBP library.
# Change log -- __2.0.3 (SNAPSHOT)__ +- __2.0.3 (03-jan-2021)__ - added service methods `JBBPUtils.traceData` to print dump of an input stream into a PrintStream - improved `JBBPTokenizerException` to show marked error position [#30](https://github.com/raydac/java-binary-block-parser/issues/30) @@ -27,9 +27,6 @@ that for Java. So I developed the JBBP library.
- [#28](https://github.com/raydac/java-binary-block-parser/issues/28) added `JBBPOut#BinForceByteOrder` to override byte order defined in `@Bin` annotations of written object. -- __2.0.1 (04-feb-2020)__ - - [#26](https://github.com/raydac/java-binary-block-parser/issues/26) fixed bug in array write with MSB0 - [Full changelog](https://github.com/raydac/java-binary-block-parser/blob/master/changelog.txt) # Maven dependency @@ -40,12 +37,12 @@ The Framework has been published in the Maven Central and can be easily added as com.igormaznitsa jbbp - 2.0.2 + 2.0.3 ``` the precompiled library jar, javadoc and sources also can be downloaded directly -from [the Maven central.](https://search.maven.org/artifact/com.igormaznitsa/jbbp/2.0.2/jar) +from [the Maven central.](https://search.maven.org/artifact/com.igormaznitsa/jbbp/2.0.3/jar) # Hello world @@ -118,7 +115,7 @@ in Maven it can be used through snippet: com.igormaznitsa jbbp-maven-plugin - 2.0.2 + 2.0.3 gen-jbbp-src diff --git a/changelog.txt b/changelog.txt index a3751a43..234755e0 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,4 @@ -2.0.3 (SNAPSHOT) +2.0.3 (03-jan-2021) - added service methods `JBBPUtils.traceData` to print dump of an input stream into a PrintStream - improved `JBBPTokenizerException` to show marked error position [#30](https://github.com/raydac/java-binary-block-parser/issues/30) diff --git a/jbbp-plugins/jbbp-gradle/build.gradle b/jbbp-plugins/jbbp-gradle/build.gradle index 75355079..58bca66b 100644 --- a/jbbp-plugins/jbbp-gradle/build.gradle +++ b/jbbp-plugins/jbbp-gradle/build.gradle @@ -7,7 +7,7 @@ def getProp(name, dflt) { } } -def jbbpVersion = getProp('jbbp_plugin_version', '2.0.3-SNAPSHOT') +def jbbpVersion = getProp('jbbp_plugin_version', '2.0.3') def metaLibVersion = getProp('meta_lib_version', '1.1.2') group = 'com.igormaznitsa' @@ -24,7 +24,7 @@ dependencies { compile gradleApi() compile localGroovy() - compile "commons-io:commons-io:2.5" + compile "commons-io:commons-io:2.8.0" compile "com.igormaznitsa:jbbp:" + jbbpVersion compile "com.igormaznitsa:meta-annotations:" + metaLibVersion compile "com.igormaznitsa:meta-utils:" + metaLibVersion diff --git a/jbbp-plugins/jbbp-gradle/pom.xml b/jbbp-plugins/jbbp-gradle/pom.xml index 3731cce9..a845f833 100644 --- a/jbbp-plugins/jbbp-gradle/pom.xml +++ b/jbbp-plugins/jbbp-gradle/pom.xml @@ -6,7 +6,7 @@ com.igormaznitsa jbbp-main-plugin-pom - 2.0.3-SNAPSHOT + 2.0.3 jbbp-gradle-plugin diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml index c1b9cbab..3f9568e2 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-maven-plugin-pom - 2.0.3-SNAPSHOT + 2.0.3 jbbp-maven-plugin-tests diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml index e954254b..484ef7b1 100644 --- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml +++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-maven-plugin-pom - 2.0.3-SNAPSHOT + 2.0.3 jbbp-maven-plugin diff --git a/jbbp-plugins/jbbp-maven/pom.xml b/jbbp-plugins/jbbp-maven/pom.xml index f3526b26..8b98dab1 100644 --- a/jbbp-plugins/jbbp-maven/pom.xml +++ b/jbbp-plugins/jbbp-maven/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-main-plugin-pom - 2.0.3-SNAPSHOT + 2.0.3 jbbp-maven-plugin-pom diff --git a/jbbp-plugins/jbbp-plugin-common/pom.xml b/jbbp-plugins/jbbp-plugin-common/pom.xml index 67381430..d7822e40 100644 --- a/jbbp-plugins/jbbp-plugin-common/pom.xml +++ b/jbbp-plugins/jbbp-plugin-common/pom.xml @@ -6,7 +6,7 @@ com.igormaznitsa jbbp-main-plugin-pom - 2.0.3-SNAPSHOT + 2.0.3 jbbp-plugin-common diff --git a/jbbp-plugins/pom.xml b/jbbp-plugins/pom.xml index 726ddf92..593da889 100644 --- a/jbbp-plugins/pom.xml +++ b/jbbp-plugins/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-main-pom - 2.0.3-SNAPSHOT + 2.0.3 jbbp-main-plugin-pom @@ -31,7 +31,7 @@ commons-io commons-io - 2.6 + 2.8.0 diff --git a/jbbp/pom.xml b/jbbp/pom.xml index 19b907f8..ff8a0c4e 100644 --- a/jbbp/pom.xml +++ b/jbbp/pom.xml @@ -5,7 +5,7 @@ com.igormaznitsa jbbp-main-pom - 2.0.3-SNAPSHOT + 2.0.3 jbbp diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/exceptions/JBBPTokenizerException.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/exceptions/JBBPTokenizerException.java index 946d371a..4c36d709 100644 --- a/jbbp/src/main/java/com/igormaznitsa/jbbp/exceptions/JBBPTokenizerException.java +++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/exceptions/JBBPTokenizerException.java @@ -108,7 +108,7 @@ private static String extractErrorPartText(final String script, final int errorP } /** - * Get error part of script where error position marked by !>..com.igormaznitsa jbbp-main-pom - 2.0.3-SNAPSHOT + 2.0.3 pom @@ -20,7 +20,7 @@ yyyyMMddHHmm 3.0 1.1.2 - 2.0.3-SNAPSHOT + 2.0.3 ${jbbp.version} 1.8 1.8 From 4a6d8e0ec83b701e5d5910fb551752db14cec373 Mon Sep 17 00:00:00 2001 From: Igor Maznitsa Date: Sun, 3 Jan 2021 15:32:14 +0200 Subject: [PATCH 022/131] updated --- .projectKnowledge/JBBP.mmd | 2 +- docs/jbbp_mm.png | Bin 184682 -> 185177 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.projectKnowledge/JBBP.mmd b/.projectKnowledge/JBBP.mmd index 2aa92079..3e2261ad 100644 --- a/.projectKnowledge/JBBP.mmd +++ b/.projectKnowledge/JBBP.mmd @@ -2,7 +2,7 @@ Mind Map generated by NB MindMap plugin > __version__=`1.1`,showJumps=`true` --- -# Java Binary
Block Parser
v 2\.0\.1 +# Java Binary
Block Parser
v 2\.0\.3 ## License > fillColor=`#33CC00`,leftSide=`true` diff --git a/docs/jbbp_mm.png b/docs/jbbp_mm.png index d5886f5407a411bc8a79ac9d52de8d809e564707..d32146d06f6411706d84326327c5d9387c7d0607 100644 GIT binary patch literal 185177 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

g>kHz|e9TJLde>C(V~71QAWa)>NXob^Qe%y9E36 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 R6PQBQ; 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%0Do}1d);kkB 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