mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-30 00:12:01 +00:00
Fixed Java LookupByKey functionality for Java 1.6
Tested: on Linux. Change-Id: Iea336f75a3b6e722743563813c3c9ed9db4d02fe
This commit is contained in:
@@ -37,6 +37,12 @@ public class Table {
|
|||||||
return Charset.forName("UTF-8").newDecoder();
|
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>();
|
private final static ThreadLocal<CharBuffer> CHAR_BUFFER = new ThreadLocal<CharBuffer>();
|
||||||
/** Used to hold the position of the `bb` buffer. */
|
/** Used to hold the position of the `bb` buffer. */
|
||||||
protected int bb_pos;
|
protected int bb_pos;
|
||||||
@@ -75,7 +81,7 @@ public class Table {
|
|||||||
protected int __indirect(int offset) {
|
protected int __indirect(int offset) {
|
||||||
return offset + bb.getInt(offset);
|
return offset + bb.getInt(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static int __indirect(int offset, ByteBuffer bb) {
|
protected static int __indirect(int offset, ByteBuffer bb) {
|
||||||
return offset + bb.getInt(offset);
|
return offset + bb.getInt(offset);
|
||||||
}
|
}
|
||||||
@@ -197,17 +203,21 @@ public class Table {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort tables by the key.
|
* Sort tables by the key.
|
||||||
*
|
*
|
||||||
* @param offsets An 'int' indexes of the tables into the bb.
|
* @param offsets An 'int' indexes of the tables into the bb.
|
||||||
* @param bb A {@code ByteBuffer} to get the tables.
|
* @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];
|
Integer[] off = new Integer[offsets.length];
|
||||||
for (int i = 0; i < offsets.length; i++) off[i] = offsets[i];
|
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];
|
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.
|
* @param bb A {@code ByteBuffer} to get the keys.
|
||||||
*/
|
*/
|
||||||
protected int keysCompare(Integer o1, Integer o2, ByteBuffer bb) { return 0; }
|
protected int keysCompare(Integer o1, Integer o2, ByteBuffer bb) { return 0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare two strings in the buffer.
|
* Compare two strings in the buffer.
|
||||||
*
|
*
|
||||||
@@ -242,7 +252,7 @@ public class Table {
|
|||||||
}
|
}
|
||||||
return len_1 - len_2;
|
return len_1 - len_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare string from the buffer with the 'String' object.
|
* Compare string from the buffer with the 'String' object.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ class GeneralGenerator : public BaseGenerator {
|
|||||||
// Save out the generated code for a single class while adding
|
// Save out the generated code for a single class while adding
|
||||||
// declaration boilerplate.
|
// declaration boilerplate.
|
||||||
bool SaveType(const std::string &defname, const Namespace &ns,
|
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;
|
if (!classcode.length()) return true;
|
||||||
|
|
||||||
std::string code;
|
std::string code;
|
||||||
@@ -684,8 +684,7 @@ std::string GenOffsetGetter(flatbuffers::FieldDef *key_field, const char *num =
|
|||||||
key_offset += num;
|
key_offset += num;
|
||||||
key_offset += (lang_.language == IDLOptions::kCSharp ?
|
key_offset += (lang_.language == IDLOptions::kCSharp ?
|
||||||
".Value, builder.DataBuffer)" : ", _bb)");
|
".Value, builder.DataBuffer)" : ", _bb)");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
key_offset += GenByteBufferLength("bb");
|
key_offset += GenByteBufferLength("bb");
|
||||||
key_offset += " - tableOffset, 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 GenLookupKeyGetter(flatbuffers::FieldDef *key_field) {
|
||||||
std::string key_getter = " ";
|
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 ";
|
key_getter += ", bb);\n ";
|
||||||
if (key_field->value.type.base_type == BASE_TYPE_STRING) {
|
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 += GenOffsetGetter(key_field);
|
||||||
key_getter += ", byteKey, bb);\n";
|
key_getter += ", byteKey, bb);\n";
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
auto get_val = GenGetter(key_field->value.type) +
|
auto get_val = GenGetter(key_field->value.type) +
|
||||||
"(" + GenOffsetGetter(key_field) + ")";
|
"(" + GenOffsetGetter(key_field) + ")";
|
||||||
if (lang_.language == IDLOptions::kCSharp) {
|
if (lang_.language == IDLOptions::kCSharp) {
|
||||||
key_getter += "comp = " + get_val + ".CompateTo(key);\n";
|
key_getter += "int comp = " + get_val + ".CompateTo(key);\n";
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
key_getter += GenTypeGet(key_field->value.type) + " val = ";
|
key_getter += GenTypeGet(key_field->value.type) + " val = ";
|
||||||
key_getter += get_val + ";\n";
|
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;
|
return key_getter;
|
||||||
@@ -1239,26 +1236,29 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
|||||||
code += " key, ByteBuffer bb) {\n";
|
code += " key, ByteBuffer bb) {\n";
|
||||||
code += " byte[] byteKey = ";
|
code += " byte[] byteKey = ";
|
||||||
if (lang_.language == IDLOptions::kJava)
|
if (lang_.language == IDLOptions::kJava)
|
||||||
code += "key.getBytes(StandardCharsets.UTF_8);\n";
|
code += "key.getBytes(Table.UTF8_CHARSET.get());\n";
|
||||||
else
|
else
|
||||||
code += "System.Text.Encoding.UTF8.GetBytes(key);\n";
|
code += "System.Text.Encoding.UTF8.GetBytes(key);\n";
|
||||||
code += " int vectorLocation = " + GenByteBufferLength("bb");
|
code += " int vectorLocation = " + GenByteBufferLength("bb");
|
||||||
code += " - vectorOffset.Value;\n int span = ";
|
code += " - vectorOffset";
|
||||||
code += "bb." + FunctionStart('G') + "etInt(vectorLocation), ";
|
if (lang_.language == IDLOptions::kCsharp) code += ".Value";
|
||||||
code += "middle, start = 0, comp, tableOffset; \n";
|
code += ";\n int span = ";
|
||||||
|
code += "bb." + FunctionStart('G') + "etInt(vectorLocation);\n";
|
||||||
|
code += " int start = 0;\n";
|
||||||
code += " vectorLocation += 4;\n";
|
code += " vectorLocation += 4;\n";
|
||||||
code += " while (span != 0) {\n";
|
code += " while (span != 0) {\n";
|
||||||
code += " int middle = span / 2;\n";
|
code += " int middle = span / 2;\n";
|
||||||
code += GenLookupKeyGetter(key_field);
|
code += GenLookupKeyGetter(key_field);
|
||||||
code += " if (comp > 0) span = middle;\n";
|
code += " if (comp > 0) {\n";
|
||||||
code += " else if (comp < 0) {\n";
|
code += " span = middle;\n";
|
||||||
|
code += " } else if (comp < 0) {\n";
|
||||||
code += " middle++;\n";
|
code += " middle++;\n";
|
||||||
code += " start += middle;\n";
|
code += " start += middle;\n";
|
||||||
code += " span -= middle;\n";
|
code += " span -= middle;\n";
|
||||||
code += " }\n";
|
code += " } else {\n";
|
||||||
code += " else return new " + struct_def.name;
|
code += " return new " + struct_def.name;
|
||||||
code += "().__init(tableOffset, bb);\n";
|
code += "().__init(tableOffset, bb);\n";
|
||||||
code += " }\n";
|
code += " }\n }\n";
|
||||||
code += " return null;\n";
|
code += " return null;\n";
|
||||||
code += " }\n";
|
code += " }\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ public sealed class Monster : Table {
|
|||||||
return new Offset<Monster>(o);
|
return new Offset<Monster>(o);
|
||||||
}
|
}
|
||||||
public static void FinishMonsterBuffer(FlatBufferBuilder builder, Offset<Monster> offset) { builder.Finish(offset.Value, "MONS"); }
|
public static void FinishMonsterBuffer(FlatBufferBuilder builder, Offset<Monster> offset) { builder.Finish(offset.Value, "MONS"); }
|
||||||
|
|
||||||
public static VectorOffset CreateMySortedVectorOfTables(FlatBufferBuilder builder, Offset<Monster>[] offsets) {
|
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));
|
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);
|
return builder.CreateVectorOfTables(offsets);
|
||||||
@@ -137,20 +137,23 @@ public sealed class Monster : Table {
|
|||||||
|
|
||||||
public static Monster LookupByKey(VectorOffset vectorOffset, string key, ByteBuffer bb) {
|
public static Monster LookupByKey(VectorOffset vectorOffset, string key, ByteBuffer bb) {
|
||||||
byte[] byteKey = System.Text.Encoding.UTF8.GetBytes(key);
|
byte[] byteKey = System.Text.Encoding.UTF8.GetBytes(key);
|
||||||
int vectorLocation = bb.Length - vectorOffset.Value;
|
int vectorLocation = bb.Length - vectorOffset;
|
||||||
int span = bb.GetInt(vectorLocation), middle, start = 0, comp, tableOffset;
|
int span = bb.GetInt(vectorLocation);
|
||||||
|
int start = 0;
|
||||||
vectorLocation += 4;
|
vectorLocation += 4;
|
||||||
while (span != 0) {
|
while (span != 0) {
|
||||||
int middle = span / 2;
|
int middle = span / 2;
|
||||||
tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
|
int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
|
||||||
comp = CompareStrings(__offset(10, bb.Length - tableOffset, bb), byteKey, bb);
|
int comp = CompareStrings(__offset(10, bb.Length - tableOffset, bb), byteKey, bb);
|
||||||
if (comp > 0) span = middle;
|
if (comp > 0) {
|
||||||
else if (comp < 0) {
|
span = middle;
|
||||||
|
} else if (comp < 0) {
|
||||||
middle++;
|
middle++;
|
||||||
start += middle;
|
start += middle;
|
||||||
span -= middle;
|
span -= middle;
|
||||||
|
} else {
|
||||||
|
return new Monster().__init(tableOffset, bb);
|
||||||
}
|
}
|
||||||
else return new Monster().__init(tableOffset, bb);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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); }
|
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) {
|
public static Monster lookupByKey(int vectorOffset, String key, ByteBuffer bb) {
|
||||||
byte[] byteKey = key.getBytes(StandardCharsets.UTF_8);
|
byte[] byteKey = key.getBytes(Table.UTF8_CHARSET.get());
|
||||||
int vectorLocation = bb.array().length - vectorOffset.Value;
|
int vectorLocation = bb.array().length - vectorOffset;
|
||||||
int span = bb.getInt(vectorLocation), middle, start = 0, comp, tableOffset;
|
int span = bb.getInt(vectorLocation);
|
||||||
|
int start = 0;
|
||||||
vectorLocation += 4;
|
vectorLocation += 4;
|
||||||
while (span != 0) {
|
while (span != 0) {
|
||||||
int middle = span / 2;
|
int middle = span / 2;
|
||||||
tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
|
int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
|
||||||
comp = compareStrings(__offset(10, bb.array().length - tableOffset, bb), byteKey, bb);
|
int comp = compareStrings(__offset(10, bb.array().length - tableOffset, bb), byteKey, bb);
|
||||||
if (comp > 0) span = middle;
|
if (comp > 0) {
|
||||||
else if (comp < 0) {
|
span = middle;
|
||||||
|
} else if (comp < 0) {
|
||||||
middle++;
|
middle++;
|
||||||
start += middle;
|
start += middle;
|
||||||
span -= middle;
|
span -= middle;
|
||||||
|
} else {
|
||||||
|
return new Monster().__init(tableOffset, bb);
|
||||||
}
|
}
|
||||||
else return new Monster().__init(tableOffset, bb);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user