Fixed Java LookupByKey functionality for Java 1.6
authorWouter van Oortmerssen <wvo@google.com>
Fri, 26 Aug 2016 20:57:40 +0000 (13:57 -0700)
committerWouter van Oortmerssen <wvo@google.com>
Fri, 26 Aug 2016 20:58:16 +0000 (13:58 -0700)
Tested: on Linux.

Change-Id: Iea336f75a3b6e722743563813c3c9ed9db4d02fe

java/com/google/flatbuffers/Table.java
src/idl_gen_general.cpp
tests/MyGame/Example/Monster.cs
tests/MyGame/Example/Monster.java

index c9c6545..b853842 100644 (file)
@@ -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.
    *
index 04deb9a..c678dc3 100644 (file)
@@ -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";
   }
index 95a303c..91c845c 100644 (file)
@@ -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;
   }
index 0633dff..a4c16d8 100644 (file)
@@ -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;
   }