From 7c69c5dc3d635e29e3442339caa8eb06b8b9775c Mon Sep 17 00:00:00 2001 From: TGIshib <justzeddicus@gmail.com> Date: Fri, 26 Aug 2016 19:41:32 +0300 Subject: [PATCH] Fix lookupByKey, improve compareStrings --- java/com/google/flatbuffers/Table.java | 24 +++++++++++------------- net/FlatBuffers/Table.cs | 20 +++++++++----------- src/idl_gen_general.cpp | 7 ++++++- tests/MyGame/Example/Monster.cs | 3 ++- tests/MyGame/Example/Monster.java | 3 ++- 5 files changed, 30 insertions(+), 27 deletions(-) diff --git a/java/com/google/flatbuffers/Table.java b/java/com/google/flatbuffers/Table.java index 7bf07113..c9c65456 100644 --- a/java/com/google/flatbuffers/Table.java +++ b/java/com/google/flatbuffers/Table.java @@ -235,35 +235,33 @@ public class Table { int startPos_1 = offset_1 + SIZEOF_INT; int startPos_2 = offset_2 + SIZEOF_INT; int len = Math.min(len_1, len_2); + byte[] bbArray = bb.array(); for(int i = 0; i < len; i++) { - if (bb.array()[i + startPos_1] != bb.array()[i + startPos_2]) - return bb.array()[i + startPos_1] - bb.array()[i + startPos_2]; + if (bbArray[i + startPos_1] != bbArray[i + startPos_2]) + return bbArray[i + startPos_1] - bbArray[i + startPos_2]; } - if (len_1 < len_2) return -1; - if (len_1 > len_2) return 1; - return 0; + return len_1 - len_2; } /** * Compare string from the buffer with the 'String' object. * * @param offset_1 An 'int' index of the first string into the bb. - * @param key Second string. + * @param key Second string as a byte array. * @param bb A {@code ByteBuffer} to get the first string. */ - protected static int compareStrings(int offset_1, String key, ByteBuffer bb) { + protected static int compareStrings(int offset_1, byte[] key, ByteBuffer bb) { offset_1 += bb.getInt(offset_1); int len_1 = bb.getInt(offset_1); - int len_2 = key.length(); + int len_2 = key.length; int startPos_1 = offset_1 + Constants.SIZEOF_INT; int len = Math.min(len_1, len_2); + byte[] bbArray = bb.array(); for (int i = 0; i < len; i++) { - if (bb.array()[i + startPos_1] != key.charAt(i)) - return bb.array()[i + startPos_1] - key.charAt(i); + if (bbArray[i + startPos_1] != key[i]) + return bbArray[i + startPos_1] - key[i]; } - if (len_1 < len_2) return -1; - if (len_1 > len_2) return 1; - return 0; + return len_1 - len_2; } } diff --git a/net/FlatBuffers/Table.cs b/net/FlatBuffers/Table.cs index 20f41f6f..ca52d7d0 100644 --- a/net/FlatBuffers/Table.cs +++ b/net/FlatBuffers/Table.cs @@ -125,30 +125,28 @@ namespace FlatBuffers var startPos_1 = offset_1 + sizeof(int); var startPos_2 = offset_2 + sizeof(int); var len = Math.Min(len_1, len_2); + byte[] bbArray = bb.Data; for(int i = 0; i < len; i++) { - if (bb.Data[i + startPos_1] != bb.Data[i + startPos_2]) - return bb.Data[i + startPos_1] - bb.Data[i + startPos_2]; + if (bbArray[i + startPos_1] != bbArray[i + startPos_2]) + return bbArray[i + startPos_1] - bbArray[i + startPos_2]; } - if (len_1 < len_2) return -1; - if (len_1 > len_2) return 1; - return 0; + return len_1 - len_2; } // Compare string from the ByteBuffer with the string object - protected static int CompareStrings(int offset_1, string key, ByteBuffer bb) + protected static int CompareStrings(int offset_1, byte[] key, ByteBuffer bb) { offset_1 += bb.GetInt(offset_1); var len_1 = bb.GetInt(offset_1); var len_2 = key.Length; var startPos_1 = offset_1 + sizeof(int); var len = Math.Min(len_1, len_2); + byte[] bbArray = bb.Data; for (int i = 0; i < len; i++) { - if (bb.Data[i + startPos_1] != key[i]) - return bb.Data[i + startPos_1] - key[i]; + if (bbArray[i + startPos_1] != key[i]) + return bbArray[i + startPos_1] - key[i]; } - if (len_1 < len_2) return -1; - if (len_1 > len_2) return 1; - return 0; + return len_1 - len_2; } } diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp index f2efe719..04deb9a0 100644 --- a/src/idl_gen_general.cpp +++ b/src/idl_gen_general.cpp @@ -699,7 +699,7 @@ std::string GenLookupKeyGetter(flatbuffers::FieldDef *key_field) { if (key_field->value.type.base_type == BASE_TYPE_STRING) { key_getter += "comp = " + FunctionStart('C') + "ompareStrings("; key_getter += GenOffsetGetter(key_field); - key_getter += ", key, bb);\n"; + key_getter += ", byteKey, bb);\n"; } else { auto get_val = GenGetter(key_field->value.type) + @@ -1237,6 +1237,11 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) { code += "ookupByKey(" + GenVectorOffsetType(); code += " vectorOffset, " + GenTypeGet(key_field->value.type); code += " key, ByteBuffer bb) {\n"; + code += " byte[] byteKey = "; + if (lang_.language == IDLOptions::kJava) + code += "key.getBytes(StandardCharsets.UTF_8);\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), "; diff --git a/tests/MyGame/Example/Monster.cs b/tests/MyGame/Example/Monster.cs index ce89443a..95a303cf 100644 --- a/tests/MyGame/Example/Monster.cs +++ b/tests/MyGame/Example/Monster.cs @@ -136,13 +136,14 @@ 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; vectorLocation += 4; while (span != 0) { int middle = span / 2; tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb); - comp = CompareStrings(__offset(10, bb.Length - tableOffset, bb), key, bb); + comp = CompareStrings(__offset(10, bb.Length - tableOffset, bb), byteKey, bb); if (comp > 0) span = middle; else if (comp < 0) { middle++; diff --git a/tests/MyGame/Example/Monster.java b/tests/MyGame/Example/Monster.java index 2c20fa7d..0633dff0 100644 --- a/tests/MyGame/Example/Monster.java +++ b/tests/MyGame/Example/Monster.java @@ -140,13 +140,14 @@ 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; 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), key, bb); + comp = compareStrings(__offset(10, bb.array().length - tableOffset, bb), byteKey, bb); if (comp > 0) span = middle; else if (comp < 0) { middle++; -- GitLab