@@ -837,11 +837,32 @@ private void generateDataEncodeMethods(
837837 byteOrderStr ,
838838 indent );
839839
840- if (null = = characterEncoding )
840+ if (null ! = characterEncoding )
841841 {
842- return ;
842+ generateCharArrayEncodeMethods (
843+ sb ,
844+ propertyName ,
845+ sizeOfLengthField ,
846+ maxLengthValue ,
847+ lengthType ,
848+ byteOrderStr ,
849+ characterEncoding ,
850+ className ,
851+ indent );
843852 }
853+ }
844854
855+ private void generateCharArrayEncodeMethods (
856+ final StringBuilder sb ,
857+ final String propertyName ,
858+ final int sizeOfLengthField ,
859+ final int maxLengthValue ,
860+ final PrimitiveType lengthType ,
861+ final String byteOrderStr ,
862+ final String characterEncoding ,
863+ final String className ,
864+ final String indent )
865+ {
845866 if (characterEncoding .contains ("ASCII" ))
846867 {
847868 sb .append (String .format ("\n " +
@@ -864,6 +885,32 @@ private void generateDataEncodeMethods(
864885 maxLengthValue ,
865886 sizeOfLengthField ,
866887 generatePut (lengthType , "limit" , "length" , byteOrderStr )));
888+
889+ sb .append (String .format ("\n " +
890+ indent + " public %1$s %2$s(final CharSequence value)\n " +
891+ indent + " {\n " +
892+ indent + " final int length = value.length();\n " +
893+ indent + " if (length > %3$d)\n " +
894+ indent + " {\n " +
895+ indent + " throw new IllegalStateException(\" length > maxValue for type: \" + length);\n " +
896+ indent + " }\n \n " +
897+ indent + " final int headerLength = %4$d;\n " +
898+ indent + " final int limit = parentMessage.limit();\n " +
899+ indent + " parentMessage.limit(limit + headerLength + length);\n " +
900+ indent + " %5$s;\n " +
901+ indent + " for (int i = 0; i < length; ++i)\n " +
902+ indent + " {\n " +
903+ indent + " final char charValue = value.charAt(i);\n " +
904+ indent + " final byte byteValue = charValue > 127 ? (byte)'?' : (byte)charValue;\n " +
905+ indent + " buffer.putByte(limit + headerLength + i, byteValue);\n " +
906+ indent + " }\n \n " +
907+ indent + " return this;\n " +
908+ indent + " }\n " ,
909+ className ,
910+ formatPropertyName (propertyName ),
911+ maxLengthValue ,
912+ sizeOfLengthField ,
913+ generatePut (lengthType , "limit" , "length" , byteOrderStr )));
867914 }
868915 else
869916 {
@@ -1054,12 +1101,13 @@ private void generateComposite(final List<Token> tokens) throws IOException
10541101 final StringBuilder sb = new StringBuilder ();
10551102 generateEncodingOffsetMethod (sb , propertyName , encodingToken .offset (), BASE_INDENT );
10561103 generateEncodingLengthMethod (sb , propertyName , encodingToken .encodedLength (), BASE_INDENT );
1104+ generateFieldSinceVersionMethod (sb , encodingToken , BASE_INDENT );
10571105
10581106 switch (encodingToken .signal ())
10591107 {
10601108 case ENCODING :
10611109 out .append (sb ).append (generatePrimitiveDecoder (
1062- true , encodingToken .name (), encodingToken , BASE_INDENT ));
1110+ true , encodingToken .name (), encodingToken , encodingToken , BASE_INDENT ));
10631111 break ;
10641112
10651113 case BEGIN_ENUM :
@@ -1477,19 +1525,24 @@ private static CharSequence generateEnumDeclaration(final String name, final Tok
14771525 }
14781526
14791527 private CharSequence generatePrimitiveDecoder (
1480- final boolean inComposite , final String propertyName , final Token token , final String indent )
1528+ final boolean inComposite ,
1529+ final String propertyName ,
1530+ final Token propertyToken ,
1531+ final Token encodingToken ,
1532+ final String indent )
14811533 {
14821534 final StringBuilder sb = new StringBuilder ();
14831535
1484- sb .append (generatePrimitiveFieldMetaData (propertyName , token , indent ));
1536+ sb .append (generatePrimitiveFieldMetaData (propertyName , encodingToken , indent ));
14851537
1486- if (token .isConstantEncoding ())
1538+ if (encodingToken .isConstantEncoding ())
14871539 {
1488- sb .append (generateConstPropertyMethods (propertyName , token , indent ));
1540+ sb .append (generateConstPropertyMethods (propertyName , encodingToken , indent ));
14891541 }
14901542 else
14911543 {
1492- sb .append (generatePrimitivePropertyDecodeMethods (inComposite , propertyName , token , indent ));
1544+ sb .append (generatePrimitivePropertyDecodeMethods (
1545+ inComposite , propertyName , propertyToken , encodingToken , indent ));
14931546 }
14941547
14951548 return sb ;
@@ -1515,11 +1568,16 @@ private CharSequence generatePrimitiveEncoder(
15151568 }
15161569
15171570 private CharSequence generatePrimitivePropertyDecodeMethods (
1518- final boolean inComposite , final String propertyName , final Token token , final String indent )
1571+ final boolean inComposite ,
1572+ final String propertyName ,
1573+ final Token propertyToken ,
1574+ final Token encodingToken ,
1575+ final String indent )
15191576 {
1520- return token .matchOnLength (
1521- () -> generatePrimitivePropertyDecode (inComposite , propertyName , token , indent ),
1522- () -> generatePrimitiveArrayPropertyDecode (inComposite , propertyName , token , indent ));
1577+ return encodingToken .matchOnLength (
1578+ () -> generatePrimitivePropertyDecode (inComposite , propertyName , propertyToken , encodingToken , indent ),
1579+ () -> generatePrimitiveArrayPropertyDecode (
1580+ inComposite , propertyName , propertyToken , encodingToken , indent ));
15231581 }
15241582
15251583 private CharSequence generatePrimitivePropertyEncodeMethods (
@@ -1570,12 +1628,16 @@ private CharSequence generatePrimitiveFieldMetaData(
15701628 }
15711629
15721630 private CharSequence generatePrimitivePropertyDecode (
1573- final boolean inComposite , final String propertyName , final Token token , final String indent )
1631+ final boolean inComposite ,
1632+ final String propertyName ,
1633+ final Token propertyToken ,
1634+ final Token encodingToken ,
1635+ final String indent )
15741636 {
1575- final Encoding encoding = token .encoding ();
1637+ final Encoding encoding = encodingToken .encoding ();
15761638 final String javaTypeName = javaTypeName (encoding .primitiveType ());
15771639
1578- final int offset = token .offset ();
1640+ final int offset = encodingToken .offset ();
15791641 final String byteOrderStr = byteOrderString (encoding );
15801642
15811643 return String .format (
@@ -1587,7 +1649,7 @@ private CharSequence generatePrimitivePropertyDecode(
15871649 indent + " }\n \n " ,
15881650 javaTypeName ,
15891651 propertyName ,
1590- generateFieldNotPresentCondition (inComposite , token .version (), encoding , indent ),
1652+ generateFieldNotPresentCondition (inComposite , propertyToken .version (), encoding , indent ),
15911653 generateGet (encoding .primitiveType (), "offset + " + offset , byteOrderStr ));
15921654 }
15931655
@@ -1660,29 +1722,38 @@ private static CharSequence generateStringNotPresentCondition(final int sinceVer
16601722 }
16611723
16621724 private static CharSequence generatePropertyNotPresentCondition (
1663- final boolean inComposite , final CodecType codecType , final int sinceVersion , final String indent )
1725+ final boolean inComposite ,
1726+ final CodecType codecType ,
1727+ final Token propertyToken ,
1728+ final String enumName ,
1729+ final String indent )
16641730 {
1665- if (inComposite || codecType == ENCODER || 0 == sinceVersion )
1731+ if (inComposite || codecType == ENCODER || 0 == propertyToken . version () )
16661732 {
16671733 return "" ;
16681734 }
16691735
16701736 return String .format (
16711737 indent + " if (parentMessage.actingVersion < %d)\n " +
16721738 indent + " {\n " +
1673- indent + " return null ;\n " +
1739+ indent + " return %s ;\n " +
16741740 indent + " }\n \n " ,
1675- sinceVersion );
1741+ propertyToken .version (),
1742+ enumName == null ? "null" : (enumName + ".NULL_VAL" ));
16761743 }
16771744
16781745 private CharSequence generatePrimitiveArrayPropertyDecode (
1679- final boolean inComposite , final String propertyName , final Token token , final String indent )
1746+ final boolean inComposite ,
1747+ final String propertyName ,
1748+ final Token propertyToken ,
1749+ final Token encodingToken ,
1750+ final String indent )
16801751 {
1681- final Encoding encoding = token .encoding ();
1752+ final Encoding encoding = encodingToken .encoding ();
16821753 final String javaTypeName = javaTypeName (encoding .primitiveType ());
1683- final int offset = token .offset ();
1754+ final int offset = encodingToken .offset ();
16841755 final String byteOrderStr = byteOrderString (encoding );
1685- final int fieldLength = token .arrayLength ();
1756+ final int fieldLength = encodingToken .arrayLength ();
16861757 final int typeSize = sizeOfPrimitive (encoding );
16871758
16881759 final StringBuilder sb = new StringBuilder ();
@@ -1703,7 +1774,7 @@ private CharSequence generatePrimitiveArrayPropertyDecode(
17031774 javaTypeName ,
17041775 propertyName ,
17051776 fieldLength ,
1706- generateFieldNotPresentCondition (inComposite , token .version (), encoding , indent ),
1777+ generateFieldNotPresentCondition (inComposite , propertyToken .version (), encoding , indent ),
17071778 offset ,
17081779 typeSize ,
17091780 generateGet (encoding .primitiveType (), "pos" , byteOrderStr )));
@@ -1727,7 +1798,7 @@ private CharSequence generatePrimitiveArrayPropertyDecode(
17271798 indent + " }\n " ,
17281799 Generators .toUpperFirstChar (propertyName ),
17291800 fieldLength ,
1730- generateArrayFieldNotPresentCondition (token .version (), indent ),
1801+ generateArrayFieldNotPresentCondition (propertyToken .version (), indent ),
17311802 offset ));
17321803
17331804 sb .append (String .format ("\n " +
@@ -1741,7 +1812,7 @@ private CharSequence generatePrimitiveArrayPropertyDecode(
17411812 indent + " return new String(dst, 0, end, %s);\n " +
17421813 indent + " }\n \n " ,
17431814 formatPropertyName (propertyName ),
1744- generateStringNotPresentCondition (token .version (), indent ),
1815+ generateStringNotPresentCondition (propertyToken .version (), indent ),
17451816 fieldLength , offset ,
17461817 fieldLength , fieldLength ,
17471818 charset (encoding .characterEncoding ())));
@@ -1858,6 +1929,32 @@ private void generateCharArrayEncodeMethods(
18581929 propertyName ,
18591930 fieldLength ,
18601931 offset ));
1932+ sb .append (String .format ("\n " +
1933+ indent + " public %1$s %2$s(final CharSequence src)\n " +
1934+ indent + " {\n " +
1935+ indent + " final int length = %3$d;\n " +
1936+ indent + " final int srcLength = src.length();\n " +
1937+ indent + " if (srcLength > length)\n " +
1938+ indent + " {\n " +
1939+ indent + " throw new IndexOutOfBoundsException(" +
1940+ "\" CharSequence too large for copy: byte length=\" + srcLength);\n " +
1941+ indent + " }\n \n " +
1942+ indent + " for (int i = 0; i < srcLength; ++i)\n " +
1943+ indent + " {\n " +
1944+ indent + " final char charValue = src.charAt(i);\n " +
1945+ indent + " final byte byteValue = charValue > 127 ? (byte)'?' : (byte)charValue;\n " +
1946+ indent + " buffer.putByte(this.offset + %4$d + i, byteValue);\n " +
1947+ indent + " }\n \n " +
1948+ indent + " for (int i = srcLength; i < length; ++i)\n " +
1949+ indent + " {\n " +
1950+ indent + " buffer.putByte(this.offset + %4$d + i, (byte)0);\n " +
1951+ indent + " }\n \n " +
1952+ indent + " return this;\n " +
1953+ indent + " }\n " ,
1954+ formatClassName (containingClassName ),
1955+ propertyName ,
1956+ fieldLength ,
1957+ offset ));
18611958 }
18621959 else
18631960 {
@@ -2259,7 +2356,7 @@ private CharSequence generateDecoderFields(final List<Token> tokens, final Strin
22592356 switch (typeToken .signal ())
22602357 {
22612358 case ENCODING :
2262- sb .append (generatePrimitiveDecoder (false , propertyName , typeToken , indent ));
2359+ sb .append (generatePrimitiveDecoder (false , propertyName , fieldToken , typeToken , indent ));
22632360 break ;
22642361
22652362 case BEGIN_ENUM :
@@ -2360,15 +2457,15 @@ private static void generateFieldMetaAttributeMethod(final StringBuilder sb, fin
23602457
23612458 private CharSequence generateEnumDecoder (
23622459 final boolean inComposite ,
2363- final Token signalToken ,
2460+ final Token fieldToken ,
23642461 final String propertyName ,
2365- final Token token ,
2462+ final Token typeToken ,
23662463 final String indent )
23672464 {
2368- final String enumName = formatClassName (token .applicableTypeName ());
2369- final Encoding encoding = token .encoding ();
2465+ final String enumName = formatClassName (typeToken .applicableTypeName ());
2466+ final Encoding encoding = typeToken .encoding ();
23702467
2371- if (token .isConstantEncoding ())
2468+ if (typeToken .isConstantEncoding ())
23722469 {
23732470 return String .format (
23742471 "\n " +
@@ -2378,7 +2475,7 @@ private CharSequence generateEnumDecoder(
23782475 indent + " }\n \n " ,
23792476 enumName ,
23802477 propertyName ,
2381- signalToken .encoding ().constValue ().toString ());
2478+ fieldToken .encoding ().constValue ().toString ());
23822479 }
23832480 else
23842481 {
@@ -2391,9 +2488,9 @@ private CharSequence generateEnumDecoder(
23912488 indent + " }\n \n " ,
23922489 enumName ,
23932490 propertyName ,
2394- generatePropertyNotPresentCondition (inComposite , DECODER , token . version () , indent ),
2491+ generatePropertyNotPresentCondition (inComposite , DECODER , fieldToken , enumName , indent ),
23952492 enumName ,
2396- generateGet (encoding .primitiveType (), "offset + " + token .offset (), byteOrderString (encoding )));
2493+ generateGet (encoding .primitiveType (), "offset + " + typeToken .offset (), byteOrderString (encoding )));
23972494 }
23982495 }
23992496
@@ -2449,7 +2546,7 @@ private CharSequence generateBitSetProperty(
24492546 generateFlyweightPropertyJavadoc (indent + INDENT , propertyToken , bitSetName ),
24502547 bitSetName ,
24512548 propertyName ,
2452- generatePropertyNotPresentCondition (inComposite , codecType , bitsetToken . version () , indent ),
2549+ generatePropertyNotPresentCondition (inComposite , codecType , propertyToken , null , indent ),
24532550 propertyName ,
24542551 bitsetToken .offset (),
24552552 propertyName ));
@@ -2485,7 +2582,7 @@ private CharSequence generateCompositeProperty(
24852582 generateFlyweightPropertyJavadoc (indent + INDENT , propertyToken , compositeName ),
24862583 compositeName ,
24872584 propertyName ,
2488- generatePropertyNotPresentCondition (inComposite , codecType , compositeToken . version () , indent ),
2585+ generatePropertyNotPresentCondition (inComposite , codecType , propertyToken , null , indent ),
24892586 propertyName ,
24902587 compositeToken .offset (),
24912588 propertyName ));
0 commit comments