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