#### Maven plugin
> fillColor=`#D1FF9C`
diff --git a/.projectKnowledge/JBBP_Types.mmd b/.projectKnowledge/JBBP_Types.mmd
index 834a3ae5..1fa5bdc4 100644
--- a/.projectKnowledge/JBBP_Types.mmd
+++ b/.projectKnowledge/JBBP_Types.mmd
@@ -82,6 +82,22 @@ Mind Map generated by NB MindMap plugin
> fillColor=`#99FFFF`
+#### uint
+> fillColor=`#9999FF`
+
+
+##### 32 bit unsigned field
+> fillColor=`#99FFFF`
+
+
+###### requires long representation
+> fillColor=`#FF6666`,mmd.emoticon=`error`
+
+
+###### can throw error in expression if value can\\t be represented as zero or positive int
+> fillColor=`#FF6666`,mmd.emoticon=`error`
+
+
#### long
> fillColor=`#9999FF`
@@ -90,11 +106,35 @@ Mind Map generated by NB MindMap plugin
> fillColor=`#99FFFF`
+#### floatj
+> fillColor=`#FFFE9F`
+
+
+##### 32 bit signed field \(Java float format\)
+> fillColor=`#99FFFF`
+
+
+#### doublej
+> fillColor=`#FFFE9F`
+
+
+##### 64 bit signed field \(Java double format\)
+> fillColor=`#99FFFF`
+
+
+#### stringj
+> fillColor=`#FFFE9F`
+
+
+##### UTF\-8 string with length info, NULL value is allowed
+> fillColor=`#99FFFF`
+
+
#### var
> fillColor=`#00FAFF`
-##### such field must be processed by special external var field processor
+##### custom field to be processed by specific code
> fillColor=`#00FAFF`
@@ -132,6 +172,14 @@ Mind Map generated by NB MindMap plugin
> fillColor=`#99FF99`
+##### bit:3 bits;
+> fillColor=`#99FF99`
+
+
+##### bit:\(a\+1\) b;
+> fillColor=`#99FF99`
+
+
## Complex types
### Arrays
@@ -162,7 +210,7 @@ Mind Map generated by NB MindMap plugin
> fillColor=`#6666FF`,textColor=`#CCFFCC`
-###### It can be placed only for the end item in script
+###### it is impossible to have fields after
> fillColor=`#FF3300`,textColor=`#FFFFFF`
@@ -196,7 +244,7 @@ Mind Map generated by NB MindMap plugin
> fillColor=`#9999FF`
-#### align\[:number\_of\_bytes|\(expression\_in\_parentheses\)\]
+#### align\[:number\_of\_bytes|:\(expression\_in\_parentheses\)\]
> fillColor=`#FFCC00`
diff --git a/README.md b/README.md
index 10ba7c8c..8523e1c2 100644
--- a/README.md
+++ b/README.md
@@ -1,136 +1,183 @@
+
+
[](http://www.apache.org/licenses/LICENSE-2.0)
-[](http://search.maven.org/#artifactdetails|com.igormaznitsa|jbbp|1.4.0|jar)
-[](https://www.codacy.com/app/rrg4400/java-binary-block-parser)
-[](http://www.oracle.com/technetwork/java/javase/downloads/index.html)
-[](http://developer.android.com/sdk/index.html)
-[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=AHWJHJFBAWGL2)
-[](http://yasobe.ru/na/iamoss)
+[](http://search.maven.org/#artifactdetails|com.igormaznitsa|jbbp|3.0.1|jar)
+[](http://www.oracle.com/technetwork/java/javase/downloads/index.html)
+[](http://developer.android.com/sdk/index.html)
+[](https://www.arthursacresanimalsanctuary.org/donate)
-
# Introduction
-Java has some embedded features to parse binary data (for instance ByteBuffer), but I wanted to work with separated bits and describe binary structure in some strong DSL(domain specific language). I was very impressed by the [the Python Struct package](https://docs.python.org/2/library/struct.html) package so that I decided to make something like that. So JBBP was born.
-p.s.
-For instance I have been very actively using the framework in [the ZX-Poly emulator](https://github.com/raydac/zxpoly) to parse snapshot files and save results.
+
+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.

# Change log
-- **1.4.0 (29-jul-2018)**
- - added type `val` which allows to create virtual field with calculated value, can play role of variable in scripts
- - `val` and `var` have been added into reserved words and can't be used as field names
- - added field `outByteOrder` attribute to `Bin` annotation, it affects logic of `JBBPOut#Bin` for output of annotated objects which fields should be saved with different byte order
- - removed deprecated method `JBBPFinderException#getNameOrPath`
- - added [auxiliary class to build JBBP script](https://github.com/raydac/java-binary-block-parser/blob/master/jbbp/src/main/java/com/igormaznitsa/jbbp/utils/JBBPDslBuilder.java)
- - added flag `JBBPParser#FLAG_NEGATIVE_EXPRESSION_RESULT_AS_ZERO` to recognize negative expression result as zero
- - improved Java 6 class source generator to process FLAG_SKIP_REMAINING_FIELDS_IF_EOF for structure fields
- - added stable automatic module name `igormaznitsa.jbbp` into manifest file
- - added support of float, double and string java types, as `floatj`,`doublej` and `stringj`
-
-- **1.3.0 (02-sep-2017)**
- - __Fixed issue [#16 NullPointerException when referencing a JBBPCustomFieldTypeProcessor parsed field"](https://github.com/raydac/java-binary-block-parser/issues/16), many thanks to @use-sparingly for the bug report__
- - [added Maven plugin to generate sources from JBBP scripts](https://search.maven.org/#artifactdetails%7Ccom.igormaznitsa%7Cjbbp-maven-plugin%7C1.3.0%7Cmaven-plugin)
- - [added Gradle plugin to generate sources from JBBP scripts](https://plugins.gradle.org/plugin/com.igormaznitsa.gradle.jbbp)
- - added extra byte array reading writing methods with byte order support into JBBPBitInputStream and JBBPBitOutputStream
- - added converter of compiled parser data into Java class sources (1.6+)
- - added method to read unsigned short values as char [] into JBBPBitInputStream
- - Class version target has been changed to Java 1.6
- - fixed compatibiity of tests with Java 1.6
- - Minor refactoring
-
-- **1.2.1 (28-JUL-2016)**
- - __Fixed issue [#10 "assertArrayLength throws exception in multi-thread"](https://github.com/raydac/java-binary-block-parser/issues/10), many thanks to @sky4star for the bug report.__
- - minor refactoring
-
-[Full changelog](https://github.com/raydac/java-binary-block-parser/blob/master/changelog.txt)
+
+- __3.0.1 (24-dec-2024)__
+ - added `MSB0_DIRECT` bit order mode, MSB0 without data
+ revers [#46](https://github.com/raydac/java-binary-block-parser/issues/46)
+ - added `JBBPBitInputStream#isDetectedPartlyReadBitField` to check that only part of bit field read during last
+ operation
+ - added flag into constructors for JBBPBitInputStream to force return -1 instead of partly accumulated bits data if
+ end of field
+
+- __3.0.0 (16-nov-2024)__
+ - __Minimum JDK Version: Updated to 11.0.__
+ - __Minimum Supported Android: Updated to 12 (API 32).__
+ - __API Changes:__ Modifications made to the CompiledBlockVisitor API.
+ - __New Feature:__ Added `JBBPUtils#findMaxStaticArraySize` for calculating the largest static array size defined in a
+ JBBP script.
+ - __Internal API:__ Certain internal APIs have been opened.
+ - __Codebase Improvements:__ General refactoring performed.
+
+- __2.1.0 (05-nov-2024)__
+ - minor changes in API for `JBBPVarFieldProcessor` and `JBBPCustomFieldTypeProcessor`
+ - provided way to control size of arrays read as stream
+ rest [#44](https://github.com/raydac/java-binary-block-parser/issues/44)
+ - provided way to control size of arrays which size calculated through
+ expressions [#45](https://github.com/raydac/java-binary-block-parser/issues/45)
+ - improved tests
+
+[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.igormaznitsajbbp
- 1.4.0
+ 3.0.1
```
-the precompiled library jar, javadoc and sources also can be downloaded directly from [the Maven central.](http://search.maven.org/#browse|808871750)
+
+the precompiled library jar, javadoc and sources also can be downloaded directly
+from [the Maven central.](https://search.maven.org/artifact/com.igormaznitsa/jbbp/3.0.1/jar)
# Hello world
-The Framework is very easy in use because it has only two main classes for its functionality com.igormaznitsa.jbbp.JBBPParser (for data parsing) and com.igormaznitsa.jbbp.io.JBBPOut (for binary block writing), both of them work over low-level IO classes com.igormaznitsa.jbbp.io.JBBPBitInputStream and com.igormaznitsa.jbbp.io.JBBPBitOutputStream which are the core for the framework.
-The Easiest case below shows how to parse 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();
```
-Of course sometime it is not a comfortable way to look for parsed fields in the result, so you can use mapping of parsed data to class fields.
+
+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(Parsed.class);
+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
-On the start the framework was created to provide comfortable way to parse data, it was not developed for hight speed. But since 1.3.0 version there has been added way to generate Java class sources from JBBP parsers and it allows to increase parsing speed dramatically (keep in mind that JBBP generates Java class sources but not compile it automaticaly). I have made some microbenchmark testing of all parsing approaches to show relative productivity of each one
-
-The Chart shows three standard ways to parse data with JBBP
-* __Dynamic__ - parsing into inside structures through interpretation of script written in DSL. It is not very fast way but you can generate parsers on fly even from dynamically formed strings.
-* __Dynamic + map to class__ - Parsing into inside structures through interpretation of script and mapping parsed data into class instance fields. the way is very slow (because it uses reflections to fill fields) and recommended only if comfortable parsing is much more preffered than speed.
-* __Static class__ - parsing with Java sources generated from a JBBP parser. It is the fastest way because Java compiler and JIT can make optimizations. The Approach can be used in High-Load systems. It is possible to compile generated Java sources on fly, [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/AbstractJBBPToJava6ConverterTest.java).
+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.
+
+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)
+ .
# Generate sources from JBBP scripts
-Since 1.3.0 version, the framework can convert JBBP scripts into sources __(the sources anyway need JBBP framework for work)__.
-For instance you can use such simple snippet to generate Java classes from JBBP script, potentially it can generate many classes but usually only one class
+
+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_1_6,"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 special plugins for Maven and Gradle to generate sources from JBBP scripts during source generate phase
-in Maven you should just add such plugin execution
+
+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
- 1.4.0
-
-
- gen-jbbp-src
-
- generate
-
-
-
+
+
+ com.igormaznitsa
+ jbbp-maven-plugin
+ 3.0.1
+
+
+ gen-jbbp-src
+
+ generate
+
+
+
```
-By default the maven plugin looks for files with `jbbp` extension in `src/jbbp` folder of project (it can be changed in options) and produces result java classes in `target/generated-sources/jbbp` folder. [I use such approach in 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
-The Example shows how to parse a byte written in non-standard MSB0 order (Java has LSB0 bit order) to bit fields, 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(outOrder = 1, name = "f1", type = BinType.BIT, outBitNumber = JBBPBitNumber.BITS_1, comment = "It's flag one") byte flag1;
- @Bin(outOrder = 2, name = "f2", type = BinType.BIT, outBitNumber = JBBPBitNumber.BITS_2, comment = "It's second flag") byte flag2;
- @Bin(outOrder = 3, name = "f3", type = BinType.BIT, outBitNumber = JBBPBitNumber.BITS_1, comment = "It's 3th flag") byte flag3;
- @Bin(outOrder = 4, name = "f4", type = BinType.BIT, outBitNumber = 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(Flags.class);
- assertEquals(1,parsed.flag1);
- assertEquals(2,parsed.flag2);
- assertEquals(0,parsed.flag3);
- assertEquals(5,parsed.flag4);
+ @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);
+ assertEquals(0, parsed.flag3);
+ assertEquals(5, parsed.flag4);
System.out.println(new JBBPTextWriter().Bin(parsed).Close().toString());
assertEquals(data, JBBPOut.BeginBin(JBBPBitOrder.MSB0).Bin(parsed).End().toByteArray()[0] & 0xFF);
```
+
The Example will print in console the text below
+
```
;--------------------------------------------------------------------------------
; START : Flags
@@ -143,65 +190,96 @@ The Example will print in console the text below
; END : Flags
;--------------------------------------------------------------------------------
```
+
# Fields
-Every field can have case insensitive name which should not contain '.' (because it is reserved for links to structure field values) and '#'(because it is also reserved for inside usage).
-Field name must not be started by a number or chars '$' and '_'. *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;
```
+

## Primitive types
-The Framework supports full set of Java numeric primitives with extra types like ubyte and bit.
+
+JBBP supports full set of Java numeric primitives with some extra types like ubyte and bit.

+
## Complex types
-The Framework provides support for arrays and structures. Just keep in mind that in expressions you can make links to field values only defined before expression.
+
+JBBP provides support both arrays and structures. __In expressions you can use links only to field values which already
+read!__

## Custom types
-it is possible to define processors for own 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/src/test/java/com/igormaznitsa/jbbp/it/CustomThreeByteIntegerTypeTest.java).
-### Float and Double types
-The Parser does not support Java float and double types out of the box. But it can be implemented through custom type processor. [there is written example and test and the code can be copy pasted](https://github.com/raydac/java-binary-block-parser/blob/master/src/test/java/com/igormaznitsa/jbbp/it/FloatAndDoubleTypesTest.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`.
## Variable fields
-If you have some data which structure is variable then you can use the `var` type for defined field and process reading of the data manually with custom [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();
final JBBPFieldStruct struct = parser.parse(new byte[]{9, 8, 33, 1, 2, 3, 4}, new JBBPVarFieldProcessor() {
- public JBBPAbstractArrayField extends JBBPAbstractField> readVarArray(final JBBPBitInputStream inStream, final int arraySize, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException {
+ public JBBPAbstractArrayField extends JBBPAbstractField> readVarArray(JBBPBitInputStream inStream, int arraySize, JBBPNamedFieldInfo fieldName, int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) throws IOException {
fail("Must not be called");
return null;
}
- public JBBPAbstractField readVarField(final JBBPBitInputStream inStream, final JBBPNamedFieldInfo fieldName, final int extraValue, final JBBPByteOrder byteOrder, final JBBPNamedNumericFieldMap numericFieldMap) throws IOException {
+ public JBBPAbstractField readVarField(JBBPBitInputStream inStream, JBBPNamedFieldInfo fieldName, int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) throws IOException {
final int value = inStream.readByte();
return new JBBPFieldByte(fieldName, (byte) value);
}
}, null);
```
-*NB! Some programmers trying to use only parser for complex data, it is 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

+
## Byte order
-Every multi-byte type can be read with different byte order.
+
+Multi-byte types can be read with different byte order.

# 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 {
@@ -211,7 +289,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
@@ -219,13 +300,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
-The Example below shows how to parse a PNG file with the JBBP parser (the example taken from tests)
+
+Example below shows how to parse a PNG file through JBBP parser:
+
```Java
final InputStream pngStream = getResourceAsInputStream("picture.png");
try {
@@ -241,15 +332,14 @@ final InputStream pngStream = getResourceAsInputStream("picture.png");
+ "}"
);
- final JBBPFieldStruct result = pngParser.parse(pngStream);
+ JBBPFieldStruct result = pngParser.parse(pngStream);
assertEquals(0x89504E470D0A1A0AL,result.findFieldForNameAndType("header",JBBPFieldLong.class).getAsLong());
- final JBBPFieldArrayStruct chunks = result.findFieldForNameAndType("chunk", JBBPFieldArrayStruct.class);
+ JBBPFieldArrayStruct chunks = result.findFieldForNameAndType("chunk", JBBPFieldArrayStruct.class);
-
- 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};
+ String [] chunkNames = new String[]{"IHDR","gAMA","bKGD","pHYs","tIME","tEXt","IDAT","IEND"};
+ int [] chunkSizes = new int[]{0x0D, 0x04, 0x06, 0x09, 0x07, 0x19, 0x0E5F, 0x00};
assertEquals(chunkNames.length,chunks.size());
@@ -261,7 +351,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;"
@@ -284,11 +376,17 @@ final JBBPParser pngParser = JBBPParser.prepare(
class Png {
long header;
Chunk [] chunk;
+
+ public Object newInstance(Class> klazz){
+ return klazz == Chunk.class ? new Chunk() : null;
+ }
}
- final Png png = pngParser.parse(pngStream).mapTo(Png.class);
+ final Png png = pngParser.parse(pngStream).mapTo(new Png());
```
-The Example from tests shows how to parse a tcp frame wrapped in a network frame
+
+Example shows how to parse TCP frame:
+
```Java
final JBBPParser tcpParser = JBBPParser.prepare(
"skip:34; // skip bytes till the frame\n"
@@ -319,15 +417,32 @@ final JBBPParser tcpParser = JBBPParser.prepare(
final JBBPFieldStruct result = pngParser.parse(tcpFrameStream);
```
+
# F.A.Q.
+
## Is it possible to use `@Bin` annotations for parsing and not only mapping?
-No, `@Bin` annotations in classes are used only for mapping and data writing, but there is [the code snippet](https://gist.github.com/raydac/28d770307bd33683aa17ea3c39d5e2c4) allows to generate JBBP DSL based on detected @Bin annotations in class.
+
+`@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! The Parser works over [com.igormaznitsa.jbbp.io.JBBPBitInputStream](https://github.com/raydac/java-binary-block-parser/blob/master/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 from a stream (for output 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 bin block instead of parsing!
-The Framework contains a special helper as the class com.igormaznitsa.jbbp.io.JBBPOut which allows to build bin blocks with some kind of DSL
+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
+
```Java
import static com.igormaznitsa.jbbp.io.JBBPOut.*;
...
diff --git a/changelog.txt b/changelog.txt
index cbd94dce..143fa08b 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,5 +1,63 @@
-Change log
---------------------------
+3.0.1 (24-dec-2024)
+ - added `MSB0_DIRECT` bit order mode, MSB0 without data revers [#46](https://github.com/raydac/java-binary-block-parser/issues/46)
+ - added `JBBPBitInputStream#isDetectedPartlyReadBitField` to check that only part of bit field read during last operation
+ - added flag into constructors for JBBPBitInputStream to force return -1 instead of partly accumulated bits data if end of field
+
+3.0.0 (16-nov-2024)
+ - Minimum JDK Version: Updated to 11.0.
+ - Minimum Supported Android: Updated to 12 (API 32).
+ - API Changes: Modifications made to the CompiledBlockVisitor API.
+ - New Feature: Added `JBBPUtils#findMaxStaticArraySize` for calculating the largest static array size defined in a JBBP script.
+ - Internal API: Certain internal APIs have been opened.
+ - Codebase Improvements: General refactoring performed.
+
+2.1.0 (05-nov-2024)
+ - minor changes in API for JBBPVarFieldProcessor and JBBPCustomFieldTypeProcessor
+ - provided way to control size of arrays read as stream rest [#44](https://github.com/raydac/java-binary-block-parser/issues/44)
+ - provided way to control size of arrays which size calculated through expressions [#45](https://github.com/raydac/java-binary-block-parser/issues/45)
+ - improved tests
+
+2.0.6 (01-jul-2023)
+ - [#42](https://github.com/raydac/java-binary-block-parser/issues/42) unexpected exception during JBBPDslBuilder.AnnotatedClass method call
+ - improved tests
+
+2.0.5 (17-jun-2023)
+ - [#41](https://github.com/raydac/java-binary-block-parser/issues/41) fix for Gradle plug-in
+ - improved tests
+
+2.0.4 (01-aug-2022)
+ - added unsigned 32 bit integer type __uint__ [#37](https://github.com/raydac/java-binary-block-parser/issues/37)
+ - provided way to filter fields for mapping operations and write object operations [#36](https://github.com/raydac/java-binary-block-parser/issues/36)
+
+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)
+
+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
+ - [#26](https://github.com/raydac/java-binary-block-parser/issues/26) fixed bug in array write with MSB0
+
+2.0.0
+ - __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
+
+1.4.1
+ - 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)
+
1.4.0
- added type `val` which allows to create virtual field with calculated value, can play role of variable in scripts
- `val` and `var` have been added into reserved words and can't be used as field names
@@ -19,7 +77,7 @@ Change log
- added converter of compiled parser data into Java class sources (1.6+)
- added method to read unsigned short values as char [] into JBBPBitInputStream
- Class version target has been changed to Java 1.6
- - fixed compatibiity of tests with Java 1.6
+ - fixed compatibility of tests with Java 1.6
- Minor refactoring
1.2.0
diff --git a/docs/arthur_sanctuary_banner.png b/docs/arthur_sanctuary_banner.png
new file mode 100644
index 00000000..566b7bd5
Binary files /dev/null and b/docs/arthur_sanctuary_banner.png differ
diff --git a/docs/jbbp_complex_types.png b/docs/jbbp_complex_types.png
index 7e06d271..155d5f70 100644
Binary files a/docs/jbbp_complex_types.png and b/docs/jbbp_complex_types.png differ
diff --git a/docs/jbbp_fields.png b/docs/jbbp_fields.png
index d8894995..79351c92 100644
Binary files a/docs/jbbp_fields.png and b/docs/jbbp_fields.png differ
diff --git a/docs/jbbp_mm.png b/docs/jbbp_mm.png
index 7977f40f..b4765040 100644
Binary files a/docs/jbbp_mm.png and b/docs/jbbp_mm.png differ
diff --git a/docs/jbbp_primitives.png b/docs/jbbp_primitives.png
index 5ee09acc..32bf5efe 100644
Binary files a/docs/jbbp_primitives.png and b/docs/jbbp_primitives.png differ
diff --git a/docs/jbbp_special_fields.png b/docs/jbbp_special_fields.png
index 7c8ac349..d87e07aa 100644
Binary files a/docs/jbbp_special_fields.png and b/docs/jbbp_special_fields.png differ
diff --git a/docs/jmh_results.ods b/docs/jmh_results.ods
index a981a9fd..96dbd502 100644
Binary files a/docs/jmh_results.ods and b/docs/jmh_results.ods differ
diff --git a/docs/jmh_results.png b/docs/jmh_results.png
index 6efb18f9..df72ec02 100644
Binary files a/docs/jmh_results.png and b/docs/jmh_results.png differ
diff --git a/docs/white_properties.properties b/docs/white_properties.properties
new file mode 100644
index 00000000..8144b61c
--- /dev/null
+++ b/docs/white_properties.properties
@@ -0,0 +1,69 @@
+#SciaReto editor settings
+#Sat Jun 17 11:11:33 EEST 2023
+MindMapPanelConfig.birdseyeBackground=-1869559553
+MindMapPanelConfig.birdseyeFront=-1879029100
+MindMapPanelConfig.birdseyeMouseButton=BUTTON_2
+MindMapPanelConfig.collapsatorBackgroundColor=-526635
+MindMapPanelConfig.collapsatorBorderColor=-12566464
+MindMapPanelConfig.collapsatorBorderWidth=1.0
+MindMapPanelConfig.collapsatorSize=16
+MindMapPanelConfig.connectorColor=-15592942
+MindMapPanelConfig.connectorWidth=1.5
+MindMapPanelConfig.drawBackground=true
+MindMapPanelConfig.dropShadow=true
+MindMapPanelConfig.elementBorderColor=-16777216
+MindMapPanelConfig.elementBorderWidth=1.0
+MindMapPanelConfig.firstLevelBackgroundColor=-5128244
+MindMapPanelConfig.firstLevelHorizontalInset=48
+MindMapPanelConfig.firstLevelTextColor=-16777216
+MindMapPanelConfig.firstLevelVerticalInset=32
+MindMapPanelConfig.font.name=Arial
+MindMapPanelConfig.font.size=16
+MindMapPanelConfig.font.style=1
+MindMapPanelConfig.gridColor=-12364185
+MindMapPanelConfig.gridStep=32
+MindMapPanelConfig.horizontalBlockGap=5
+MindMapPanelConfig.jumpLinkColor=-15597313
+MindMapPanelConfig.jumpLinkWidth=1.5
+MindMapPanelConfig.otherLevelBackgroundColor=-131587
+MindMapPanelConfig.otherLevelHorizontalInset=32
+MindMapPanelConfig.otherLevelTextColor=-16777216
+MindMapPanelConfig.otherLevelVerticalInset=16
+MindMapPanelConfig.paperColor=-1
+MindMapPanelConfig.paperMargins=20
+MindMapPanelConfig.renderQuality=QUALITY
+MindMapPanelConfig.rootBackgroundColor=-16573903
+MindMapPanelConfig.rootTextColor=-1
+MindMapPanelConfig.scale=1.0
+MindMapPanelConfig.scaleModifiers=2
+MindMapPanelConfig.selectLineColor=-14336
+MindMapPanelConfig.selectLineGap=5
+MindMapPanelConfig.selectLineWidth=3.0
+MindMapPanelConfig.shadowColor=805306368
+MindMapPanelConfig.shadowOffset=5.0
+MindMapPanelConfig.showGrid=false
+MindMapPanelConfig.smartTextPaste=false
+MindMapPanelConfig.textMargins=10
+mapShortCut.addChildAndStartEdit=addChildAndStartEdit*900000000
+mapShortCut.addSiblingAndStartEdit=addSiblingAndStartEdit*A00000000
+mapShortCut.birdsEyeModifiers=birdsEyeModifiers*7FFFFFFF00000000
+mapShortCut.cancelEdit=cancelEdit*1B00000000
+mapShortCut.deleteSelectedTopic=deleteSelectedTopic*7F00000000
+mapShortCut.focusToRootOrStartEdit=focusToRootOrStartEdit*2000000002
+mapShortCut.moveFocusDown=moveFocusDown*2800000000
+mapShortCut.moveFocusDownAddFocused=moveFocusDownAddFocused*2800000001
+mapShortCut.moveFocusLeft=moveFocusLeft*2500000000
+mapShortCut.moveFocusLeftAddFocused=moveFocusLeftAddFocused*2500000001
+mapShortCut.moveFocusRight=moveFocusRight*2700000000
+mapShortCut.moveFocusRightAddFocused=moveFocusRightAddFocused*2700000001
+mapShortCut.moveFocusUp=moveFocusUp*2600000000
+mapShortCut.moveFocusUpAddFocused=moveFocusUpAddFocused*2600000001
+mapShortCut.nextLineInTopicText=nextLineInTopicText*A00000001
+mapShortCut.showPopupMenu=showPopupMenu*200000000A
+mapShortCut.topicFold=topicFold*2D00000000
+mapShortCut.topicFoldAll=topicFoldAll*2D00000008
+mapShortCut.topicUnfold=topicUnfold*3D00000000
+mapShortCut.topicUnfoldAll=topicUnfoldAll*3D00000008
+mapShortCut.zoomIn=zoomIn*3D00000002
+mapShortCut.zoomOut=zoomOut*2D00000002
+mapShortCut.zoomReset=zoomReset*3000000002
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/build.gradle b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/build.gradle
new file mode 100644
index 00000000..9d314477
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/build.gradle
@@ -0,0 +1,36 @@
+plugins {
+ id 'java'
+ id 'com.igormaznitsa.gradle.jbbp' version "${jbbp_plugin_version}"
+}
+
+group = 'com.igormaznitsa.jbbp.gradle.test'
+version = '0.0.0-SNAPSHOT'
+
+repositories {
+ mavenLocal()
+ mavenCentral()
+}
+
+dependencies {
+ implementation "com.igormaznitsa:jbbp:${jbbp_plugin_version}"
+ testImplementation platform("org.junit:junit-bom:${junit_version}")
+ testImplementation 'org.junit.jupiter:junit-jupiter'
+}
+
+test {
+ useJUnitPlatform()
+}
+
+import com.igormaznitsa.jbbp.plugin.common.converters.ParserFlags
+
+jbbp {
+ headComment = 'Free license'
+ addBinAnnotations = true
+ addGettersSetters = true
+ customTypes = ['some']
+ interfaces = ['java.lang.Runnable']
+ customText = 'public void run () {}'
+ parserFlags = [ParserFlags.SKIP_REMAINING_FIELDS_IF_EOF]
+}
+
+compileJava.dependsOn(jbbpGenerate)
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/pom.xml b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/pom.xml
new file mode 100644
index 00000000..09e1c195
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/pom.xml
@@ -0,0 +1,80 @@
+
+
+ 4.0.0
+
+
+ com.igormaznitsa
+ jbbp-gradle-tests
+ 0.0.0-SNAPSHOT
+
+
+ jbbp-gradle5-plugin-test
+ pom
+
+
+ gradle5
+
+
+
+
+
+ maven-clean-plugin
+
+
+
+ ${project.basedir}/gradle
+ false
+
+
+ ${project.basedir}
+
+ gradlew
+ gradlew.bat
+
+ false
+
+
+ ${project.basedir}/downloaded
+ false
+
+
+ ${project.basedir}/build
+ false
+
+
+ ${project.basedir}/out
+ false
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+
+
+ gradle
+ compile
+
+ ${gradle.executable}
+
+ clean
+ test
+ --info
+ --scan
+ --no-daemon
+ -Pjbbp_plugin_version=${jbbp.test.version}
+ -Pjunit_version=${junit5.version}
+
+
+
+ exec
+
+
+
+
+
+
+
+
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/settings.gradle b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/settings.gradle
new file mode 100644
index 00000000..a21b7724
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/settings.gradle
@@ -0,0 +1,9 @@
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ mavenLocal()
+ }
+}
+
+rootProject.name = 'jbbp-gradle5-plugin-test'
+
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp
new file mode 100644
index 00000000..b1f6c18f
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp
@@ -0,0 +1,10 @@
+ubyte len;
+uint uintField;
+uint [1] uintArr;
+some1 {
+ bit:4 [len] someField;
+ ubyte len;
+ some2 {
+ byte [len] field;
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp
new file mode 100644
index 00000000..58f5edc9
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp
@@ -0,0 +1,8 @@
+ubyte len;
+some1 {
+ bit:4 [len] someField;
+ ubyte len;
+ some2 {
+ byte [len] field;
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-getterssetters/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp
similarity index 100%
rename from jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-getterssetters/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp
rename to jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.WholeStreamByteArray.jbbp b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.WholeStreamByteArray.jbbp
new file mode 100644
index 00000000..32cfce5b
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.WholeStreamByteArray.jbbp
@@ -0,0 +1,2 @@
+// some easy JBBP script to test
+byte [_] array;
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java
new file mode 100644
index 00000000..3d1b935d
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java
@@ -0,0 +1,93 @@
+package com.igormaznitsa.mvn.tst;
+
+import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo;
+import com.igormaznitsa.jbbp.compiler.tokenizer.JBBPFieldTypeParameterContainer;
+import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
+import com.igormaznitsa.jbbp.io.JBBPBitOutputStream;
+import com.igormaznitsa.jbbp.io.JBBPByteOrder;
+import com.igormaznitsa.jbbp.model.JBBPAbstractArrayField;
+import com.igormaznitsa.jbbp.model.JBBPAbstractField;
+import com.igormaznitsa.jbbp.model.JBBPFieldArrayLong;
+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()));
+ }
+
+ @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());
+ }
+
+ @Override
+ 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 extends JBBPAbstractField> 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));
+ }
+ }
+
+ @Override
+ public void run() {
+ }
+
+ @Override
+ 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 extends JBBPAbstractField> 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()) {
+ outStream.writeLong(l, byteOrder);
+ }
+ } else {
+ final long[] larr = a.getArray();
+ for (int i = 0; i < arraySizeToWrite; i++) {
+ outStream.writeLong(larr[i], byteOrder);
+ }
+ }
+ }
+
+}
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/main/java/org/example/Main.java b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/main/java/org/example/Main.java
new file mode 100644
index 00000000..407f157b
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/main/java/org/example/Main.java
@@ -0,0 +1,7 @@
+package org.example;
+
+public class Main {
+ public static void main(String[] args) {
+ System.out.println("Hello world!");
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/test/java/org/example/MainTest.java b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/test/java/org/example/MainTest.java
new file mode 100644
index 00000000..f98a9f30
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle5-plugin-test/src/test/java/org/example/MainTest.java
@@ -0,0 +1,124 @@
+package org.example;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import com.igormaznitsa.jbbp.JBBPParser;
+import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
+import com.igormaznitsa.jbbp.io.JBBPBitOutputStream;
+import com.igormaznitsa.mvn.tst.VarCustomImpl;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Random;
+import java.io.IOException;
+import org.junit.jupiter.api.Test;
+
+import com.igormaznitsa.mvn.test.jbbp.*;
+
+public class MainTest {
+
+ @Test
+ void testReadWrite_Annotations_Static() throws IOException {
+ final byte[] testData = new byte[] {
+ 4,
+ (byte)0xFF, (byte)0x1A, (byte)0x1B, (byte)0x1C,
+ (byte)0xFF, (byte)0x2A, (byte)0x2B, (byte)0x2C,
+ (byte) 0x12, (byte) 0x34, 3, 5, 6, 7
+ };
+
+ final GenAnnotations result =
+ new GenAnnotations().read(new JBBPBitInputStream(new ByteArrayInputStream(testData)));
+ assertEquals(4, result.getLEN());
+ assertEquals(3, result.getSOME1().getSOME2().getFIELD().length);
+
+ final String script = "ubyte len;"
+ + " uint uintField;"
+ + " uint [1] uintArr;"
+ + "some1 {"
+ + " bit:4 [len] someField;"
+ + " ubyte len;"
+ + " some2 {"
+ + " byte [len] field;"
+ + " }"
+ + "}";
+
+ final GenAnnotations instance =
+ JBBPParser.prepare(script).parse(testData).mapTo(new GenAnnotations());
+
+ assertEquals(result.getUINTFIELD(), instance.getUINTFIELD());
+ assertArrayEquals(result.getUINTARR(), instance.getUINTARR());
+ 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());
+ }
+
+ @Test
+ void testReadWrite_Annotations_NonStatic() 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)));
+ assertEquals(4, result.getLEN());
+ assertEquals(3, result.getSOME1().getSOME2().getFIELD().length);
+
+ final String script = "ubyte len;"
+ + "some1 {"
+ + " bit:4 [len] someField;"
+ + " ubyte len;"
+ + " some2 {"
+ + " byte [len] field;"
+ + " }"
+ + "}";
+
+ 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());
+ }
+
+ private static final Random RND = new Random(12345);
+
+ @Test
+ public void testReadWrite_VarCustom() throws Exception {
+ final VarCustomImpl impl = new VarCustomImpl();
+
+ final byte[] etalonArray = new byte[319044];
+ RND.nextBytes(etalonArray);
+ etalonArray[0] = 1;
+
+ impl.read(new JBBPBitInputStream(new ByteArrayInputStream(etalonArray)));
+
+ assertEquals(1, impl.getBYTEA());
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final JBBPBitOutputStream bios = new JBBPBitOutputStream(bos);
+
+ impl.write(bios);
+ bios.close();
+
+ assertArrayEquals(etalonArray, bos.toByteArray());
+ }
+
+ @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})));
+ assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, struct.getARRAY());
+ }
+
+ @Test
+ public void testWrite_DefaultBitOrder() throws IOException {
+ final WholeStreamByteArray struct = new WholeStreamByteArray();
+ struct.setARRAY(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final JBBPBitOutputStream bitOut = new JBBPBitOutputStream(out);
+ struct.write(bitOut);
+ bitOut.close();
+ assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, out.toByteArray());
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/build.gradle b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/build.gradle
new file mode 100644
index 00000000..9d314477
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/build.gradle
@@ -0,0 +1,36 @@
+plugins {
+ id 'java'
+ id 'com.igormaznitsa.gradle.jbbp' version "${jbbp_plugin_version}"
+}
+
+group = 'com.igormaznitsa.jbbp.gradle.test'
+version = '0.0.0-SNAPSHOT'
+
+repositories {
+ mavenLocal()
+ mavenCentral()
+}
+
+dependencies {
+ implementation "com.igormaznitsa:jbbp:${jbbp_plugin_version}"
+ testImplementation platform("org.junit:junit-bom:${junit_version}")
+ testImplementation 'org.junit.jupiter:junit-jupiter'
+}
+
+test {
+ useJUnitPlatform()
+}
+
+import com.igormaznitsa.jbbp.plugin.common.converters.ParserFlags
+
+jbbp {
+ headComment = 'Free license'
+ addBinAnnotations = true
+ addGettersSetters = true
+ customTypes = ['some']
+ interfaces = ['java.lang.Runnable']
+ customText = 'public void run () {}'
+ parserFlags = [ParserFlags.SKIP_REMAINING_FIELDS_IF_EOF]
+}
+
+compileJava.dependsOn(jbbpGenerate)
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/pom.xml b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/pom.xml
new file mode 100644
index 00000000..9f3903b1
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/pom.xml
@@ -0,0 +1,80 @@
+
+
+ 4.0.0
+
+
+ com.igormaznitsa
+ jbbp-gradle-tests
+ 0.0.0-SNAPSHOT
+
+
+ jbbp-gradle6-plugin-test
+ pom
+
+
+ gradle6
+
+
+
+
+
+ maven-clean-plugin
+
+
+
+ ${project.basedir}/gradle
+ false
+
+
+ ${project.basedir}
+
+ gradlew
+ gradlew.bat
+
+ false
+
+
+ ${project.basedir}/downloaded
+ false
+
+
+ ${project.basedir}/build
+ false
+
+
+ ${project.basedir}/out
+ false
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+
+
+ gradle
+ compile
+
+ ${gradle.executable}
+
+ clean
+ test
+ --info
+ --scan
+ --no-daemon
+ -Pjbbp_plugin_version=${jbbp.test.version}
+ -Pjunit_version=${junit5.version}
+
+
+
+ exec
+
+
+
+
+
+
+
+
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/settings.gradle b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/settings.gradle
new file mode 100644
index 00000000..713e1502
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/settings.gradle
@@ -0,0 +1,9 @@
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ mavenLocal()
+ }
+}
+
+rootProject.name = 'jbbp-gradle6-plugin-test'
+
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp
new file mode 100644
index 00000000..b1f6c18f
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp
@@ -0,0 +1,10 @@
+ubyte len;
+uint uintField;
+uint [1] uintArr;
+some1 {
+ bit:4 [len] someField;
+ ubyte len;
+ some2 {
+ byte [len] field;
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp
new file mode 100644
index 00000000..58f5edc9
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp
@@ -0,0 +1,8 @@
+ubyte len;
+some1 {
+ bit:4 [len] someField;
+ ubyte len;
+ some2 {
+ byte [len] field;
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp
new file mode 100644
index 00000000..39d99c87
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp
@@ -0,0 +1,11 @@
+// custom and var fields
+byte bytea;
+some field1;
+ 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));
+ }
+ }
+
+ @Override
+ public void run() {
+ }
+
+ @Override
+ 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 extends JBBPAbstractField> 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()) {
+ outStream.writeLong(l, byteOrder);
+ }
+ } else {
+ final long[] larr = a.getArray();
+ for (int i = 0; i < arraySizeToWrite; i++) {
+ outStream.writeLong(larr[i], byteOrder);
+ }
+ }
+ }
+
+}
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/main/java/org/example/Main.java b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/main/java/org/example/Main.java
new file mode 100644
index 00000000..407f157b
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/main/java/org/example/Main.java
@@ -0,0 +1,7 @@
+package org.example;
+
+public class Main {
+ public static void main(String[] args) {
+ System.out.println("Hello world!");
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/test/java/org/example/MainTest.java b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/test/java/org/example/MainTest.java
new file mode 100644
index 00000000..f98a9f30
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle6-plugin-test/src/test/java/org/example/MainTest.java
@@ -0,0 +1,124 @@
+package org.example;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import com.igormaznitsa.jbbp.JBBPParser;
+import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
+import com.igormaznitsa.jbbp.io.JBBPBitOutputStream;
+import com.igormaznitsa.mvn.tst.VarCustomImpl;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Random;
+import java.io.IOException;
+import org.junit.jupiter.api.Test;
+
+import com.igormaznitsa.mvn.test.jbbp.*;
+
+public class MainTest {
+
+ @Test
+ void testReadWrite_Annotations_Static() throws IOException {
+ final byte[] testData = new byte[] {
+ 4,
+ (byte)0xFF, (byte)0x1A, (byte)0x1B, (byte)0x1C,
+ (byte)0xFF, (byte)0x2A, (byte)0x2B, (byte)0x2C,
+ (byte) 0x12, (byte) 0x34, 3, 5, 6, 7
+ };
+
+ final GenAnnotations result =
+ new GenAnnotations().read(new JBBPBitInputStream(new ByteArrayInputStream(testData)));
+ assertEquals(4, result.getLEN());
+ assertEquals(3, result.getSOME1().getSOME2().getFIELD().length);
+
+ final String script = "ubyte len;"
+ + " uint uintField;"
+ + " uint [1] uintArr;"
+ + "some1 {"
+ + " bit:4 [len] someField;"
+ + " ubyte len;"
+ + " some2 {"
+ + " byte [len] field;"
+ + " }"
+ + "}";
+
+ final GenAnnotations instance =
+ JBBPParser.prepare(script).parse(testData).mapTo(new GenAnnotations());
+
+ assertEquals(result.getUINTFIELD(), instance.getUINTFIELD());
+ assertArrayEquals(result.getUINTARR(), instance.getUINTARR());
+ 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());
+ }
+
+ @Test
+ void testReadWrite_Annotations_NonStatic() 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)));
+ assertEquals(4, result.getLEN());
+ assertEquals(3, result.getSOME1().getSOME2().getFIELD().length);
+
+ final String script = "ubyte len;"
+ + "some1 {"
+ + " bit:4 [len] someField;"
+ + " ubyte len;"
+ + " some2 {"
+ + " byte [len] field;"
+ + " }"
+ + "}";
+
+ 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());
+ }
+
+ private static final Random RND = new Random(12345);
+
+ @Test
+ public void testReadWrite_VarCustom() throws Exception {
+ final VarCustomImpl impl = new VarCustomImpl();
+
+ final byte[] etalonArray = new byte[319044];
+ RND.nextBytes(etalonArray);
+ etalonArray[0] = 1;
+
+ impl.read(new JBBPBitInputStream(new ByteArrayInputStream(etalonArray)));
+
+ assertEquals(1, impl.getBYTEA());
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final JBBPBitOutputStream bios = new JBBPBitOutputStream(bos);
+
+ impl.write(bios);
+ bios.close();
+
+ assertArrayEquals(etalonArray, bos.toByteArray());
+ }
+
+ @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})));
+ assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, struct.getARRAY());
+ }
+
+ @Test
+ public void testWrite_DefaultBitOrder() throws IOException {
+ final WholeStreamByteArray struct = new WholeStreamByteArray();
+ struct.setARRAY(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final JBBPBitOutputStream bitOut = new JBBPBitOutputStream(out);
+ struct.write(bitOut);
+ bitOut.close();
+ assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, out.toByteArray());
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/build.gradle b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/build.gradle
new file mode 100644
index 00000000..9d314477
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/build.gradle
@@ -0,0 +1,36 @@
+plugins {
+ id 'java'
+ id 'com.igormaznitsa.gradle.jbbp' version "${jbbp_plugin_version}"
+}
+
+group = 'com.igormaznitsa.jbbp.gradle.test'
+version = '0.0.0-SNAPSHOT'
+
+repositories {
+ mavenLocal()
+ mavenCentral()
+}
+
+dependencies {
+ implementation "com.igormaznitsa:jbbp:${jbbp_plugin_version}"
+ testImplementation platform("org.junit:junit-bom:${junit_version}")
+ testImplementation 'org.junit.jupiter:junit-jupiter'
+}
+
+test {
+ useJUnitPlatform()
+}
+
+import com.igormaznitsa.jbbp.plugin.common.converters.ParserFlags
+
+jbbp {
+ headComment = 'Free license'
+ addBinAnnotations = true
+ addGettersSetters = true
+ customTypes = ['some']
+ interfaces = ['java.lang.Runnable']
+ customText = 'public void run () {}'
+ parserFlags = [ParserFlags.SKIP_REMAINING_FIELDS_IF_EOF]
+}
+
+compileJava.dependsOn(jbbpGenerate)
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/pom.xml b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/pom.xml
new file mode 100644
index 00000000..397b970d
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/pom.xml
@@ -0,0 +1,80 @@
+
+
+ 4.0.0
+
+
+ com.igormaznitsa
+ jbbp-gradle-tests
+ 0.0.0-SNAPSHOT
+
+
+ jbbp-gradle7-plugin-test
+ pom
+
+
+ gradle7
+
+
+
+
+
+ maven-clean-plugin
+
+
+
+ ${project.basedir}/gradle
+ false
+
+
+ ${project.basedir}
+
+ gradlew
+ gradlew.bat
+
+ false
+
+
+ ${project.basedir}/downloaded
+ false
+
+
+ ${project.basedir}/build
+ false
+
+
+ ${project.basedir}/out
+ false
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+
+
+ gradle
+ compile
+
+ ${gradle.executable}
+
+ clean
+ test
+ --info
+ --scan
+ --no-daemon
+ -Pjbbp_plugin_version=${jbbp.test.version}
+ -Pjunit_version=${junit5.version}
+
+
+
+ exec
+
+
+
+
+
+
+
+
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/settings.gradle b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/settings.gradle
new file mode 100644
index 00000000..944d2e3c
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/settings.gradle
@@ -0,0 +1,9 @@
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ mavenLocal()
+ }
+}
+
+rootProject.name = 'jbbp-gradle7-plugin-test'
+
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp
new file mode 100644
index 00000000..b1f6c18f
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp
@@ -0,0 +1,10 @@
+ubyte len;
+uint uintField;
+uint [1] uintArr;
+some1 {
+ bit:4 [len] someField;
+ ubyte len;
+ some2 {
+ byte [len] field;
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp
new file mode 100644
index 00000000..58f5edc9
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp
@@ -0,0 +1,8 @@
+ubyte len;
+some1 {
+ bit:4 [len] someField;
+ ubyte len;
+ some2 {
+ byte [len] field;
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp
new file mode 100644
index 00000000..39d99c87
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp
@@ -0,0 +1,11 @@
+// custom and var fields
+byte bytea;
+some field1;
+ 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));
+ }
+ }
+
+ @Override
+ public void run() {
+ }
+
+ @Override
+ 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 extends JBBPAbstractField> 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()) {
+ outStream.writeLong(l, byteOrder);
+ }
+ } else {
+ final long[] larr = a.getArray();
+ for (int i = 0; i < arraySizeToWrite; i++) {
+ outStream.writeLong(larr[i], byteOrder);
+ }
+ }
+ }
+
+}
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/main/java/org/example/Main.java b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/main/java/org/example/Main.java
new file mode 100644
index 00000000..407f157b
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/main/java/org/example/Main.java
@@ -0,0 +1,7 @@
+package org.example;
+
+public class Main {
+ public static void main(String[] args) {
+ System.out.println("Hello world!");
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/test/java/org/example/MainTest.java b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/test/java/org/example/MainTest.java
new file mode 100644
index 00000000..f98a9f30
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle7-plugin-test/src/test/java/org/example/MainTest.java
@@ -0,0 +1,124 @@
+package org.example;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import com.igormaznitsa.jbbp.JBBPParser;
+import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
+import com.igormaznitsa.jbbp.io.JBBPBitOutputStream;
+import com.igormaznitsa.mvn.tst.VarCustomImpl;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Random;
+import java.io.IOException;
+import org.junit.jupiter.api.Test;
+
+import com.igormaznitsa.mvn.test.jbbp.*;
+
+public class MainTest {
+
+ @Test
+ void testReadWrite_Annotations_Static() throws IOException {
+ final byte[] testData = new byte[] {
+ 4,
+ (byte)0xFF, (byte)0x1A, (byte)0x1B, (byte)0x1C,
+ (byte)0xFF, (byte)0x2A, (byte)0x2B, (byte)0x2C,
+ (byte) 0x12, (byte) 0x34, 3, 5, 6, 7
+ };
+
+ final GenAnnotations result =
+ new GenAnnotations().read(new JBBPBitInputStream(new ByteArrayInputStream(testData)));
+ assertEquals(4, result.getLEN());
+ assertEquals(3, result.getSOME1().getSOME2().getFIELD().length);
+
+ final String script = "ubyte len;"
+ + " uint uintField;"
+ + " uint [1] uintArr;"
+ + "some1 {"
+ + " bit:4 [len] someField;"
+ + " ubyte len;"
+ + " some2 {"
+ + " byte [len] field;"
+ + " }"
+ + "}";
+
+ final GenAnnotations instance =
+ JBBPParser.prepare(script).parse(testData).mapTo(new GenAnnotations());
+
+ assertEquals(result.getUINTFIELD(), instance.getUINTFIELD());
+ assertArrayEquals(result.getUINTARR(), instance.getUINTARR());
+ 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());
+ }
+
+ @Test
+ void testReadWrite_Annotations_NonStatic() 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)));
+ assertEquals(4, result.getLEN());
+ assertEquals(3, result.getSOME1().getSOME2().getFIELD().length);
+
+ final String script = "ubyte len;"
+ + "some1 {"
+ + " bit:4 [len] someField;"
+ + " ubyte len;"
+ + " some2 {"
+ + " byte [len] field;"
+ + " }"
+ + "}";
+
+ 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());
+ }
+
+ private static final Random RND = new Random(12345);
+
+ @Test
+ public void testReadWrite_VarCustom() throws Exception {
+ final VarCustomImpl impl = new VarCustomImpl();
+
+ final byte[] etalonArray = new byte[319044];
+ RND.nextBytes(etalonArray);
+ etalonArray[0] = 1;
+
+ impl.read(new JBBPBitInputStream(new ByteArrayInputStream(etalonArray)));
+
+ assertEquals(1, impl.getBYTEA());
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final JBBPBitOutputStream bios = new JBBPBitOutputStream(bos);
+
+ impl.write(bios);
+ bios.close();
+
+ assertArrayEquals(etalonArray, bos.toByteArray());
+ }
+
+ @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})));
+ assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, struct.getARRAY());
+ }
+
+ @Test
+ public void testWrite_DefaultBitOrder() throws IOException {
+ final WholeStreamByteArray struct = new WholeStreamByteArray();
+ struct.setARRAY(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final JBBPBitOutputStream bitOut = new JBBPBitOutputStream(out);
+ struct.write(bitOut);
+ bitOut.close();
+ assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, out.toByteArray());
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/build.gradle b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/build.gradle
new file mode 100644
index 00000000..9d314477
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/build.gradle
@@ -0,0 +1,36 @@
+plugins {
+ id 'java'
+ id 'com.igormaznitsa.gradle.jbbp' version "${jbbp_plugin_version}"
+}
+
+group = 'com.igormaznitsa.jbbp.gradle.test'
+version = '0.0.0-SNAPSHOT'
+
+repositories {
+ mavenLocal()
+ mavenCentral()
+}
+
+dependencies {
+ implementation "com.igormaznitsa:jbbp:${jbbp_plugin_version}"
+ testImplementation platform("org.junit:junit-bom:${junit_version}")
+ testImplementation 'org.junit.jupiter:junit-jupiter'
+}
+
+test {
+ useJUnitPlatform()
+}
+
+import com.igormaznitsa.jbbp.plugin.common.converters.ParserFlags
+
+jbbp {
+ headComment = 'Free license'
+ addBinAnnotations = true
+ addGettersSetters = true
+ customTypes = ['some']
+ interfaces = ['java.lang.Runnable']
+ customText = 'public void run () {}'
+ parserFlags = [ParserFlags.SKIP_REMAINING_FIELDS_IF_EOF]
+}
+
+compileJava.dependsOn(jbbpGenerate)
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/pom.xml b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/pom.xml
new file mode 100644
index 00000000..b7765735
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/pom.xml
@@ -0,0 +1,80 @@
+
+
+ 4.0.0
+
+
+ com.igormaznitsa
+ jbbp-gradle-tests
+ 0.0.0-SNAPSHOT
+
+
+ jbbp-gradle8-plugin-test
+ pom
+
+
+ gradle8
+
+
+
+
+
+ maven-clean-plugin
+
+
+
+ ${project.basedir}/gradle
+ false
+
+
+ ${project.basedir}
+
+ gradlew
+ gradlew.bat
+
+ false
+
+
+ ${project.basedir}/downloaded
+ false
+
+
+ ${project.basedir}/build
+ false
+
+
+ ${project.basedir}/out
+ false
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+
+
+ gradle
+ compile
+
+ ${gradle.executable}
+
+ clean
+ test
+ --info
+ --scan
+ --no-daemon
+ -Pjbbp_plugin_version=${jbbp.test.version}
+ -Pjunit_version=${junit5.version}
+
+
+
+ exec
+
+
+
+
+
+
+
+
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/settings.gradle b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/settings.gradle
new file mode 100644
index 00000000..2422dece
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/settings.gradle
@@ -0,0 +1,9 @@
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ mavenLocal()
+ }
+}
+
+rootProject.name = 'jbbp-gradle8-plugin-test'
+
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp
new file mode 100644
index 00000000..b1f6c18f
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp
@@ -0,0 +1,10 @@
+ubyte len;
+uint uintField;
+uint [1] uintArr;
+some1 {
+ bit:4 [len] someField;
+ ubyte len;
+ some2 {
+ byte [len] field;
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp
new file mode 100644
index 00000000..58f5edc9
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp
@@ -0,0 +1,8 @@
+ubyte len;
+some1 {
+ bit:4 [len] someField;
+ ubyte len;
+ some2 {
+ byte [len] field;
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp
new file mode 100644
index 00000000..39d99c87
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp
@@ -0,0 +1,11 @@
+// custom and var fields
+byte bytea;
+some field1;
+ 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));
+ }
+ }
+
+ @Override
+ public void run() {
+ }
+
+ @Override
+ 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 extends JBBPAbstractField> 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()) {
+ outStream.writeLong(l, byteOrder);
+ }
+ } else {
+ final long[] larr = a.getArray();
+ for (int i = 0; i < arraySizeToWrite; i++) {
+ outStream.writeLong(larr[i], byteOrder);
+ }
+ }
+ }
+
+}
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/main/java/org/example/Main.java b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/main/java/org/example/Main.java
new file mode 100644
index 00000000..407f157b
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/main/java/org/example/Main.java
@@ -0,0 +1,7 @@
+package org.example;
+
+public class Main {
+ public static void main(String[] args) {
+ System.out.println("Hello world!");
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/test/java/org/example/MainTest.java b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/test/java/org/example/MainTest.java
new file mode 100644
index 00000000..f98a9f30
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/jbbp-gradle8-plugin-test/src/test/java/org/example/MainTest.java
@@ -0,0 +1,124 @@
+package org.example;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import com.igormaznitsa.jbbp.JBBPParser;
+import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
+import com.igormaznitsa.jbbp.io.JBBPBitOutputStream;
+import com.igormaznitsa.mvn.tst.VarCustomImpl;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Random;
+import java.io.IOException;
+import org.junit.jupiter.api.Test;
+
+import com.igormaznitsa.mvn.test.jbbp.*;
+
+public class MainTest {
+
+ @Test
+ void testReadWrite_Annotations_Static() throws IOException {
+ final byte[] testData = new byte[] {
+ 4,
+ (byte)0xFF, (byte)0x1A, (byte)0x1B, (byte)0x1C,
+ (byte)0xFF, (byte)0x2A, (byte)0x2B, (byte)0x2C,
+ (byte) 0x12, (byte) 0x34, 3, 5, 6, 7
+ };
+
+ final GenAnnotations result =
+ new GenAnnotations().read(new JBBPBitInputStream(new ByteArrayInputStream(testData)));
+ assertEquals(4, result.getLEN());
+ assertEquals(3, result.getSOME1().getSOME2().getFIELD().length);
+
+ final String script = "ubyte len;"
+ + " uint uintField;"
+ + " uint [1] uintArr;"
+ + "some1 {"
+ + " bit:4 [len] someField;"
+ + " ubyte len;"
+ + " some2 {"
+ + " byte [len] field;"
+ + " }"
+ + "}";
+
+ final GenAnnotations instance =
+ JBBPParser.prepare(script).parse(testData).mapTo(new GenAnnotations());
+
+ assertEquals(result.getUINTFIELD(), instance.getUINTFIELD());
+ assertArrayEquals(result.getUINTARR(), instance.getUINTARR());
+ 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());
+ }
+
+ @Test
+ void testReadWrite_Annotations_NonStatic() 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)));
+ assertEquals(4, result.getLEN());
+ assertEquals(3, result.getSOME1().getSOME2().getFIELD().length);
+
+ final String script = "ubyte len;"
+ + "some1 {"
+ + " bit:4 [len] someField;"
+ + " ubyte len;"
+ + " some2 {"
+ + " byte [len] field;"
+ + " }"
+ + "}";
+
+ 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());
+ }
+
+ private static final Random RND = new Random(12345);
+
+ @Test
+ public void testReadWrite_VarCustom() throws Exception {
+ final VarCustomImpl impl = new VarCustomImpl();
+
+ final byte[] etalonArray = new byte[319044];
+ RND.nextBytes(etalonArray);
+ etalonArray[0] = 1;
+
+ impl.read(new JBBPBitInputStream(new ByteArrayInputStream(etalonArray)));
+
+ assertEquals(1, impl.getBYTEA());
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final JBBPBitOutputStream bios = new JBBPBitOutputStream(bos);
+
+ impl.write(bios);
+ bios.close();
+
+ assertArrayEquals(etalonArray, bos.toByteArray());
+ }
+
+ @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})));
+ assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, struct.getARRAY());
+ }
+
+ @Test
+ public void testWrite_DefaultBitOrder() throws IOException {
+ final WholeStreamByteArray struct = new WholeStreamByteArray();
+ struct.setARRAY(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final JBBPBitOutputStream bitOut = new JBBPBitOutputStream(out);
+ struct.write(bitOut);
+ bitOut.close();
+ assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, out.toByteArray());
+ }
+}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle-tests/pom.xml b/jbbp-plugins/jbbp-gradle-tests/pom.xml
new file mode 100644
index 00000000..f4e5c5cf
--- /dev/null
+++ b/jbbp-plugins/jbbp-gradle-tests/pom.xml
@@ -0,0 +1,26 @@
+
+ 4.0.0
+
+
+ com.igormaznitsa
+ jbbp-main-plugin-pom
+ 3.0.2-SNAPSHOT
+
+
+ jbbp-gradle-tests
+ 0.0.0-SNAPSHOT
+ pom
+
+
+ ${jbbp.version}
+
+
+
+ jbbp-gradle5-plugin-test
+ jbbp-gradle6-plugin-test
+ jbbp-gradle7-plugin-test
+ jbbp-gradle8-plugin-test
+
+
+
diff --git a/jbbp-plugins/jbbp-gradle/build.gradle b/jbbp-plugins/jbbp-gradle/build.gradle
index 6758bad5..5e9ef93d 100644
--- a/jbbp-plugins/jbbp-gradle/build.gradle
+++ b/jbbp-plugins/jbbp-gradle/build.gradle
@@ -1,35 +1,36 @@
-def getProp(name, dflt) {
- if (project.hasProperty(name)) {
- return project.getProperty(name)
+def getProp(name) {
+ String found = project.findProperty(name)
+ if (found == null) {
+ GradleException('Property not found: ' + name)
} else {
- logger.warn('Can not find property "' + name + '" is not found')
- return dflt
+ return project.getProperty(name)
}
}
-def jbbpVersion = getProp('jbbp_plugin_version', '1.4.1-SNAPSHOT')
-def metaLibVersion = getProp('meta_lib_version', '1.1.2')
+def jbbpVersion = getProp('jbbp_plugin_version')
+def metaLibVersion = getProp('meta_lib_version')
+def commonsIoVersion = getProp('commons_io_version')
+def junitVersion = getProp('junit_version')
group = 'com.igormaznitsa'
version = jbbpVersion
apply plugin: 'groovy'
-apply plugin: 'maven'
+apply plugin: 'maven-publish'
apply plugin: "com.gradle.plugin-publish"
-sourceCompatibility = 1.6
-targetCompatibility = 1.6
+sourceCompatibility = 11
+targetCompatibility = 11
dependencies {
- compile gradleApi()
- compile localGroovy()
+ implementation gradleApi()
+ implementation localGroovy()
- compile "commons-io:commons-io:2.5"
- compile "com.igormaznitsa:jbbp:" + jbbpVersion
- compile "com.igormaznitsa:meta-annotations:" + metaLibVersion
- compile "com.igormaznitsa:meta-utils:" + metaLibVersion
+ implementation "commons-io:commons-io:" + commonsIoVersion
+ implementation "com.igormaznitsa:meta-annotations:" + metaLibVersion
+ implementation "com.igormaznitsa:meta-utils:" + metaLibVersion
- testCompile 'junit:junit:4.12'
+ testImplementation "junit:junit:" + junitVersion
}
repositories {
@@ -44,29 +45,48 @@ buildscript {
}
}
dependencies {
- classpath "com.gradle.publish:plugin-publish-plugin:0.9.7"
+ classpath "com.gradle.publish:plugin-publish-plugin:1.1.0"
}
}
+tasks.withType(JavaCompile) {
+ options.compilerArgs << "-Xlint:deprecation"
+}
+
+task sourcesJar(type: Jar) {
+ duplicatesStrategy = 'include'
+ archiveClassifier = 'sources'
+ from sourceSets.main.allSource
+}
+
sourceSets {
main {
java {
+ srcDirs '../../jbbp/src/main/java'
srcDirs 'src/main/java'
srcDirs '../jbbp-plugin-common/src/main/java'
}
}
}
-pluginBundle {
+gradlePlugin {
website = 'https://github.com/raydac/java-binary-block-parser'
vcsUrl = 'https://github.com/raydac/java-binary-block-parser'
- description = 'JBBP script translator!'
- tags = ['jbbp', 'converter']
-
plugins {
- JBBPPlugin {
+ jbbpPlugin {
id = 'com.igormaznitsa.gradle.jbbp'
displayName = 'JBBP Sources Generator plugin'
+ implementationClass = 'com.igormaznitsa.jbbp.plugin.gradle.JBBPPlugin'
+ description = 'The plug-in processes JBBP scripts and generate Java classes from them'
+ tags = ['jbbp', 'converter']
+ }
+ }
+}
+
+publishing {
+ publications {
+ maven(MavenPublication) {
+ from components.java
}
}
}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle/pom.xml b/jbbp-plugins/jbbp-gradle/pom.xml
index 2bfeee9e..76bc97ea 100644
--- a/jbbp-plugins/jbbp-gradle/pom.xml
+++ b/jbbp-plugins/jbbp-gradle/pom.xml
@@ -6,7 +6,7 @@
com.igormaznitsajbbp-main-plugin-pom
- 1.4.1-SNAPSHOT
+ 3.0.2-SNAPSHOTjbbp-gradle-plugin
@@ -22,12 +22,13 @@
- install
+ gradle8
+ publishToMavenLocal
- publishGradle
+ publish-gradlepublishPlugins
@@ -38,7 +39,6 @@
maven-clean-plugin
- 3.0.0
@@ -71,7 +71,6 @@
org.codehaus.mojoproperties-maven-plugin
- 1.0.0
@@ -81,7 +80,7 @@
gradle.prop.jbbp_plugin_version
- ${project.version}
+ ${jbbp.plugin.version}gradle.prop.meta_lib_version
@@ -93,29 +92,29 @@
- org.fortasoft
- gradle-maven-plugin
- 1.0.8
-
-
- org.gradle
- gradle-tooling-api
- 4.2.1
-
-
-
-
- 4.2.1
-
- clean
- ${gradleGoal}
-
-
+ org.codehaus.mojo
+ exec-maven-plugin
+ gradlecompile
+
+ ${gradle.executable}
+
+ clean
+ build
+ ${gradleGoal}
+ --info
+ --scan
+ --no-daemon
+ -Pjbbp_plugin_version=${project.version}
+ -Pmeta_lib_version=${meta.version}
+ -Pcommons_io_version=${commonsio.version}
+ -Pjunit_version=${junit4.version}
+
+
- invoke
+ exec
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/JBBPExtension.java b/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPExtension.java
index fdd4aefa..ff2a6832 100644
--- a/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPExtension.java
+++ b/jbbp-plugins/jbbp-gradle/src/main/java/com/igormaznitsa/jbbp/plugin/gradle/JBBPExtension.java
@@ -2,15 +2,14 @@
import com.igormaznitsa.jbbp.plugin.common.converters.ParserFlags;
import com.igormaznitsa.jbbp.plugin.common.converters.Target;
-import org.gradle.api.Project;
-import org.gradle.api.file.ConfigurableFileTree;
-
-import javax.annotation.Nonnull;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import javax.annotation.Nonnull;
+import org.gradle.api.Project;
+import org.gradle.api.file.ConfigurableFileTree;
/**
* JBBP extension settings.
@@ -27,7 +26,7 @@ public class JBBPExtension {
/**
* Target of translation.
*/
- public Target target = Target.JAVA_1_6;
+ public Target target = Target.JAVA;
/**
* Flag to generate getters and setters in result class, all fields will be
@@ -134,6 +133,16 @@ public class JBBPExtension {
*/
public ConfigurableFileTree source;
+ /**
+ * Generate methods newInstance in generated classes.
+ */
+ public boolean addNewInstanceMethods;
+
+ /**
+ * Generate Bin annotations for fields
+ */
+ public boolean addBinAnnotations;
+
public JBBPExtension(@Nonnull final Project project) {
this.source = project.fileTree("src/jbbp");
}
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 e9b5fc31..9c021429 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
@@ -1,8 +1,11 @@
package com.igormaznitsa.jbbp.plugin.gradle;
+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.JBBPArraySizeLimiter;
import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
import com.igormaznitsa.jbbp.io.JBBPBitOrder;
import com.igormaznitsa.jbbp.model.JBBPAbstractField;
@@ -13,20 +16,18 @@
import com.igormaznitsa.meta.annotation.MustNotContainNull;
import com.igormaznitsa.meta.common.utils.Assertions;
import com.igormaznitsa.meta.common.utils.GetUtils;
-import org.gradle.api.GradleException;
-import org.gradle.api.plugins.JavaPlugin;
-import org.gradle.api.plugins.JavaPluginConvention;
-import org.gradle.api.tasks.Input;
-import org.gradle.api.tasks.Optional;
-import org.gradle.api.tasks.SourceSet;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.gradle.api.GradleException;
+import org.gradle.api.plugins.JavaPlugin;
+import org.gradle.api.plugins.JavaPluginConvention;
+import org.gradle.api.tasks.Input;
+import org.gradle.api.tasks.SourceSet;
/**
* Task to translate found JBBP scripts in source files.
@@ -39,12 +40,15 @@ public class JBBPGenerateTask extends AbstractJBBPTask {
* Flag to register the output folder in Java source folders at the end of process.
*/
@Input
- @Optional
protected boolean addSource = true;
+ public boolean isAddSource() {
+ return this.addSource;
+ }
+
@Override
protected void doTaskAction(@Nonnull final JBBPExtension ext) {
- final Target target = GetUtils.ensureNonNull(ext.target, Target.JAVA_1_6);
+ final Target target = GetUtils.ensureNonNull(ext.target, Target.JAVA);
final Set normalizedCustomTypeNames = new HashSet();
if (ext.customTypes != null) {
@@ -52,13 +56,14 @@ 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);
}
getLogger().debug("Defined normalized custom types : " + normalizedCustomTypeNames);
}
- final String[] customTypesArray = normalizedCustomTypeNames.toArray(new String[normalizedCustomTypeNames.size()]);
+ final String[] customTypesArray = normalizedCustomTypeNames.toArray(ARRAY_STRING_EMPTY);
final JBBPCustomFieldTypeProcessor customFieldProcessor = new JBBPCustomFieldTypeProcessor() {
@Override
@@ -69,7 +74,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());
@@ -79,7 +86,16 @@ 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,
+ final JBBPArraySizeLimiter arraySizeLimiter)
+ throws IOException {
throw new Error("Must not be called");
}
};
@@ -97,6 +113,8 @@ public JBBPAbstractField readCustomFieldType(@Nonnull final JBBPBitInputStream i
.setEncodingOut(CommonUtils.ensureEncodingName(ext.outEncoding))
.setCustomFieldTypeProcessor(customFieldProcessor)
.setSuperClass(ext.superClass)
+ .setAddNewInstanceMethods(ext.addNewInstanceMethods)
+ .setAddBinAnnotations(ext.addBinAnnotations)
.setClassImplements(ext.interfaces)
.setSubClassInterfaces(ext.mapSubClassInterfaces)
.setSubClassSuperclasses(ext.mapSubClassSuperclasses)
@@ -113,19 +131,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..41c08ba5 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,16 +1,20 @@
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
public void apply(@Nonnull final Project project) {
- project.getExtensions().create(JBBPExtension.EXT_NAME, JBBPExtension.class, project);
- project.getTasks().create("jbbpGenerate", JBBPGenerateTask.class);
- project.getTasks().create("jbbpClean", JBBPCleanTask.class);
+ JBBPExtension extension = project.getExtensions()
+ .create(JBBPExtension.class, JBBPExtension.EXT_NAME, JBBPExtension.class, project);
+ project.getTasks().register("jbbpGenerate", JBBPGenerateTask.class, task -> {
+ task.setDescription("Generate JBBP stuff.");
+ });
+ project.getTasks().register("jbbpClean", JBBPCleanTask.class, task -> {
+ task.setDescription("Clean all JBBP stuff.");
+ });
}
}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle/src/main/resources/META-INF/gradle-plugins/com.igormaznitsa.gradle.jbbp.properties b/jbbp-plugins/jbbp-gradle/src/main/resources/META-INF/gradle-plugins/com.igormaznitsa.gradle.jbbp.properties
deleted file mode 100644
index 282c28f3..00000000
--- a/jbbp-plugins/jbbp-gradle/src/main/resources/META-INF/gradle-plugins/com.igormaznitsa.gradle.jbbp.properties
+++ /dev/null
@@ -1 +0,0 @@
-implementation-class=com.igormaznitsa.jbbp.plugin.gradle.JBBPPlugin
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-gradle/src/test/groovy/com/igormaznitsa/jbbp/plugin/gradle/JBBPPluginTest.groovy b/jbbp-plugins/jbbp-gradle/src/test/groovy/com/igormaznitsa/jbbp/plugin/gradle/JBBPPluginTest.groovy
index 02a42fbe..714ed009 100644
--- a/jbbp-plugins/jbbp-gradle/src/test/groovy/com/igormaznitsa/jbbp/plugin/gradle/JBBPPluginTest.groovy
+++ b/jbbp-plugins/jbbp-gradle/src/test/groovy/com/igormaznitsa/jbbp/plugin/gradle/JBBPPluginTest.groovy
@@ -2,17 +2,18 @@ import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
import org.junit.Test
-import static org.junit.Assert.assertTrue
+import static org.junit.Assert.assertNotNull
class JBBPPluginTest {
@Test
void demo_plugin_should_add_task_to_project() {
Project project = ProjectBuilder.builder().build()
- project.getPlugins().apply 'jbbp'
+ project.tasks.create("jbbpGenerate")
+ project.tasks.create("jbbpClean")
- assertTrue(project.tasks.jbbpGenerate instanceof JBBPGenerateTask)
- assertTrue(project.tasks.jbbpClean instanceof JBBPCleanTask)
+ assertNotNull(project.tasks.getByName("jbbpGenerate"))
+ assertNotNull(project.tasks.getByName("jbbpClean"))
}
}
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-getterssetters/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-getterssetters/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java
deleted file mode 100644
index 312bda2f..00000000
--- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-getterssetters/src/main/java/com/igormaznitsa/mvn/tst/VarCustomImpl.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2017 Igor Maznitsa.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.igormaznitsa.mvn.tst;
-
-import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo;
-import com.igormaznitsa.jbbp.compiler.tokenizer.JBBPFieldTypeParameterContainer;
-import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
-import com.igormaznitsa.jbbp.io.JBBPBitOutputStream;
-import com.igormaznitsa.jbbp.io.JBBPByteOrder;
-import com.igormaznitsa.jbbp.model.JBBPAbstractArrayField;
-import com.igormaznitsa.jbbp.model.JBBPAbstractField;
-import com.igormaznitsa.jbbp.model.JBBPFieldArrayLong;
-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()));
- }
-
- @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());
- }
-
- @Override
- 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 extends JBBPAbstractField> 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));
- }
- }
-
- @Override
- public void run() {
- }
-
- @Override
- 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 extends JBBPAbstractField> 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()) {
- outStream.writeLong(l, byteOrder);
- }
- } else {
- final long[] larr = a.getArray();
- for (int i = 0; i < arraySizeToWrite; i++) {
- outStream.writeLong(larr[i], byteOrder);
- }
- }
- }
-
-}
diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-customvars/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-customvars/pom.xml
index 2630d1f7..e138b327 100644
--- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-customvars/pom.xml
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-customvars/pom.xml
@@ -5,7 +5,7 @@
com.igormaznitsajbbp-maven-plugin-tests
- 1.4.1-SNAPSHOT
+ 0.0.0-SNAPSHOTjbbp-mvn-test-customvars
@@ -16,7 +16,7 @@
${project.groupId}jbbp-maven-plugin
- ${project.version}
+ ${jbbp.plugin.version}
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 extends JBBPAbstractField> readVarArray(Object sourceStruct, JBBPBitInputStream inStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, boolean readWholeStream, int arraySize) throws IOException {
+ public JBBPAbstractArrayField extends JBBPAbstractField> 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 extends JBBPAbstractField> array, JBBPBitOutputStream outStream, JBBPByteOrder byteOrder, JBBPNamedFieldInfo nullableNamedFieldInfo, int extraValue, int arraySizeToWrite) throws IOException {
+ public void writeVarArray(Object sourceStruct,
+ JBBPAbstractArrayField extends JBBPAbstractField> 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/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations-nonstatic/pom.xml
new file mode 100644
index 00000000..99d152bb
--- /dev/null
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations-nonstatic/pom.xml
@@ -0,0 +1,37 @@
+
+
+ 4.0.0
+
+ com.igormaznitsa
+ jbbp-maven-plugin-tests
+ 0.0.0-SNAPSHOT
+
+
+ jbbp-mvn-test-genannotations-nonstatic
+ jar
+
+
+
+
+ ${project.groupId}
+ jbbp-maven-plugin
+ ${jbbp.plugin.version}
+
+
+
+ generate
+
+
+
+
+ Generated with annotations
+ true
+ true
+ true
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations-nonstatic/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations-nonstatic/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp
new file mode 100644
index 00000000..58f5edc9
--- /dev/null
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations-nonstatic/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotationsNonStatic.jbbp
@@ -0,0 +1,8 @@
+ubyte len;
+some1 {
+ bit:4 [len] someField;
+ ubyte len;
+ some2 {
+ byte [len] field;
+ }
+}
\ No newline at end of file
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
new file mode 100644
index 00000000..ed031763
--- /dev/null
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations-nonstatic/src/test/java/com/igormaznitsa/mvn/test/jbbp/GenAnnotationsNonStaticTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2019 Igor Maznitsa.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.igormaznitsa.mvn.test.jbbp;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+
+import com.igormaznitsa.jbbp.JBBPParser;
+import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import org.junit.jupiter.api.Test;
+
+class GenAnnotationsNonStaticTest {
+
+ @Test
+ 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)));
+ assertEquals(4, result.getLEN());
+ assertEquals(3, result.getSOME1().getSOME2().getFIELD().length);
+
+ final String script = "ubyte len;"
+ + "some1 {"
+ + " bit:4 [len] someField;"
+ + " ubyte len;"
+ + " some2 {"
+ + " byte [len] field;"
+ + " }"
+ + "}";
+
+ 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());
+ }
+}
diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations/pom.xml
new file mode 100644
index 00000000..aec17ea0
--- /dev/null
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations/pom.xml
@@ -0,0 +1,36 @@
+
+
+ 4.0.0
+
+ com.igormaznitsa
+ jbbp-maven-plugin-tests
+ 0.0.0-SNAPSHOT
+
+
+ jbbp-mvn-test-genannotations
+ jar
+
+
+
+
+ ${project.groupId}
+ jbbp-maven-plugin
+ ${jbbp.plugin.version}
+
+
+
+ generate
+
+
+
+
+ Generated with annotations
+ true
+ true
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp
new file mode 100644
index 00000000..b1f6c18f
--- /dev/null
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations/src/jbbp/com.igormaznitsa.mvn.test.jbbp.GenAnnotations.jbbp
@@ -0,0 +1,10 @@
+ubyte len;
+uint uintField;
+uint [1] uintArr;
+some1 {
+ bit:4 [len] someField;
+ ubyte len;
+ some2 {
+ byte [len] field;
+ }
+}
\ No newline at end of file
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
new file mode 100644
index 00000000..f137c3a1
--- /dev/null
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-genannotations/src/test/java/com/igormaznitsa/mvn/test/jbbp/GenAnnotationsTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2019 Igor Maznitsa.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.igormaznitsa.mvn.test.jbbp;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+
+import com.igormaznitsa.jbbp.JBBPParser;
+import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import org.junit.jupiter.api.Test;
+
+class GenAnnotationsTest {
+
+ @Test
+ void testReadWrite() throws IOException {
+ final byte[] testData = new byte[] {
+ 4,
+ (byte)0xFF, (byte)0x1A, (byte)0x1B, (byte)0x1C,
+ (byte)0xFF, (byte)0x2A, (byte)0x2B, (byte)0x2C,
+ (byte) 0x12, (byte) 0x34, 3, 5, 6, 7};
+
+ final GenAnnotations result =
+ new GenAnnotations().read(new JBBPBitInputStream(new ByteArrayInputStream(testData)));
+ assertEquals(4, result.getLEN());
+ assertEquals(3, result.getSOME1().getSOME2().getFIELD().length);
+
+ final String script = "ubyte len;"
+ + " uint uintField;"
+ + " uint [1] uintArr;"
+ + "some1 {"
+ + " bit:4 [len] someField;"
+ + " ubyte len;"
+ + " some2 {"
+ + " byte [len] field;"
+ + " }"
+ + "}";
+
+ final GenAnnotations instance =
+ JBBPParser.prepare(script).parse(testData).mapTo(new GenAnnotations());
+ assertEquals(result.getUINTFIELD(), instance.getUINTFIELD());
+ assertArrayEquals(result.getUINTARR(), instance.getUINTARR());
+ 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());
+ }
+}
diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-getterssetters/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-getterssetters/pom.xml
similarity index 93%
rename from jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-getterssetters/pom.xml
rename to jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-getterssetters/pom.xml
index 53b361a2..b79d321b 100644
--- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-getterssetters/pom.xml
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-getterssetters/pom.xml
@@ -5,7 +5,7 @@
com.igormaznitsajbbp-maven-plugin-tests
- 1.4.1-SNAPSHOT
+ 0.0.0-SNAPSHOTjbbp-mvn-test-getterssetters
@@ -16,7 +16,7 @@
${project.groupId}jbbp-maven-plugin
- ${project.version}
+ ${jbbp.plugin.version}
diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-getterssetters/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-getterssetters/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp
new file mode 100644
index 00000000..39d99c87
--- /dev/null
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-getterssetters/src/jbbp/com.igormaznitsa.mvn.test.jbbp.VarCustom.jbbp
@@ -0,0 +1,11 @@
+// custom and var fields
+byte bytea;
+some field1;
+ 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));
+ }
+ }
+
+ @Override
+ public void run() {
+ }
+
+ @Override
+ 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 extends JBBPAbstractField> 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()) {
+ outStream.writeLong(l, byteOrder);
+ }
+ } else {
+ final long[] larr = a.getArray();
+ for (int i = 0; i < arraySizeToWrite; i++) {
+ outStream.writeLong(larr[i], byteOrder);
+ }
+ }
+ }
+
+}
diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-getterssetters/src/test/java/com/igormaznitsa/mvn/test/jbbp/VarCustomTest.java b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-getterssetters/src/test/java/com/igormaznitsa/mvn/test/jbbp/VarCustomTest.java
similarity index 100%
rename from jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-getterssetters/src/test/java/com/igormaznitsa/mvn/test/jbbp/VarCustomTest.java
rename to jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-getterssetters/src/test/java/com/igormaznitsa/mvn/test/jbbp/VarCustomTest.java
index a5059ae1..0eccb1b7 100644
--- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-getterssetters/src/test/java/com/igormaznitsa/mvn/test/jbbp/VarCustomTest.java
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-getterssetters/src/test/java/com/igormaznitsa/mvn/test/jbbp/VarCustomTest.java
@@ -16,17 +16,17 @@
package com.igormaznitsa.mvn.test.jbbp;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+
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 static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.Test;
public class VarCustomTest {
diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-primitives/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-primitives/pom.xml
index bfbffd35..530f888e 100644
--- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-primitives/pom.xml
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/jbbp-mvn-test-primitives/pom.xml
@@ -5,7 +5,7 @@
com.igormaznitsajbbp-maven-plugin-tests
- 1.4.1-SNAPSHOT
+ 0.0.0-SNAPSHOTjbbp-mvn-test-primitives
@@ -16,7 +16,7 @@
${project.groupId}jbbp-maven-plugin
- ${project.version}
+ ${jbbp.plugin.version}
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-tests/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml
index 2c538dd6..709f4ec2 100644
--- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin-tests/pom.xml
@@ -5,18 +5,21 @@
com.igormaznitsajbbp-maven-plugin-pom
- 1.4.1-SNAPSHOT
+ 3.0.2-SNAPSHOTjbbp-maven-plugin-testspom
+ 0.0.0-SNAPSHOTIntegration tests for JBBP Maven pluginjbbp-mvn-test-primitivesjbbp-mvn-test-customvars
- jbbp-mvn-getterssetters
+ jbbp-mvn-test-getterssetters
+ jbbp-mvn-test-genannotations
+ jbbp-mvn-test-genannotations-nonstatic
@@ -28,7 +31,6 @@
org.apache.maven.sharedmaven-verifier
- 1.6test
diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/pom.xml
index a96a7f1f..f73897be 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.igormaznitsajbbp-maven-plugin-pom
- 1.4.1-SNAPSHOT
+ 3.0.2-SNAPSHOTjbbp-maven-plugin
@@ -22,7 +22,6 @@
com.igormaznitsauber-pom
- 1.0.1parent
@@ -42,7 +41,6 @@
org.apache.maven.pluginsmaven-source-plugin
- 3.0.1generate-sources
@@ -56,7 +54,6 @@
org.apache.maven.pluginsmaven-javadoc-plugin
- 3.0.0generate-javadoc
@@ -64,13 +61,15 @@
jar
+
+ 1.8
+ org.apache.maven.pluginsmaven-gpg-plugin
- 1.6sign-artifacts
@@ -81,6 +80,33 @@
+
+ net.nicoulaj.maven.plugins
+ checksum-maven-plugin
+
+
+ verify
+
+ files
+
+
+
+
+ ${project.build.directory}
+
+ *.jar
+ *.pom
+
+
+
+
+ SHA-1
+ MD5
+
+
+
+
+
@@ -164,7 +190,7 @@
com.igormaznitsauber-pom
- 1.0.1
+ 1.0.3parent
@@ -181,31 +207,10 @@
-
- org.codehaus.mojo
- animal-sniffer-maven-plugin
- 1.16
-
-
- org.codehaus.mojo.signature
- java16-sun
- 1.10
-
-
-
-
- animal-sniffer
- test
-
- check
-
-
-
- org.apache.maven.pluginsmaven-plugin-plugin
- 3.5
+ 3.8.1truejbbp
diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/assemble/bundle.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/assemble/bundle.xml
index 1d3c7e7f..008c1efd 100644
--- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/assemble/bundle.xml
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/assemble/bundle.xml
@@ -7,17 +7,21 @@
false
- jar
+ tar.gz${project.build.directory}
- /
+ /com/igormaznitsa/${project.artifactId}/${project.version}
- *.jar.asc*.jar
+ *.jar.asc
+ *.jar.sha1
+ *.jar.md5*.pom*.pom.asc
+ *.pom.sha1
+ *.pom.md5original*.*
diff --git a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/assemble/distribution.xml b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/assemble/distribution.xml
deleted file mode 100644
index 22c183dc..00000000
--- a/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/assemble/distribution.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-
- distr
-
- false
- false
-
-
- tar.gz
-
-
-
- ${project.basedir}
- /project
-
- target/
- texts/
- nbactions.xml
- catalog.xml
- **/.*
-
-
-
- /lib
- ${project.basedir}/target
-
- ${project.build.finalName}.jar
-
-
-
- /lib
- ${project.basedir}
-
- pom.xml
-
-
-
- /
- ${basedir}/texts
-
- *.*
-
-
-
-
\ No newline at end of file
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 64cd1226..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
@@ -60,7 +59,7 @@ public abstract class AbstractJBBPMojo extends AbstractMojo {
*
* @see Target
*/
- @Parameter(alias = "target", defaultValue = "JAVA_1_6")
+ @Parameter(alias = "target", defaultValue = "JAVA")
protected String target;
/**
* Flag to skip processing of the plug-in.
@@ -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 1df44d58..ac17f190 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
@@ -16,25 +16,21 @@
package com.igormaznitsa.jbbp.plugin.mvn;
+import static com.igormaznitsa.jbbp.plugin.common.utils.CommonUtils.ensureEncodingName;
+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.JBBPArraySizeLimiter;
import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
import com.igormaznitsa.jbbp.io.JBBPBitOrder;
+import com.igormaznitsa.jbbp.mapper.Bin;
import com.igormaznitsa.jbbp.model.JBBPAbstractField;
import com.igormaznitsa.jbbp.plugin.common.converters.JBBPScriptTranslator;
import com.igormaznitsa.jbbp.plugin.common.converters.ParserFlags;
import com.igormaznitsa.jbbp.plugin.common.converters.Target;
import com.igormaznitsa.meta.annotation.MustNotContainNull;
-import org.apache.commons.io.FileUtils;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.plugins.annotations.LifecyclePhase;
-import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.Parameter;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
@@ -42,8 +38,14 @@
import java.util.Locale;
import java.util.Map;
import java.util.Set;
-
-import static com.igormaznitsa.jbbp.plugin.common.utils.CommonUtils.ensureEncodingName;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
/**
* The Mojo looks for all JBBP scripts in source and generate sources.
@@ -162,6 +164,23 @@ public class JBBPGenerateMojo extends AbstractJBBPMojo {
@Parameter(alias = "addToTestSourceFolders")
private boolean addToTestSourceFolders;
+ /**
+ * Turn on generate of newInstance methods inside generated classes.
+ *
+ * @since 2.0.0
+ */
+ @Parameter(alias = "addNewInstanceMethods", defaultValue = "false")
+ private boolean addNewInstanceMethods;
+
+ /**
+ * Add Bin annotations
+ *
+ * @see Bin
+ * @since 2.0.0
+ */
+ @Parameter(alias = "addBinAnnotations", defaultValue = "false")
+ private boolean addBinAnnotations;
+
public boolean isAddToSourceFolders() {
return this.addToSourceFolders;
}
@@ -183,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;
@@ -261,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;
@@ -324,13 +343,14 @@ 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);
}
getLog().debug("Defined normalized custom types : " + normalizedCustomTypeNames);
- final String[] customTypesArray = normalizedCustomTypeNames.toArray(new String[normalizedCustomTypeNames.size()]);
+ final String[] customTypesArray = normalizedCustomTypeNames.toArray(ARRAY_STRING_EMPTY);
final JBBPCustomFieldTypeProcessor customFieldProcessor = new JBBPCustomFieldTypeProcessor() {
@Override
@@ -341,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());
@@ -351,7 +373,17 @@ 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,
+ @Nonnull
+ final JBBPArraySizeLimiter arraySizeLimiter)
+ throws IOException {
throw new Error("Must not be called");
}
};
@@ -377,7 +409,9 @@ public JBBPAbstractField readCustomFieldType(@Nonnull final JBBPBitInputStream i
.setSubClassSuperclasses(this.getMapStructToSuperclasses())
.setAddGettersSetters(this.getAddGettersSetters())
.setDoAbstract(this.isDoAbstract())
- .setDisableGenerateFields(this.isDisableGenerateFields());
+ .setDisableGenerateFields(this.isDisableGenerateFields())
+ .setAddBinAnnotations(this.isAddBinAnnotations())
+ .setAddNewInstanceMethods(this.isAddNewInstanceMethods());
for (final File aScript : foundJBBPScripts) {
parameters.setScriptFile(aScript).assertAllOk();
@@ -386,20 +420,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());
}
}
@@ -407,4 +445,19 @@ public JBBPAbstractField readCustomFieldType(@Nonnull final JBBPBitInputStream i
registerSourceRoot(this.output);
}
+ public boolean isAddNewInstanceMethods() {
+ return this.addNewInstanceMethods;
+ }
+
+ public void setAddNewInstanceMethods(final boolean addNewInstanceMethods) {
+ this.addNewInstanceMethods = addNewInstanceMethods;
+ }
+
+ public boolean isAddBinAnnotations() {
+ return addBinAnnotations;
+ }
+
+ public void setAddBinAnnotations(boolean addBinAnnotations) {
+ this.addBinAnnotations = addBinAnnotations;
+ }
}
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
new file mode 100644
index 00000000..430d4962
--- /dev/null
+++ b/jbbp-plugins/jbbp-maven/jbbp-maven-plugin/src/test/java/com/igormaznitsa/jbbp/plugin/common/converters/JavaConverterTest.java
@@ -0,0 +1,50 @@
+package com.igormaznitsa.jbbp.plugin.common.converters;
+
+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 java.io.File;
+import org.junit.jupiter.api.Test;
+
+class JavaConverterTest {
+
+ @Test
+ void testTranslateParameters() {
+ final JBBPScriptTranslator.Parameters parameters = new JBBPScriptTranslator.Parameters();
+
+ assertTrue(parameters.setAddNewInstanceMethods(true).isAddNewInstanceMethods());
+ assertFalse(parameters.setAddNewInstanceMethods(false).isAddNewInstanceMethods());
+
+ assertTrue(parameters.setAddBinAnnotations(true).isAddBinAnnotations());
+ assertFalse(parameters.setAddBinAnnotations(false).isAddBinAnnotations());
+
+ assertTrue(parameters.setAddGettersSetters(true).isAddGettersSetters());
+ assertFalse(parameters.setAddGettersSetters(false).isAddGettersSetters());
+
+ assertTrue(parameters.setDisableGenerateFields(true).isDisableGenerateFields());
+ assertFalse(parameters.setDisableGenerateFields(false).isDisableGenerateFields());
+
+ assertTrue(parameters.setDoAbstract(true).isDoAbstract());
+ assertFalse(parameters.setDoAbstract(false).isDoAbstract());
+
+ 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("bit a;", parameters.setScriptText("bit a;").getScriptText());
+ assertEquals("SomeSuperClass", parameters.setSuperClass("SomeSuperClass").getSuperClass());
+ assertEquals(1234, parameters.setParserFlags(1234).getParserFlags());
+ assertEquals("UTF-8", parameters.setEncodingIn("UTF-8").getEncodingIn());
+ assertEquals("UTF-8", parameters.setEncodingOut("UTF-8").getEncodingOut());
+
+ parameters.setScriptFile(null);
+ }
+
+}
\ No newline at end of file
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 7df92da4..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
@@ -16,6 +16,13 @@
package com.igormaznitsa.jbbp.plugin.mvn;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
import org.apache.maven.execution.DefaultMavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
@@ -26,13 +33,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import java.io.File;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-
public class JBBPGenerateMojoTest extends AbstractMojoTestCase {
private JBBPGenerateMojo findMojo(final String pomName, final String goal) throws Exception {
@@ -62,6 +62,17 @@ private String[] set2array(final Set set) {
return arr;
}
+ private void assertPath(final String expected, final String check) {
+ final String normalized = expected.replace('/', File.separatorChar);
+ if (check.endsWith(normalized)) {
+ final String start = check.substring(0, check.length() - expected.length());
+ if (start.length() == 0 || start.endsWith(":")) {
+ return;
+ }
+ }
+ fail(String.format("Expected %s but detected %s", expected, check));
+ }
+
@Test
public void testConfig() throws Exception {
final JBBPGenerateMojo mojo = findMojo("mojoConfig.xml", "generate");
@@ -70,13 +81,13 @@ public void testConfig() throws Exception {
assertTrue(mojo.getGenerateTestSources());
assertTrue(mojo.getSkip());
assertTrue(mojo.getVerbose());
- assertEquals("/some/custom/file", mojo.getCustomTextFile().getPath());
+ assertPath("/some/custom/file", mojo.getCustomTextFile().getPath());
assertEquals("public void test(){}", mojo.getCustomText());
assertEquals("uber.package", mojo.getPackageName());
- assertEquals("/some/cap/file", mojo.getHeadCommentFile().getPath());
+ assertPath("/some/cap/file", mojo.getHeadCommentFile().getPath());
assertEquals("some cap text", mojo.getHeadComment());
- assertEquals("/some/source", mojo.getSource().getPath());
- assertEquals("/some/output", mojo.getOutput().getPath());
+ assertPath("/some/source", mojo.getSource().getPath());
+ assertPath("/some/output", mojo.getOutput().getPath());
assertEquals("IN-8", mojo.getInputEncoding());
assertEquals("OUT-8", mojo.getOutputEncoding());
assertEquals("com.igormaznitsa.Super", mojo.getSuperClass());
@@ -87,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-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 7980b5b8..cf77af0d 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.igormaznitsajbbp-maven-plugin
- 1.4.1-SNAPSHOT
+ 2.0.4-SNAPSHOTgenerate
diff --git a/jbbp-plugins/jbbp-maven/pom.xml b/jbbp-plugins/jbbp-maven/pom.xml
index a2acf2db..1da1b5aa 100644
--- a/jbbp-plugins/jbbp-maven/pom.xml
+++ b/jbbp-plugins/jbbp-maven/pom.xml
@@ -5,7 +5,7 @@
com.igormaznitsajbbp-main-plugin-pom
- 1.4.1-SNAPSHOT
+ 3.0.2-SNAPSHOTjbbp-maven-plugin-pom
@@ -23,22 +23,12 @@
org.apache.maven.pluginsmaven-jar-plugin
- 3.0.2**/.netbeans_automatic_build
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.6.1
-
- 1.6
- 1.6
-
-
diff --git a/jbbp-plugins/jbbp-plugin-common/pom.xml b/jbbp-plugins/jbbp-plugin-common/pom.xml
index 87d54352..c320c4b8 100644
--- a/jbbp-plugins/jbbp-plugin-common/pom.xml
+++ b/jbbp-plugins/jbbp-plugin-common/pom.xml
@@ -6,7 +6,7 @@
com.igormaznitsajbbp-main-plugin-pom
- 1.4.1-SNAPSHOT
+ 3.0.2-SNAPSHOTjbbp-plugin-common
@@ -18,7 +18,7 @@
${project.groupId}jbbp
- ${project.version}
+ ${jbbp.version}
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 a5a8767d..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
@@ -2,9 +2,6 @@
import com.igormaznitsa.jbbp.JBBPCustomFieldTypeProcessor;
import com.igormaznitsa.meta.common.utils.Assertions;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
@@ -12,6 +9,8 @@
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
/**
* Interface for auxiliary class to process found JBBP script and translate them into set of files.
@@ -35,7 +34,7 @@ public interface JBBPScriptTranslator {
*
* @since 1.3.0
*/
- final class Parameters {
+ public final class Parameters {
/**
* Map of interface names to be implemented by subclasses.
*/
@@ -48,28 +47,34 @@ 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
- protected String superClass = null;
+ private String superClass = null;
/**
- * Processor for custom types.
+ * Destination file name.
+ *
+ * @since 2.0.0
*/
@Nullable
- JBBPCustomFieldTypeProcessor customFieldTypeProcessor = null;
+ private String destFileName = null;
/**
* Disable generate class fields.
*
@@ -89,6 +94,12 @@ final class Parameters {
*/
@Nullable
private File scriptFile = null;
+ /**
+ * Script text, it will be used only if {@link #scriptFile} is null
+ *
+ * @since 2.0.0
+ */
+ private String scriptText = null;
/**
* Package name for main class.
*/
@@ -123,6 +134,18 @@ final class Parameters {
* Parser flags.
*/
private int parserFlags;
+ /**
+ * Turn on generate Bin annotations for fields.
+ *
+ * @since 2.0.0
+ */
+ private boolean addBinAnnotations;
+ /**
+ * Generate newInstance methods in classes.
+ *
+ * @since 2.0.0
+ */
+ private boolean addNewInstanceMethods;
@Nullable
public String getPackageName() {
@@ -135,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;
}
@@ -151,6 +168,17 @@ public Parameters setAddGettersSetters(final boolean value) {
return this;
}
+ @Nullable
+ public String getDestFileName() {
+ return this.destFileName;
+ }
+
+ @Nonnull
+ public Parameters setDestFileName(@Nullable final String name) {
+ this.destFileName = name;
+ return this;
+ }
+
public boolean isDisableGenerateFields() {
return this.disableGenerateFields;
}
@@ -178,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;
}
@@ -194,16 +230,28 @@ public boolean isDoInternalClassesNonStatic() {
}
@Nonnull
- public Parameters setSubClassSuperclasses(@Nonnull final Map value) {
- this.subClassSuperclasses.clear();
- this.subClassSuperclasses.putAll(value);
+ public Parameters setDoInternalClassesNonStatic(final boolean flag) {
+ this.doInternalClassesNonStatic = flag;
return this;
}
+ public boolean isAddNewInstanceMethods() {
+ return this.addNewInstanceMethods;
+ }
+
@Nonnull
- public Parameters setSubClassInterfaces(@Nonnull final Map value) {
- this.subClassInterfaces.clear();
- this.subClassInterfaces.putAll(value);
+ public Parameters setAddNewInstanceMethods(final boolean flag) {
+ this.addNewInstanceMethods = flag;
+ return this;
+ }
+
+ public boolean isAddBinAnnotations() {
+ return this.addBinAnnotations;
+ }
+
+ @Nonnull
+ public Parameters setAddBinAnnotations(final boolean flag) {
+ this.addBinAnnotations = flag;
return this;
}
@@ -238,14 +286,25 @@ public Parameters setOutputDir(@Nullable final File dir) {
return this;
}
- @Nonnull
+ @Nullable
public File getScriptFile() {
- return Assertions.assertNotNull(this.scriptFile);
+ return this.scriptFile;
}
@Nonnull
- public Parameters setScriptFile(@Nonnull final File file) {
- this.scriptFile = Assertions.assertNotNull(file);
+ public Parameters setScriptFile(@Nullable final File file) {
+ this.scriptFile = file;
+ return this;
+ }
+
+ @Nullable
+ public String getScriptText() {
+ return this.scriptText;
+ }
+
+ @Nonnull
+ public Parameters setScriptText(@Nonnull final String text) {
+ this.scriptText = Assertions.assertNotNull(text);
return this;
}
@@ -299,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;
}
@@ -311,5 +371,16 @@ public Parameters assertAllOk() {
}
return this;
}
+
+ @Nullable
+ 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/Java16Converter.java b/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/JavaConverter.java
similarity index 52%
rename from jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/Java16Converter.java
rename to jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/JavaConverter.java
index aa3053ef..28595c4a 100644
--- a/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/Java16Converter.java
+++ b/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/JavaConverter.java
@@ -1,42 +1,59 @@
package com.igormaznitsa.jbbp.plugin.common.converters;
+import static com.igormaznitsa.jbbp.utils.JBBPUtils.ARRAY_STRING_EMPTY;
+
+
import com.igormaznitsa.jbbp.JBBPParser;
-import com.igormaznitsa.jbbp.compiler.conversion.JBBPToJava6Converter;
+import com.igormaznitsa.jbbp.compiler.conversion.JBBPToJavaConverter;
import com.igormaznitsa.jbbp.io.JBBPBitOrder;
import com.igormaznitsa.jbbp.plugin.common.utils.CommonUtils;
import com.igormaznitsa.meta.common.utils.Assertions;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.FilenameUtils;
-
-import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
+import javax.annotation.Nonnull;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
-public class Java16Converter implements JBBPScriptTranslator {
+public class JavaConverter implements JBBPScriptTranslator {
@Override
@Nonnull
- public Set translate(@Nonnull final Parameters parameters, final boolean dryRun) throws IOException {
- final File scriptToProcess = Assertions.assertNotNull(parameters.getScriptFile());
-
- final String text = FileUtils.readFileToString(scriptToProcess, parameters.getEncodingIn());
- final String rawFileName = FilenameUtils.getBaseName(scriptToProcess.getName());
+ 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());
+ } 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(new String[parameters.getClassImplements().size()]);
+ final String[] implementsSorted = parameters.getClassImplements().toArray(ARRAY_STRING_EMPTY);
Arrays.sort(implementsSorted);
- final JBBPToJava6Converter.Builder builder = JBBPToJava6Converter.makeBuilder(parser)
+ final JBBPToJavaConverter.Builder builder = JBBPToJavaConverter.makeBuilder(parser)
.setMapSubClassesInterfaces(parameters.getSubClassInterfaces())
.setMapSubClassesSuperclasses(parameters.getSubClassSuperclasses())
.setMainClassName(className)
@@ -47,7 +64,15 @@ public Set translate(@Nonnull final Parameters parameters, final boolean d
.setDoMainClassAbstract(parameters.isDoAbstract())
.setMainClassImplements(implementsSorted)
.setParserFlags(parameters.getParserFlags())
- .setSuperClass(parameters.superClass);
+ .setSuperClass(parameters.getSuperClass());
+
+ if (parameters.isAddBinAnnotations()) {
+ builder.addBinAnnotations();
+ }
+
+ if (parameters.isAddNewInstanceMethods()) {
+ builder.addNewInstanceMethods();
+ }
if (parameters.isDoInternalClassesNonStatic()) {
builder.doInternalClassesNonStatic();
@@ -56,7 +81,7 @@ public Set translate(@Nonnull final Parameters parameters, final boolean d
if (parameters.isDisableGenerateFields()) {
builder.disableGenerateFields();
}
-
+
FileUtils.write(resultJavaFile, builder.build().convert(), parameters.getEncodingOut());
}
return resultFiles;
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/converters/Target.java b/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/Target.java
index dc4d8099..9747899e 100644
--- a/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/Target.java
+++ b/jbbp-plugins/jbbp-plugin-common/src/main/java/com/igormaznitsa/jbbp/plugin/common/converters/Target.java
@@ -3,7 +3,7 @@
import javax.annotation.Nonnull;
public enum Target {
- JAVA_1_6(new Java16Converter());
+ JAVA(new JavaConverter());
private final JBBPScriptTranslator JBBPScriptTranslator;
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-plugins/pom.xml b/jbbp-plugins/pom.xml
index e6d6d5d5..f1cc9863 100644
--- a/jbbp-plugins/pom.xml
+++ b/jbbp-plugins/pom.xml
@@ -5,7 +5,7 @@
com.igormaznitsajbbp-main-pom
- 1.4.1-SNAPSHOT
+ 3.0.2-SNAPSHOTjbbp-main-plugin-pom
@@ -31,10 +31,18 @@
commons-iocommons-io
- 2.6
+
+
+ gradle-tests
+
+ jbbp-gradle-tests
+
+
+
+
@@ -42,10 +50,8 @@
meta-checker${meta.version}
- 6truetrue
-
risky
diff --git a/jbbp/pom.xml b/jbbp/pom.xml
index 00f8f55f..9f031e0f 100644
--- a/jbbp/pom.xml
+++ b/jbbp/pom.xml
@@ -5,7 +5,7 @@
com.igormaznitsajbbp-main-pom
- 1.4.1-SNAPSHOT
+ 3.0.2-SNAPSHOTjbbp
@@ -17,7 +17,8 @@
- 1.21
+ 1.8
+ 1.8
@@ -36,19 +37,22 @@
org.apache.commonscommons-lang3
- 3.7
+ 3.18.0testnet.minidevjson-smart
- 2.3test
- org.apache.commons
+ commons-iocommons-io
- 1.3.2
+ test
+
+
+ commons-codec
+ commons-codectest
@@ -111,7 +115,7 @@
test
- java
+ java8-classpath
@@ -137,7 +141,6 @@
org.apache.maven.pluginsmaven-source-plugin
- 3.0.1generate-sources
@@ -151,8 +154,8 @@
org.apache.maven.pluginsmaven-javadoc-plugin
- 3.0.0
+ falsetrueprotectedUTF-8
@@ -164,13 +167,15 @@
jar
+
+ 8
+ org.apache.maven.pluginsmaven-gpg-plugin
- 1.6sign-artifacts
@@ -181,6 +186,33 @@
+
+ net.nicoulaj.maven.plugins
+ checksum-maven-plugin
+
+
+ verify
+
+ files
+
+
+
+
+ ${project.build.directory}
+
+ *.jar
+ *.pom
+
+
+
+
+ SHA-1
+ MD5
+
+
+
+
+
@@ -191,7 +223,6 @@
com.igormaznitsauber-pom
- 1.0.1parent
@@ -211,7 +242,6 @@
org.apache.maven.pluginsmaven-jar-plugin
- 3.0.2
@@ -223,33 +253,18 @@
org.codehaus.mojoanimal-sniffer-maven-plugin
- 1.16
- ensure-java-1.6-class-library
- test
-
- check
-
-
-
- org.codehaus.mojo.signature
- java16-sun
- 1.0
-
-
-
-
- ensure-android-2.0-class-library
+ ensure-android-api-32-class-librarytestcheck
- net.sf.androidscents.signature
- android-api-level-5
- 2.0_r1
+ com.toasttab.android
+ gummy-bears-api-32
+ 0.10.0sun.misc.Unsafe
diff --git a/jbbp/src/assemble/bundle.xml b/jbbp/src/assemble/bundle.xml
index d0fd4c70..008c1efd 100644
--- a/jbbp/src/assemble/bundle.xml
+++ b/jbbp/src/assemble/bundle.xml
@@ -1,19 +1,3 @@
-
-
@@ -23,19 +7,24 @@
false
- jar
+ tar.gz${project.build.directory}
- /
+ /com/igormaznitsa/${project.artifactId}/${project.version}
- *.jar.asc*.jar
+ *.jar.asc
+ *.jar.sha1
+ *.jar.md5*.pom*.pom.asc
+ *.pom.sha1
+ *.pom.md5
+ original*.**.zip
diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPCustomFieldTypeProcessor.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPCustomFieldTypeProcessor.java
index 25fb3452..c0453dae 100644
--- a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPCustomFieldTypeProcessor.java
+++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPCustomFieldTypeProcessor.java
@@ -18,10 +18,11 @@
import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo;
import com.igormaznitsa.jbbp.compiler.tokenizer.JBBPFieldTypeParameterContainer;
+import com.igormaznitsa.jbbp.exceptions.JBBPReachedArraySizeLimitException;
+import com.igormaznitsa.jbbp.io.JBBPArraySizeLimiter;
import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
import com.igormaznitsa.jbbp.io.JBBPBitOrder;
import com.igormaznitsa.jbbp.model.JBBPAbstractField;
-
import java.io.IOException;
/**
@@ -46,7 +47,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.
@@ -59,8 +61,20 @@ public interface JBBPCustomFieldTypeProcessor {
* @param extraData extra numeric value for the field, followed by ':', if not presented then 0
* @param readWholeStream if true then the field is array which should contain parse data for whole stream till the end
* @param arrayLength -1 if it is not array else length of the array to be read.
+ * @param arraySizeLimiter limiter to check number of elements during whole stream array read, must not be null
* @return parsed data as JBBP field, must not be null
- * @throws IOException it can be thrown for transport errors
+ * @throws IOException it can be thrown for transport errors
+ * @throws JBBPReachedArraySizeLimitException thrown if reached limit for a whole stream array
+ * @since 2.1.0
+ * @see JBBPArraySizeLimiter#isBreakReadWholeStream(int, JBBPArraySizeLimiter)
+ * @see JBBPArraySizeLimiter#NO_LIMIT_FOR_ARRAY_SIZE
*/
- 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,
+ JBBPArraySizeLimiter arraySizeLimiter) 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 48264658..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;
@@ -59,7 +58,7 @@ public JBBPNamedNumericFieldMap() {
* @param externalValueProvider an external value provider, it can be null
*/
public JBBPNamedNumericFieldMap(final JBBPExternalValueProvider externalValueProvider) {
- this.fieldMap = new LinkedHashMap();
+ this.fieldMap = new LinkedHashMap<>();
this.externalValueProvider = externalValueProvider;
}
@@ -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 e7644f8b..da3c2ce9 100644
--- a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPParser.java
+++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPParser.java
@@ -16,13 +16,18 @@
package com.igormaznitsa.jbbp;
+import static com.igormaznitsa.jbbp.io.JBBPArraySizeLimiter.NO_LIMIT_FOR_ARRAY_SIZE;
+import static com.igormaznitsa.jbbp.utils.JBBPUtils.ARRAY_FIELD_EMPTY;
+
import com.igormaznitsa.jbbp.compiler.JBBPCompiledBlock;
import com.igormaznitsa.jbbp.compiler.JBBPCompiler;
import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo;
-import com.igormaznitsa.jbbp.compiler.conversion.JBBPToJava6Converter;
+import com.igormaznitsa.jbbp.compiler.conversion.JBBPToJavaConverter;
import com.igormaznitsa.jbbp.compiler.tokenizer.JBBPFieldTypeParameterContainer;
import com.igormaznitsa.jbbp.compiler.varlen.JBBPIntegerValueEvaluator;
import com.igormaznitsa.jbbp.exceptions.JBBPParsingException;
+import com.igormaznitsa.jbbp.exceptions.JBBPReachedArraySizeLimitException;
+import com.igormaznitsa.jbbp.io.JBBPArraySizeLimiter;
import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
import com.igormaznitsa.jbbp.io.JBBPBitNumber;
import com.igormaznitsa.jbbp.io.JBBPBitOrder;
@@ -40,6 +45,7 @@
import com.igormaznitsa.jbbp.model.JBBPFieldArrayString;
import com.igormaznitsa.jbbp.model.JBBPFieldArrayStruct;
import com.igormaznitsa.jbbp.model.JBBPFieldArrayUByte;
+import com.igormaznitsa.jbbp.model.JBBPFieldArrayUInt;
import com.igormaznitsa.jbbp.model.JBBPFieldArrayUShort;
import com.igormaznitsa.jbbp.model.JBBPFieldBit;
import com.igormaznitsa.jbbp.model.JBBPFieldBoolean;
@@ -52,12 +58,12 @@
import com.igormaznitsa.jbbp.model.JBBPFieldString;
import com.igormaznitsa.jbbp.model.JBBPFieldStruct;
import com.igormaznitsa.jbbp.model.JBBPFieldUByte;
+import com.igormaznitsa.jbbp.model.JBBPFieldUInt;
import com.igormaznitsa.jbbp.model.JBBPFieldUShort;
import com.igormaznitsa.jbbp.model.JBBPNumericField;
import com.igormaznitsa.jbbp.utils.JBBPIntCounter;
import com.igormaznitsa.jbbp.utils.JBBPUtils;
import com.igormaznitsa.jbbp.utils.TargetSources;
-
import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.IOException;
@@ -74,7 +80,7 @@
*
* @since 1.0
*/
-@SuppressWarnings( {"WeakerAccess", "ConstantConditions"})
+@SuppressWarnings({"WeakerAccess"})
public final class JBBPParser {
/**
@@ -87,6 +93,15 @@ public final class JBBPParser {
* @since 1.4.0
*/
public static final int FLAG_NEGATIVE_EXPRESSION_RESULT_AS_ZERO = 2;
+
+ /**
+ * Default expression array size controller. It is doing nothing.
+ *
+ * @since 2.1.0
+ */
+ public static final JBBPParserExpressionArraySizeController
+ DEFAULT_EXPRESSION_ARRAY_SIZE_CONTROLLER =
+ (parser, expressionEvaluator, fieldName, arraySize) -> arraySize;
/**
* Empty structure array
*/
@@ -107,22 +122,29 @@ public final class JBBPParser {
* Custom field type processor for the parser, it can be null.
*/
private final JBBPCustomFieldTypeProcessor customFieldTypeProcessor;
+ /**
+ * Controller to get and change values calculated by expressions as size for array fields.
+ *
+ * @since 2.1.0
+ */
+ private JBBPParserExpressionArraySizeController expressionArraySizeController =
+ DEFAULT_EXPRESSION_ARRAY_SIZE_CONTROLLER;
/**
* The Variable contains the last parsing counter value.
*/
private long finalStreamByteCounter;
-
/**
* Constructor.
*
* @param source the source script to parse binary blocks and streams, must
* not be null
- * @param bitOrder the bit order for bit reading operations, must not be null
+ * @param bitOrder the bit order for a bit reading operations, must not be null
* @param customFieldTypeProcessor custom field type processor for the parser instance, it can be null
* @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;
@@ -143,7 +165,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) +
+ ']');
}
}
@@ -161,7 +185,7 @@ public static JBBPParser prepare(final String script, final JBBPBitOrder bitOrde
}
/**
- * Prepare a parser for a script with defined bit order and special flags.
+ * Prepare a parser for a script with defined a bit order and special flags.
*
* @param script a text script contains field order and types reference, it
* must not be null
@@ -173,12 +197,13 @@ 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);
}
/**
- * Prepare a parser for a script with defined bit order and special flags.
+ * Prepare a parser for a script with defined a bit order and special flags.
*
* @param script a text script contains field order and types reference, it
* must not be null
@@ -191,7 +216,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);
}
@@ -216,7 +243,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);
}
@@ -235,34 +263,72 @@ public static JBBPParser prepare(final String script, final int flags) {
return JBBPParser.prepare(script, JBBPBitOrder.LSB0, flags);
}
+ /**
+ * Get current registered instance of controller to check array size calculated by expression.
+ *
+ * @return current instance of array size observer, can't be null
+ * @since 2.1.0
+ */
+ public JBBPParserExpressionArraySizeController getExpressionArraySizeController() {
+ return this.expressionArraySizeController;
+ }
+
+ /**
+ * Set current registered instance of controller to check array size calculated by expression.
+ *
+ * @param arraySizeController instance of array size observer, must not be null.
+ * @return instance of the parser.
+ * @throws NullPointerException if argument is null
+ * @see #DEFAULT_EXPRESSION_ARRAY_SIZE_CONTROLLER
+ * @since 2.1.0
+ */
+ public JBBPParser setExpressionArraySizeController(
+ final JBBPParserExpressionArraySizeController arraySizeController) {
+ if (arraySizeController == null) {
+ throw new NullPointerException("Controller value must not be null");
+ }
+ this.expressionArraySizeController = arraySizeController;
+ return this;
+ }
+
/**
* Inside method to parse a structure.
*
* @param inStream the input stream, must not be null
* @param positionAtCompiledBlock the current position in the compiled script
* block
- * @param varFieldProcessor a processor to process var fields, it can be null
+ * @param varFieldProcessor a processor to process var fields, it can be null,
* but it will thrown NPE if a var field is met
* @param namedNumericFieldMap the named numeric field map
* @param positionAtNamedFieldList the current position at the named field
* list
* @param positionAtVarLengthProcessors the current position at the variable
* array length processor list
+ * @param arraySizeLimiter limiter for only whole stream arrays, must not be null
* @param skipStructureFields the flag shows that content of fields must be
* skipped because the structure is skipped
* @return list of read fields for the structure
- * @throws IOException it will be thrown for transport errors
+ * @throws IOException it will be thrown for transport errors
+ * @throws JBBPReachedArraySizeLimitException thrown if reached limit for a whole stream array
*/
- @SuppressWarnings("ConstantConditions")
- 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();
+ private List parseStruct(final JBBPBitInputStream inStream,
+ final JBBPIntCounter positionAtCompiledBlock,
+ final JBBPVarFieldProcessor varFieldProcessor,
+ final JBBPNamedNumericFieldMap namedNumericFieldMap,
+ final JBBPIntCounter positionAtNamedFieldList,
+ final JBBPIntCounter positionAtVarLengthProcessors,
+ final JBBPArraySizeLimiter arraySizeLimiter,
+ final boolean skipStructureFields)
+ throws IOException {
+ final List structureFields = skipStructureFields ? null : new ArrayList<>();
final byte[] compiled = this.compiledBlock.getCompiledData();
boolean endStructureNotMet = true;
while (endStructureNotMet && positionAtCompiledBlock.get() < compiled.length) {
- if (!inStream.hasAvailableData() && (flags & FLAG_SKIP_REMAINING_FIELDS_IF_EOF) != 0) {
- // Break reading because the ignore flag for EOF has been set
+ if (inStream.isDetectedArrayLimit() ||
+ (!inStream.hasAvailableData() && (flags & FLAG_SKIP_REMAINING_FIELDS_IF_EOF) != 0)) {
+ // Break reading because the ignore flag for EOF has been set or reached limit for whole stream array read
break;
}
@@ -273,17 +339,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);
}
@@ -298,7 +371,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);
@@ -313,13 +387,20 @@ 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);
}
+ resultOfExpression =
+ this.expressionArraySizeController.onCalculatedArraySize(this, evaluator, name,
+ resultOfExpression);
} else {
resultOfExpression = 0;
}
@@ -348,14 +429,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);
@@ -363,7 +446,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)");
}
}
}
@@ -371,35 +456,52 @@ 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,
+ arraySizeLimiter),
+ 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 extends JBBPAbstractField> 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 extends JBBPAbstractField> array = varFieldProcessor
+ .readVarArray(inStream, wholeStreamArray ? -1 : arrayLength, name, extraField,
+ byteOrder, namedNumericFieldMap, arraySizeLimiter);
+ 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);
}
@@ -407,10 +509,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, arraySizeLimiter);
JBBPUtils.assertNotNull(field, "Must not return null as read result");
if (arrayLength < 0) {
@@ -424,9 +531,17 @@ private List parseStruct(final JBBPBitInputStream inStream, f
case JBBPCompiler.CODE_BYTE: {
if (resultNotIgnored) {
if (arrayLength < 0) {
- singleAtomicField = new JBBPFieldByte(name, (byte) inStream.readByte());
+ singleAtomicField = fieldTypeDiff ?
+ new JBBPFieldUInt(name, inStream.readInt(byteOrder) & 0xFFFFFFFFL) :
+ new JBBPFieldByte(name, (byte) inStream.readByte());
} else {
- structureFields.add(new JBBPFieldArrayByte(name, inStream.readByteArray(wholeStreamArray ? -1 : arrayLength, byteOrder)));
+ structureFields.add(fieldTypeDiff ?
+ new JBBPFieldArrayUInt(name,
+ inStream.readIntArray(wholeStreamArray ? -1 : arrayLength, byteOrder,
+ arraySizeLimiter)) :
+ new JBBPFieldArrayByte(name,
+ inStream.readByteArray(wholeStreamArray ? -1 : arrayLength, byteOrder,
+ arraySizeLimiter)));
}
}
}
@@ -436,7 +551,9 @@ 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,
+ arraySizeLimiter)));
}
}
}
@@ -444,11 +561,17 @@ 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,
+ arraySizeLimiter)) :
+ new JBBPFieldArrayBoolean(name,
+ inStream.readBoolArray(wholeStreamArray ? -1 : arrayLength,
+ arraySizeLimiter))
);
}
}
@@ -457,11 +580,17 @@ 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,
+ arraySizeLimiter)) :
+ new JBBPFieldArrayInt(name,
+ inStream.readIntArray(wholeStreamArray ? -1 : arrayLength, byteOrder,
+ arraySizeLimiter))
);
}
}
@@ -470,11 +599,17 @@ 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,
+ arraySizeLimiter)) :
+ new JBBPFieldArrayLong(name,
+ inStream.readLongArray(wholeStreamArray ? -1 : arrayLength, byteOrder,
+ arraySizeLimiter))
);
}
}
@@ -486,7 +621,9 @@ 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,
+ arraySizeLimiter)));
}
}
}
@@ -497,18 +634,24 @@ 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,
+ arraySizeLimiter)));
}
}
}
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,
+ arraySizeLimiter, skipStructureFields);
// skip offset
JBBPUtils.unpackInt(compiled, positionAtCompiledBlock);
if (resultNotIgnored) {
- structureFields.add(new JBBPFieldStruct(name, structFields.toArray(new JBBPAbstractField[structFields.size()])));
+ structureFields
+ .add(new JBBPFieldStruct(name, structFields.toArray(ARRAY_FIELD_EMPTY)));
}
} else {
final int nameFieldCurrent = positionAtNamedFieldList.get();
@@ -518,14 +661,23 @@ private List parseStruct(final JBBPBitInputStream inStream, f
if (resultNotIgnored) {
if (wholeStreamArray) {
// read till the stream end
- final List list = new ArrayList();
+ final List list = new ArrayList<>();
while (inStream.hasAvailableData()) {
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, arraySizeLimiter, skipStructureFields);
list.add(new JBBPFieldStruct(name, fieldsForStruct));
+ if (JBBPArraySizeLimiter.isBreakReadWholeStream(list.size(),
+ arraySizeLimiter)) {
+ inStream.setDetectedArrayLimit(true);
+ break;
+ }
+
final int structStart = JBBPUtils.unpackInt(compiled, positionAtCompiledBlock);
if (inStream.hasAvailableData()) {
@@ -533,20 +685,26 @@ private List parseStruct(final JBBPBitInputStream inStream, f
}
}
- result = list.isEmpty() ? EMPTY_STRUCT_ARRAY : list.toArray(new JBBPFieldStruct[list.size()]);
+ result = list.isEmpty() ? EMPTY_STRUCT_ARRAY : list.toArray(EMPTY_STRUCT_ARRAY);
} else {
// read number of items
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, arraySizeLimiter, 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, arraySizeLimiter, skipStructureFields);
+ final int structBodyStart =
+ JBBPUtils.unpackInt(compiled, positionAtCompiledBlock);
result[i] = new JBBPFieldStruct(name, fieldsForStruct);
@@ -554,7 +712,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));
}
}
}
@@ -564,7 +723,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,
+ arraySizeLimiter, skipStructureFields);
JBBPUtils.unpackInt(compiled, positionAtCompiledBlock);
}
}
@@ -582,13 +743,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);
}
}
@@ -621,8 +784,43 @@ 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 {
+ return this.parse(
+ in,
+ varFieldProcessor,
+ externalValueProvider,
+ NO_LIMIT_FOR_ARRAY_SIZE
+ );
+ }
+
+ /**
+ * Parse am input stream with defined external value provider.
+ *
+ * @param in an input stream which content will be parsed, it must not be null
+ * @param varFieldProcessor a var field processor, it may be null if there is
+ * not any var field in a script, otherwise NPE will be thrown during parsing
+ * @param externalValueProvider an external value provider, it can be null but
+ * only if the script doesn't have fields desired the provider
+ * @param arraySizeLimiter limiter to read whole stream arrays, must not be null
+ * @return the parsed content as the root structure
+ * @throws IOException it will be thrown for transport errors
+ * @throws JBBPReachedArraySizeLimitException thrown if reached limit for a whole stream array
+ * @see JBBPArraySizeLimiter#NO_LIMIT_FOR_ARRAY_SIZE
+ * @since 2.1.0
+ */
+ public JBBPFieldStruct parse(
+ final InputStream in,
+ final JBBPVarFieldProcessor varFieldProcessor,
+ final JBBPExternalValueProvider externalValueProvider,
+ final JBBPArraySizeLimiter arraySizeLimiter
+ ) throws IOException {
+ final JBBPBitInputStream bitInStream =
+ in instanceof JBBPBitInputStream ? (JBBPBitInputStream) in :
+ new JBBPBitInputStream(in, bitOrder);
this.finalStreamByteCounter = bitInStream.getCounter();
final JBBPNamedNumericFieldMap fieldMap;
@@ -633,10 +831,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(), arraySizeLimiter, false));
} finally {
this.finalStreamByteCounter = bitInStream.getCounter();
}
@@ -677,7 +878,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);
}
@@ -711,50 +914,49 @@ public JBBPCompiledBlock getCompiledBlock() {
* @param name name of result, depends on target, must not be null, for instance class name (example 'com.test.jbbp.Parser')
* @return list of source items generated during operation, must not be null and must not be empty
* @throws IllegalArgumentException if target is unsupported
- * @see JBBPToJava6Converter
- * @see JBBPToJava6Converter.Builder
+ * @see JBBPToJavaConverter
+ * @see JBBPToJavaConverter.Builder
* @since 1.3.0
*/
public List convertToSrc(final TargetSources target, final String name) {
JBBPUtils.assertNotNull(name, "Name must not be null");
- switch (target) {
- case JAVA_1_6: {
- final Properties metadata = new Properties();
- metadata.setProperty("script", this.compiledBlock.getSource());
- metadata.setProperty("name", name);
- metadata.setProperty("target", target.name());
- metadata.setProperty("converter", JBBPToJava6Converter.class.getCanonicalName());
-
- final int nameStart = name.lastIndexOf('.');
- final String packageName;
- final String className;
- if (nameStart < 0) {
- packageName = "";
- className = name;
- } else {
- packageName = name.substring(0, nameStart);
- className = name.substring(nameStart + 1);
- }
+ if (target == TargetSources.JAVA) {
+ final Properties metadata = new Properties();
+ metadata.setProperty("script", this.compiledBlock.getSource());
+ metadata.setProperty("name", name);
+ metadata.setProperty("target", target.name());
+ metadata.setProperty("converter", JBBPToJavaConverter.class.getCanonicalName());
+
+ final int nameStart = name.lastIndexOf('.');
+ final String packageName;
+ final String className;
+ if (nameStart < 0) {
+ packageName = "";
+ className = name;
+ } else {
+ packageName = name.substring(0, nameStart);
+ className = name.substring(nameStart + 1);
+ }
- final String resultSources = JBBPToJava6Converter.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
- public Properties getMetadata() {
- return metadata;
- }
+ return Collections.singletonList(new ResultSrcItem() {
+ @Override
+ public Properties getMetadata() {
+ return metadata;
+ }
- @Override
- public Map getResult() {
- return resultMap;
- }
- });
- }
- default: {
- throw new IllegalArgumentException("Unsupported target : " + target);
- }
+ @Override
+ public Map getResult() {
+ return resultMap;
+ }
+ });
}
+ throw new IllegalArgumentException("Unsupported target : " + target);
}
}
diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPParserExpressionArraySizeController.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPParserExpressionArraySizeController.java
new file mode 100644
index 00000000..9d56f5f9
--- /dev/null
+++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPParserExpressionArraySizeController.java
@@ -0,0 +1,26 @@
+package com.igormaznitsa.jbbp;
+
+import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo;
+import com.igormaznitsa.jbbp.compiler.varlen.JBBPIntegerValueEvaluator;
+
+/**
+ * Controller to get value for every array field which size calculated by expression.
+ *
+ * @see JBBPParser#setExpressionArraySizeController(JBBPParserExpressionArraySizeController)
+ * @see JBBPParser#getExpressionArraySizeController()
+ * @since 2.1.0
+ */
+@FunctionalInterface
+public interface JBBPParserExpressionArraySizeController {
+ /**
+ * Called for every calculation of an array size by expression.
+ *
+ * @param parser source parser, must not be null
+ * @param expressionEvaluator expression evaluator used for calculation, must not be null
+ * @param fieldInfo target field info, must not be null
+ * @param calculatedArraySize calculated array size
+ * @return array size which can be same as provided size or changed
+ */
+ int onCalculatedArraySize(JBBPParser parser, JBBPIntegerValueEvaluator expressionEvaluator,
+ JBBPNamedFieldInfo fieldInfo, int calculatedArraySize);
+}
diff --git a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPVarFieldProcessor.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPVarFieldProcessor.java
index ec7aebf4..445ded67 100644
--- a/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPVarFieldProcessor.java
+++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPVarFieldProcessor.java
@@ -17,11 +17,12 @@
package com.igormaznitsa.jbbp;
import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo;
+import com.igormaznitsa.jbbp.exceptions.JBBPReachedArraySizeLimitException;
+import com.igormaznitsa.jbbp.io.JBBPArraySizeLimiter;
import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
import com.igormaznitsa.jbbp.io.JBBPByteOrder;
import com.igormaznitsa.jbbp.model.JBBPAbstractArrayField;
import com.igormaznitsa.jbbp.model.JBBPAbstractField;
-
import java.io.IOException;
/**
@@ -39,10 +40,22 @@ public interface JBBPVarFieldProcessor {
* @param extraValue the extra value for the field, by default it is 0, it is the integer value after ':' char in the field type
* @param byteOrder the byte order for the field, it must not be null
* @param numericFieldMap the numeric field map for the session, it must not be null, it can be used for access to already read values of another numeric fields.
+ * @param arraySizeLimiter limiter to check number of elements during whole stream array read, must not be null
* @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
+ * @throws IOException it can be thrown for transport errors or another process exceptions
+ * @throws JBBPReachedArraySizeLimitException thrown if reached limit for whole stream array
+ * @since 2.1.0
+ * @see JBBPArraySizeLimiter#isBreakReadWholeStream(int, JBBPArraySizeLimiter)
+ * @see JBBPArraySizeLimiter#NO_LIMIT_FOR_ARRAY_SIZE
*/
- JBBPAbstractArrayField extends JBBPAbstractField> readVarArray(JBBPBitInputStream inStream, int arraySize, JBBPNamedFieldInfo fieldName, int extraValue, JBBPByteOrder byteOrder, JBBPNamedNumericFieldMap numericFieldMap) throws IOException;
+ JBBPAbstractArrayField extends JBBPAbstractField> readVarArray(JBBPBitInputStream inStream,
+ int arraySize,
+ JBBPNamedFieldInfo fieldName,
+ int extraValue,
+ JBBPByteOrder byteOrder,
+ JBBPNamedNumericFieldMap numericFieldMap,
+ JBBPArraySizeLimiter arraySizeLimiter)
+ 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 +72,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 9b9c2ad4..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;
@@ -33,6 +32,12 @@
*/
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];
+
/**
* The Array of named field info items.
*/
@@ -70,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;
@@ -193,9 +201,9 @@ public int findFieldOffsetForPath(final String fieldPath) {
*/
public final static class Builder {
- private final List namedFields = new ArrayList();
- private final List varLenProcessors = new ArrayList();
- private final List customTypeFields = new ArrayList();
+ private final List namedFields = new ArrayList<>();
+ private final List varLenProcessors = new ArrayList<>();
+ private final List customTypeFields = new ArrayList<>();
private String source;
private byte[] compiledData;
private boolean hasVarFields;
@@ -211,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(new JBBPNamedFieldInfo[this.namedFields.size()]), this.varLenProcessors.isEmpty() ? null : this.varLenProcessors.toArray(new JBBPIntegerValueEvaluator[this.varLenProcessors.size()]), this.compiledData, this.hasVarFields, this.customTypeFields.toArray(new JBBPFieldTypeParameterContainer[this.customTypeFields.size()]));
+ 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 d89e2b77..94979261 100644
--- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompiler.java
+++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompiler.java
@@ -28,8 +28,8 @@
import com.igormaznitsa.jbbp.model.JBBPFieldDouble;
import com.igormaznitsa.jbbp.model.JBBPFieldFloat;
import com.igormaznitsa.jbbp.model.JBBPFieldString;
+import com.igormaznitsa.jbbp.model.JBBPFieldUInt;
import com.igormaznitsa.jbbp.utils.JBBPUtils;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -114,12 +114,12 @@ public final class JBBPCompiler {
*/
public static final int FLAG_NAMED = 0x10;
/**
- * The Byte-Code Flag shows that the field is an array but it must be omitted
+ * The Byte-Code Flag shows that the field is an array, but it must be omitted
* for unlimited field arrays.
*/
public static final int FLAG_ARRAY = 0x20;
/**
- * The Byte-Code Flag shows that a multi-byte field must be decoded as
+ * The Byte-Code Flag shows that a multibyte field must be decoded as
* Little-endian one.
*/
public static final int FLAG_LITTLE_ENDIAN = 0x40;
@@ -157,33 +157,27 @@ 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);
}
}
private static void assertTokenNamed(final String fieldType, final JBBPToken token) {
if (token.getFieldName() == null) {
- final String fieldName = token.getFieldName() == null ? "" : token.getFieldName();
- throw new JBBPCompilationException('\'' + fieldType + "' must be named (" + fieldName + ')', token);
+ throw new JBBPCompilationException('\'' + fieldType + "' must be named", token);
}
}
private static void assertTokenNotNamed(final String fieldType, final JBBPToken token) {
if (token.getFieldName() != null) {
- final String fieldName = token.getFieldName() == null ? "" : token.getFieldName();
- throw new JBBPCompilationException('\'' + fieldType + "' must not be named (" + fieldName + ')', token);
+ throw new JBBPCompilationException(
+ '\'' + fieldType + "' must not be named (" + token.getFieldName() + ')', token);
}
}
private static void assertTokenHasExtraData(final String fieldType, final JBBPToken token) {
if (token.getFieldTypeParameters().getExtraData() == null) {
- throw new JBBPCompilationException('\'' + fieldType + "\' doesn't have extra value", token);
- }
- }
-
- private static void assertTokenDoesntHaveExtraData(final String fieldType, final JBBPToken token) {
- if (token.getFieldTypeParameters().getExtraData() != null) {
- throw new JBBPCompilationException('\'' + fieldType + "\' has extra value", token);
+ throw new JBBPCompilationException('\'' + fieldType + "' doesn't have extra value", token);
}
}
@@ -198,19 +192,21 @@ 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);
- final List namedFields = new ArrayList();
- final List customTypeFields = new ArrayList();
- final List varLengthEvaluators = new ArrayList();
+ final List namedFields = new ArrayList<>();
+ final List customTypeFields = new ArrayList<>();
+ final List varLengthEvaluators = new ArrayList<>();
final ByteArrayOutputStream out = new ByteArrayOutputStream();
int offset = 0;
- final List structureStack = new ArrayList();
+ final List structureStack = new ArrayList<>();
final JBBPTokenizer parser = new JBBPTokenizer(script, customTypeFieldProcessor);
int fieldUnrestrictedArrayOffset = -1;
@@ -240,7 +236,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) {
@@ -254,7 +251,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) {
@@ -263,12 +262,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 {
@@ -287,7 +289,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;
@@ -311,7 +315,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;
@@ -325,7 +331,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);
}
}
}
@@ -333,7 +340,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;
@@ -347,7 +356,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);
}
}
}
@@ -356,7 +367,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;
@@ -366,7 +379,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);
}
}
}
@@ -375,22 +390,30 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie
case CODE_RESET_COUNTER: {
assertTokenNotArray("Reset counter", token);
assertTokenNotNamed("Reset counter", token);
- assertTokenDoesntHaveExtraData("Reset counter", token);
+ assertTokenHasNotExtraData("Reset counter", token);
}
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);
}
}
@@ -400,30 +423,35 @@ 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, token.getArraySizeAsInt());
+ offset += writePackedInt(out, fixedArraySize);
}
}
@@ -438,31 +466,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
@@ -474,6 +508,13 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie
.build();
}
+ private static void assertTokenHasNotExtraData(final String fieldType,
+ final JBBPToken token) {
+ if (token.getFieldTypeParameters().getExtraData() != null) {
+ throw new JBBPCompilationException('\'' + fieldType + "' has extra value", token);
+ }
+ }
+
/**
* The Method checks a value for negative.
*
@@ -483,7 +524,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);
}
}
@@ -496,7 +539,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);
}
}
@@ -510,11 +554,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));
@@ -542,7 +590,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: {
@@ -552,50 +601,72 @@ 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);
- if ("skip".equals(name) || "val".equals(name)) {
- result |= CODE_SKIP;
- } else if ("align".equals(name)) {
- result |= CODE_ALIGN;
- } else if ("bit".equals(name)) {
- result |= CODE_BIT;
- } else if ("var".equals(name)) {
- result |= CODE_VAR;
- } else if ("bool".equals(name) || JBBPFieldString.TYPE_NAME.equals(name)) {
- result |= CODE_BOOL;
- } else if ("ubyte".equals(name)) {
- result |= CODE_UBYTE;
- } else if ("byte".equals(name)) {
- result |= CODE_BYTE;
- } else if ("ushort".equals(name)) {
- result |= CODE_USHORT;
- } else if ("short".equals(name)) {
- result |= CODE_SHORT;
- } else if ("int".equals(name) || JBBPFieldFloat.TYPE_NAME.equals(name)) {
- result |= CODE_INT;
- } else if ("long".equals(name) || JBBPFieldDouble.TYPE_NAME.equals(name)) {
- result |= CODE_LONG;
- } else if ("reset$$".equals(name)) {
- result |= CODE_RESET_COUNTER;
- } else {
- boolean unsupportedType = true;
- if (customTypeFieldProcessor != null) {
- for (final String s : customTypeFieldProcessor.getCustomFieldTypes()) {
- if (name.equals(s)) {
- result |= CODE_CUSTOMTYPE;
- unsupportedType = false;
- break;
+ switch (name) {
+ case "skip":
+ case "val":
+ result |= CODE_SKIP;
+ break;
+ case "align":
+ result |= CODE_ALIGN;
+ break;
+ case "bit":
+ result |= CODE_BIT;
+ break;
+ case "var":
+ result |= CODE_VAR;
+ break;
+ case "bool":
+ case JBBPFieldString.TYPE_NAME:
+ result |= CODE_BOOL;
+ break;
+ case "ubyte":
+ result |= CODE_UBYTE;
+ break;
+ case "byte":
+ case JBBPFieldUInt.TYPE_NAME:
+ result |= CODE_BYTE;
+ break;
+ case "ushort":
+ result |= CODE_USHORT;
+ break;
+ case "short":
+ result |= CODE_SHORT;
+ break;
+ case "int":
+ case JBBPFieldFloat.TYPE_NAME:
+ result |= CODE_INT;
+ break;
+ case "long":
+ case JBBPFieldDouble.TYPE_NAME:
+ result |= CODE_LONG;
+ break;
+ case "reset$$":
+ result |= CODE_RESET_COUNTER;
+ break;
+ default:
+ boolean unsupportedType = true;
+ if (customTypeFieldProcessor != null) {
+ for (final String s : customTypeFieldProcessor.getCustomFieldTypes()) {
+ if (name.equals(s)) {
+ result |= CODE_CUSTOMTYPE;
+ unsupportedType = false;
+ break;
+ }
}
}
- }
- if (unsupportedType) {
- throw new JBBPCompilationException("Unsupported type [" + descriptor.getTypeName() + ']', token);
- }
+ if (unsupportedType) {
+ throw new JBBPCompilationException(
+ "Unsupported type [" + descriptor.getTypeName() + ']', token);
+ }
+ break;
}
}
break;
@@ -604,7 +675,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;
}
@@ -643,7 +715,7 @@ private static final class StructStackItem {
private final int namedFieldCounter;
/**
- * Flag shows that the structure is array which shoukd be read till end of stream
+ * Flag shows that the structure is array which should be read till end of stream
*/
private final boolean arrayToReadTillEndOfStream;
@@ -654,11 +726,13 @@ private static final class StructStackItem {
* start
* @param startStructureOffset the offset of the start structure byte-code
* instruction
- * @param arrayToReadTillEnd if true then it is array to read till end
+ * @param arrayToReadTillEnd if true then it is an array to read till end
* @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..5bfe4be5 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,12 @@
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 +38,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 +59,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--) {
@@ -73,30 +74,36 @@ public static JBBPNamedFieldInfo findForFieldPath(final String fieldPath, final
}
/**
- * Check a field in a compiled list defined by its named field info, that the field is not an array and it is not inside a structure array.
+ * Check a field in a compiled list defined by it's named field info, that the field is not an array and it is not inside a structure array.
*
* @param fieldToCheck a named field info to be checked, must not be null
* @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
- final String[] splittedFieldPath = JBBPUtils.splitString(fieldToCheck.getFieldPath(), '.');
+ final String[] splitFieldPath = JBBPUtils.splitString(fieldToCheck.getFieldPath(), '.');
final StringBuilder fieldPath = new StringBuilder();
// process till the field name because we have already checked the field
- for (int i = 0; i < splittedFieldPath.length - 1; i++) {
+ for (int i = 0; i < splitFieldPath.length - 1; i++) {
if (fieldPath.length() != 0) {
fieldPath.append('.');
}
- fieldPath.append(splittedFieldPath[i]);
- final JBBPNamedFieldInfo structureEnd = JBBPCompilerUtils.findForFieldPath(fieldPath.toString(), namedFieldList);
+ fieldPath.append(splitFieldPath[i]);
+ 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..59bb84f8 100644
--- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPNamedFieldInfo.java
+++ b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPNamedFieldInfo.java
@@ -17,12 +17,11 @@
package com.igormaznitsa.jbbp.compiler;
import com.igormaznitsa.jbbp.utils.JBBPUtils;
-
import java.io.Serializable;
/**
* The Class describes a named field info item. Such objects are presented
- * inside of compiled blocks only for fields which have names.
+ * inside compiled blocks only for fields which have names.
*
* @since 1.0
*/
@@ -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 aac9508c..5ab3512b 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
@@ -68,7 +68,6 @@ protected boolean isFlagSkipRemainingFieldsIfEOF() {
*
* @return the instance of the visitor, must not be null
*/
- @SuppressWarnings("unchecked")
public final CompiledBlockVisitor visit() {
this.visitStart();
@@ -89,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;
}
@@ -103,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): {
@@ -114,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: {
@@ -133,10 +139,12 @@ 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, name, evaluator);
+ visitValField(theOffset, byteOrder, name, evaluator);
} else {
throw new Error("Unexpected code:" + theCode);
}
@@ -147,8 +155,11 @@ public final CompiledBlockVisitor visit() {
break;
case JBBPCompiler.CODE_BIT: {
- final JBBPIntegerValueEvaluator numberOfBits = extraFieldNumAsExpr ? extraFieldValueEvaluator : new IntConstValueEvaluator(JBBPUtils.unpackInt(compiledData, positionAtCompiledBlock));
- visitBitField(theOffset, name, numberOfBits, arraySizeEvaluator);
+ final JBBPIntegerValueEvaluator numberOfBits =
+ extraFieldNumAsExpr ? extraFieldValueEvaluator : new IntConstValueEvaluator(
+ JBBPUtils.unpackInt(compiledData, positionAtCompiledBlock));
+ visitBitField(theOffset, byteOrder, name, readWholeStream, numberOfBits,
+ arraySizeEvaluator);
}
break;
@@ -159,12 +170,13 @@ 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;
case JBBPCompiler.CODE_STRUCT_START: {
- visitStructureStart(theOffset, name, arraySizeEvaluator);
+ visitStructureStart(theOffset, byteOrder, readWholeStream, name, arraySizeEvaluator);
}
break;
@@ -175,15 +187,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:
@@ -206,18 +226,23 @@ 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.
+ * Visit field contains virtual field defined through VAL type.
*
* @param offsetInCompiledBlock offset in the compiled block
+ * @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, JBBPNamedFieldInfo nameFieldInfo, JBBPIntegerValueEvaluator expression) {
+ public void visitValField(int offsetInCompiledBlock,
+ JBBPByteOrder byteOrder,
+ JBBPNamedFieldInfo nameFieldInfo,
+ JBBPIntegerValueEvaluator expression) {
}
/**
@@ -227,7 +252,7 @@ public void visitValField(int offsetInCompiledBlock, JBBPNamedFieldInfo nameFiel
* @param primitiveType the primitive type
* @param nullableNameFieldInfo field info, null if the field is anonymous one
* @param byteOrder byte order for the field, must not be null
- * @param readWholeStreamAsArray if true then it is array with unknown size till the stream end
+ * @param readWholeStreamAsArray if true then it is an array with unknown size till the stream end
* @param altFieldType flag shows that field type is alternative one, INT should be recognized as FLOAT and LONG as DOUBLE and BOOL as STRING
* @param nullableArraySize array size if the field is array, null if the field is not array or variable length array
* @see JBBPCompiler#CODE_BYTE
@@ -239,37 +264,106 @@ public void visitValField(int offsetInCompiledBlock, JBBPNamedFieldInfo nameFiel
* @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) {
}
/**
* Visit a variable field (which is defined with var data type)
*
- * @param offsetInCompiledBlock offset in the compiled block
- * @param nullableNameFieldInfo field info, null if the field is anonymous one
- * @param byteOrder byte order for the field, must not be null
- * @param readWholeStreamIntoArray true if whole stream should be read as array of var type, false otherwise
- * @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
+ * @param offsetInCompiledBlock offset in the compiled block
+ * @param nullableNameFieldInfo field info, null if the field is anonymous one
+ * @param byteOrder byte order for the field, must not be null
+ * @param readWholeStream true if whole stream should be read as array of var type, false otherwise
+ * @param nullableArraySize if not null then evaluator of array size to be read from stream
+ * @param extraDataValue 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 readWholeStream,
+ JBBPIntegerValueEvaluator nullableArraySize,
+ JBBPIntegerValueEvaluator extraDataValue) {
}
- public void visitCustomField(int offsetInCompiledBlock, JBBPFieldTypeParameterContainer notNullFieldType, JBBPNamedFieldInfo nullableNameFieldInfo, JBBPByteOrder byteOrder, boolean readWholeStream, JBBPIntegerValueEvaluator nullableArraySizeEvaluator, JBBPIntegerValueEvaluator extraDataValueEvaluator) {
+ /**
+ * Visit a custom type field.
+ *
+ * @param offsetInCompiledBlock offset in the compiled block
+ * @param notNullFieldType field type info, must not be null
+ * @param nullableNameFieldInfo field info, null if the field is anonymous one
+ * @param byteOrder byte order for the field, must not be null
+ * @param readWholeStream true if whole stream should be read as array of var type, false otherwise
+ * @param nullableArraySize if not null then evaluator of array size to be read from stream
+ * @param extraDataValue if not null then extra data evaluator for the var field
+ */
+ public void visitCustomField(int offsetInCompiledBlock,
+ JBBPFieldTypeParameterContainer notNullFieldType,
+ JBBPNamedFieldInfo nullableNameFieldInfo,
+ JBBPByteOrder byteOrder,
+ boolean readWholeStream,
+ JBBPIntegerValueEvaluator nullableArraySize,
+ JBBPIntegerValueEvaluator extraDataValue) {
}
- public void visitBitField(int offsetInCompiledBlock, JBBPNamedFieldInfo nullableNameFieldInfo, JBBPIntegerValueEvaluator notNullFieldSize, JBBPIntegerValueEvaluator nullableArraySize) {
+ /**
+ * Visit a custom type field.
+ *
+ * @param offsetInCompiledBlock offset in the compiled block
+ * @param byteOrder byte order for the field, must not be null
+ * @param nullableNameFieldInfo field info, null if the field is anonymous one
+ * @param readWholeStream true if whole stream should be read as array of var type, false otherwise
+ * @param notNullFieldSize evaluator to calculate size of the field, must not be null
+ * @param nullableArraySize if not null then evaluator of array size to be read from stream
+ */
+ public void visitBitField(int offsetInCompiledBlock,
+ JBBPByteOrder byteOrder,
+ JBBPNamedFieldInfo nullableNameFieldInfo,
+ boolean readWholeStream,
+ JBBPIntegerValueEvaluator notNullFieldSize,
+ JBBPIntegerValueEvaluator nullableArraySize) {
}
- public void visitStructureStart(int offsetInCompiledBlock, JBBPNamedFieldInfo nullableNameFieldInfo, JBBPIntegerValueEvaluator nullableArraySize) {
+ /**
+ * Visit a structure field.
+ *
+ * @param offsetInCompiledBlock offset in the compiled block
+ * @param byteOrder byte order for the field, must not be null
+ * @param readWholeStream true if whole stream should be read as array of var type, false otherwise
+ * @param nullableNameFieldInfo field info, null if the field is anonymous one
+ * @param nullableArraySize if not null then evaluator of array size to be read from stream
+ */
+ public void visitStructureStart(int offsetInCompiledBlock,
+ JBBPByteOrder byteOrder,
+ boolean readWholeStream,
+ JBBPNamedFieldInfo nullableNameFieldInfo,
+ JBBPIntegerValueEvaluator nullableArraySize) {
}
- public void visitStructureEnd(int offsetInCompiledBlock, JBBPNamedFieldInfo nullableNameFieldInfo) {
+ /**
+ * End visit of a structure
+ *
+ * @param offsetInCompiledBlock offset in the compiled block
+ * @param nullableNameFieldInfo field info, null if the field is anonymous one
+ */
+ public void visitStructureEnd(int offsetInCompiledBlock,
+ JBBPNamedFieldInfo nullableNameFieldInfo) {
}
+ /**
+ * Called before visit of each item.
+ */
public void visitStart() {
}
+ /**
+ * Called after visit each item.
+ */
public void visitEnd() {
}
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..2a140524 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
@@ -26,7 +26,7 @@
*
* @since 1.3.0
*/
-final class IntConstValueEvaluator implements JBBPIntegerValueEvaluator {
+public final class IntConstValueEvaluator implements JBBPIntegerValueEvaluator {
private static final long serialVersionUID = 4640385518512384490L;
@@ -40,12 +40,20 @@ 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/JBBPToJava6Converter.java b/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJava6Converter.java
deleted file mode 100644
index cc216e93..00000000
--- a/jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJava6Converter.java
+++ /dev/null
@@ -1,1392 +0,0 @@
-/*
- * Copyright 2017 Igor Maznitsa.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.igormaznitsa.jbbp.compiler.conversion;
-
-import com.igormaznitsa.jbbp.JBBPParser;
-import com.igormaznitsa.jbbp.compiler.JBBPNamedFieldInfo;
-import com.igormaznitsa.jbbp.compiler.tokenizer.JBBPFieldTypeParameterContainer;
-import com.igormaznitsa.jbbp.compiler.varlen.JBBPIntegerValueEvaluator;
-import com.igormaznitsa.jbbp.io.JBBPBitNumber;
-import com.igormaznitsa.jbbp.io.JBBPByteOrder;
-import com.igormaznitsa.jbbp.utils.JavaSrcTextBuffer;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import static com.igormaznitsa.jbbp.compiler.JBBPCompiler.*;
-
-/**
- * Converter to produce Java class sources (1.6+) from JBBPParser. If a parser contains variable field, custom fields or external
- * values in expressions then the result class will be abstract one and its
- * abstract methods must be implemented in successor.
- *
- * @since 1.3.0
- */
-@SuppressWarnings("SpellCheckingInspection")
-public final class JBBPToJava6Converter extends CompiledBlockVisitor {
-
- private static final int FLAG_DETECTED_CUSTOM_FIELDS = 1;
- private static final int FLAG_DETECTED_EXTERNAL_FIELDS = 2;
- private static final int FLAG_DETECTED_VAR_FIELDS = 4;
- private static final int FLAG_ADD_ASSERT_NOT_NEGATIVE_EXPR = 8;
-
- /**
- * 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.
- */
- private final AtomicInteger flagSet = new AtomicInteger();
-
- /**
- * Map of detected named fields to their name field info object.
- */
- private final Map foundNamedFields = new HashMap();
- /**
- * Counter of anonymous fields to generate unique names.
- */
- private final AtomicInteger anonymousFieldCounter = new AtomicInteger();
- /**
- * Counter of special fields to generate their unique names.
- */
- private final AtomicInteger specialFieldsCounter = new AtomicInteger();
- /**
- * The List implements stack of current processing structures. The 0 contains
- * the root.
- */
- private final List structStack = new ArrayList();
- /**
- * Text buffer for the special section.
- */
- private final JavaSrcTextBuffer specialSection = new JavaSrcTextBuffer();
- /**
- * Text buffer for the special methods.
- */
- private final JavaSrcTextBuffer specialMethods = new JavaSrcTextBuffer();
- /**
- * The Builder instance to be used as the data source for the parser. It must
- * not be null.
- */
- private final Builder builder;
- /**
- * The Field contains conversion result after process end.
- */
- private String result;
-
- /**
- * The Only Constructor based on a builder instance.
- *
- * @param builder a builder instance, must not be null
- */
- private JBBPToJava6Converter(final Builder builder) {
- super(builder.parserFlags, builder.srcParser.getCompiledBlock());
- this.builder = builder;
- }
-
- /**
- * Make new builder.
- *
- * @param parser parser instance to be used as the base for translation, must not be
- * null
- * @return the new builder instance, must not be null.
- */
- public static Builder makeBuilder(final JBBPParser parser) {
- return new Builder(parser);
- }
-
- /**
- * Do conversion.
- *
- * @return generated class with needed parameters as text, must not be null.
- */
- public String convert() {
- return JBBPToJava6Converter.class.cast(this.visit()).getResult();
- }
-
- private void registerNamedField(final JBBPNamedFieldInfo fieldInfo, final FieldType fieldType) {
- if (fieldInfo != null) {
- if (this.foundNamedFields.containsKey(fieldInfo)) {
- throw new Error("Detected duplication of named field : " + fieldInfo);
- }
- this.foundNamedFields.put(fieldInfo, new NamedFieldInfo(fieldInfo, this.getCurrentStruct(), fieldType));
- }
- }
-
- private Struct getCurrentStruct() {
- return this.structStack.get(0);
- }
-
- @Override
- public void visitStart() {
- this.flagSet.set(0);
- this.foundNamedFields.clear();
- this.anonymousFieldCounter.set(1234);
- this.specialFieldsCounter.set(1);
- this.specialSection.clean();
- this.structStack.clear();
- this.specialMethods.clean();
-
- this.structStack.add(new Struct(null, this.builder.mainClassName, "public"));
- }
-
- /**
- * Get result of the conversion process.
- *
- * @return the result, it will not be null if the process completed without
- * errors.
- */
- public String getResult() {
- return this.result;
- }
-
- @Override
- public void visitEnd() {
- final JavaSrcTextBuffer buffer = new JavaSrcTextBuffer();
-
- if (this.builder.headComment != null) {
- buffer.printCommentMultiLinesWithIndent(this.builder.headComment);
- }
-
- if (this.builder.mainClassPackage != null && this.builder.mainClassPackage.length() != 0) {
- buffer.print("package ").print(this.builder.mainClassPackage).println(";");
- }
-
- buffer.println();
-
- buffer.println("import com.igormaznitsa.jbbp.model.*;");
- buffer.println("import com.igormaznitsa.jbbp.io.*;");
- buffer.println("import com.igormaznitsa.jbbp.compiler.*;");
- buffer.println("import com.igormaznitsa.jbbp.compiler.tokenizer.*;");
- buffer.println("import java.io.IOException;");
- buffer.println("import java.util.*;");
-
- 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);
-
- 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.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;");
- }
-
- 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);");
- }
-
- 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.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 extends JBBPAbstractField> 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.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 extends JBBPAbstractField> 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; }");
- }
-
- 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;
-
- buffer.printJavaDocLinesWithIndent("Generated from JBBP script by internal JBBP Class Source Generator");
-
- this.structStack.get(0).write(buffer,
- hasAbstractMethods ? "abstract" : null,
- this.builder.superClass,
- this.builder.mainClassImplements,
- this.builder.mapSubClassesInterfaces,
- this.builder.mapSubClassesSuperclasses,
- this.specialSection.toString(),
- specialMethodsText.length() == 0 ? null : specialMethodsText,
- this.builder.mainClassCustomText,
- true
- );
-
- this.result = buffer.toString();
- }
-
- @Override
- public void visitStructureStart(final int offsetInCompiledBlock, final JBBPNamedFieldInfo nullableNameFieldInfo, final JBBPIntegerValueEvaluator nullableArraySize) {
- final String structName = (nullableNameFieldInfo == null ? makeAnonymousStructName() : 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 fieldModifier = makeModifier(nullableNameFieldInfo);
-
- final String toType;
- if (this.builder.generateFields) {
- toType = "";
- } else {
- toType = '(' + structBaseTypeName + ')';
- }
-
- final String structType;
- if (nullableArraySize == null) {
- structType = structBaseTypeName;
- if (this.builder.generateFields) {
- this.getCurrentStruct().getFields().indent().print(fieldModifier).printf(" %s %s;", structType, structName).println();
- }
-
- processSkipRemainingFlag();
- processSkipRemainingFlagForWriting("this." + structName);
-
- this.getCurrentStruct().getReadFunc().indent()
- .printf("if ( this.%1$s == null) { this.%1$s = new %2$s(%3$s);}", structName, structType, this.structStack.size() == 1 ? "this" : "this." + NAME_ROOT_STRUCT)
- .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) {
- this.getCurrentStruct().getFields().indent().print(fieldModifier).printf(" %s %s;", structType, structName).println();
- }
- 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",
- structName,
- arraySizeIn,
- structBaseTypeName,
- (this.structStack.size() == 1 ? "this" : NAME_ROOT_STRUCT),
- NAME_INPUT_STREAM);
- this.getCurrentStruct().getWriteFunc().indent().printf("for (int I=0;I stack = new ArrayList