Skip to content

Commit 8594b9a

Browse files
committed
added type 'val' to make virtual field
1 parent 6b15ca7 commit 8594b9a

File tree

8 files changed

+181
-63
lines changed

8 files changed

+181
-63
lines changed

jbbp/src/main/java/com/igormaznitsa/jbbp/JBBPParser.java

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ private List<JBBPAbstractField> parseStruct(final JBBPBitInputStream inStream, f
271271
final int ec = wideCode ? compiled[positionAtCompiledBlock.getAndIncrement()] & 0xFF : 0;
272272
final boolean extraFieldNumAsExpr = (ec & JBBPCompiler.EXT_FLAG_EXTRA_AS_EXPRESSION) != 0;
273273
final int code = (ec << 8) | c;
274-
final boolean fieldIsFloatDoubleOrString = (ec & JBBPCompiler.EXT_FLAG_EXTRA_AS_FLOAT_DOUBLE_OR_STRING) != 0;
274+
final boolean fieldTypeDiff = (ec & JBBPCompiler.EXT_FLAG_EXTRA_DIFF_TYPE) != 0;
275275

276276
final JBBPNamedFieldInfo name = (code & JBBPCompiler.FLAG_NAMED) == 0 ? null : compiledBlock.getNamedFields()[positionAtNamedFieldList.getAndIncrement()];
277277
final JBBPByteOrder byteOrder = (code & JBBPCompiler.FLAG_LITTLE_ENDIAN) == 0 ? JBBPByteOrder.BIG_ENDIAN : JBBPByteOrder.LITTLE_ENDIAN;
@@ -356,10 +356,16 @@ private List<JBBPAbstractField> parseStruct(final JBBPBitInputStream inStream, f
356356
break;
357357
case JBBPCompiler.CODE_SKIP: {
358358
final int skipByteNumber = extraFieldNumAsExpr ? extraFieldNumExprResult : JBBPUtils.unpackInt(compiled, positionAtCompiledBlock);
359-
if (resultNotIgnored && skipByteNumber > 0) {
360-
final long skippedBytes = inStream.skip(skipByteNumber);
361-
if (skippedBytes != skipByteNumber) {
362-
throw new EOFException("Can't skip " + skipByteNumber + " byte(s), skipped only " + skippedBytes + " byte(s)");
359+
if (resultNotIgnored) {
360+
if (fieldTypeDiff) {
361+
singleAtomicField = new JBBPFieldInt(name, skipByteNumber);
362+
} else {
363+
if (skipByteNumber > 0) {
364+
final long skippedBytes = inStream.skip(skipByteNumber);
365+
if (skippedBytes != skipByteNumber) {
366+
throw new EOFException("Can't skip " + skipByteNumber + " byte(s), skipped only " + skippedBytes + " byte(s)");
367+
}
368+
}
363369
}
364370
}
365371
}
@@ -438,9 +444,9 @@ private List<JBBPAbstractField> parseStruct(final JBBPBitInputStream inStream, f
438444
case JBBPCompiler.CODE_BOOL: {
439445
if (resultNotIgnored) {
440446
if (arrayLength < 0) {
441-
singleAtomicField = fieldIsFloatDoubleOrString ? new JBBPFieldString(name, inStream.readString(byteOrder)) : new JBBPFieldBoolean(name, inStream.readBoolean());
447+
singleAtomicField = fieldTypeDiff ? new JBBPFieldString(name, inStream.readString(byteOrder)) : new JBBPFieldBoolean(name, inStream.readBoolean());
442448
} else {
443-
structureFields.add(fieldIsFloatDoubleOrString ?
449+
structureFields.add(fieldTypeDiff ?
444450
new JBBPFieldArrayString(name, inStream.readStringArray(wholeStreamArray ? -1 : arrayLength, byteOrder)) :
445451
new JBBPFieldArrayBoolean(name, inStream.readBoolArray(wholeStreamArray ? -1 : arrayLength))
446452
);
@@ -451,9 +457,9 @@ private List<JBBPAbstractField> parseStruct(final JBBPBitInputStream inStream, f
451457
case JBBPCompiler.CODE_INT: {
452458
if (resultNotIgnored) {
453459
if (arrayLength < 0) {
454-
singleAtomicField = fieldIsFloatDoubleOrString ? new JBBPFieldFloat(name, inStream.readFloat(byteOrder)) : new JBBPFieldInt(name, inStream.readInt(byteOrder));
460+
singleAtomicField = fieldTypeDiff ? new JBBPFieldFloat(name, inStream.readFloat(byteOrder)) : new JBBPFieldInt(name, inStream.readInt(byteOrder));
455461
} else {
456-
structureFields.add(fieldIsFloatDoubleOrString ?
462+
structureFields.add(fieldTypeDiff ?
457463
new JBBPFieldArrayFloat(name, inStream.readFloatArray(wholeStreamArray ? -1 : arrayLength, byteOrder)) :
458464
new JBBPFieldArrayInt(name, inStream.readIntArray(wholeStreamArray ? -1 : arrayLength, byteOrder))
459465
);
@@ -464,9 +470,9 @@ private List<JBBPAbstractField> parseStruct(final JBBPBitInputStream inStream, f
464470
case JBBPCompiler.CODE_LONG: {
465471
if (resultNotIgnored) {
466472
if (arrayLength < 0) {
467-
singleAtomicField = fieldIsFloatDoubleOrString ? new JBBPFieldDouble(name, inStream.readDouble(byteOrder)) : new JBBPFieldLong(name, inStream.readLong(byteOrder));
473+
singleAtomicField = fieldTypeDiff ? new JBBPFieldDouble(name, inStream.readDouble(byteOrder)) : new JBBPFieldLong(name, inStream.readLong(byteOrder));
468474
} else {
469-
structureFields.add(fieldIsFloatDoubleOrString ?
475+
structureFields.add(fieldTypeDiff ?
470476
new JBBPFieldArrayDouble(name, inStream.readDoubleArray(wholeStreamArray ? -1 : arrayLength, byteOrder)) :
471477
new JBBPFieldArrayLong(name, inStream.readLongArray(wholeStreamArray ? -1 : arrayLength, byteOrder))
472478
);

jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/JBBPCompiler.java

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,50 @@ public final class JBBPCompiler {
143143
public static final int EXT_FLAG_EXTRA_AS_EXPRESSION = 0x02;
144144

145145
/**
146-
* The Flag shows that the type of data should be recognized as float (if int) or as double (if long).
146+
* The Flag shows that the type of data should be recognized differently.
147+
* as float (if int), as double (if long), as virtual value (if skip).
147148
*
148149
* @since 1.4.0
149150
*/
150-
public static final int EXT_FLAG_EXTRA_AS_FLOAT_DOUBLE_OR_STRING = 0x04;
151+
public static final int EXT_FLAG_EXTRA_DIFF_TYPE = 0x04;
151152

152153
public static JBBPCompiledBlock compile(final String script) throws IOException {
153154
return compile(script, null);
154155
}
155156

157+
private static void assertTokenNotArray(final String fieldType, final JBBPToken token) {
158+
if (token.getArraySizeAsString() != null) {
159+
final String fieldName = token.getFieldName() == null ? "<ANONYM>" : token.getFieldName();
160+
throw new JBBPCompilationException('\'' + fieldType + "' can't be array (" + fieldName + ')', token);
161+
}
162+
}
163+
164+
private static void assertTokenNamed(final String fieldType, final JBBPToken token) {
165+
if (token.getFieldName() == null) {
166+
final String fieldName = token.getFieldName() == null ? "<ANONYM>" : token.getFieldName();
167+
throw new JBBPCompilationException('\'' + fieldType + "' must be named (" + fieldName + ')', token);
168+
}
169+
}
170+
171+
private static void assertTokenNotNamed(final String fieldType, final JBBPToken token) {
172+
if (token.getFieldName() != null) {
173+
final String fieldName = token.getFieldName() == null ? "<ANONYM>" : token.getFieldName();
174+
throw new JBBPCompilationException('\'' + fieldType + "' must not be named (" + fieldName + ')', token);
175+
}
176+
}
177+
178+
private static void assertTokenHasExtraData(final String fieldType, final JBBPToken token) {
179+
if (token.getFieldTypeParameters().getExtraData() == null) {
180+
throw new JBBPCompilationException('\'' + fieldType + "\' doesn't have extra value", token);
181+
}
182+
}
183+
184+
private static void assertTokenDoesntHaveExtraData(final String fieldType, final JBBPToken token) {
185+
if (token.getFieldTypeParameters().getExtraData() != null) {
186+
throw new JBBPCompilationException('\'' + fieldType + "\' has extra value", token);
187+
}
188+
}
189+
156190
/**
157191
* Compile a text script into its byte code representation/
158192
*
@@ -212,7 +246,7 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie
212246
}
213247

214248
final boolean extraFieldNumericDataAsExpression = ((code >>> 8) & EXT_FLAG_EXTRA_AS_EXPRESSION) != 0;
215-
final boolean fieldIsFloatOrDouble = ((code >>> 8) & EXT_FLAG_EXTRA_AS_FLOAT_DOUBLE_OR_STRING) != 0;
249+
final boolean fieldTypeDiff = ((code >>> 8) & EXT_FLAG_EXTRA_DIFF_TYPE) != 0;
216250

217251
switch (code & 0xF) {
218252
case CODE_BOOL:
@@ -249,11 +283,13 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie
249283
}
250284
break;
251285
case CODE_SKIP: {
252-
if (token.getArraySizeAsString() != null) {
253-
throw new JBBPCompilationException("'skip' can't be array", token);
254-
}
255-
if (token.getFieldName() != null) {
256-
throw new JBBPCompilationException("'skip' must not be named", token);
286+
if (fieldTypeDiff) {
287+
assertTokenNotArray("val", token);
288+
assertTokenNamed("val", token);
289+
assertTokenHasExtraData("val", token);
290+
} else {
291+
assertTokenNotArray("skip", token);
292+
assertTokenNotNamed("skip", token);
257293
}
258294
if (extraFieldNumericDataAsExpression) {
259295
varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance().make(token.getFieldTypeParameters().getExtraDataExpression(), namedFields, out.toByteArray()));
@@ -265,21 +301,19 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie
265301
} else {
266302
try {
267303
extraFieldNumberAsInt = Integer.parseInt(extraNumberAsStr);
268-
assertNonNegativeValue(extraFieldNumberAsInt, token);
269-
} catch (NumberFormatException ex) {
304+
if (!fieldTypeDiff) {
305+
assertNonNegativeValue(extraFieldNumberAsInt, token);
306+
}
307+
} catch (final NumberFormatException ex) {
270308
extraFieldNumberAsInt = -1;
271309
}
272310
}
273311
}
274312
}
275313
break;
276314
case CODE_ALIGN: {
277-
if (token.getArraySizeAsString() != null) {
278-
throw new JBBPCompilationException("'align' can't be array", token);
279-
}
280-
if (token.getFieldName() != null) {
281-
throw new JBBPCompilationException("'align' must not be named", token);
282-
}
315+
assertTokenNotArray("align", token);
316+
assertTokenNotNamed("align", token);
283317

284318
if (extraFieldNumericDataAsExpression) {
285319
varLengthEvaluators.add(JBBPEvaluatorFactory.getInstance().make(token.getFieldTypeParameters().getExtraDataExpression(), namedFields, out.toByteArray()));
@@ -344,15 +378,9 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie
344378
}
345379
break;
346380
case CODE_RESET_COUNTER: {
347-
if (token.getArraySizeAsString() != null) {
348-
throw new JBBPCompilationException("A Reset counter field can't be array", token);
349-
}
350-
if (token.getFieldName() != null) {
351-
throw new JBBPCompilationException("A Reset counter field can't be named [" + token.getFieldName() + ']', token);
352-
}
353-
if (token.getFieldTypeParameters().getExtraData() != null) {
354-
throw new JBBPCompilationException("A Reset counter field doesn't use extra value [" + token.getFieldName() + ']', token);
355-
}
381+
assertTokenNotArray("Reset counter", token);
382+
assertTokenNotNamed("Reset counter", token);
383+
assertTokenDoesntHaveExtraData("Reset counter", token);
356384
}
357385
break;
358386
case CODE_STRUCT_START: {
@@ -519,11 +547,11 @@ private static int prepareCodeForToken(final JBBPToken token, final JBBPCustomFi
519547

520548
result |= token.getArraySizeAsString() == null ? 0 : (token.isVarArrayLength() ? FLAG_ARRAY | FLAG_WIDE | (EXT_FLAG_EXPRESSION_OR_WHOLESTREAM << 8) : FLAG_ARRAY);
521549
result |= hasExpressionAsExtraNumber ? FLAG_WIDE | (EXT_FLAG_EXTRA_AS_EXPRESSION << 8) : 0;
522-
result |= token.getFieldTypeParameters().isFloatDoubleOrString() ? FLAG_WIDE | (EXT_FLAG_EXTRA_AS_FLOAT_DOUBLE_OR_STRING << 8) : 0;
550+
result |= token.getFieldTypeParameters().isSpecialField() ? FLAG_WIDE | (EXT_FLAG_EXTRA_DIFF_TYPE << 8) : 0;
523551
result |= token.getFieldName() == null ? 0 : FLAG_NAMED;
524552

525553
final String name = descriptor.getTypeName().toLowerCase(Locale.ENGLISH);
526-
if ("skip".equals(name)) {
554+
if ("skip".equals(name) || "val".equals(name)) {
527555
result |= CODE_SKIP;
528556
} else if ("align".equals(name)) {
529557
result |= CODE_ALIGN;

jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/CompiledBlockVisitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public final CompiledBlockVisitor visit() {
8585
final int c = compiledData[positionAtCompiledBlock.getAndIncrement()] & 0xFF;
8686
final boolean wideCode = (c & JBBPCompiler.FLAG_WIDE) != 0;
8787
final int ec = wideCode ? compiledData[positionAtCompiledBlock.getAndIncrement()] & 0xFF : 0;
88-
final boolean isFloatDoubleOrStringField = (ec & JBBPCompiler.EXT_FLAG_EXTRA_AS_FLOAT_DOUBLE_OR_STRING) != 0;
88+
final boolean isFloatDoubleOrStringField = (ec & JBBPCompiler.EXT_FLAG_EXTRA_DIFF_TYPE) != 0;
8989
final boolean extraFieldNumAsExpr = (ec & JBBPCompiler.EXT_FLAG_EXTRA_AS_EXPRESSION) != 0;
9090
final int code = (ec << 8) | c;
9191

jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPFieldTypeParameterContainer.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,16 @@ public boolean hasExpressionAsExtraData() {
108108
}
109109

110110
/**
111-
* Check that the type is float, double or string.
111+
* Check that the type is a special one ('floatj', 'doublej', 'stringj' or 'value').
112112
*
113-
* @return true if the type is either float, double or string
113+
* @return true if the type is a special one
114114
* @see JBBPFieldFloat#TYPE_NAME
115115
* @see JBBPFieldDouble#TYPE_NAME
116116
* @see JBBPFieldString#TYPE_NAME
117117
* @since 1.4.0
118118
*/
119-
public boolean isFloatDoubleOrString() {
120-
return this.typeName.equals(JBBPFieldFloat.TYPE_NAME) || this.typeName.equals(JBBPFieldDouble.TYPE_NAME) || this.typeName.equals(JBBPFieldString.TYPE_NAME);
119+
public boolean isSpecialField() {
120+
return this.typeName.equals(JBBPFieldFloat.TYPE_NAME) || this.typeName.equals(JBBPFieldDouble.TYPE_NAME) || this.typeName.equals(JBBPFieldString.TYPE_NAME) || this.typeName.equals("val");
121121
}
122122

123123
@Override

jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/tokenizer/JBBPTokenizer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ public final class JBBPTokenizer implements Iterable<JBBPToken>, Iterator<JBBPTo
6868
GLOBAL_RESERVED_TYPE_NAMES.add("long");
6969
GLOBAL_RESERVED_TYPE_NAMES.add("align");
7070
GLOBAL_RESERVED_TYPE_NAMES.add("skip");
71+
GLOBAL_RESERVED_TYPE_NAMES.add("var");
72+
GLOBAL_RESERVED_TYPE_NAMES.add("val");
7173
GLOBAL_RESERVED_TYPE_NAMES.add("$");
7274
}
7375

0 commit comments

Comments
 (0)