Skip to content

Commit 189e189

Browse files
authored
Merge pull request #397 from Starch/getString
[Java] add new convenience methods to get char arrays as string.
2 parents 8a078ef + 4e1e52d commit 189e189

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/java/JavaGenerator.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,6 +1621,23 @@ private CharSequence generatePrimitiveArrayPropertyDecode(final String propertyN
16211621
fieldLength,
16221622
generateArrayFieldNotPresentCondition(token.version(), indent),
16231623
offset));
1624+
1625+
sb.append(String.format(
1626+
"\n" +
1627+
indent + " public String %s()\n" +
1628+
indent + " {\n" +
1629+
"%s" +
1630+
indent + " final byte[] dst = new byte[%d];\n" +
1631+
indent + " buffer.getBytes(this.offset + %d, dst, 0, %d);\n\n" +
1632+
indent + " int end = 0;\n" +
1633+
indent + " for (; end < %d && dst[end] != 0; ++end);\n\n" +
1634+
indent + " return new String(dst, 0, end, %s);\n" +
1635+
indent + " }\n\n",
1636+
formatPropertyName(propertyName),
1637+
generateStringNotPresentCondition(token.version(), indent),
1638+
fieldLength, offset,
1639+
fieldLength, fieldLength,
1640+
charset(encoding.characterEncoding())));
16241641
}
16251642

16261643
return sb;
@@ -1695,6 +1712,30 @@ private CharSequence generatePrimitiveArrayPropertyEncode(
16951712
toUpperFirstChar(propertyName),
16961713
fieldLength,
16971714
offset));
1715+
1716+
sb.append(String.format(
1717+
indent + " public %s %s(final String src)\n" +
1718+
indent + " {\n" +
1719+
indent + " final int length = %d;\n" +
1720+
indent + " final byte[] bytes = src.getBytes(%s);\n" +
1721+
indent + " if (bytes.length > length)\n" +
1722+
indent + " {\n" +
1723+
indent + " throw new IndexOutOfBoundsException(" +
1724+
"\"string too large for copy: byte length=\" + bytes.length);\n" +
1725+
indent + " }\n\n" +
1726+
indent + " buffer.putBytes(this.offset + %d, bytes, 0, bytes.length);\n\n" +
1727+
indent + " for (int start = bytes.length; start < length; ++start)\n" +
1728+
indent + " {\n" +
1729+
indent + " buffer.putByte(this.offset + %d + start, (byte) 0);\n" +
1730+
indent + " }\n\n" +
1731+
indent + " return this;\n" +
1732+
indent + " }\n",
1733+
formatClassName(containingClassName),
1734+
propertyName,
1735+
fieldLength,
1736+
charset(encoding.characterEncoding()),
1737+
offset,
1738+
offset));
16981739
}
16991740

17001741
return sb;

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/java/JavaUtil.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@
1919
import uk.co.real_logic.sbe.SbeTool;
2020
import uk.co.real_logic.sbe.util.ValidationUtil;
2121

22+
import java.lang.reflect.Field;
23+
import java.lang.reflect.Modifier;
24+
import java.nio.charset.Charset;
25+
import java.nio.charset.StandardCharsets;
2226
import java.util.EnumMap;
27+
import java.util.HashMap;
2328
import java.util.Map;
2429

2530
/**
@@ -83,6 +88,30 @@ public String toString()
8388
TYPE_NAME_BY_PRIMITIVE_TYPE_MAP.put(PrimitiveType.DOUBLE, "double");
8489
}
8590

91+
/** Indexes known charset aliases to the name of the instance in {@link StandardCharsets}. */
92+
private static final Map<String, String> STD_CHARSETS = new HashMap<>();
93+
94+
static
95+
{
96+
try
97+
{
98+
for (Field f : StandardCharsets.class.getDeclaredFields())
99+
{
100+
if (Charset.class.isAssignableFrom(f.getType())
101+
&& ((f.getModifiers() & Modifier.STATIC) == Modifier.STATIC))
102+
{
103+
final Charset c = (Charset) f.get(null);
104+
STD_CHARSETS.put(c.name(), f.getName());
105+
c.aliases().forEach(alias -> STD_CHARSETS.put(alias, f.getName()));
106+
}
107+
}
108+
}
109+
catch (IllegalAccessException e)
110+
{
111+
throw new RuntimeException(e);
112+
}
113+
}
114+
86115
/**
87116
* Map the name of a {@link uk.co.real_logic.sbe.PrimitiveType} to a Java primitive type name.
88117
*
@@ -168,4 +197,22 @@ public static void append(final StringBuilder builder, final String indent, fina
168197
{
169198
builder.append(indent).append(line).append('\n');
170199
}
200+
201+
/**
202+
* Return java code to fetch an instance of {@link java.nio.charset.Charset} corresponding to the given encoding.
203+
* @param encoding the encoding (eg. UTF-8).
204+
* @return the code to fetch the assiciated charset.
205+
*/
206+
public static String charset(String encoding)
207+
{
208+
final String charset = STD_CHARSETS.get(encoding);
209+
if (charset != null)
210+
{
211+
return "java.nio.charset.StandardCharsets." + charset;
212+
}
213+
else
214+
{
215+
return "java.nio.charset.Charset.forName(\"" + encoding + "\")";
216+
}
217+
}
171218
}

sbe-tool/src/test/java/uk/co/real_logic/sbe/generation/java/JavaGeneratorTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,25 @@ public void shouldGenerateEnumCodecs() throws Exception
351351
assertThat(get(decoder, "code"), hasToString("B"));
352352
}
353353

354+
@Test
355+
public void shouldGenerateGetString() throws Exception
356+
{
357+
final UnsafeBuffer buffer = new UnsafeBuffer(new byte[4096]);
358+
generator().generate();
359+
360+
final Object encoder = wrap(buffer, compileCarEncoder().newInstance());
361+
final Object decoder = getCarDecoder(buffer, encoder);
362+
363+
set(encoder, "vehicleCode", String.class, "R11");
364+
assertThat(get(decoder, "vehicleCode"), is("R11"));
365+
366+
set(encoder, "vehicleCode", String.class, "");
367+
assertThat(get(decoder, "vehicleCode"), is(""));
368+
369+
set(encoder, "vehicleCode", String.class, "R11R12");
370+
assertThat(get(decoder, "vehicleCode"), is("R11R12"));
371+
}
372+
354373
private Class<?> getModelClass(final Object encoder) throws ClassNotFoundException
355374
{
356375
final String className = "Model";

0 commit comments

Comments
 (0)