From ef2b962cf31f53eb7546683b3c46627b4be05bf9 Mon Sep 17 00:00:00 2001 From: yevgenp Date: Wed, 19 Jun 2024 12:05:09 +0300 Subject: [PATCH] Make value generation locale independent. Closes https://github.com/OpenHFT/Chronicle-Map/issues/476 --- .../PrimitiveBackedHeapMemberGenerator.java | 6 +- .../net/openhft/chronicle/values/Utils.java | 4 +- .../chronicle/values/ValueGeneratorTest.java | 90 ++++++++++--------- 3 files changed, 56 insertions(+), 44 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/values/PrimitiveBackedHeapMemberGenerator.java b/src/main/java/net/openhft/chronicle/values/PrimitiveBackedHeapMemberGenerator.java index 74f5afd03..20efff435 100644 --- a/src/main/java/net/openhft/chronicle/values/PrimitiveBackedHeapMemberGenerator.java +++ b/src/main/java/net/openhft/chronicle/values/PrimitiveBackedHeapMemberGenerator.java @@ -20,6 +20,8 @@ import com.squareup.javapoet.MethodSpec; +import java.util.Locale; + import static net.openhft.chronicle.values.Primitives.boxed; import static net.openhft.chronicle.values.Utils.capitalize; @@ -34,7 +36,7 @@ class PrimitiveBackedHeapMemberGenerator extends HeapMemberGenerator { fieldType = determineFieldType(); assert fieldType.isPrimitive(); capType = capitalize(fieldType.getName()); - upperType = fieldType.getName().toUpperCase(); + upperType = fieldType.getName().toUpperCase(Locale.ROOT); } PrimitiveBackedHeapMemberGenerator(FieldModel fieldModel, Class fieldType) { @@ -42,7 +44,7 @@ class PrimitiveBackedHeapMemberGenerator extends HeapMemberGenerator { this.fieldType = fieldType; assert fieldType.isPrimitive(); capType = capitalize(fieldType.getName()); - upperType = fieldType.getName().toUpperCase(); + upperType = fieldType.getName().toUpperCase(Locale.ROOT); } @Override diff --git a/src/main/java/net/openhft/chronicle/values/Utils.java b/src/main/java/net/openhft/chronicle/values/Utils.java index e29076934..3ec9b7a3b 100644 --- a/src/main/java/net/openhft/chronicle/values/Utils.java +++ b/src/main/java/net/openhft/chronicle/values/Utils.java @@ -18,6 +18,8 @@ package net.openhft.chronicle.values; +import java.util.Locale; + final class Utils { static final Class UNSAFE_CLASS; @@ -37,7 +39,7 @@ public static int roundUp(int divident, int divisor) { } static String capitalize(String s) { - return s.substring(0, 1).toUpperCase() + s.substring(1); + return s.substring(0, 1).toUpperCase(Locale.ROOT) + s.substring(1); } static String formatIntOrLong(long v) { diff --git a/src/test/java/net/openhft/chronicle/values/ValueGeneratorTest.java b/src/test/java/net/openhft/chronicle/values/ValueGeneratorTest.java index 3cd8df178..c6ecc3553 100644 --- a/src/test/java/net/openhft/chronicle/values/ValueGeneratorTest.java +++ b/src/test/java/net/openhft/chronicle/values/ValueGeneratorTest.java @@ -27,13 +27,14 @@ import java.lang.reflect.InvocationTargetException; import java.nio.ByteBuffer; import java.util.Date; +import java.util.Locale; import static net.openhft.chronicle.values.Generators.generateHeapClass; import static net.openhft.chronicle.values.Generators.generateNativeClass; import static net.openhft.chronicle.values.Values.newHeapInstance; import static net.openhft.chronicle.values.Values.newNativeReference; -import static org.junit.Assert.*; import static net.openhft.compiler.CompilerUtils.CACHED_COMPILER; +import static org.junit.Assert.*; /** * User: peter.lawrey Date: 06/10/13 Time: 20:13 @@ -64,42 +65,49 @@ public void testGenerateJavaCode() { @Test public void testGenerateJavaCode2() { - MinimalInterface mi = newHeapInstance(MinimalInterface.class); - - mi.byte$((byte) 1); - mi.char$('2'); - mi.short$((short) 3); - mi.int$(4); - mi.float$(5); - mi.long$(6); - mi.double$(7); - mi.flag(true); - - assertEquals(1, mi.byte$()); - assertEquals('2', mi.char$()); - assertEquals(3, mi.short$()); - assertEquals(4, mi.int$()); - assertEquals(5.0, mi.float$(), 0); - assertEquals(6, mi.long$()); - assertEquals(7.0, mi.double$(), 0.0); - assertTrue(mi.flag()); - - Bytes bbb = Bytes.wrapForWrite(ByteBuffer.allocate(64)); - mi.writeMarshallable(bbb); - System.out.println("size: " + bbb.writePosition()); - - MinimalInterface mi2 = newHeapInstance(MinimalInterface.class); - bbb.readPosition(0); - mi2.readMarshallable(bbb); - - assertEquals(1, mi2.byte$()); - assertEquals('2', mi2.char$()); - assertEquals(3, mi2.short$()); - assertEquals(4, mi2.int$()); - assertEquals(5.0, mi2.float$(), 0); - assertEquals(6, mi2.long$()); - assertEquals(7.0, mi2.double$(), 0.0); - assertTrue(mi2.flag()); + Locale defaultLocale = Locale.getDefault(); + Locale.setDefault(Locale.forLanguageTag("tr")); + try { + MinimalInterface mi = newHeapInstance(MinimalInterface.class); + + mi.byte$((byte) 1); + mi.char$('2'); + mi.short$((short) 3); + mi.int$(4); + mi.float$(5); + mi.long$(6); + mi.double$(7); + mi.flag(true); + + assertEquals(1, mi.byte$()); + assertEquals('2', mi.char$()); + assertEquals(3, mi.short$()); + assertEquals(4, mi.int$()); + assertEquals(5.0, mi.float$(), 0); + assertEquals(6, mi.long$()); + assertEquals(7.0, mi.double$(), 0.0); + assertTrue(mi.flag()); + + Bytes bbb = Bytes.wrapForWrite(ByteBuffer.allocate(64)); + mi.writeMarshallable(bbb); + System.out.println("size: " + bbb.writePosition()); + + MinimalInterface mi2 = newHeapInstance(MinimalInterface.class); + bbb.readPosition(0); + mi2.readMarshallable(bbb); + + assertEquals(1, mi2.byte$()); + assertEquals('2', mi2.char$()); + assertEquals(3, mi2.short$()); + assertEquals(4, mi2.int$()); + assertEquals(5.0, mi2.float$(), 0); + assertEquals(6, mi2.long$()); + assertEquals(7.0, mi2.double$(), 0.0); + assertTrue(mi2.flag()); + } + finally { + Locale.setDefault(defaultLocale); + } } @SuppressWarnings("rawtypes") @@ -111,7 +119,7 @@ public void testGenerateNativeWithGetUsing() throws ClassNotFoundException, Ille Class aClass = CACHED_COMPILER.loadFromJava( BytecodeGen.getClassLoader(JavaBeanInterfaceGetUsing.class), JavaBeanInterfaceGetUsing.class.getName() + "$$Native", actual); - JavaBeanInterfaceGetUsing jbi = (JavaBeanInterfaceGetUsing) aClass.asSubclass(JavaBeanInterfaceGetUsing.class).getDeclaredConstructor().newInstance(); + JavaBeanInterfaceGetUsing jbi = aClass.asSubclass(JavaBeanInterfaceGetUsing.class).getDeclaredConstructor().newInstance(); BytesStore bytes = BytesStore.wrap(ByteBuffer.allocate(64)); ((Byteable) jbi).bytesStore(bytes, 0L, ((Byteable) jbi).maxSize()); @@ -207,7 +215,7 @@ private T loadNativeTypeAndCreateValue(Class type) throws InstantiationEx Class aClass = Values.nativeClassFor(type); T jbi; try { - jbi = (T) aClass.asSubclass(type).getConstructor().newInstance(); + jbi = aClass.asSubclass(type).getConstructor().newInstance(); } catch (NoSuchMethodException | InvocationTargetException e) { throw new RuntimeException(e); } @@ -221,7 +229,7 @@ private T loadHeapTypeAndCreateValue(Class type) throws InstantiationExce ValueModel.simpleName(type) + "$$Heap"); System.out.println(actual); Class aClass = Values.heapClassFor(type); - T jbi = (T) aClass.asSubclass(type).getDeclaredConstructor().newInstance(); + T jbi = aClass.asSubclass(type).getDeclaredConstructor().newInstance(); return jbi; } @@ -327,7 +335,7 @@ public void testGenerateInterfaceWithDateOnHeap() { } @Test - public void testGenerateInterfaceWithDateNativeInstace() { + public void testGenerateInterfaceWithDateNativeInstance() { //dvg.setDumpCode(true); JavaBeanInterfaceGetDate jbid = newNativeReference(JavaBeanInterfaceGetDate.class); BytesStore bytes = BytesStore.wrap(ByteBuffer.allocate(64));