summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--java/com/google/flatbuffers/FlexBuffers.java18
-rw-r--r--java/com/google/flatbuffers/FlexBuffersBuilder.java17
-rw-r--r--tests/JavaTest.java97
3 files changed, 106 insertions, 26 deletions
diff --git a/java/com/google/flatbuffers/FlexBuffers.java b/java/com/google/flatbuffers/FlexBuffers.java
index 0605c1b2..ff8ea8d8 100644
--- a/java/com/google/flatbuffers/FlexBuffers.java
+++ b/java/com/google/flatbuffers/FlexBuffers.java
@@ -77,7 +77,9 @@ public class FlexBuffers {
/** Represent a vector of keys type */
public static final int FBT_VECTOR_KEY = 14;
/** Represent a vector of strings type */
- public static final int FBT_VECTOR_STRING = 15;
+ // DEPRECATED, use FBT_VECTOR or FBT_VECTOR_KEY instead.
+ // more info on thttps://github.com/google/flatbuffers/issues/5627.
+ public static final int FBT_VECTOR_STRING_DEPRECATED = 15;
/// @cond FLATBUFFERS_INTERNAL
public static final int FBT_VECTOR_INT2 = 16; // Typed tuple = no type table; no size field).
@@ -107,7 +109,7 @@ public class FlexBuffers {
* @return true if typed vector
*/
static boolean isTypedVector(int type) {
- return (type >= FBT_VECTOR_INT && type <= FBT_VECTOR_STRING) || type == FBT_VECTOR_BOOL;
+ return (type >= FBT_VECTOR_INT && type <= FBT_VECTOR_STRING_DEPRECATED) || type == FBT_VECTOR_BOOL;
}
/**
@@ -145,7 +147,7 @@ public class FlexBuffers {
}
static boolean isTypedVectorElementType(int type) {
- return (type >= FBT_INT && type <= FBT_STRING) || type == FBT_BOOL;
+ return (type >= FBT_INT && type <= FBT_KEY) || type == FBT_BOOL;
}
// return position of the element that the offset is pointing to
@@ -322,8 +324,7 @@ public class FlexBuffers {
* @return true if a typed vector type
*/
public boolean isTypedVector() {
- return (type >= FBT_VECTOR_INT && type <= FBT_VECTOR_STRING) ||
- type == FBT_VECTOR_BOOL;
+ return FlexBuffers.isTypedVector(type);
}
/**
@@ -482,7 +483,7 @@ public class FlexBuffers {
public String asString() {
if (isString()) {
int start = indirect(bb, end, parentWidth);
- int size = readInt(bb, start - byteWidth, byteWidth);
+ int size = (int) readUInt(bb, start - byteWidth, byteWidth);
return Utf8.getDefault().decodeUtf8(bb, start, size);
}
else if (isKey()){
@@ -516,6 +517,9 @@ public class FlexBuffers {
public Vector asVector() {
if (isVector()) {
return new Vector(bb, indirect(bb, end, parentWidth), byteWidth);
+ } else if(type == FlexBuffers.FBT_VECTOR_STRING_DEPRECATED) {
+ // deprecated. Should be treated as key vector
+ return new TypedVector(bb, indirect(bb, end, parentWidth), byteWidth, FlexBuffers.FBT_KEY);
} else if (FlexBuffers.isTypedVector(type)) {
return new TypedVector(bb, indirect(bb, end, parentWidth), byteWidth, FlexBuffers.toTypedVectorElementType(type));
} else {
@@ -590,7 +594,7 @@ public class FlexBuffers {
case FBT_VECTOR_UINT:
case FBT_VECTOR_FLOAT:
case FBT_VECTOR_KEY:
- case FBT_VECTOR_STRING:
+ case FBT_VECTOR_STRING_DEPRECATED:
case FBT_VECTOR_BOOL:
return sb.append(asVector());
case FBT_VECTOR_INT2:
diff --git a/java/com/google/flatbuffers/FlexBuffersBuilder.java b/java/com/google/flatbuffers/FlexBuffersBuilder.java
index 64db751f..c8438bba 100644
--- a/java/com/google/flatbuffers/FlexBuffersBuilder.java
+++ b/java/com/google/flatbuffers/FlexBuffersBuilder.java
@@ -358,24 +358,24 @@ public class FlexBuffersBuilder {
}
private Value writeString(int key, String s) {
- return writeBlob(key, s.getBytes(StandardCharsets.UTF_8), FBT_STRING);
+ return writeBlob(key, s.getBytes(StandardCharsets.UTF_8), FBT_STRING, true);
}
// in bits to fit a unsigned int
- private static int widthUInBits(long len) {
+ static int widthUInBits(long len) {
if (len <= byteToUnsignedInt((byte)0xff)) return WIDTH_8;
if (len <= shortToUnsignedInt((short)0xffff)) return WIDTH_16;
if (len <= intToUnsignedLong(0xffff_ffff)) return WIDTH_32;
return WIDTH_64;
}
- private Value writeBlob(int key, byte[] blob, int type) {
+ private Value writeBlob(int key, byte[] blob, int type, boolean trailing) {
int bitWidth = widthUInBits(blob.length);
int byteWidth = align(bitWidth);
writeInt(blob.length, byteWidth);
int sloc = bb.position();
bb.put(blob);
- if (type == FBT_STRING) {
+ if (trailing) {
bb.put((byte) 0);
}
return Value.blob(key, sloc, type, bitWidth);
@@ -384,7 +384,7 @@ public class FlexBuffersBuilder {
// Align to prepare for writing a scalar with a certain size.
private int align(int alignment) {
int byteWidth = 1 << alignment;
- int padBytes = Value.paddingBytes(bb.capacity(), byteWidth);
+ int padBytes = Value.paddingBytes(bb.position(), byteWidth);
while (padBytes-- != 0) {
bb.put((byte) 0);
}
@@ -417,7 +417,7 @@ public class FlexBuffersBuilder {
*/
public int putBlob(String key, byte[] val) {
int iKey = putKey(key);
- Value value = writeBlob(iKey, val, FBT_BLOB);
+ Value value = writeBlob(iKey, val, FBT_BLOB, false);
stack.add(value);
return (int) value.iValue;
}
@@ -504,6 +504,9 @@ public class FlexBuffersBuilder {
if (typed) {
if (i == start) {
vectorType = stack.get(i).type;
+ if (!FlexBuffers.isTypedVectorElementType(vectorType)) {
+ throw new FlexBufferException("TypedVector does not support this element type");
+ }
} else {
// If you get this assert, you are writing a typed vector with
// elements that are not all the same type.
@@ -659,7 +662,7 @@ public class FlexBuffersBuilder {
}
static Value blob(int key, int position, int type, int bitWidth) {
- return new Value(key, type, WIDTH_8, position);
+ return new Value(key, type, bitWidth, position);
}
static Value int8(int key, int value) {
diff --git a/tests/JavaTest.java b/tests/JavaTest.java
index 1443b779..766d3525 100644
--- a/tests/JavaTest.java
+++ b/tests/JavaTest.java
@@ -12,6 +12,10 @@ import com.google.flatbuffers.FlexBuffers;
import com.google.flatbuffers.FlexBuffersBuilder;
import com.google.flatbuffers.StringVector;
import com.google.flatbuffers.UnionVector;
+import com.google.flatbuffers.FlexBuffers.FlexBufferException;
+import com.google.flatbuffers.FlexBuffers.Reference;
+import com.google.flatbuffers.FlexBuffers.Vector;
+
import java.io.*;
import java.math.BigInteger;
import java.nio.ByteBuffer;
@@ -694,6 +698,60 @@ class JavaTest {
TestEq(mymap.get("blob").toString(), "\"AC\"");
}
+ public static void testFlexBufferVectorStrings() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000000));
+
+ int size = 3000;
+ StringBuilder sb = new StringBuilder();
+ for (int i=0; i< size; i++) {
+ sb.append("a");
+ }
+
+ String text = sb.toString();
+ TestEq(text.length(), size);
+
+ int pos = builder.startVector();
+
+ for (int i=0; i<size; i++) {
+ builder.putString(text);
+ }
+
+ try {
+ builder.endVector(null, pos, true, false);
+ // this should raise an exception as
+ // typed vector of string was deprecated
+ assert false;
+ } catch(FlexBufferException fb) {
+ // no op
+ }
+ // we finish the vector again as non-typed
+ builder.endVector(null, pos, false, false);
+
+ ByteBuffer b = builder.finish();
+ Vector v = FlexBuffers.getRoot(b).asVector();
+
+ TestEq(v.size(), size);
+ for (int i=0; i<size; i++) {
+ TestEq(v.get(i).asString().length(), size);
+ TestEq(v.get(i).asString(), text);
+ }
+ }
+
+ public static void testDeprecatedTypedVectorString() {
+ // tests whether we are able to support reading deprecated typed vector string
+ // data is equivalent to [ "abc", "abc", "abc", "abc"]
+ byte[] data = new byte[] {0x03, 0x61, 0x62, 0x63, 0x00, 0x03, 0x61, 0x62, 0x63, 0x00,
+ 0x03, 0x61, 0x62, 0x63, 0x00, 0x03, 0x61, 0x62, 0x63, 0x00, 0x04, 0x14, 0x10,
+ 0x0c, 0x08, 0x04, 0x3c, 0x01};
+ Reference ref = FlexBuffers.getRoot(ByteBuffer.wrap(data));
+ TestEq(ref.getType(), FlexBuffers.FBT_VECTOR_STRING_DEPRECATED);
+ TestEq(ref.isTypedVector(), true);
+ Vector vec = ref.asVector();
+ for (int i=0; i< vec.size(); i++) {
+ TestEq("abc", vec.get(i).asString());
+ }
+ }
+
public static void testSingleElementBoolean() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(100));
builder.putBoolean(true);
@@ -743,13 +801,32 @@ class JavaTest {
TestEq(Double.compare(Double.MAX_VALUE, FlexBuffers.getRoot(b).asFloat()), 0);
}
- public static void testSingleElementString() {
- FlexBuffersBuilder builder = new FlexBuffersBuilder();
- builder.putString("wow");
+ public static void testSingleElementBigString() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000));
+ StringBuilder sb = new StringBuilder();
+
+ for (int i=0; i< 3000; i++) {
+ sb.append("a");
+ }
+
+ builder.putString(sb.toString());
+ ByteBuffer b = builder.finish();
+
+ FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+
+ TestEq(FlexBuffers.FBT_STRING, r.getType());
+ TestEq(sb.toString(), r.asString());
+ }
+
+ public static void testSingleElementSmallString() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000));
+
+ builder.putString("aa");
ByteBuffer b = builder.finish();
FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+
TestEq(FlexBuffers.FBT_STRING, r.getType());
- TestEq("wow", r.asString());
+ TestEq("aa", r.asString());
}
public static void testSingleElementBlob() {
@@ -814,12 +891,6 @@ class JavaTest {
builder.endVector("floats", vecPos, true, false);
vecPos = builder.startVector();
- for (final String i : strings) {
- builder.putString(i);
- }
- builder.endVector("strings", vecPos, true, false);
-
- vecPos = builder.startVector();
for (final boolean i : booleans) {
builder.putBoolean(i);
}
@@ -832,7 +903,6 @@ class JavaTest {
FlexBuffers.Reference r = FlexBuffers.getRoot(b);
assert(r.asMap().get("ints").isTypedVector());
assert(r.asMap().get("floats").isTypedVector());
- assert(r.asMap().get("strings").isTypedVector());
assert(r.asMap().get("booleans").isTypedVector());
}
@@ -944,7 +1014,8 @@ class JavaTest {
testSingleElementLong();
testSingleElementFloat();
testSingleElementDouble();
- testSingleElementString();
+ testSingleElementSmallString();
+ testSingleElementBigString();
testSingleElementBlob();
testSingleElementVector();
testSingleFixedTypeVector();
@@ -955,6 +1026,8 @@ class JavaTest {
testFlexBuffersTest();
testHashMapToMap();
testFlexBuferEmpty();
+ testFlexBufferVectorStrings();
+ testDeprecatedTypedVectorString();
}
static void TestVectorOfBytes() {