diff options
4 files changed, 113 insertions, 23 deletions
diff --git a/examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java b/examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java index c75f454..8466647 100644 --- a/examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java +++ b/examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java @@ -11,6 +11,7 @@ import org.zwobble.example.types.data.OuterStruct; import org.zwobble.example.types.data.StructWithBool; import org.zwobble.example.types.data.StructWithInt32; import org.zwobble.example.types.data.StructWithInt64; +import org.zwobble.example.types.data.StructWithString; public class Transient0Tests { @Test @@ -56,6 +57,20 @@ public class Transient0Tests { } @Test + public void structWithString() throws IOException { + var value = new StructWithString("abc", "def"); + + var outputStream = new ByteArrayOutputStream(); + HobgoblinTransient0Data.encodeStructWithString(value, outputStream); + var bytes = outputStream.toByteArray(); + + var inputStream = new ByteArrayInputStream(bytes); + var decodedValue = HobgoblinTransient0Data.decodeStructWithString(inputStream); + + Assertions.assertEquals(value, decodedValue); + } + + @Test public void nestedStruct() throws IOException { var value = new OuterStruct(new InnerStruct(10, 25), 42); diff --git a/examples/10-transient-0/src/data.hob b/examples/10-transient-0/src/data.hob index d2ad016..c750cdd 100644 --- a/examples/10-transient-0/src/data.hob +++ b/examples/10-transient-0/src/data.hob @@ -13,6 +13,11 @@ struct StructWithInt64 { field b: Int64; } +struct StructWithString { + field a: String; + field b: String; +} + struct OuterStruct { field inner: InnerStruct; field c: Int32; diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java index 346bde0..e61146a 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java @@ -90,7 +90,9 @@ public class JavaTransient0Generator implements Generator { generateEncodeInt32Method(), generateDecodeInt32Method(), generateEncodeInt64Method(), - generateDecodeInt64Method() + generateDecodeInt64Method(), + generateEncodeStringMethod(), + generateDecodeStringMethod() ), new JavaCustomArea(transient0JavaTypeRef, "body"), DocComment.EMPTY @@ -206,6 +208,75 @@ public class JavaTransient0Generator implements Generator { return generateDecodeMethod(type, new JavaBlock(statements)); } + private JavaMethodDeclaration generateEncodeStringMethod() { + var bytesVariableName = JavaIdentifier.of("bytes"); + + return generateEncodeMethod( + NativeTypes.STRING, + new JavaBlock(List.of( + new JavaLocalVariableDeclaration( + Optional.empty(), + bytesVariableName, + new JavaMethodCall( + new JavaRef(VALUE_NAME), + JavaIdentifier.of("getBytes"), + List.of(new JavaStaticFieldAccess( + JavaTypeRef.STANDARD_CHARSETS, + JavaIdentifier.of("UTF_8") + )) + ) + ), + generateEncode( + new JavaCast(JavaTypeRef.LONG, new JavaFieldAccess( + new JavaRef(bytesVariableName), + JavaIdentifier.of("length") + )), + NativeTypes.INT_64 + ), + new JavaExpressionStatement(generateOutputStreamWrite( + new JavaRef(bytesVariableName) + )) + )) + ); + } + + private JavaMethodDeclaration generateDecodeStringMethod() { + var bytesLengthVariableName = JavaIdentifier.of("bytesLength"); + var bytesVariableName = JavaIdentifier.of("bytes"); + + return generateDecodeMethod( + NativeTypes.STRING, + new JavaBlock(List.of( + generateDecode( + bytesLengthVariableName, + NativeTypes.INT_64 + ), + new JavaLocalVariableDeclaration( + Optional.empty(), + bytesVariableName, + new JavaMethodCall( + new JavaRef(INPUT_STREAM_NAME), + JavaIdentifier.of("readNBytes"), + // TODO: handle very long strings + List.of(new JavaCast(JavaTypeRef.INT, new JavaRef(bytesLengthVariableName))) + ) + ), + new JavaReturn( + new JavaNewExpression( + JavaTypeRef.STRING, + List.of( + new JavaRef(bytesVariableName), + new JavaStaticFieldAccess( + JavaTypeRef.STANDARD_CHARSETS, + JavaIdentifier.of("UTF_8") + ) + ) + ) + ) + )) + ); + } + private List<JavaCompilationUnit> generateNamespace( TypedNamespaceNode namespace, Context context @@ -272,7 +343,7 @@ public class JavaTransient0Generator implements Generator { structDefinition.type(), new JavaBlock( structDefinition.fields().stream() - .flatMap(field -> generateEncode( + .map(field -> generateEncode( new JavaMethodCall( new JavaRef(VALUE_NAME), this.javaGenerator.generateFieldName(field.name()), @@ -288,7 +359,7 @@ public class JavaTransient0Generator implements Generator { new JavaBlock( Stream.concat( structDefinition.fields().stream() - .flatMap(field -> generateDecode( + .map(field -> generateDecode( this.javaGenerator.generateFieldName(field.name()), field.type().value() )), @@ -355,7 +426,7 @@ public class JavaTransient0Generator implements Generator { ); } - private Stream<JavaBlockStatement> generateEncode(JavaExpression value, Type type) { + private JavaBlockStatement generateEncode(JavaExpression value, Type type) { return switch (type) { case ConstructedNativeType constructedNativeType -> { throw new UnsupportedOperationException("TODO"); @@ -395,23 +466,21 @@ public class JavaTransient0Generator implements Generator { }; } - private Stream<JavaBlockStatement> generateEncode( + private JavaBlockStatement generateEncode( JavaExpression value, NamespaceName typeNamespaceName, Type type ) { - return Stream.of( - new JavaExpressionStatement( - new JavaStaticMethodCall( - generateTransient0TypeRef(typeNamespaceName), - encodeMethodName(type), - List.of(value, new JavaRef(OUTPUT_STREAM_NAME)) - ) + return new JavaExpressionStatement( + new JavaStaticMethodCall( + generateTransient0TypeRef(typeNamespaceName), + encodeMethodName(type), + List.of(value, new JavaRef(OUTPUT_STREAM_NAME)) ) ); } - private Stream<JavaBlockStatement> generateDecode(JavaIdentifier target, Type type) { + private JavaBlockStatement generateDecode(JavaIdentifier target, Type type) { return switch (type) { case ConstructedNativeType constructedNativeType -> { throw new UnsupportedOperationException("TODO"); @@ -451,20 +520,18 @@ public class JavaTransient0Generator implements Generator { }; } - private Stream<JavaBlockStatement> generateDecode( + private JavaBlockStatement generateDecode( JavaIdentifier target, NamespaceName typeNamespaceName, Type type ) { - return Stream.of( - new JavaLocalVariableDeclaration( - Optional.empty(), - target, - new JavaStaticMethodCall( - generateTransient0TypeRef(typeNamespaceName), - decodeMethodName(type), - List.of(new JavaRef(INPUT_STREAM_NAME)) - ) + return new JavaLocalVariableDeclaration( + Optional.empty(), + target, + new JavaStaticMethodCall( + generateTransient0TypeRef(typeNamespaceName), + decodeMethodName(type), + List.of(new JavaRef(INPUT_STREAM_NAME)) ) ); } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java index 1d1274e..0975e4e 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java @@ -35,6 +35,7 @@ public record JavaTypeRef(JavaPackageName packageName, List<JavaIdentifier> type private static class JavaPackages { private static final JavaPackageName JAVA_IO = JavaPackageName.of("java", "io"); private static final JavaPackageName JAVA_LANG = JavaPackageName.of("java", "lang"); + private static final JavaPackageName JAVA_NIO_CHARSET = JavaPackageName.of("java", "nio", "charset"); private static final JavaPackageName JAVA_UTIL = JavaPackageName.of("java", "util"); private static final JavaPackageName JAVA_UTIL_STREAM = JavaPackageName.of("java", "util", "stream"); } @@ -76,5 +77,7 @@ public record JavaTypeRef(JavaPackageName packageName, List<JavaIdentifier> type public static final JavaTypeRef OUTPUT_STREAM = topLevel(JavaPackages.JAVA_IO, JavaIdentifier.of("OutputStream")); + public static final JavaTypeRef STANDARD_CHARSETS = topLevel(JavaPackages.JAVA_NIO_CHARSET, JavaIdentifier.of("StandardCharsets")); + public static final JavaTypeRef STREAM = topLevel(JavaPackages.JAVA_UTIL_STREAM, JavaIdentifier.of("Stream")); } |
