diff --git a/java/com/google/flatbuffers/Table.java b/java/com/google/flatbuffers/Table.java index c9c6545616a7ee79db4080c4f12e6e66659956ad..b853842a77cd2311ae13b0a3d44437fd9c2da0ca 100644 --- a/java/com/google/flatbuffers/Table.java +++ b/java/com/google/flatbuffers/Table.java @@ -37,6 +37,12 @@ public class Table { return Charset.forName("UTF-8").newDecoder(); } }; + public final static ThreadLocal<Charset> UTF8_CHARSET = new ThreadLocal<Charset>() { + @Override + protected Charset initialValue() { + return Charset.forName("UTF-8"); + } + }; private final static ThreadLocal<CharBuffer> CHAR_BUFFER = new ThreadLocal<CharBuffer>(); /** Used to hold the position of the `bb` buffer. */ protected int bb_pos; @@ -75,7 +81,7 @@ public class Table { protected int __indirect(int offset) { return offset + bb.getInt(offset); } - + protected static int __indirect(int offset, ByteBuffer bb) { return offset + bb.getInt(offset); } @@ -197,17 +203,21 @@ public class Table { } return true; } - + /** * Sort tables by the key. * * @param offsets An 'int' indexes of the tables into the bb. * @param bb A {@code ByteBuffer} to get the tables. */ - protected void sortTables(int[] offsets, ByteBuffer bb) { + protected void sortTables(int[] offsets, final ByteBuffer bb) { Integer[] off = new Integer[offsets.length]; for (int i = 0; i < offsets.length; i++) off[i] = offsets[i]; - Arrays.sort(off, (Integer o1, Integer o2) -> keysCompare(o1, o2, bb)); + java.util.Arrays.sort(off, new java.util.Comparator<Integer>() { + public int compare(Integer o1, Integer o2) { + return keysCompare(o1, o2, bb); + } + }); for (int i = 0; i < offsets.length; i++) offsets[i] = off[i]; } @@ -219,7 +229,7 @@ public class Table { * @param bb A {@code ByteBuffer} to get the keys. */ protected int keysCompare(Integer o1, Integer o2, ByteBuffer bb) { return 0; } - + /** * Compare two strings in the buffer. * @@ -242,7 +252,7 @@ public class Table { } return len_1 - len_2; } - + /** * Compare string from the buffer with the 'String' object. * diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp index 04deb9a0b8046a394e29f8bc30009c258958c660..c678dc3f6d3f5325d8e64719fb772e2ae65b0e2a 100644 --- a/src/idl_gen_general.cpp +++ b/src/idl_gen_general.cpp @@ -237,7 +237,7 @@ class GeneralGenerator : public BaseGenerator { // Save out the generated code for a single class while adding // declaration boilerplate. bool SaveType(const std::string &defname, const Namespace &ns, - const std::string &classcode, bool needs_includes) { + const std::string &classcode, bool needs_includes) { if (!classcode.length()) return true; std::string code; @@ -684,8 +684,7 @@ std::string GenOffsetGetter(flatbuffers::FieldDef *key_field, const char *num = key_offset += num; key_offset += (lang_.language == IDLOptions::kCSharp ? ".Value, builder.DataBuffer)" : ", _bb)"); - } - else { + } else { key_offset += GenByteBufferLength("bb"); key_offset += " - tableOffset, bb)"; } @@ -694,23 +693,21 @@ std::string GenOffsetGetter(flatbuffers::FieldDef *key_field, const char *num = std::string GenLookupKeyGetter(flatbuffers::FieldDef *key_field) { std::string key_getter = " "; - key_getter += "tableOffset = __indirect(vectorLocation + 4 * (start + middle)"; + key_getter += "int tableOffset = __indirect(vectorLocation + 4 * (start + middle)"; key_getter += ", bb);\n "; if (key_field->value.type.base_type == BASE_TYPE_STRING) { - key_getter += "comp = " + FunctionStart('C') + "ompareStrings("; + key_getter += "int comp = " + FunctionStart('C') + "ompareStrings("; key_getter += GenOffsetGetter(key_field); key_getter += ", byteKey, bb);\n"; - } - else { + } else { auto get_val = GenGetter(key_field->value.type) + "(" + GenOffsetGetter(key_field) + ")"; if (lang_.language == IDLOptions::kCSharp) { - key_getter += "comp = " + get_val + ".CompateTo(key);\n"; - } - else { + key_getter += "int comp = " + get_val + ".CompateTo(key);\n"; + } else { key_getter += GenTypeGet(key_field->value.type) + " val = "; key_getter += get_val + ";\n"; - key_getter += " comp = val > key ? 1 : val < key ? -1 : 0;\n"; + key_getter += " int comp = val > key ? 1 : val < key ? -1 : 0;\n"; } } return key_getter; @@ -1239,26 +1236,29 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) { code += " key, ByteBuffer bb) {\n"; code += " byte[] byteKey = "; if (lang_.language == IDLOptions::kJava) - code += "key.getBytes(StandardCharsets.UTF_8);\n"; + code += "key.getBytes(Table.UTF8_CHARSET.get());\n"; else code += "System.Text.Encoding.UTF8.GetBytes(key);\n"; code += " int vectorLocation = " + GenByteBufferLength("bb"); - code += " - vectorOffset.Value;\n int span = "; - code += "bb." + FunctionStart('G') + "etInt(vectorLocation), "; - code += "middle, start = 0, comp, tableOffset; \n"; + code += " - vectorOffset"; + if (lang_.language == IDLOptions::kCsharp) code += ".Value"; + code += ";\n int span = "; + code += "bb." + FunctionStart('G') + "etInt(vectorLocation);\n"; + code += " int start = 0;\n"; code += " vectorLocation += 4;\n"; code += " while (span != 0) {\n"; code += " int middle = span / 2;\n"; code += GenLookupKeyGetter(key_field); - code += " if (comp > 0) span = middle;\n"; - code += " else if (comp < 0) {\n"; + code += " if (comp > 0) {\n"; + code += " span = middle;\n"; + code += " } else if (comp < 0) {\n"; code += " middle++;\n"; code += " start += middle;\n"; code += " span -= middle;\n"; - code += " }\n"; - code += " else return new " + struct_def.name; + code += " } else {\n"; + code += " return new " + struct_def.name; code += "().__init(tableOffset, bb);\n"; - code += " }\n"; + code += " }\n }\n"; code += " return null;\n"; code += " }\n"; } diff --git a/tests/MyGame/Example/Monster.cs b/tests/MyGame/Example/Monster.cs index 95a303cf414fc0f39872a96ee8c412fa451998ba..91c845c64d40a6d36746f808e5396a60b6a268c4 100644 --- a/tests/MyGame/Example/Monster.cs +++ b/tests/MyGame/Example/Monster.cs @@ -129,7 +129,7 @@ public sealed class Monster : Table { return new Offset<Monster>(o); } public static void FinishMonsterBuffer(FlatBufferBuilder builder, Offset<Monster> offset) { builder.Finish(offset.Value, "MONS"); } - + public static VectorOffset CreateMySortedVectorOfTables(FlatBufferBuilder builder, Offset<Monster>[] offsets) { Array.Sort(offsets, (Offset<Monster> o1, Offset<Monster> o2) => CompareStrings(__offset(10, o1.Value, builder.DataBuffer), __offset(10, o2.Value, builder.DataBuffer), builder.DataBuffer)); return builder.CreateVectorOfTables(offsets); @@ -137,20 +137,23 @@ public sealed class Monster : Table { public static Monster LookupByKey(VectorOffset vectorOffset, string key, ByteBuffer bb) { byte[] byteKey = System.Text.Encoding.UTF8.GetBytes(key); - int vectorLocation = bb.Length - vectorOffset.Value; - int span = bb.GetInt(vectorLocation), middle, start = 0, comp, tableOffset; + int vectorLocation = bb.Length - vectorOffset; + int span = bb.GetInt(vectorLocation); + int start = 0; vectorLocation += 4; while (span != 0) { int middle = span / 2; - tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb); - comp = CompareStrings(__offset(10, bb.Length - tableOffset, bb), byteKey, bb); - if (comp > 0) span = middle; - else if (comp < 0) { + int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb); + int comp = CompareStrings(__offset(10, bb.Length - tableOffset, bb), byteKey, bb); + if (comp > 0) { + span = middle; + } else if (comp < 0) { middle++; start += middle; span -= middle; + } else { + return new Monster().__init(tableOffset, bb); } - else return new Monster().__init(tableOffset, bb); } return null; } diff --git a/tests/MyGame/Example/Monster.java b/tests/MyGame/Example/Monster.java index 0633dff08a51e13e91c8154597325d518a109279..a4c16d8aeea644761fa141e13ad6c409c65bc3df 100644 --- a/tests/MyGame/Example/Monster.java +++ b/tests/MyGame/Example/Monster.java @@ -140,21 +140,24 @@ public final class Monster extends Table { protected int keysCompare(Integer o1, Integer o2, ByteBuffer _bb) { return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb); } public static Monster lookupByKey(int vectorOffset, String key, ByteBuffer bb) { - byte[] byteKey = key.getBytes(StandardCharsets.UTF_8); - int vectorLocation = bb.array().length - vectorOffset.Value; - int span = bb.getInt(vectorLocation), middle, start = 0, comp, tableOffset; + byte[] byteKey = key.getBytes(Table.UTF8_CHARSET.get()); + int vectorLocation = bb.array().length - vectorOffset; + int span = bb.getInt(vectorLocation); + int start = 0; vectorLocation += 4; while (span != 0) { int middle = span / 2; - tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb); - comp = compareStrings(__offset(10, bb.array().length - tableOffset, bb), byteKey, bb); - if (comp > 0) span = middle; - else if (comp < 0) { + int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb); + int comp = compareStrings(__offset(10, bb.array().length - tableOffset, bb), byteKey, bb); + if (comp > 0) { + span = middle; + } else if (comp < 0) { middle++; start += middle; span -= middle; + } else { + return new Monster().__init(tableOffset, bb); } - else return new Monster().__init(tableOffset, bb); } return null; }