diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/java/JavaGenerator.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/java/JavaGenerator.java index 6f2c3df1d1..f99a085eac 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/java/JavaGenerator.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/java/JavaGenerator.java @@ -837,11 +837,32 @@ private void generateDataEncodeMethods( byteOrderStr, indent); - if (null == characterEncoding) + if (null != characterEncoding) { - return; + generateCharArrayEncodeMethods( + sb, + propertyName, + sizeOfLengthField, + maxLengthValue, + lengthType, + byteOrderStr, + characterEncoding, + className, + indent); } + } + private void generateCharArrayEncodeMethods( + final StringBuilder sb, + final String propertyName, + final int sizeOfLengthField, + final int maxLengthValue, + final PrimitiveType lengthType, + final String byteOrderStr, + final String characterEncoding, + final String className, + final String indent) + { if (characterEncoding.contains("ASCII")) { sb.append(String.format("\n" + @@ -864,6 +885,32 @@ private void generateDataEncodeMethods( maxLengthValue, sizeOfLengthField, generatePut(lengthType, "limit", "length", byteOrderStr))); + + sb.append(String.format("\n" + + indent + " public %1$s %2$s(final CharSequence value)\n" + + indent + " {\n" + + indent + " final int length = value.length();\n" + + indent + " if (length > %3$d)\n" + + indent + " {\n" + + indent + " throw new IllegalStateException(\"length > maxValue for type: \" + length);\n" + + indent + " }\n\n" + + indent + " final int headerLength = %4$d;\n" + + indent + " final int limit = parentMessage.limit();\n" + + indent + " parentMessage.limit(limit + headerLength + length);\n" + + indent + " %5$s;\n" + + indent + " for (int i = 0; i < length; ++i)\n" + + indent + " {\n" + + indent + " final char charValue = value.charAt(i);\n" + + indent + " final byte byteValue = charValue > 127 ? (byte)'?' : (byte)charValue;\n" + + indent + " buffer.putByte(limit + headerLength + i, byteValue);\n" + + indent + " }\n\n" + + indent + " return this;\n" + + indent + " }\n", + className, + formatPropertyName(propertyName), + maxLengthValue, + sizeOfLengthField, + generatePut(lengthType, "limit", "length", byteOrderStr))); } else { @@ -1858,6 +1905,32 @@ private void generateCharArrayEncodeMethods( propertyName, fieldLength, offset)); + sb.append(String.format("\n" + + indent + " public %1$s %2$s(final CharSequence src)\n" + + indent + " {\n" + + indent + " final int length = %3$d;\n" + + indent + " final int srcLength = src.length();\n" + + indent + " if (srcLength > length)\n" + + indent + " {\n" + + indent + " throw new IndexOutOfBoundsException(" + + "\"CharSequence too large for copy: byte length=\" + srcLength);\n" + + indent + " }\n\n" + + indent + " for (int i = 0; i < srcLength; ++i)\n" + + indent + " {\n" + + indent + " final char charValue = src.charAt(i);\n" + + indent + " final byte byteValue = charValue > 127 ? (byte)'?' : (byte)charValue;\n" + + indent + " buffer.putByte(this.offset + %4$d + i, byteValue);\n" + + indent + " }\n\n" + + indent + " for (int i = srcLength; i < length; ++i)\n" + + indent + " {\n" + + indent + " buffer.putByte(this.offset + %4$d + i, (byte)0);\n" + + indent + " }\n\n" + + indent + " return this;\n" + + indent + " }\n", + formatClassName(containingClassName), + propertyName, + fieldLength, + offset)); } else { diff --git a/sbe-tool/src/test/java/uk/co/real_logic/sbe/generation/java/JavaGeneratorTest.java b/sbe-tool/src/test/java/uk/co/real_logic/sbe/generation/java/JavaGeneratorTest.java index c0d799058a..d264b5d224 100644 --- a/sbe-tool/src/test/java/uk/co/real_logic/sbe/generation/java/JavaGeneratorTest.java +++ b/sbe-tool/src/test/java/uk/co/real_logic/sbe/generation/java/JavaGeneratorTest.java @@ -372,6 +372,25 @@ public void shouldGenerateGetString() throws Exception assertThat(get(decoder, "vehicleCode"), is("R11R12")); } + @Test + public void shouldGeneratePutCharSequence() throws Exception + { + final UnsafeBuffer buffer = new UnsafeBuffer(new byte[4096]); + generator().generate(); + + final Object encoder = wrap(buffer, compileCarEncoder().newInstance()); + final Object decoder = getCarDecoder(buffer, encoder); + + set(encoder, "vehicleCode", CharSequence.class, "R11"); + assertThat(get(decoder, "vehicleCode"), is("R11")); + + set(encoder, "vehicleCode", CharSequence.class, ""); + assertThat(get(decoder, "vehicleCode"), is("")); + + set(encoder, "vehicleCode", CharSequence.class, "R11R12"); + assertThat(get(decoder, "vehicleCode"), is("R11R12")); + } + private Class getModelClass(final Object encoder) throws ClassNotFoundException { final String className = "Model";