@@ -254,9 +254,11 @@ public void visitEnd() {
254254 this .builder .superClass ,
255255 this .builder .mainClassImplements ,
256256 this .builder .mapSubClassesInterfaces ,
257+ this .builder .mapSubClassesSuperclasses ,
257258 this .specialSection .toString (),
258259 specialMethodsText .length () == 0 ? null : specialMethodsText ,
259- this .builder .mainClassCustomText
260+ this .builder .mainClassCustomText ,
261+ true
260262 );
261263
262264 this .result = buffer .toString ();
@@ -272,18 +274,27 @@ public void visitStructureStart(final int offsetInCompiledBlock, final JBBPNamed
272274
273275 final String fieldModifier = makeModifier (nullableNameFieldInfo );
274276
277+ final String toType ;
278+ if (this .builder .generateFields ) {
279+ toType = "" ;
280+ } else {
281+ toType = '(' +structBaseTypeName +')' ;
282+ }
283+
275284 final String structType ;
276285 if (nullableArraySize == null ) {
277286 structType = structBaseTypeName ;
278287 if (this .builder .generateFields ) {
279288 this .getCurrentStruct ().getFields ().indent ().print (fieldModifier ).printf (" %s %s;" , structType , structName ).println ();
280289 }
290+
281291 processSkipRemainingFlag ();
282292 processSkipRemainingFlagForWriting ("this." + structName );
293+
283294 this .getCurrentStruct ().getReadFunc ().indent ()
284295 .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 )
285- .printf (" this. %s.read(%s);%n" , structName , NAME_INPUT_STREAM );
286- this .getCurrentStruct ().getWriteFunc ().indent ().print (structName ).println (".write(Out);" );
296+ .printf (" %s.read(%s);%n" , toType . length () == 0 ? "this." + structName : '(' + toType + "this." + structName + ')' , NAME_INPUT_STREAM );
297+ this .getCurrentStruct ().getWriteFunc ().indent ().print (toType . length () == 0 ? structName : '(' + toType + structName + ')' ).println (".write(Out);" );
287298 } else {
288299 structType = structBaseTypeName + " []" ;
289300 if (this .builder .generateFields ) {
@@ -293,13 +304,18 @@ public void visitStructureStart(final int offsetInCompiledBlock, final JBBPNamed
293304 processSkipRemainingFlagForWriting ("this." + structName );
294305 if ("-1" .equals (arraySizeIn )) {
295306 this .getCurrentStruct ().getReadFunc ().indent ()
296- .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 );
297- this .getCurrentStruct ().getWriteFunc ().indent ().printf ("for (int I=0;I<this.%1$s.length;I++){ this.%1$s[I].write(%2$s); }%n" , structName , NAME_OUTPUT_STREAM );
307+ .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" ,
308+ structName ,
309+ arraySizeIn ,
310+ structBaseTypeName ,
311+ (this .structStack .size () == 1 ? "this" : NAME_ROOT_STRUCT ),
312+ NAME_INPUT_STREAM );
313+ this .getCurrentStruct ().getWriteFunc ().indent ().printf ("for (int I=0;I<this.%1$s.length;I++){ %2$s.write(%3$s); }%n" , structName , toType .length () == 0 ? "this." +structName + "[I]" : '(' + toType +"this." +structName + "[I])" , NAME_OUTPUT_STREAM );
298314 } else {
299315 this .getCurrentStruct ().getReadFunc ().indent ()
300316 .printf ("if (this.%1$s == null || this.%1$s.length != %2$s){ this.%1$s = new %3$s[%2$s]; for(int I=0;I<%2$s;I++){ this.%1$s[I] = new %3$s(%4$s);}}" , structName , arraySizeIn , structBaseTypeName , (this .structStack .size () == 1 ? "this" : "this." + NAME_ROOT_STRUCT ))
301- .printf ("for (int I=0;I<%2$s;I++){ this.%1$s[I].read(%3$s); }%n" , structName , arraySizeIn , NAME_INPUT_STREAM );
302- this .getCurrentStruct ().getWriteFunc ().indent ().printf ("for (int I=0;I<%2$s;I++){ this.%1$s[I].write(%3$s); }" , structName , arraySizeOut , NAME_OUTPUT_STREAM );
317+ .printf ("for (int I=0;I<%2$s;I++){ this.%1$s[I].read(%3$s); }%n" , toType + structName , arraySizeIn , NAME_INPUT_STREAM );
318+ this .getCurrentStruct ().getWriteFunc ().indent ().printf ("for (int I=0;I<%2$s;I++){ this.%1$s[I].write(%3$s); }" , toType + structName , arraySizeOut , NAME_OUTPUT_STREAM );
303319 }
304320 }
305321
@@ -951,6 +967,10 @@ public static final class Builder {
951967 * Interfaces to be implemented by generated subclasses, also getters return the interface type.
952968 */
953969 private final Map <String , String > mapSubClassesInterfaces = new HashMap <String , String >();
970+ /**
971+ * Superclasses to be extended by generated subclasses.
972+ */
973+ private final Map <String , String > mapSubClassesSuperclasses = new HashMap <String , String >();
954974 /**
955975 * The Package name for the result class.
956976 */
@@ -1021,6 +1041,22 @@ public Builder setMapSubClassesInterfaces(final Map<String, String> mapClassName
10211041 return this ;
10221042 }
10231043
1044+ /**
1045+ * Add superclasses to classes generated for inside structures, a structure class will extend mapped class.
1046+ *
1047+ * @param mapClassNameToSuperclasses map with structure path as the key and the interface name as value, it can be null. <b>Names of structures should be in the lower case form amd dot separated for their hierarchy. (example: "a.b.c")</b>
1048+ * @return the builder instance, must not be null
1049+ * @since 1.4.0
1050+ */
1051+ public Builder setMapSubClassesSuperclasses (final Map <String , String > mapClassNameToSuperclasses ) {
1052+ assertNonLocked ();
1053+ this .mapSubClassesSuperclasses .clear ();
1054+ if (mapClassNameToSuperclasses != null ) {
1055+ this .mapSubClassesSuperclasses .putAll (mapClassNameToSuperclasses );
1056+ }
1057+ return this ;
1058+ }
1059+
10241060 /**
10251061 * Set custom text, the text will be added into the end of the result class.
10261062 *
@@ -1203,7 +1239,17 @@ Struct findRoot() {
12031239 return this .parent .findRoot ();
12041240 }
12051241
1206- void write (final JavaSrcTextBuffer buffer , final String extraModifier , final String superClass , final Set <String > implementedInterfaces , final Map <String , String > mapStructInterfaces , final String commonSectionText , final String specialMethods , final String customText ) {
1242+ void write (
1243+ final JavaSrcTextBuffer buffer ,
1244+ final String extraModifier ,
1245+ final String superClass ,
1246+ final Set <String > implementedInterfaces ,
1247+ final Map <String , String > mapStructInterfaces ,
1248+ final Map <String , String > mapStructSuperclasses ,
1249+ final String commonSectionText ,
1250+ final String specialMethods ,
1251+ final String customText ,
1252+ final boolean useSuperclassForReadWrite ) {
12071253 final String interfaceForGetSet = mapStructInterfaces == null ? null : mapStructInterfaces .get (this .getPath ());
12081254
12091255 buffer .indent ().printf (
@@ -1221,7 +1267,7 @@ void write(final JavaSrcTextBuffer buffer, final String extraModifier, final Str
12211267 }
12221268
12231269 for (final Struct c : this .children ) {
1224- c .write (buffer , null , null , null , mapStructInterfaces , null , null , null );
1270+ c .write (buffer , null , mapStructSuperclasses . get ( c . getPath ()) , null , mapStructInterfaces , mapStructSuperclasses , null , null , null , false );
12251271 }
12261272 buffer .println ();
12271273
@@ -1245,7 +1291,7 @@ void write(final JavaSrcTextBuffer buffer, final String extraModifier, final Str
12451291
12461292 buffer .println ();
12471293
1248- buffer .indent ().printf ("public %s read(final JBBPBitInputStream In) throws IOException {%n" , superClass == null ? this . className : superClass );
1294+ buffer .indent ().printf ("public %s read(final JBBPBitInputStream In) throws IOException {%n" , useSuperclassForReadWrite && superClass != null ? superClass : this . className );
12491295 buffer .incIndent ();
12501296 buffer .printLinesWithIndent (this .readFunc .toString ());
12511297 buffer .indent ().println ("return this;" );
@@ -1254,7 +1300,7 @@ void write(final JavaSrcTextBuffer buffer, final String extraModifier, final Str
12541300
12551301 buffer .println ();
12561302
1257- buffer .indent ().printf ("public %s write(final JBBPBitOutputStream Out) throws IOException {%n" , superClass == null ? this . className : superClass );
1303+ buffer .indent ().printf ("public %s write(final JBBPBitOutputStream Out) throws IOException {%n" , useSuperclassForReadWrite && superClass != null ? superClass : this . className );
12581304 buffer .incIndent ();
12591305 buffer .printLinesWithIndent (this .writeFunc .toString ());
12601306 buffer .indent ().println ("return this;" );
0 commit comments