bulk code format fix (#8707)

This commit is contained in:
Derek Bailey
2025-09-23 21:50:27 -07:00
committed by GitHub
parent 0e047869da
commit caf3b494db
559 changed files with 38871 additions and 31276 deletions

View File

@@ -1,6 +1,5 @@
// automatically generated by the FlatBuffers compiler, do not modify // automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_ANIMAL_COM_FBS_APP_H_ #ifndef FLATBUFFERS_GENERATED_ANIMAL_COM_FBS_APP_H_
#define FLATBUFFERS_GENERATED_ANIMAL_COM_FBS_APP_H_ #define FLATBUFFERS_GENERATED_ANIMAL_COM_FBS_APP_H_
@@ -27,29 +26,24 @@ struct Animal FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
VT_SOUND = 6, VT_SOUND = 6,
VT_WEIGHT = 8 VT_WEIGHT = 8
}; };
const ::flatbuffers::String *name() const { const ::flatbuffers::String* name() const {
return GetPointer<const ::flatbuffers::String *>(VT_NAME); return GetPointer<const ::flatbuffers::String*>(VT_NAME);
} }
const ::flatbuffers::String *sound() const { const ::flatbuffers::String* sound() const {
return GetPointer<const ::flatbuffers::String *>(VT_SOUND); return GetPointer<const ::flatbuffers::String*>(VT_SOUND);
} }
uint16_t weight() const { uint16_t weight() const { return GetField<uint16_t>(VT_WEIGHT, 0); }
return GetField<uint16_t>(VT_WEIGHT, 0); bool Verify(::flatbuffers::Verifier& verifier) const {
} return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_NAME) &&
bool Verify(::flatbuffers::Verifier &verifier) const { verifier.VerifyString(name()) && VerifyOffset(verifier, VT_SOUND) &&
return VerifyTableStart(verifier) &&
VerifyOffset(verifier, VT_NAME) &&
verifier.VerifyString(name()) &&
VerifyOffset(verifier, VT_SOUND) &&
verifier.VerifyString(sound()) && verifier.VerifyString(sound()) &&
VerifyField<uint16_t>(verifier, VT_WEIGHT, 2) && VerifyField<uint16_t>(verifier, VT_WEIGHT, 2) && verifier.EndTable();
verifier.EndTable();
} }
}; };
struct AnimalBuilder { struct AnimalBuilder {
typedef Animal Table; typedef Animal Table;
::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::FlatBufferBuilder& fbb_;
::flatbuffers::uoffset_t start_; ::flatbuffers::uoffset_t start_;
void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { void add_name(::flatbuffers::Offset<::flatbuffers::String> name) {
fbb_.AddOffset(Animal::VT_NAME, name); fbb_.AddOffset(Animal::VT_NAME, name);
@@ -60,8 +54,7 @@ struct AnimalBuilder {
void add_weight(uint16_t weight) { void add_weight(uint16_t weight) {
fbb_.AddElement<uint16_t>(Animal::VT_WEIGHT, weight, 0); fbb_.AddElement<uint16_t>(Animal::VT_WEIGHT, weight, 0);
} }
explicit AnimalBuilder(::flatbuffers::FlatBufferBuilder &_fbb) explicit AnimalBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) {
: fbb_(_fbb) {
start_ = fbb_.StartTable(); start_ = fbb_.StartTable();
} }
::flatbuffers::Offset<Animal> Finish() { ::flatbuffers::Offset<Animal> Finish() {
@@ -72,7 +65,7 @@ struct AnimalBuilder {
}; };
inline ::flatbuffers::Offset<Animal> CreateAnimal( inline ::flatbuffers::Offset<Animal> CreateAnimal(
::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::FlatBufferBuilder& _fbb,
::flatbuffers::Offset<::flatbuffers::String> name = 0, ::flatbuffers::Offset<::flatbuffers::String> name = 0,
::flatbuffers::Offset<::flatbuffers::String> sound = 0, ::flatbuffers::Offset<::flatbuffers::String> sound = 0,
uint16_t weight = 0) { uint16_t weight = 0) {
@@ -84,45 +77,37 @@ inline ::flatbuffers::Offset<Animal> CreateAnimal(
} }
inline ::flatbuffers::Offset<Animal> CreateAnimalDirect( inline ::flatbuffers::Offset<Animal> CreateAnimalDirect(
::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::FlatBufferBuilder& _fbb, const char* name = nullptr,
const char *name = nullptr, const char* sound = nullptr, uint16_t weight = 0) {
const char *sound = nullptr,
uint16_t weight = 0) {
auto name__ = name ? _fbb.CreateString(name) : 0; auto name__ = name ? _fbb.CreateString(name) : 0;
auto sound__ = sound ? _fbb.CreateString(sound) : 0; auto sound__ = sound ? _fbb.CreateString(sound) : 0;
return com::fbs::app::CreateAnimal( return com::fbs::app::CreateAnimal(_fbb, name__, sound__, weight);
_fbb,
name__,
sound__,
weight);
} }
inline const com::fbs::app::Animal *GetAnimal(const void *buf) { inline const com::fbs::app::Animal* GetAnimal(const void* buf) {
return ::flatbuffers::GetRoot<com::fbs::app::Animal>(buf); return ::flatbuffers::GetRoot<com::fbs::app::Animal>(buf);
} }
inline const com::fbs::app::Animal *GetSizePrefixedAnimal(const void *buf) { inline const com::fbs::app::Animal* GetSizePrefixedAnimal(const void* buf) {
return ::flatbuffers::GetSizePrefixedRoot<com::fbs::app::Animal>(buf); return ::flatbuffers::GetSizePrefixedRoot<com::fbs::app::Animal>(buf);
} }
inline bool VerifyAnimalBuffer( inline bool VerifyAnimalBuffer(::flatbuffers::Verifier& verifier) {
::flatbuffers::Verifier &verifier) {
return verifier.VerifyBuffer<com::fbs::app::Animal>(nullptr); return verifier.VerifyBuffer<com::fbs::app::Animal>(nullptr);
} }
inline bool VerifySizePrefixedAnimalBuffer( inline bool VerifySizePrefixedAnimalBuffer(::flatbuffers::Verifier& verifier) {
::flatbuffers::Verifier &verifier) {
return verifier.VerifySizePrefixedBuffer<com::fbs::app::Animal>(nullptr); return verifier.VerifySizePrefixedBuffer<com::fbs::app::Animal>(nullptr);
} }
inline void FinishAnimalBuffer( inline void FinishAnimalBuffer(
::flatbuffers::FlatBufferBuilder &fbb, ::flatbuffers::FlatBufferBuilder& fbb,
::flatbuffers::Offset<com::fbs::app::Animal> root) { ::flatbuffers::Offset<com::fbs::app::Animal> root) {
fbb.Finish(root); fbb.Finish(root);
} }
inline void FinishSizePrefixedAnimalBuffer( inline void FinishSizePrefixedAnimalBuffer(
::flatbuffers::FlatBufferBuilder &fbb, ::flatbuffers::FlatBufferBuilder& fbb,
::flatbuffers::Offset<com::fbs::app::Animal> root) { ::flatbuffers::Offset<com::fbs::app::Animal> root) {
fbb.FinishSizePrefixed(root); fbb.FinishSizePrefixed(root);
} }

View File

@@ -1,9 +1,9 @@
package com.flatbuffers.app package com.flatbuffers.app
import android.annotation.SuppressLint import android.annotation.SuppressLint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.fbs.app.Animal import com.fbs.app.Animal
import com.google.flatbuffers.FlatBufferBuilder import com.google.flatbuffers.FlatBufferBuilder
import java.nio.ByteBuffer import java.nio.ByteBuffer
@@ -27,13 +27,14 @@ class MainActivity : AppCompatActivity() {
private external fun createAnimalFromJNI(): ByteArray private external fun createAnimalFromJNI(): ByteArray
// Create a "Cow" Animal flatbuffers from Kotlin // Create a "Cow" Animal flatbuffers from Kotlin
private fun createAnimalFromKotlin():Animal { private fun createAnimalFromKotlin(): Animal {
val fb = FlatBufferBuilder(100) val fb = FlatBufferBuilder(100)
val cowOffset = Animal.createAnimal( val cowOffset =
Animal.createAnimal(
builder = fb, builder = fb,
nameOffset = fb.createString("Cow"), nameOffset = fb.createString("Cow"),
soundOffset = fb.createString("Moo"), soundOffset = fb.createString("Moo"),
weight = 720u weight = 720u,
) )
fb.finish(cowOffset) fb.finish(cowOffset)
return Animal.getRootAsAnimal(fb.dataBuffer()) return Animal.getRootAsAnimal(fb.dataBuffer())

View File

@@ -2,21 +2,11 @@
package com.fbs.app package com.fbs.app
import com.google.flatbuffers.BaseVector
import com.google.flatbuffers.BooleanVector
import com.google.flatbuffers.ByteVector
import com.google.flatbuffers.Constants import com.google.flatbuffers.Constants
import com.google.flatbuffers.DoubleVector
import com.google.flatbuffers.FlatBufferBuilder import com.google.flatbuffers.FlatBufferBuilder
import com.google.flatbuffers.FloatVector
import com.google.flatbuffers.LongVector
import com.google.flatbuffers.StringVector
import com.google.flatbuffers.Struct
import com.google.flatbuffers.Table import com.google.flatbuffers.Table
import com.google.flatbuffers.UnionVector
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.nio.ByteOrder import java.nio.ByteOrder
import kotlin.math.sign
@Suppress("unused") @Suppress("unused")
@kotlin.ExperimentalUnsignedTypes @kotlin.ExperimentalUnsignedTypes
@@ -25,11 +15,13 @@ class Animal : Table() {
fun __init(_i: Int, _bb: ByteBuffer) { fun __init(_i: Int, _bb: ByteBuffer) {
__reset(_i, _bb) __reset(_i, _bb)
} }
fun __assign(_i: Int, _bb: ByteBuffer) : Animal {
fun __assign(_i: Int, _bb: ByteBuffer): Animal {
__init(_i, _bb) __init(_i, _bb)
return this return this
} }
val name : String?
val name: String?
get() { get() {
val o = __offset(4) val o = __offset(4)
return if (o != 0) { return if (o != 0) {
@@ -38,9 +30,13 @@ class Animal : Table() {
null null
} }
} }
val nameAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(4, 1)
fun nameInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 4, 1) val nameAsByteBuffer: ByteBuffer
val sound : String? get() = __vector_as_bytebuffer(4, 1)
fun nameInByteBuffer(_bb: ByteBuffer): ByteBuffer = __vector_in_bytebuffer(_bb, 4, 1)
val sound: String?
get() { get() {
val o = __offset(6) val o = __offset(6)
return if (o != 0) { return if (o != 0) {
@@ -49,36 +45,58 @@ class Animal : Table() {
null null
} }
} }
val soundAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(6, 1)
fun soundInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 6, 1) val soundAsByteBuffer: ByteBuffer
val weight : UShort get() = __vector_as_bytebuffer(6, 1)
fun soundInByteBuffer(_bb: ByteBuffer): ByteBuffer = __vector_in_bytebuffer(_bb, 6, 1)
val weight: UShort
get() { get() {
val o = __offset(8) val o = __offset(8)
return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u return if (o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
} }
companion object { companion object {
fun validateVersion() = Constants.FLATBUFFERS_25_2_10() fun validateVersion() = Constants.FLATBUFFERS_25_2_10()
fun getRootAsAnimal(_bb: ByteBuffer): Animal = getRootAsAnimal(_bb, Animal()) fun getRootAsAnimal(_bb: ByteBuffer): Animal = getRootAsAnimal(_bb, Animal())
fun getRootAsAnimal(_bb: ByteBuffer, obj: Animal): Animal { fun getRootAsAnimal(_bb: ByteBuffer, obj: Animal): Animal {
_bb.order(ByteOrder.LITTLE_ENDIAN) _bb.order(ByteOrder.LITTLE_ENDIAN)
return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)) return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
} }
fun createAnimal(builder: FlatBufferBuilder, nameOffset: Int, soundOffset: Int, weight: UShort) : Int {
fun createAnimal(
builder: FlatBufferBuilder,
nameOffset: Int,
soundOffset: Int,
weight: UShort,
): Int {
builder.startTable(3) builder.startTable(3)
addSound(builder, soundOffset) addSound(builder, soundOffset)
addName(builder, nameOffset) addName(builder, nameOffset)
addWeight(builder, weight) addWeight(builder, weight)
return endAnimal(builder) return endAnimal(builder)
} }
fun startAnimal(builder: FlatBufferBuilder) = builder.startTable(3) fun startAnimal(builder: FlatBufferBuilder) = builder.startTable(3)
fun addName(builder: FlatBufferBuilder, name: Int) = builder.addOffset(0, name, 0) fun addName(builder: FlatBufferBuilder, name: Int) = builder.addOffset(0, name, 0)
fun addSound(builder: FlatBufferBuilder, sound: Int) = builder.addOffset(1, sound, 0) fun addSound(builder: FlatBufferBuilder, sound: Int) = builder.addOffset(1, sound, 0)
fun addWeight(builder: FlatBufferBuilder, weight: UShort) = builder.addShort(2, weight.toShort(), 0)
fun endAnimal(builder: FlatBufferBuilder) : Int { fun addWeight(builder: FlatBufferBuilder, weight: UShort) =
builder.addShort(2, weight.toShort(), 0)
fun endAnimal(builder: FlatBufferBuilder): Int {
val o = builder.endTable() val o = builder.endTable()
return o return o
} }
fun finishAnimalBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset) fun finishAnimalBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset)
fun finishSizePrefixedAnimalBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finishSizePrefixed(offset)
fun finishSizePrefixedAnimalBuffer(builder: FlatBufferBuilder, offset: Int) =
builder.finishSizePrefixed(offset)
} }
} }

View File

@@ -8,10 +8,10 @@ struct Bench {
inline void Add(int64_t value) { sum += value; } inline void Add(int64_t value) { sum += value; }
virtual uint8_t *Encode(void *buf, int64_t &len) = 0; virtual uint8_t* Encode(void* buf, int64_t& len) = 0;
virtual void *Decode(void *buf, int64_t len) = 0; virtual void* Decode(void* buf, int64_t len) = 0;
virtual int64_t Use(void *decoded) = 0; virtual int64_t Use(void* decoded) = 0;
virtual void Dealloc(void *decoded) = 0; virtual void Dealloc(void* decoded) = 0;
int64_t sum = 0; int64_t sum = 0;
}; };

View File

@@ -1,6 +1,5 @@
// automatically generated by the FlatBuffers compiler, do not modify // automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_BENCH_BENCHMARKS_FLATBUFFERS_H_ #ifndef FLATBUFFERS_GENERATED_BENCH_BENCHMARKS_FLATBUFFERS_H_
#define FLATBUFFERS_GENERATED_BENCH_BENCHMARKS_FLATBUFFERS_H_ #define FLATBUFFERS_GENERATED_BENCH_BENCHMARKS_FLATBUFFERS_H_
@@ -34,25 +33,16 @@ enum Enum : int16_t {
}; };
inline const Enum (&EnumValuesEnum())[3] { inline const Enum (&EnumValuesEnum())[3] {
static const Enum values[] = { static const Enum values[] = {Enum_Apples, Enum_Pears, Enum_Bananas};
Enum_Apples,
Enum_Pears,
Enum_Bananas
};
return values; return values;
} }
inline const char * const *EnumNamesEnum() { inline const char* const* EnumNamesEnum() {
static const char * const names[4] = { static const char* const names[4] = {"Apples", "Pears", "Bananas", nullptr};
"Apples",
"Pears",
"Bananas",
nullptr
};
return names; return names;
} }
inline const char *EnumNameEnum(Enum e) { inline const char* EnumNameEnum(Enum e) {
if (flatbuffers::IsOutRange(e, Enum_Apples, Enum_Bananas)) return ""; if (flatbuffers::IsOutRange(e, Enum_Apples, Enum_Bananas)) return "";
const size_t index = static_cast<size_t>(e); const size_t index = static_cast<size_t>(e);
return EnumNamesEnum()[index]; return EnumNamesEnum()[index];
@@ -67,12 +57,7 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Foo FLATBUFFERS_FINAL_CLASS {
uint32_t length_; uint32_t length_;
public: public:
Foo() Foo() : id_(0), count_(0), prefix_(0), padding0__(0), length_(0) {
: id_(0),
count_(0),
prefix_(0),
padding0__(0),
length_(0) {
(void)padding0__; (void)padding0__;
} }
Foo(uint64_t _id, int16_t _count, int8_t _prefix, uint32_t _length) Foo(uint64_t _id, int16_t _count, int8_t _prefix, uint32_t _length)
@@ -83,18 +68,10 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Foo FLATBUFFERS_FINAL_CLASS {
length_(flatbuffers::EndianScalar(_length)) { length_(flatbuffers::EndianScalar(_length)) {
(void)padding0__; (void)padding0__;
} }
uint64_t id() const { uint64_t id() const { return flatbuffers::EndianScalar(id_); }
return flatbuffers::EndianScalar(id_); int16_t count() const { return flatbuffers::EndianScalar(count_); }
} int8_t prefix() const { return flatbuffers::EndianScalar(prefix_); }
int16_t count() const { uint32_t length() const { return flatbuffers::EndianScalar(length_); }
return flatbuffers::EndianScalar(count_);
}
int8_t prefix() const {
return flatbuffers::EndianScalar(prefix_);
}
uint32_t length() const {
return flatbuffers::EndianScalar(length_);
}
}; };
FLATBUFFERS_STRUCT_END(Foo, 16); FLATBUFFERS_STRUCT_END(Foo, 16);
@@ -104,20 +81,17 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Bar FLATBUFFERS_FINAL_CLASS {
int32_t time_; int32_t time_;
float ratio_; float ratio_;
uint16_t size_; uint16_t size_;
int16_t padding0__; int32_t padding1__; int16_t padding0__;
int32_t padding1__;
public: public:
Bar() Bar()
: parent_(), : parent_(), time_(0), ratio_(0), size_(0), padding0__(0), padding1__(0) {
time_(0),
ratio_(0),
size_(0),
padding0__(0),
padding1__(0) {
(void)padding0__; (void)padding0__;
(void)padding1__; (void)padding1__;
} }
Bar(const benchmarks_flatbuffers::Foo &_parent, int32_t _time, float _ratio, uint16_t _size) Bar(const benchmarks_flatbuffers::Foo& _parent, int32_t _time, float _ratio,
uint16_t _size)
: parent_(_parent), : parent_(_parent),
time_(flatbuffers::EndianScalar(_time)), time_(flatbuffers::EndianScalar(_time)),
ratio_(flatbuffers::EndianScalar(_ratio)), ratio_(flatbuffers::EndianScalar(_ratio)),
@@ -127,18 +101,10 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Bar FLATBUFFERS_FINAL_CLASS {
(void)padding0__; (void)padding0__;
(void)padding1__; (void)padding1__;
} }
const benchmarks_flatbuffers::Foo &parent() const { const benchmarks_flatbuffers::Foo& parent() const { return parent_; }
return parent_; int32_t time() const { return flatbuffers::EndianScalar(time_); }
} float ratio() const { return flatbuffers::EndianScalar(ratio_); }
int32_t time() const { uint16_t size() const { return flatbuffers::EndianScalar(size_); }
return flatbuffers::EndianScalar(time_);
}
float ratio() const {
return flatbuffers::EndianScalar(ratio_);
}
uint16_t size() const {
return flatbuffers::EndianScalar(size_);
}
}; };
FLATBUFFERS_STRUCT_END(Bar, 32); FLATBUFFERS_STRUCT_END(Bar, 32);
@@ -150,34 +116,28 @@ struct FooBar FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_RATING = 8, VT_RATING = 8,
VT_POSTFIX = 10 VT_POSTFIX = 10
}; };
const benchmarks_flatbuffers::Bar *sibling() const { const benchmarks_flatbuffers::Bar* sibling() const {
return GetStruct<const benchmarks_flatbuffers::Bar *>(VT_SIBLING); return GetStruct<const benchmarks_flatbuffers::Bar*>(VT_SIBLING);
} }
const flatbuffers::String *name() const { const flatbuffers::String* name() const {
return GetPointer<const flatbuffers::String *>(VT_NAME); return GetPointer<const flatbuffers::String*>(VT_NAME);
} }
double rating() const { double rating() const { return GetField<double>(VT_RATING, 0.0); }
return GetField<double>(VT_RATING, 0.0); uint8_t postfix() const { return GetField<uint8_t>(VT_POSTFIX, 0); }
} bool Verify(flatbuffers::Verifier& verifier) const {
uint8_t postfix() const {
return GetField<uint8_t>(VT_POSTFIX, 0);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) && return VerifyTableStart(verifier) &&
VerifyField<benchmarks_flatbuffers::Bar>(verifier, VT_SIBLING, 8) && VerifyField<benchmarks_flatbuffers::Bar>(verifier, VT_SIBLING, 8) &&
VerifyOffset(verifier, VT_NAME) && VerifyOffset(verifier, VT_NAME) && verifier.VerifyString(name()) &&
verifier.VerifyString(name()) &&
VerifyField<double>(verifier, VT_RATING, 8) && VerifyField<double>(verifier, VT_RATING, 8) &&
VerifyField<uint8_t>(verifier, VT_POSTFIX, 1) && VerifyField<uint8_t>(verifier, VT_POSTFIX, 1) && verifier.EndTable();
verifier.EndTable();
} }
}; };
struct FooBarBuilder { struct FooBarBuilder {
typedef FooBar Table; typedef FooBar Table;
flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::FlatBufferBuilder& fbb_;
flatbuffers::uoffset_t start_; flatbuffers::uoffset_t start_;
void add_sibling(const benchmarks_flatbuffers::Bar *sibling) { void add_sibling(const benchmarks_flatbuffers::Bar* sibling) {
fbb_.AddStruct(FooBar::VT_SIBLING, sibling); fbb_.AddStruct(FooBar::VT_SIBLING, sibling);
} }
void add_name(flatbuffers::Offset<flatbuffers::String> name) { void add_name(flatbuffers::Offset<flatbuffers::String> name) {
@@ -189,8 +149,7 @@ struct FooBarBuilder {
void add_postfix(uint8_t postfix) { void add_postfix(uint8_t postfix) {
fbb_.AddElement<uint8_t>(FooBar::VT_POSTFIX, postfix, 0); fbb_.AddElement<uint8_t>(FooBar::VT_POSTFIX, postfix, 0);
} }
explicit FooBarBuilder(flatbuffers::FlatBufferBuilder &_fbb) explicit FooBarBuilder(flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) {
: fbb_(_fbb) {
start_ = fbb_.StartTable(); start_ = fbb_.StartTable();
} }
flatbuffers::Offset<FooBar> Finish() { flatbuffers::Offset<FooBar> Finish() {
@@ -201,10 +160,9 @@ struct FooBarBuilder {
}; };
inline flatbuffers::Offset<FooBar> CreateFooBar( inline flatbuffers::Offset<FooBar> CreateFooBar(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder& _fbb,
const benchmarks_flatbuffers::Bar *sibling = nullptr, const benchmarks_flatbuffers::Bar* sibling = nullptr,
flatbuffers::Offset<flatbuffers::String> name = 0, flatbuffers::Offset<flatbuffers::String> name = 0, double rating = 0.0,
double rating = 0.0,
uint8_t postfix = 0) { uint8_t postfix = 0) {
FooBarBuilder builder_(_fbb); FooBarBuilder builder_(_fbb);
builder_.add_rating(rating); builder_.add_rating(rating);
@@ -215,17 +173,11 @@ inline flatbuffers::Offset<FooBar> CreateFooBar(
} }
inline flatbuffers::Offset<FooBar> CreateFooBarDirect( inline flatbuffers::Offset<FooBar> CreateFooBarDirect(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder& _fbb,
const benchmarks_flatbuffers::Bar *sibling = nullptr, const benchmarks_flatbuffers::Bar* sibling = nullptr,
const char *name = nullptr, const char* name = nullptr, double rating = 0.0, uint8_t postfix = 0) {
double rating = 0.0,
uint8_t postfix = 0) {
auto name__ = name ? _fbb.CreateString(name) : 0; auto name__ = name ? _fbb.CreateString(name) : 0;
return benchmarks_flatbuffers::CreateFooBar( return benchmarks_flatbuffers::CreateFooBar(_fbb, sibling, name__, rating,
_fbb,
sibling,
name__,
rating,
postfix); postfix);
} }
@@ -237,48 +189,52 @@ struct FooBarContainer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_FRUIT = 8, VT_FRUIT = 8,
VT_LOCATION = 10 VT_LOCATION = 10
}; };
const flatbuffers::Vector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>> *list() const { const flatbuffers::Vector<
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>> *>(VT_LIST); flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>*
} list() const {
bool initialized() const { return GetPointer<const flatbuffers::Vector<
return GetField<uint8_t>(VT_INITIALIZED, 0) != 0; flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>*>(VT_LIST);
} }
bool initialized() const { return GetField<uint8_t>(VT_INITIALIZED, 0) != 0; }
benchmarks_flatbuffers::Enum fruit() const { benchmarks_flatbuffers::Enum fruit() const {
return static_cast<benchmarks_flatbuffers::Enum>(GetField<int16_t>(VT_FRUIT, 0)); return static_cast<benchmarks_flatbuffers::Enum>(
GetField<int16_t>(VT_FRUIT, 0));
} }
const flatbuffers::String *location() const { const flatbuffers::String* location() const {
return GetPointer<const flatbuffers::String *>(VT_LOCATION); return GetPointer<const flatbuffers::String*>(VT_LOCATION);
} }
bool Verify(flatbuffers::Verifier &verifier) const { bool Verify(flatbuffers::Verifier& verifier) const {
return VerifyTableStart(verifier) && return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_LIST) &&
VerifyOffset(verifier, VT_LIST) &&
verifier.VerifyVector(list()) && verifier.VerifyVector(list()) &&
verifier.VerifyVectorOfTables(list()) && verifier.VerifyVectorOfTables(list()) &&
VerifyField<uint8_t>(verifier, VT_INITIALIZED, 1) && VerifyField<uint8_t>(verifier, VT_INITIALIZED, 1) &&
VerifyField<int16_t>(verifier, VT_FRUIT, 2) && VerifyField<int16_t>(verifier, VT_FRUIT, 2) &&
VerifyOffset(verifier, VT_LOCATION) && VerifyOffset(verifier, VT_LOCATION) &&
verifier.VerifyString(location()) && verifier.VerifyString(location()) && verifier.EndTable();
verifier.EndTable();
} }
}; };
struct FooBarContainerBuilder { struct FooBarContainerBuilder {
typedef FooBarContainer Table; typedef FooBarContainer Table;
flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::FlatBufferBuilder& fbb_;
flatbuffers::uoffset_t start_; flatbuffers::uoffset_t start_;
void add_list(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>> list) { void add_list(flatbuffers::Offset<flatbuffers::Vector<
flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>>
list) {
fbb_.AddOffset(FooBarContainer::VT_LIST, list); fbb_.AddOffset(FooBarContainer::VT_LIST, list);
} }
void add_initialized(bool initialized) { void add_initialized(bool initialized) {
fbb_.AddElement<uint8_t>(FooBarContainer::VT_INITIALIZED, static_cast<uint8_t>(initialized), 0); fbb_.AddElement<uint8_t>(FooBarContainer::VT_INITIALIZED,
static_cast<uint8_t>(initialized), 0);
} }
void add_fruit(benchmarks_flatbuffers::Enum fruit) { void add_fruit(benchmarks_flatbuffers::Enum fruit) {
fbb_.AddElement<int16_t>(FooBarContainer::VT_FRUIT, static_cast<int16_t>(fruit), 0); fbb_.AddElement<int16_t>(FooBarContainer::VT_FRUIT,
static_cast<int16_t>(fruit), 0);
} }
void add_location(flatbuffers::Offset<flatbuffers::String> location) { void add_location(flatbuffers::Offset<flatbuffers::String> location) {
fbb_.AddOffset(FooBarContainer::VT_LOCATION, location); fbb_.AddOffset(FooBarContainer::VT_LOCATION, location);
} }
explicit FooBarContainerBuilder(flatbuffers::FlatBufferBuilder &_fbb) explicit FooBarContainerBuilder(flatbuffers::FlatBufferBuilder& _fbb)
: fbb_(_fbb) { : fbb_(_fbb) {
start_ = fbb_.StartTable(); start_ = fbb_.StartTable();
} }
@@ -290,8 +246,10 @@ struct FooBarContainerBuilder {
}; };
inline flatbuffers::Offset<FooBarContainer> CreateFooBarContainer( inline flatbuffers::Offset<FooBarContainer> CreateFooBarContainer(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder& _fbb,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>> list = 0, flatbuffers::Offset<flatbuffers::Vector<
flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>>
list = 0,
bool initialized = false, bool initialized = false,
benchmarks_flatbuffers::Enum fruit = benchmarks_flatbuffers::Enum_Apples, benchmarks_flatbuffers::Enum fruit = benchmarks_flatbuffers::Enum_Apples,
flatbuffers::Offset<flatbuffers::String> location = 0) { flatbuffers::Offset<flatbuffers::String> location = 0) {
@@ -304,47 +262,52 @@ inline flatbuffers::Offset<FooBarContainer> CreateFooBarContainer(
} }
inline flatbuffers::Offset<FooBarContainer> CreateFooBarContainerDirect( inline flatbuffers::Offset<FooBarContainer> CreateFooBarContainerDirect(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder& _fbb,
const std::vector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>> *list = nullptr, const std::vector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>*
list = nullptr,
bool initialized = false, bool initialized = false,
benchmarks_flatbuffers::Enum fruit = benchmarks_flatbuffers::Enum_Apples, benchmarks_flatbuffers::Enum fruit = benchmarks_flatbuffers::Enum_Apples,
const char *location = nullptr) { const char* location = nullptr) {
auto list__ = list ? _fbb.CreateVector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>(*list) : 0; auto list__ =
list ? _fbb.CreateVector<
flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>(*list)
: 0;
auto location__ = location ? _fbb.CreateString(location) : 0; auto location__ = location ? _fbb.CreateString(location) : 0;
return benchmarks_flatbuffers::CreateFooBarContainer( return benchmarks_flatbuffers::CreateFooBarContainer(
_fbb, _fbb, list__, initialized, fruit, location__);
list__,
initialized,
fruit,
location__);
} }
inline const benchmarks_flatbuffers::FooBarContainer *GetFooBarContainer(const void *buf) { inline const benchmarks_flatbuffers::FooBarContainer* GetFooBarContainer(
const void* buf) {
return flatbuffers::GetRoot<benchmarks_flatbuffers::FooBarContainer>(buf); return flatbuffers::GetRoot<benchmarks_flatbuffers::FooBarContainer>(buf);
} }
inline const benchmarks_flatbuffers::FooBarContainer *GetSizePrefixedFooBarContainer(const void *buf) { inline const benchmarks_flatbuffers::FooBarContainer*
return flatbuffers::GetSizePrefixedRoot<benchmarks_flatbuffers::FooBarContainer>(buf); GetSizePrefixedFooBarContainer(const void* buf) {
return flatbuffers::GetSizePrefixedRoot<
benchmarks_flatbuffers::FooBarContainer>(buf);
} }
inline bool VerifyFooBarContainerBuffer( inline bool VerifyFooBarContainerBuffer(flatbuffers::Verifier& verifier) {
flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<benchmarks_flatbuffers::FooBarContainer>(
return verifier.VerifyBuffer<benchmarks_flatbuffers::FooBarContainer>(nullptr); nullptr);
} }
inline bool VerifySizePrefixedFooBarContainerBuffer( inline bool VerifySizePrefixedFooBarContainerBuffer(
flatbuffers::Verifier &verifier) { flatbuffers::Verifier& verifier) {
return verifier.VerifySizePrefixedBuffer<benchmarks_flatbuffers::FooBarContainer>(nullptr); return verifier
.VerifySizePrefixedBuffer<benchmarks_flatbuffers::FooBarContainer>(
nullptr);
} }
inline void FinishFooBarContainerBuffer( inline void FinishFooBarContainerBuffer(
flatbuffers::FlatBufferBuilder &fbb, flatbuffers::FlatBufferBuilder& fbb,
flatbuffers::Offset<benchmarks_flatbuffers::FooBarContainer> root) { flatbuffers::Offset<benchmarks_flatbuffers::FooBarContainer> root) {
fbb.Finish(root); fbb.Finish(root);
} }
inline void FinishSizePrefixedFooBarContainerBuffer( inline void FinishSizePrefixedFooBarContainerBuffer(
flatbuffers::FlatBufferBuilder &fbb, flatbuffers::FlatBufferBuilder& fbb,
flatbuffers::Offset<benchmarks_flatbuffers::FooBarContainer> root) { flatbuffers::Offset<benchmarks_flatbuffers::FooBarContainer> root) {
fbb.FinishSizePrefixed(root); fbb.FinishSizePrefixed(root);
} }

View File

@@ -8,16 +8,16 @@
#include "include/flatbuffers/flatbuffers.h" #include "include/flatbuffers/flatbuffers.h"
struct StaticAllocator : public flatbuffers::Allocator { struct StaticAllocator : public flatbuffers::Allocator {
explicit StaticAllocator(uint8_t *buffer) : buffer_(buffer) {} explicit StaticAllocator(uint8_t* buffer) : buffer_(buffer) {}
uint8_t *allocate(size_t) override { return buffer_; } uint8_t* allocate(size_t) override { return buffer_; }
void deallocate(uint8_t *, size_t) override {} void deallocate(uint8_t*, size_t) override {}
uint8_t *buffer_; uint8_t* buffer_;
}; };
std::unique_ptr<Bench> NewFlatBuffersBench( std::unique_ptr<Bench> NewFlatBuffersBench(
int64_t initial_size = 1024, flatbuffers::Allocator *allocator = nullptr); int64_t initial_size = 1024, flatbuffers::Allocator* allocator = nullptr);
#endif // BENCHMARKS_CPP_FLATBUFFERS_FB_BENCH_H_ #endif // BENCHMARKS_CPP_FLATBUFFERS_FB_BENCH_H_

View File

@@ -88,8 +88,8 @@ let benchmarks = {
Benchmark( Benchmark(
"Allocating ByteBuffer 1GB", "Allocating ByteBuffer 1GB",
configuration: singleConfiguration) configuration: singleConfiguration
{ benchmark in ) { benchmark in
let memory = UnsafeMutableRawPointer.allocate( let memory = UnsafeMutableRawPointer.allocate(
byteCount: 1_024_000_000, byteCount: 1_024_000_000,
alignment: 1) alignment: 1)
@@ -108,7 +108,7 @@ let benchmarks = {
} }
Benchmark("Strings 10") { benchmark in Benchmark("Strings 10") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for _ in benchmark.scaledIterations { for _ in benchmark.scaledIterations {
blackHole(fb.create(string: str10)) blackHole(fb.create(string: str10))
@@ -116,7 +116,7 @@ let benchmarks = {
} }
Benchmark("Strings 100") { benchmark in Benchmark("Strings 100") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for _ in benchmark.scaledIterations { for _ in benchmark.scaledIterations {
blackHole(fb.create(string: str100)) blackHole(fb.create(string: str100))
@@ -124,7 +124,7 @@ let benchmarks = {
} }
Benchmark("Vector 1 Bytes") { benchmark in Benchmark("Vector 1 Bytes") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for _ in benchmark.scaledIterations { for _ in benchmark.scaledIterations {
blackHole(fb.createVector(bytes: bytes)) blackHole(fb.createVector(bytes: bytes))
@@ -132,7 +132,7 @@ let benchmarks = {
} }
Benchmark("Vector 1 Ints") { benchmark in Benchmark("Vector 1 Ints") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for _ in benchmark.scaledIterations { for _ in benchmark.scaledIterations {
blackHole(fb.createVector(ints)) blackHole(fb.createVector(ints))
@@ -140,7 +140,7 @@ let benchmarks = {
} }
Benchmark("Vector 100 Ints") { benchmark in Benchmark("Vector 100 Ints") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for i in benchmark.scaledIterations { for i in benchmark.scaledIterations {
blackHole(fb.createVector(ints)) blackHole(fb.createVector(ints))
@@ -148,7 +148,7 @@ let benchmarks = {
} }
Benchmark("Vector 100 Bytes") { benchmark in Benchmark("Vector 100 Bytes") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for i in benchmark.scaledIterations { for i in benchmark.scaledIterations {
blackHole(fb.createVector(bytes)) blackHole(fb.createVector(bytes))
@@ -156,7 +156,7 @@ let benchmarks = {
} }
Benchmark("Vector 100 ContiguousBytes") { benchmark in Benchmark("Vector 100 ContiguousBytes") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for i in benchmark.scaledIterations { for i in benchmark.scaledIterations {
blackHole(fb.createVector(bytes: bytes)) blackHole(fb.createVector(bytes: bytes))
@@ -165,8 +165,8 @@ let benchmarks = {
Benchmark( Benchmark(
"FlatBufferBuilder Add", "FlatBufferBuilder Add",
configuration: kiloConfiguration) configuration: kiloConfiguration
{ benchmark in ) { benchmark in
var fb = FlatBufferBuilder(initialSize: 1024 * 1024 * 32) var fb = FlatBufferBuilder(initialSize: 1024 * 1024 * 32)
benchmark.startMeasurement() benchmark.startMeasurement()
for _ in benchmark.scaledIterations { for _ in benchmark.scaledIterations {
@@ -182,8 +182,8 @@ let benchmarks = {
Benchmark( Benchmark(
"FlatBufferBuilder Start table", "FlatBufferBuilder Start table",
configuration: kiloConfiguration) configuration: kiloConfiguration
{ benchmark in ) { benchmark in
var fb = FlatBufferBuilder(initialSize: 1024 * 1024 * 32) var fb = FlatBufferBuilder(initialSize: 1024 * 1024 * 32)
benchmark.startMeasurement() benchmark.startMeasurement()
for _ in benchmark.scaledIterations { for _ in benchmark.scaledIterations {

View File

@@ -20,7 +20,7 @@ import PackageDescription
let package = Package( let package = Package(
name: "benchmarks", name: "benchmarks",
platforms: [ platforms: [
.macOS(.v13), .macOS(.v13)
], ],
dependencies: [ dependencies: [
.package(path: "../.."), .package(path: "../.."),
@@ -37,6 +37,6 @@ let package = Package(
], ],
path: "Benchmarks/FlatbuffersBenchmarks", path: "Benchmarks/FlatbuffersBenchmarks",
plugins: [ plugins: [
.plugin(name: "BenchmarkPlugin", package: "package-benchmark"), .plugin(name: "BenchmarkPlugin", package: "package-benchmark")
]), ])
]) ])

View File

@@ -6,10 +6,11 @@ import subprocess
from cpt.packager import ConanMultiPackager from cpt.packager import ConanMultiPackager
def get_branch(): def get_branch():
try: try:
for line in subprocess.check_output("git branch", shell=True).decode().splitlines(): for line in (
subprocess.check_output("git branch", shell=True).decode().splitlines()
):
line = line.strip() line = line.strip()
if line.startswith("*") and " (HEAD detached" not in line: if line.startswith("*") and " (HEAD detached" not in line:
return line.replace("*", "", 1).strip() return line.replace("*", "", 1).strip()
@@ -34,17 +35,25 @@ def get_reference(username):
if __name__ == "__main__": if __name__ == "__main__":
login_username = os.getenv("CONAN_LOGIN_USERNAME", "aardappel") login_username = os.getenv("CONAN_LOGIN_USERNAME", "aardappel")
username = os.getenv("CONAN_USERNAME", "google") username = os.getenv("CONAN_USERNAME", "google")
upload = os.getenv("CONAN_UPLOAD", "https://api.bintray.com/conan/aardappel/flatbuffers") upload = os.getenv(
stable_branch_pattern = os.getenv("CONAN_STABLE_BRANCH_PATTERN", r"v\d+\.\d+\.\d+.*") "CONAN_UPLOAD", "https://api.bintray.com/conan/aardappel/flatbuffers"
test_folder = os.getenv("CPT_TEST_FOLDER", os.path.join("conan", "test_package")) )
stable_branch_pattern = os.getenv(
"CONAN_STABLE_BRANCH_PATTERN", r"v\d+\.\d+\.\d+.*"
)
test_folder = os.getenv(
"CPT_TEST_FOLDER", os.path.join("conan", "test_package")
)
upload_only_when_stable = os.getenv("CONAN_UPLOAD_ONLY_WHEN_STABLE", True) upload_only_when_stable = os.getenv("CONAN_UPLOAD_ONLY_WHEN_STABLE", True)
builder = ConanMultiPackager(reference=get_reference(username), builder = ConanMultiPackager(
reference=get_reference(username),
username=username, username=username,
login_username=login_username, login_username=login_username,
upload=upload, upload=upload,
stable_branch_pattern=stable_branch_pattern, stable_branch_pattern=stable_branch_pattern,
upload_only_when_stable=upload_only_when_stable, upload_only_when_stable=upload_only_when_stable,
test_folder=test_folder) test_folder=test_folder,
)
builder.add_common_builds(pure_c=False) builder.add_common_builds(pure_c=False)
builder.run() builder.run()

View File

@@ -1,8 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from conans import ConanFile, CMake
import os import os
from conans import CMake, ConanFile
class TestPackageConan(ConanFile): class TestPackageConan(ConanFile):

View File

@@ -1,11 +1,10 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Conan recipe package for Google FlatBuffers """Conan recipe package for Google FlatBuffers"""
"""
import os import os
import shutil import shutil
from conans import ConanFile, CMake, tools from conans import CMake, ConanFile, tools
class FlatbuffersConan(ConanFile): class FlatbuffersConan(ConanFile):
@@ -21,23 +20,27 @@ class FlatbuffersConan(ConanFile):
default_options = {"shared": False, "fPIC": True} default_options = {"shared": False, "fPIC": True}
generators = "cmake" generators = "cmake"
exports = "LICENSE" exports = "LICENSE"
exports_sources = ["CMake/*", "include/*", "src/*", "grpc/*", "CMakeLists.txt", "conan/CMakeLists.txt"] exports_sources = [
"CMake/*",
"include/*",
"src/*",
"grpc/*",
"CMakeLists.txt",
"conan/CMakeLists.txt",
]
def source(self): def source(self):
"""Wrap the original CMake file to call conan_basic_setup """Wrap the original CMake file to call conan_basic_setup"""
"""
shutil.move("CMakeLists.txt", "CMakeListsOriginal.txt") shutil.move("CMakeLists.txt", "CMakeListsOriginal.txt")
shutil.move(os.path.join("conan", "CMakeLists.txt"), "CMakeLists.txt") shutil.move(os.path.join("conan", "CMakeLists.txt"), "CMakeLists.txt")
def config_options(self): def config_options(self):
"""Remove fPIC option on Windows platform """Remove fPIC option on Windows platform"""
"""
if self.settings.os == "Windows": if self.settings.os == "Windows":
self.options.remove("fPIC") self.options.remove("fPIC")
def configure_cmake(self): def configure_cmake(self):
"""Create CMake instance and execute configure step """Create CMake instance and execute configure step"""
"""
cmake = CMake(self) cmake = CMake(self)
cmake.definitions["FLATBUFFERS_BUILD_TESTS"] = False cmake.definitions["FLATBUFFERS_BUILD_TESTS"] = False
cmake.definitions["FLATBUFFERS_BUILD_SHAREDLIB"] = self.options.shared cmake.definitions["FLATBUFFERS_BUILD_SHAREDLIB"] = self.options.shared
@@ -46,30 +49,35 @@ class FlatbuffersConan(ConanFile):
return cmake return cmake
def build(self): def build(self):
"""Configure, build and install FlatBuffers using CMake. """Configure, build and install FlatBuffers using CMake."""
"""
cmake = self.configure_cmake() cmake = self.configure_cmake()
cmake.build() cmake.build()
def package(self): def package(self):
"""Copy Flatbuffers' artifacts to package folder """Copy Flatbuffers' artifacts to package folder"""
"""
cmake = self.configure_cmake() cmake = self.configure_cmake()
cmake.install() cmake.install()
self.copy(pattern="LICENSE", dst="licenses") self.copy(pattern="LICENSE", dst="licenses")
self.copy(pattern="FindFlatBuffers.cmake", dst=os.path.join("lib", "cmake", "flatbuffers"), src="CMake") self.copy(
pattern="FindFlatBuffers.cmake",
dst=os.path.join("lib", "cmake", "flatbuffers"),
src="CMake",
)
self.copy(pattern="flathash*", dst="bin", src="bin") self.copy(pattern="flathash*", dst="bin", src="bin")
self.copy(pattern="flatc*", dst="bin", src="bin") self.copy(pattern="flatc*", dst="bin", src="bin")
if self.settings.os == "Windows" and self.options.shared: if self.settings.os == "Windows" and self.options.shared:
if self.settings.compiler == "Visual Studio": if self.settings.compiler == "Visual Studio":
shutil.move(os.path.join(self.package_folder, "lib", "%s.dll" % self.name), shutil.move(
os.path.join(self.package_folder, "bin", "%s.dll" % self.name)) os.path.join(self.package_folder, "lib", "%s.dll" % self.name),
os.path.join(self.package_folder, "bin", "%s.dll" % self.name),
)
elif self.settings.compiler == "gcc": elif self.settings.compiler == "gcc":
shutil.move(os.path.join(self.package_folder, "lib", "lib%s.dll" % self.name), shutil.move(
os.path.join(self.package_folder, "bin", "lib%s.dll" % self.name)) os.path.join(self.package_folder, "lib", "lib%s.dll" % self.name),
os.path.join(self.package_folder, "bin", "lib%s.dll" % self.name),
)
def package_info(self): def package_info(self):
"""Collect built libraries names and solve flatc path. """Collect built libraries names and solve flatc path."""
"""
self.cpp_info.libs = tools.collect_libs(self) self.cpp_info.libs = tools.collect_libs(self)
self.user_info.flatc = os.path.join(self.package_folder, "bin", "flatc") self.user_info.flatc = os.path.join(self.package_folder, "bin", "flatc")

View File

@@ -15,6 +15,7 @@
*/ */
import 'package:flat_buffers/flat_buffers.dart' as fb; import 'package:flat_buffers/flat_buffers.dart' as fb;
import './monster_my_game.sample_generated.dart' as my_game; import './monster_my_game.sample_generated.dart' as my_game;
// Example how to use FlatBuffers to create and read binary buffers. // Example how to use FlatBuffers to create and read binary buffers.
@@ -78,7 +79,8 @@ void builderTest() {
builder.finish(monsteroff); builder.finish(monsteroff);
if (verify(builder.buffer)) { if (verify(builder.buffer)) {
print( print(
"The FlatBuffer was successfully created with a builder and verified!"); "The FlatBuffer was successfully created with a builder and verified!",
);
} }
} }
@@ -94,7 +96,10 @@ void objectBuilderTest() {
name: 'Orc', name: 'Orc',
inventory: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], inventory: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
color: my_game.Color.Red, color: my_game.Color.Red,
weapons: [my_game.WeaponObjectBuilder(name: 'Sword', damage: 3), axe], weapons: [
my_game.WeaponObjectBuilder(name: 'Sword', damage: 3),
axe,
],
equippedType: my_game.EquipmentTypeId.Weapon, equippedType: my_game.EquipmentTypeId.Weapon,
equipped: axe, equipped: axe,
); );
@@ -108,7 +113,8 @@ void objectBuilderTest() {
// Instead, we're going to access it right away (as if we just received it). // Instead, we're going to access it right away (as if we just received it).
if (verify(buffer)) { if (verify(buffer)) {
print( print(
"The FlatBuffer was successfully created with an object builder and verified!"); "The FlatBuffer was successfully created with an object builder and verified!",
);
} }
} }

View File

@@ -4,8 +4,8 @@
library my_game.sample; library my_game.sample;
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb;
import 'package:flat_buffers/flat_buffers.dart' as fb;
class Color { class Color {
final int value; final int value;
@@ -29,10 +29,7 @@ class Color {
static const Color Red = Color._(0); static const Color Red = Color._(0);
static const Color Green = Color._(1); static const Color Green = Color._(1);
static const Color Blue = Color._(2); static const Color Blue = Color._(2);
static const Map<int, Color> values = { static const Map<int, Color> values = {0: Red, 1: Green, 2: Blue};
0: Red,
1: Green,
2: Blue};
static const fb.Reader<Color> reader = _ColorReader(); static const fb.Reader<Color> reader = _ColorReader();
@@ -60,7 +57,9 @@ class EquipmentTypeId {
factory EquipmentTypeId.fromValue(int value) { factory EquipmentTypeId.fromValue(int value) {
final result = values[value]; final result = values[value];
if (result == null) { if (result == null) {
throw StateError('Invalid value $value for bit flag enum EquipmentTypeId'); throw StateError(
'Invalid value $value for bit flag enum EquipmentTypeId',
);
} }
return result; return result;
} }
@@ -74,9 +73,7 @@ class EquipmentTypeId {
static const EquipmentTypeId NONE = EquipmentTypeId._(0); static const EquipmentTypeId NONE = EquipmentTypeId._(0);
static const EquipmentTypeId Weapon = EquipmentTypeId._(1); static const EquipmentTypeId Weapon = EquipmentTypeId._(1);
static const Map<int, EquipmentTypeId> values = { static const Map<int, EquipmentTypeId> values = {0: NONE, 1: Weapon};
0: NONE,
1: Weapon};
static const fb.Reader<EquipmentTypeId> reader = _EquipmentTypeIdReader(); static const fb.Reader<EquipmentTypeId> reader = _EquipmentTypeIdReader();
@@ -122,8 +119,7 @@ class _Vec3Reader extends fb.StructReader<Vec3> {
int get size => 12; int get size => 12;
@override @override
Vec3 createObject(fb.BufferContext bc, int offset) => Vec3 createObject(fb.BufferContext bc, int offset) => Vec3._(bc, offset);
Vec3._(bc, offset);
} }
class Vec3Builder { class Vec3Builder {
@@ -137,7 +133,6 @@ class Vec3Builder {
fbBuilder.putFloat32(x); fbBuilder.putFloat32(x);
return fbBuilder.offset; return fbBuilder.offset;
} }
} }
class Vec3ObjectBuilder extends fb.ObjectBuilder { class Vec3ObjectBuilder extends fb.ObjectBuilder {
@@ -145,11 +140,7 @@ class Vec3ObjectBuilder extends fb.ObjectBuilder {
final double _y; final double _y;
final double _z; final double _z;
Vec3ObjectBuilder({ Vec3ObjectBuilder({required double x, required double y, required double z})
required double x,
required double y,
required double z,
})
: _x = x, : _x = x,
_y = y, _y = y,
_z = z; _z = z;
@@ -171,6 +162,7 @@ class Vec3ObjectBuilder extends fb.ObjectBuilder {
return fbBuilder.buffer; return fbBuilder.buffer;
} }
} }
class Monster { class Monster {
Monster._(this._bc, this._bcOffset); Monster._(this._bc, this._bcOffset);
factory Monster(List<int> bytes) { factory Monster(List<int> bytes) {
@@ -186,18 +178,30 @@ class Monster {
Vec3? get pos => Vec3.reader.vTableGetNullable(_bc, _bcOffset, 4); Vec3? get pos => Vec3.reader.vTableGetNullable(_bc, _bcOffset, 4);
int get mana => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 150); int get mana => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 150);
int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100); int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
String? get name => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 10); String? get name =>
List<int>? get inventory => const fb.Uint8ListReader().vTableGetNullable(_bc, _bcOffset, 14); const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 10);
Color get color => Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 16, 2)); List<int>? get inventory =>
List<Weapon>? get weapons => const fb.ListReader<Weapon>(Weapon.reader).vTableGetNullable(_bc, _bcOffset, 18); const fb.Uint8ListReader().vTableGetNullable(_bc, _bcOffset, 14);
EquipmentTypeId? get equippedType => EquipmentTypeId._createOrNull(const fb.Uint8Reader().vTableGetNullable(_bc, _bcOffset, 20)); Color get color =>
Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 16, 2));
List<Weapon>? get weapons => const fb.ListReader<Weapon>(
Weapon.reader,
).vTableGetNullable(_bc, _bcOffset, 18);
EquipmentTypeId? get equippedType => EquipmentTypeId._createOrNull(
const fb.Uint8Reader().vTableGetNullable(_bc, _bcOffset, 20),
);
dynamic get equipped { dynamic get equipped {
switch (equippedType?.value) { switch (equippedType?.value) {
case 1: return Weapon.reader.vTableGetNullable(_bc, _bcOffset, 22); case 1:
default: return null; return Weapon.reader.vTableGetNullable(_bc, _bcOffset, 22);
default:
return null;
} }
} }
List<Vec3>? get path => const fb.ListReader<Vec3>(Vec3.reader).vTableGetNullable(_bc, _bcOffset, 24);
List<Vec3>? get path => const fb.ListReader<Vec3>(
Vec3.reader,
).vTableGetNullable(_bc, _bcOffset, 24);
@override @override
String toString() { String toString() {
@@ -226,38 +230,47 @@ class MonsterBuilder {
fbBuilder.addStruct(0, offset); fbBuilder.addStruct(0, offset);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addMana(int? mana) { int addMana(int? mana) {
fbBuilder.addInt16(1, mana); fbBuilder.addInt16(1, mana);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addHp(int? hp) { int addHp(int? hp) {
fbBuilder.addInt16(2, hp); fbBuilder.addInt16(2, hp);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addNameOffset(int? offset) { int addNameOffset(int? offset) {
fbBuilder.addOffset(3, offset); fbBuilder.addOffset(3, offset);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addInventoryOffset(int? offset) { int addInventoryOffset(int? offset) {
fbBuilder.addOffset(5, offset); fbBuilder.addOffset(5, offset);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addColor(Color? color) { int addColor(Color? color) {
fbBuilder.addInt8(6, color?.value); fbBuilder.addInt8(6, color?.value);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addWeaponsOffset(int? offset) { int addWeaponsOffset(int? offset) {
fbBuilder.addOffset(7, offset); fbBuilder.addOffset(7, offset);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addEquippedType(EquipmentTypeId? equippedType) { int addEquippedType(EquipmentTypeId? equippedType) {
fbBuilder.addUint8(8, equippedType?.value); fbBuilder.addUint8(8, equippedType?.value);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addEquippedOffset(int? offset) { int addEquippedOffset(int? offset) {
fbBuilder.addOffset(9, offset); fbBuilder.addOffset(9, offset);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addPathOffset(int? offset) { int addPathOffset(int? offset) {
fbBuilder.addOffset(10, offset); fbBuilder.addOffset(10, offset);
return fbBuilder.offset; return fbBuilder.offset;
@@ -291,8 +304,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
EquipmentTypeId? equippedType, EquipmentTypeId? equippedType,
dynamic equipped, dynamic equipped,
List<Vec3ObjectBuilder>? path, List<Vec3ObjectBuilder>? path,
}) }) : _pos = pos,
: _pos = pos,
_mana = mana, _mana = mana,
_hp = hp, _hp = hp,
_name = name, _name = name,
@@ -306,14 +318,20 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override
int finish(fb.Builder fbBuilder) { int finish(fb.Builder fbBuilder) {
final int? nameOffset = _name == null ? null final int? nameOffset = _name == null
? null
: fbBuilder.writeString(_name!); : fbBuilder.writeString(_name!);
final int? inventoryOffset = _inventory == null ? null final int? inventoryOffset = _inventory == null
? null
: fbBuilder.writeListUint8(_inventory!); : fbBuilder.writeListUint8(_inventory!);
final int? weaponsOffset = _weapons == null ? null final int? weaponsOffset = _weapons == null
: fbBuilder.writeList(_weapons!.map((b) => b.getOrCreateOffset(fbBuilder)).toList()); ? null
: fbBuilder.writeList(
_weapons!.map((b) => b.getOrCreateOffset(fbBuilder)).toList(),
);
final int? equippedOffset = _equipped?.getOrCreateOffset(fbBuilder); final int? equippedOffset = _equipped?.getOrCreateOffset(fbBuilder);
final int? pathOffset = _path == null ? null final int? pathOffset = _path == null
? null
: fbBuilder.writeListOfStructs(_path!); : fbBuilder.writeListOfStructs(_path!);
fbBuilder.startTable(10); fbBuilder.startTable(10);
if (_pos != null) { if (_pos != null) {
@@ -339,6 +357,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
return fbBuilder.buffer; return fbBuilder.buffer;
} }
} }
class Weapon { class Weapon {
Weapon._(this._bc, this._bcOffset); Weapon._(this._bc, this._bcOffset);
factory Weapon(List<int> bytes) { factory Weapon(List<int> bytes) {
@@ -351,7 +370,8 @@ class Weapon {
final fb.BufferContext _bc; final fb.BufferContext _bc;
final int _bcOffset; final int _bcOffset;
String? get name => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 4); String? get name =>
const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 4);
int get damage => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 0); int get damage => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 0);
@override @override
@@ -364,8 +384,7 @@ class _WeaponReader extends fb.TableReader<Weapon> {
const _WeaponReader(); const _WeaponReader();
@override @override
Weapon createObject(fb.BufferContext bc, int offset) => Weapon createObject(fb.BufferContext bc, int offset) => Weapon._(bc, offset);
Weapon._(bc, offset);
} }
class WeaponBuilder { class WeaponBuilder {
@@ -381,6 +400,7 @@ class WeaponBuilder {
fbBuilder.addOffset(0, offset); fbBuilder.addOffset(0, offset);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addDamage(int? damage) { int addDamage(int? damage) {
fbBuilder.addInt16(1, damage); fbBuilder.addInt16(1, damage);
return fbBuilder.offset; return fbBuilder.offset;
@@ -395,17 +415,15 @@ class WeaponObjectBuilder extends fb.ObjectBuilder {
final String? _name; final String? _name;
final int? _damage; final int? _damage;
WeaponObjectBuilder({ WeaponObjectBuilder({String? name, int? damage})
String? name,
int? damage,
})
: _name = name, : _name = name,
_damage = damage; _damage = damage;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override
int finish(fb.Builder fbBuilder) { int finish(fb.Builder fbBuilder) {
final int? nameOffset = _name == null ? null final int? nameOffset = _name == null
? null
: fbBuilder.writeString(_name!); : fbBuilder.writeString(_name!);
fbBuilder.startTable(2); fbBuilder.startTable(2);
fbBuilder.addOffset(0, nameOffset); fbBuilder.addOffset(0, nameOffset);

View File

@@ -27,10 +27,11 @@ class BufferContext {
ByteData get buffer => _buffer; ByteData get buffer => _buffer;
/// Create from a FlatBuffer represented by a list of bytes (uint8). /// Create from a FlatBuffer represented by a list of bytes (uint8).
factory BufferContext.fromBytes(List<int> byteList) => factory BufferContext.fromBytes(List<int> byteList) => BufferContext(
BufferContext(byteList is Uint8List byteList is Uint8List
? byteList.buffer.asByteData(byteList.offsetInBytes) ? byteList.buffer.asByteData(byteList.offsetInBytes)
: ByteData.view(Uint8List.fromList(byteList).buffer)); : ByteData.view(Uint8List.fromList(byteList).buffer),
);
/// Create from a FlatBuffer represented by ByteData. /// Create from a FlatBuffer represented by ByteData.
BufferContext(this._buffer); BufferContext(this._buffer);
@@ -350,8 +351,10 @@ class Builder {
Uint8List get buffer { Uint8List get buffer {
assert(_finished); assert(_finished);
final finishedSize = size(); final finishedSize = size();
return _buf.buffer return _buf.buffer.asUint8List(
.asUint8List(_buf.lengthInBytes - finishedSize, finishedSize); _buf.lengthInBytes - finishedSize,
finishedSize,
);
} }
/// Finish off the creation of the buffer. The given [offset] is used as the /// Finish off the creation of the buffer. The given [offset] is used as the
@@ -368,14 +371,18 @@ class Builder {
if (fileIdentifier != null) { if (fileIdentifier != null) {
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
_setUint8AtTail( _setUint8AtTail(
finishedSize - _sizeofUint32 - i, fileIdentifier.codeUnitAt(i)); finishedSize - _sizeofUint32 - i,
fileIdentifier.codeUnitAt(i),
);
} }
} }
// zero out the added padding // zero out the added padding
for (var i = sizeBeforePadding + 1; for (
var i = sizeBeforePadding + 1;
i <= finishedSize - requiredBytes; i <= finishedSize - requiredBytes;
i++) { i++
) {
_setUint8AtTail(i, 0); _setUint8AtTail(i, 0);
} }
_finished = true; _finished = true;
@@ -687,8 +694,10 @@ class Builder {
int writeString(String value, {bool asciiOptimization = false}) { int writeString(String value, {bool asciiOptimization = false}) {
assert(!_inVTable); assert(!_inVTable);
if (_strings != null) { if (_strings != null) {
return _strings! return _strings!.putIfAbsent(
.putIfAbsent(value, () => _writeString(value, asciiOptimization)); value,
() => _writeString(value, asciiOptimization),
);
} else { } else {
return _writeString(value, asciiOptimization); return _writeString(value, asciiOptimization);
} }
@@ -1005,8 +1014,11 @@ class ListReader<E> extends Reader<List<E>> {
: List<E>.generate( : List<E>.generate(
bc.buffer.getUint32(listOffset, Endian.little), bc.buffer.getUint32(listOffset, Endian.little),
(int index) => _elementReader.read( (int index) => _elementReader.read(
bc, listOffset + size + _elementReader.size * index), bc,
growable: true); listOffset + size + _elementReader.size * index,
),
growable: true,
);
} }
} }
@@ -1454,7 +1466,11 @@ abstract class Allocator {
/// Params [inUseBack] and [inUseFront] indicate how much of [oldData] is /// Params [inUseBack] and [inUseFront] indicate how much of [oldData] is
/// actually in use at each end, and needs to be copied. /// actually in use at each end, and needs to be copied.
ByteData resize( ByteData resize(
ByteData oldData, int newSize, int inUseBack, int inUseFront) { ByteData oldData,
int newSize,
int inUseBack,
int inUseFront,
) {
final newData = allocate(newSize); final newData = allocate(newSize);
_copyDownward(oldData, newData, inUseBack, inUseFront); _copyDownward(oldData, newData, inUseBack, inUseFront);
deallocate(oldData); deallocate(oldData);
@@ -1465,17 +1481,25 @@ abstract class Allocator {
/// memory of size [inUseFront] and [inUseBack] will be copied from the front /// memory of size [inUseFront] and [inUseBack] will be copied from the front
/// and back of the old memory allocation. /// and back of the old memory allocation.
void _copyDownward( void _copyDownward(
ByteData oldData, ByteData newData, int inUseBack, int inUseFront) { ByteData oldData,
ByteData newData,
int inUseBack,
int inUseFront,
) {
if (inUseBack != 0) { if (inUseBack != 0) {
newData.buffer.asUint8List().setAll( newData.buffer.asUint8List().setAll(
newData.lengthInBytes - inUseBack, newData.lengthInBytes - inUseBack,
oldData.buffer.asUint8List().getRange( oldData.buffer.asUint8List().getRange(
oldData.lengthInBytes - inUseBack, oldData.lengthInBytes)); oldData.lengthInBytes - inUseBack,
oldData.lengthInBytes,
),
);
} }
if (inUseFront != 0) { if (inUseFront != 0) {
newData.buffer newData.buffer.asUint8List().setAll(
.asUint8List() 0,
.setAll(0, oldData.buffer.asUint8List().getRange(0, inUseFront)); oldData.buffer.asUint8List().getRange(0, inUseFront),
);
} }
} }
} }

View File

@@ -107,8 +107,11 @@ class Builder {
final newOffset = _newOffset(length + 1); final newOffset = _newOffset(length + 1);
_pushBuffer(utf8String); _pushBuffer(utf8String);
_offset = newOffset; _offset = newOffset;
final stackValue = final stackValue = _StackValue.withOffset(
_StackValue.withOffset(stringOffset, ValueType.String, bitWidth); stringOffset,
ValueType.String,
bitWidth,
);
_stack.add(stackValue); _stack.add(stackValue);
_stringCache[value] = stackValue; _stringCache[value] = stackValue;
} }
@@ -128,8 +131,11 @@ class Builder {
final newOffset = _newOffset(length + 1); final newOffset = _newOffset(length + 1);
_pushBuffer(utf8String); _pushBuffer(utf8String);
_offset = newOffset; _offset = newOffset;
final stackValue = final stackValue = _StackValue.withOffset(
_StackValue.withOffset(keyOffset, ValueType.Key, BitWidth.width8); keyOffset,
ValueType.Key,
BitWidth.width8,
);
_stack.add(stackValue); _stack.add(stackValue);
_keyCache[value] = stackValue; _keyCache[value] = stackValue;
} }
@@ -147,8 +153,11 @@ class Builder {
final newOffset = _newOffset(length); final newOffset = _newOffset(length);
_pushBuffer(value.asUint8List()); _pushBuffer(value.asUint8List());
_offset = newOffset; _offset = newOffset;
final stackValue = final stackValue = _StackValue.withOffset(
_StackValue.withOffset(blobOffset, ValueType.Blob, bitWidth); blobOffset,
ValueType.Blob,
bitWidth,
);
_stack.add(stackValue); _stack.add(stackValue);
} }
@@ -170,7 +179,10 @@ class Builder {
final valueOffset = _offset; final valueOffset = _offset;
_pushBuffer(stackValue.asU8List(stackValue.width)); _pushBuffer(stackValue.asU8List(stackValue.width));
final stackOffset = _StackValue.withOffset( final stackOffset = _StackValue.withOffset(
valueOffset, ValueType.IndirectInt, stackValue.width); valueOffset,
ValueType.IndirectInt,
stackValue.width,
);
_stack.add(stackOffset); _stack.add(stackOffset);
_offset = newOffset; _offset = newOffset;
if (cache) { if (cache) {
@@ -195,7 +207,10 @@ class Builder {
final valueOffset = _offset; final valueOffset = _offset;
_pushBuffer(stackValue.asU8List(stackValue.width)); _pushBuffer(stackValue.asU8List(stackValue.width));
final stackOffset = _StackValue.withOffset( final stackOffset = _StackValue.withOffset(
valueOffset, ValueType.IndirectFloat, stackValue.width); valueOffset,
ValueType.IndirectFloat,
stackValue.width,
);
_stack.add(stackOffset); _stack.add(stackOffset);
_offset = newOffset; _offset = newOffset;
if (cache) { if (cache) {
@@ -252,9 +267,10 @@ class Builder {
tmp._offset = _offset; tmp._offset = _offset;
tmp._stack = List.from(_stack); tmp._stack = List.from(_stack);
tmp._stackPointers = List.from(_stackPointers); tmp._stackPointers = List.from(_stackPointers);
tmp._buffer.buffer tmp._buffer.buffer.asUint8List().setAll(
.asUint8List() 0,
.setAll(0, _buffer.buffer.asUint8List(0, _offset)); _buffer.buffer.asUint8List(0, _offset),
);
for (var i = 0; i < tmp._stackPointers.length; i++) { for (var i = 0; i < tmp._stackPointers.length; i++) {
tmp.end(); tmp.end();
} }
@@ -271,7 +287,8 @@ class Builder {
if (_stackPointers.isNotEmpty && _stackPointers.last.isVector == false) { if (_stackPointers.isNotEmpty && _stackPointers.last.isVector == false) {
if (_stack.last.type != ValueType.Key) { if (_stack.last.type != ValueType.Key) {
throw StateError( throw StateError(
'Adding value to a map before adding a key is prohibited'); 'Adding value to a map before adding a key is prohibited',
);
} }
} }
} }
@@ -288,7 +305,8 @@ class Builder {
void _finish() { void _finish() {
if (_stack.length != 1) { if (_stack.length != 1) {
throw StateError( throw StateError(
'Stack has to be exactly 1, but is ${_stack.length}. You have to end all started vectors and maps, before calling [finish]'); 'Stack has to be exactly 1, but is ${_stack.length}. You have to end all started vectors and maps, before calling [finish]',
);
} }
final value = _stack[0]; final value = _stack[0];
final byteWidth = _align(value.elementWidth(_offset, 0)); final byteWidth = _align(value.elementWidth(_offset, 0));
@@ -298,8 +316,12 @@ class Builder {
_finished = true; _finished = true;
} }
_StackValue _createVector(int start, int vecLength, int step, _StackValue _createVector(
[_StackValue? keys]) { int start,
int vecLength,
int step, [
_StackValue? keys,
]) {
var bitWidth = BitWidthUtil.uwidth(vecLength); var bitWidth = BitWidthUtil.uwidth(vecLength);
var prefixElements = 1; var prefixElements = 1;
if (keys != null) { if (keys != null) {
@@ -326,7 +348,8 @@ class Builder {
} }
} }
final byteWidth = _align(bitWidth); final byteWidth = _align(bitWidth);
final fix = typed & ValueTypeUtils.isNumber(vectorType) && final fix =
typed & ValueTypeUtils.isNumber(vectorType) &&
vecLength >= 2 && vecLength >= 2 &&
vecLength <= 4; vecLength <= 4;
if (keys != null) { if (keys != null) {
@@ -349,8 +372,10 @@ class Builder {
return _StackValue.withOffset(vecOffset, ValueType.Map, bitWidth); return _StackValue.withOffset(vecOffset, ValueType.Map, bitWidth);
} }
if (typed) { if (typed) {
final vType = final vType = ValueTypeUtils.toTypedVector(
ValueTypeUtils.toTypedVector(vectorType, fix ? vecLength : 0); vectorType,
fix ? vecLength : 0,
);
return _StackValue.withOffset(vecOffset, vType, bitWidth); return _StackValue.withOffset(vecOffset, vType, bitWidth);
} }
return _StackValue.withOffset(vecOffset, ValueType.Vector, bitWidth); return _StackValue.withOffset(vecOffset, ValueType.Vector, bitWidth);
@@ -366,7 +391,8 @@ class Builder {
void _sortKeysAndEndMap(_StackPointer pointer) { void _sortKeysAndEndMap(_StackPointer pointer) {
if (((_stack.length - pointer.stackPosition) & 1) == 1) { if (((_stack.length - pointer.stackPosition) & 1) == 1) {
throw StateError( throw StateError(
'The stack needs to hold key value pairs (even number of elements). Check if you combined [addKey] with add... method calls properly.'); 'The stack needs to hold key value pairs (even number of elements). Check if you combined [addKey] with add... method calls properly.',
);
} }
var sorted = true; var sorted = true;
@@ -412,8 +438,12 @@ class Builder {
keysStackValue = _createVector(pointer.stackPosition, vecLength, 2); keysStackValue = _createVector(pointer.stackPosition, vecLength, 2);
_keyVectorCache[keysHash] = keysStackValue; _keyVectorCache[keysHash] = keysStackValue;
} }
final vec = final vec = _createVector(
_createVector(pointer.stackPosition + 1, vecLength, 2, keysStackValue); pointer.stackPosition + 1,
vecLength,
2,
keysStackValue,
);
_stack.removeRange(pointer.stackPosition, _stack.length); _stack.removeRange(pointer.stackPosition, _stack.length);
_stack.add(vec); _stack.add(vec);
} }
@@ -421,7 +451,8 @@ class Builder {
bool _shouldFlip(_StackValue v1, _StackValue v2) { bool _shouldFlip(_StackValue v1, _StackValue v2) {
if (v1.type != ValueType.Key || v2.type != ValueType.Key) { if (v1.type != ValueType.Key || v2.type != ValueType.Key) {
throw StateError( throw StateError(
'Stack values are not keys $v1 | $v2. Check if you combined [addKey] with add... method calls properly.'); 'Stack values are not keys $v1 | $v2. Check if you combined [addKey] with add... method calls properly.',
);
} }
late int c1, c2; late int c1, c2;
@@ -450,7 +481,8 @@ class Builder {
_writeUInt(relativeOffset, byteWidth); _writeUInt(relativeOffset, byteWidth);
} else { } else {
throw StateError( throw StateError(
'Unexpected size $byteWidth. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new'); 'Unexpected size $byteWidth. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new',
);
} }
} else { } else {
_pushBuffer(value.asU8List(BitWidthUtil.fromByteWidth(byteWidth))); _pushBuffer(value.asU8List(BitWidthUtil.fromByteWidth(byteWidth)));
@@ -523,9 +555,7 @@ class _StackValue {
final ValueType _type; final ValueType _type;
final BitWidth _width; final BitWidth _width;
_StackValue.withNull() _StackValue.withNull() : _type = ValueType.Null, _width = BitWidth.width8;
: _type = ValueType.Null,
_width = BitWidth.width8;
_StackValue.withInt(int value) _StackValue.withInt(int value)
: _type = ValueType.Int, : _type = ValueType.Int,
@@ -562,16 +592,16 @@ class _StackValue {
final offset = _offset!; final offset = _offset!;
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
final width = 1 << i; final width = 1 << i;
final bitWidth = BitWidthUtil.uwidth(size + final bitWidth = BitWidthUtil.uwidth(
BitWidthUtil.paddingSize(size, width) + size + BitWidthUtil.paddingSize(size, width) + index * width - offset,
index * width - );
offset);
if (1 << bitWidth.index == width) { if (1 << bitWidth.index == width) {
return bitWidth; return bitWidth;
} }
} }
throw StateError( throw StateError(
'Element is of unknown. Size: $size at index: $index. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new'); 'Element is of unknown. Size: $size at index: $index. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new',
);
} }
List<int> asU8List(BitWidth width) { List<int> asU8List(BitWidth width) {
@@ -619,7 +649,8 @@ class _StackValue {
} }
throw StateError( throw StateError(
'Unexpected type: $_type. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new'); 'Unexpected type: $_type. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new',
);
} }
ValueType get type { ValueType get type {

View File

@@ -1,6 +1,7 @@
import 'dart:collection'; import 'dart:collection';
import 'dart:convert'; import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'types.dart'; import 'types.dart';
/// Main class to read a value out of a FlexBuffer. /// Main class to read a value out of a FlexBuffer.
@@ -16,9 +17,14 @@ class Reference {
int? _length; int? _length;
Reference._( Reference._(
this._buffer, this._offset, this._parentWidth, int packedType, this._path, this._buffer,
[int? byteWidth, ValueType? valueType]) this._offset,
: _byteWidth = byteWidth ?? 1 << (packedType & 3), this._parentWidth,
int packedType,
this._path, [
int? byteWidth,
ValueType? valueType,
]) : _byteWidth = byteWidth ?? 1 << (packedType & 3),
_valueType = valueType ?? ValueTypeUtils.fromInt(packedType >> 2); _valueType = valueType ?? ValueTypeUtils.fromInt(packedType >> 2);
/// Use this method to access the root value of a FlexBuffer. /// Use this method to access the root value of a FlexBuffer.
@@ -31,8 +37,13 @@ class Reference {
final byteWidth = byteData.getUint8(len - 1); final byteWidth = byteData.getUint8(len - 1);
final packedType = byteData.getUint8(len - 2); final packedType = byteData.getUint8(len - 2);
final offset = len - byteWidth - 2; final offset = len - byteWidth - 2;
return Reference._(ByteData.view(buffer), offset, return Reference._(
BitWidthUtil.fromByteWidth(byteWidth), packedType, "/"); ByteData.view(buffer),
offset,
BitWidthUtil.fromByteWidth(byteWidth),
packedType,
"/",
);
} }
/// Returns true if the underlying value is null. /// Returns true if the underlying value is null.
@@ -138,7 +149,8 @@ class Reference {
final index = key; final index = key;
if (index >= length || index < 0) { if (index >= length || index < 0) {
throw ArgumentError( throw ArgumentError(
'Key: [$key] is not applicable on: $_path of: $_valueType length: $length'); 'Key: [$key] is not applicable on: $_path of: $_valueType length: $length',
);
} }
final elementOffset = _indirect + index * _byteWidth; final elementOffset = _indirect + index * _byteWidth;
int packedType = 0; int packedType = 0;
@@ -160,7 +172,8 @@ class Reference {
packedType, packedType,
"$_path[$index]", "$_path[$index]",
byteWidth, byteWidth,
valueType); valueType,
);
} }
if (key is String && _valueType == ValueType.Map) { if (key is String && _valueType == ValueType.Map) {
final index = _keyIndex(key); final index = _keyIndex(key);
@@ -169,7 +182,8 @@ class Reference {
} }
} }
throw ArgumentError( throw ArgumentError(
'Key: [$key] is not applicable on: $_path of: $_valueType'); 'Key: [$key] is not applicable on: $_path of: $_valueType',
);
} }
/// Get an iterable if the underlying flexBuffer value is a vector. /// Get an iterable if the underlying flexBuffer value is a vector.
@@ -213,18 +227,24 @@ class Reference {
ValueTypeUtils.isAVector(_valueType) || ValueTypeUtils.isAVector(_valueType) ||
_valueType == ValueType.Map) { _valueType == ValueType.Map) {
_length = _readUInt( _length = _readUInt(
_indirect - _byteWidth, BitWidthUtil.fromByteWidth(_byteWidth)); _indirect - _byteWidth,
BitWidthUtil.fromByteWidth(_byteWidth),
);
} else if (_valueType == ValueType.Null) { } else if (_valueType == ValueType.Null) {
_length = 0; _length = 0;
} else if (_valueType == ValueType.String) { } else if (_valueType == ValueType.String) {
final indirect = _indirect; final indirect = _indirect;
var sizeByteWidth = _byteWidth; var sizeByteWidth = _byteWidth;
var size = _readUInt(indirect - sizeByteWidth, var size = _readUInt(
BitWidthUtil.fromByteWidth(sizeByteWidth)); indirect - sizeByteWidth,
BitWidthUtil.fromByteWidth(sizeByteWidth),
);
while (_buffer.getInt8(indirect + size) != 0) { while (_buffer.getInt8(indirect + size) != 0) {
sizeByteWidth <<= 1; sizeByteWidth <<= 1;
size = _readUInt(indirect - sizeByteWidth, size = _readUInt(
BitWidthUtil.fromByteWidth(sizeByteWidth)); indirect - sizeByteWidth,
BitWidthUtil.fromByteWidth(sizeByteWidth),
);
} }
_length = size; _length = size;
} else if (_valueType == ValueType.Key) { } else if (_valueType == ValueType.Key) {
@@ -289,7 +309,8 @@ class Reference {
return result.toString(); return result.toString();
} }
throw UnsupportedError( throw UnsupportedError(
'Type: $_valueType is not supported for JSON conversion'); 'Type: $_valueType is not supported for JSON conversion',
);
} }
/// Computes the indirect offset of the value. /// Computes the indirect offset of the value.
@@ -354,10 +375,13 @@ class Reference {
int? _keyIndex(String key) { int? _keyIndex(String key) {
final input = utf8.encode(key); final input = utf8.encode(key);
final keysVectorOffset = _indirect - _byteWidth * 3; final keysVectorOffset = _indirect - _byteWidth * 3;
final indirectOffset = keysVectorOffset - final indirectOffset =
keysVectorOffset -
_readUInt(keysVectorOffset, BitWidthUtil.fromByteWidth(_byteWidth)); _readUInt(keysVectorOffset, BitWidthUtil.fromByteWidth(_byteWidth));
final byteWidth = _readUInt( final byteWidth = _readUInt(
keysVectorOffset + _byteWidth, BitWidthUtil.fromByteWidth(_byteWidth)); keysVectorOffset + _byteWidth,
BitWidthUtil.fromByteWidth(_byteWidth),
);
var low = 0; var low = 0;
var high = length - 1; var high = length - 1;
while (low <= high) { while (low <= high) {
@@ -390,24 +414,37 @@ class Reference {
final indirect = _indirect; final indirect = _indirect;
final elementOffset = indirect + index * _byteWidth; final elementOffset = indirect + index * _byteWidth;
final packedType = _buffer.getUint8(indirect + length * _byteWidth + index); final packedType = _buffer.getUint8(indirect + length * _byteWidth + index);
return Reference._(_buffer, elementOffset, return Reference._(
BitWidthUtil.fromByteWidth(_byteWidth), packedType, "$_path/$key"); _buffer,
elementOffset,
BitWidthUtil.fromByteWidth(_byteWidth),
packedType,
"$_path/$key",
);
} }
Reference _valueForIndex(int index) { Reference _valueForIndex(int index) {
final indirect = _indirect; final indirect = _indirect;
final elementOffset = indirect + index * _byteWidth; final elementOffset = indirect + index * _byteWidth;
final packedType = _buffer.getUint8(indirect + length * _byteWidth + index); final packedType = _buffer.getUint8(indirect + length * _byteWidth + index);
return Reference._(_buffer, elementOffset, return Reference._(
BitWidthUtil.fromByteWidth(_byteWidth), packedType, "$_path/[$index]"); _buffer,
elementOffset,
BitWidthUtil.fromByteWidth(_byteWidth),
packedType,
"$_path/[$index]",
);
} }
String _keyForIndex(int index) { String _keyForIndex(int index) {
final keysVectorOffset = _indirect - _byteWidth * 3; final keysVectorOffset = _indirect - _byteWidth * 3;
final indirectOffset = keysVectorOffset - final indirectOffset =
keysVectorOffset -
_readUInt(keysVectorOffset, BitWidthUtil.fromByteWidth(_byteWidth)); _readUInt(keysVectorOffset, BitWidthUtil.fromByteWidth(_byteWidth));
final byteWidth = _readUInt( final byteWidth = _readUInt(
keysVectorOffset + _byteWidth, BitWidthUtil.fromByteWidth(_byteWidth)); keysVectorOffset + _byteWidth,
BitWidthUtil.fromByteWidth(_byteWidth),
);
final keyOffset = indirectOffset + index * byteWidth; final keyOffset = indirectOffset + index * byteWidth;
final keyIndirectOffset = final keyIndirectOffset =
keyOffset - _readUInt(keyOffset, BitWidthUtil.fromByteWidth(byteWidth)); keyOffset - _readUInt(keyOffset, BitWidthUtil.fromByteWidth(byteWidth));

View File

@@ -86,7 +86,8 @@ enum ValueType {
VectorFloat, VectorFloat,
VectorKey, VectorKey,
@Deprecated( @Deprecated(
'VectorString is deprecated due to a flaw in the binary format (https://github.com/google/flatbuffers/issues/5627)') 'VectorString is deprecated due to a flaw in the binary format (https://github.com/google/flatbuffers/issues/5627)',
)
VectorString, VectorString,
VectorInt2, VectorInt2,
VectorUInt2, VectorUInt2,
@@ -99,7 +100,7 @@ enum ValueType {
VectorFloat4, VectorFloat4,
Blob, Blob,
Bool, Bool,
VectorBool VectorBool,
} }
class ValueTypeUtils { class ValueTypeUtils {
@@ -153,31 +154,37 @@ class ValueTypeUtils {
static ValueType toTypedVector(ValueType self, int length) { static ValueType toTypedVector(ValueType self, int length) {
if (length == 0) { if (length == 0) {
return ValueTypeUtils.fromInt( return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt)); toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt),
);
} }
if (length == 2) { if (length == 2) {
return ValueTypeUtils.fromInt( return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt2)); toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt2),
);
} }
if (length == 3) { if (length == 3) {
return ValueTypeUtils.fromInt( return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt3)); toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt3),
);
} }
if (length == 4) { if (length == 4) {
return ValueTypeUtils.fromInt( return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt4)); toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt4),
);
} }
throw Exception('unexpected length ' + length.toString()); throw Exception('unexpected length ' + length.toString());
} }
static ValueType typedVectorElementType(ValueType self) { static ValueType typedVectorElementType(ValueType self) {
return ValueTypeUtils.fromInt( return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.VectorInt) + toInt(ValueType.Int)); toInt(self) - toInt(ValueType.VectorInt) + toInt(ValueType.Int),
);
} }
static ValueType fixedTypedVectorElementType(ValueType self) { static ValueType fixedTypedVectorElementType(ValueType self) {
return ValueTypeUtils.fromInt( return ValueTypeUtils.fromInt(
(toInt(self) - toInt(ValueType.VectorInt2)) % 3 + toInt(ValueType.Int)); (toInt(self) - toInt(ValueType.VectorInt2)) % 3 + toInt(ValueType.Int),
);
} }
static int fixedTypedVectorElementSize(ValueType self) { static int fixedTypedVectorElementSize(ValueType self) {

View File

@@ -2,8 +2,8 @@
// ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable, constant_identifier_names // ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable, constant_identifier_names
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb;
import 'package:flat_buffers/flat_buffers.dart' as fb;
class Foo { class Foo {
Foo._(this._bc, this._bcOffset); Foo._(this._bc, this._bcOffset);
@@ -17,15 +17,15 @@ class Foo {
final fb.BufferContext _bc; final fb.BufferContext _bc;
final int _bcOffset; final int _bcOffset;
FooProperties? get myFoo => FooProperties.reader.vTableGetNullable(_bc, _bcOffset, 4); FooProperties? get myFoo =>
FooProperties.reader.vTableGetNullable(_bc, _bcOffset, 4);
@override @override
String toString() { String toString() {
return 'Foo{myFoo: ${myFoo}}'; return 'Foo{myFoo: ${myFoo}}';
} }
FooT unpack() => FooT( FooT unpack() => FooT(myFoo: myFoo?.unpack());
myFoo: myFoo?.unpack());
static int pack(fb.Builder fbBuilder, FooT? object) { static int pack(fb.Builder fbBuilder, FooT? object) {
if (object == null) return 0; if (object == null) return 0;
@@ -36,8 +36,7 @@ class Foo {
class FooT implements fb.Packable { class FooT implements fb.Packable {
FooPropertiesT? myFoo; FooPropertiesT? myFoo;
FooT({ FooT({this.myFoo});
this.myFoo});
@override @override
int pack(fb.Builder fbBuilder) { int pack(fb.Builder fbBuilder) {
@@ -58,8 +57,7 @@ class _FooReader extends fb.TableReader<Foo> {
const _FooReader(); const _FooReader();
@override @override
Foo createObject(fb.BufferContext bc, int offset) => Foo createObject(fb.BufferContext bc, int offset) => Foo._(bc, offset);
Foo._(bc, offset);
} }
class FooBuilder { class FooBuilder {
@@ -84,10 +82,7 @@ class FooBuilder {
class FooObjectBuilder extends fb.ObjectBuilder { class FooObjectBuilder extends fb.ObjectBuilder {
final FooPropertiesObjectBuilder? _myFoo; final FooPropertiesObjectBuilder? _myFoo;
FooObjectBuilder({ FooObjectBuilder({FooPropertiesObjectBuilder? myFoo}) : _myFoo = myFoo;
FooPropertiesObjectBuilder? myFoo,
})
: _myFoo = myFoo;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override
@@ -107,6 +102,7 @@ class FooObjectBuilder extends fb.ObjectBuilder {
return fbBuilder.buffer; return fbBuilder.buffer;
} }
} }
class FooProperties { class FooProperties {
FooProperties._(this._bc, this._bcOffset); FooProperties._(this._bc, this._bcOffset);
@@ -123,9 +119,7 @@ class FooProperties {
return 'FooProperties{a: ${a}, b: ${b}}'; return 'FooProperties{a: ${a}, b: ${b}}';
} }
FooPropertiesT unpack() => FooPropertiesT( FooPropertiesT unpack() => FooPropertiesT(a: a, b: b);
a: a,
b: b);
static int pack(fb.Builder fbBuilder, FooPropertiesT? object) { static int pack(fb.Builder fbBuilder, FooPropertiesT? object) {
if (object == null) return 0; if (object == null) return 0;
@@ -137,9 +131,7 @@ class FooPropertiesT implements fb.Packable {
bool a; bool a;
bool b; bool b;
FooPropertiesT({ FooPropertiesT({required this.a, required this.b});
required this.a,
required this.b});
@override @override
int pack(fb.Builder fbBuilder) { int pack(fb.Builder fbBuilder) {
@@ -175,17 +167,13 @@ class FooPropertiesBuilder {
fbBuilder.putBool(a); fbBuilder.putBool(a);
return fbBuilder.offset; return fbBuilder.offset;
} }
} }
class FooPropertiesObjectBuilder extends fb.ObjectBuilder { class FooPropertiesObjectBuilder extends fb.ObjectBuilder {
final bool _a; final bool _a;
final bool _b; final bool _b;
FooPropertiesObjectBuilder({ FooPropertiesObjectBuilder({required bool a, required bool b})
required bool a,
required bool b,
})
: _a = a, : _a = a,
_b = b; _b = b;

View File

@@ -2,8 +2,8 @@
// ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable, constant_identifier_names // ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable, constant_identifier_names
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb;
import 'package:flat_buffers/flat_buffers.dart' as fb;
enum OptionsEnum { enum OptionsEnum {
A(1), A(1),
@@ -15,10 +15,14 @@ enum OptionsEnum {
factory OptionsEnum.fromValue(int value) { factory OptionsEnum.fromValue(int value) {
switch (value) { switch (value) {
case 1: return OptionsEnum.A; case 1:
case 2: return OptionsEnum.B; return OptionsEnum.A;
case 3: return OptionsEnum.C; case 2:
default: throw StateError('Invalid value $value for bit flag enum'); return OptionsEnum.B;
case 3:
return OptionsEnum.C;
default:
throw StateError('Invalid value $value for bit flag enum');
} }
} }
@@ -53,7 +57,9 @@ class MyTable {
final fb.BufferContext _bc; final fb.BufferContext _bc;
final int _bcOffset; final int _bcOffset;
List<OptionsEnum>? get options => const fb.ListReader<OptionsEnum>(OptionsEnum.reader).vTableGetNullable(_bc, _bcOffset, 4); List<OptionsEnum>? get options => const fb.ListReader<OptionsEnum>(
OptionsEnum.reader,
).vTableGetNullable(_bc, _bcOffset, 4);
@override @override
String toString() { String toString() {
@@ -61,7 +67,11 @@ class MyTable {
} }
MyTableT unpack() => MyTableT( MyTableT unpack() => MyTableT(
options: const fb.ListReader<OptionsEnum>(OptionsEnum.reader, lazy: false).vTableGetNullable(_bc, _bcOffset, 4)); options: const fb.ListReader<OptionsEnum>(
OptionsEnum.reader,
lazy: false,
).vTableGetNullable(_bc, _bcOffset, 4),
);
static int pack(fb.Builder fbBuilder, MyTableT? object) { static int pack(fb.Builder fbBuilder, MyTableT? object) {
if (object == null) return 0; if (object == null) return 0;
@@ -72,12 +82,12 @@ class MyTable {
class MyTableT implements fb.Packable { class MyTableT implements fb.Packable {
List<OptionsEnum>? options; List<OptionsEnum>? options;
MyTableT({ MyTableT({this.options});
this.options});
@override @override
int pack(fb.Builder fbBuilder) { int pack(fb.Builder fbBuilder) {
final int? optionsOffset = options == null ? null final int? optionsOffset = options == null
? null
: fbBuilder.writeListUint32(options!.map((f) => f.value).toList()); : fbBuilder.writeListUint32(options!.map((f) => f.value).toList());
fbBuilder.startTable(1); fbBuilder.startTable(1);
fbBuilder.addOffset(0, optionsOffset); fbBuilder.addOffset(0, optionsOffset);
@@ -120,15 +130,13 @@ class MyTableBuilder {
class MyTableObjectBuilder extends fb.ObjectBuilder { class MyTableObjectBuilder extends fb.ObjectBuilder {
final List<OptionsEnum>? _options; final List<OptionsEnum>? _options;
MyTableObjectBuilder({ MyTableObjectBuilder({List<OptionsEnum>? options}) : _options = options;
List<OptionsEnum>? options,
})
: _options = options;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override
int finish(fb.Builder fbBuilder) { int finish(fb.Builder fbBuilder) {
final int? optionsOffset = _options == null ? null final int? optionsOffset = _options == null
? null
: fbBuilder.writeListUint32(_options!.map((f) => f.value).toList()); : fbBuilder.writeListUint32(_options!.map((f) => f.value).toList());
fbBuilder.startTable(1); fbBuilder.startTable(1);
fbBuilder.addOffset(0, optionsOffset); fbBuilder.addOffset(0, optionsOffset);

View File

@@ -1,16 +1,15 @@
import 'dart:typed_data';
import 'dart:io' as io; import 'dart:io' as io;
import 'dart:typed_data';
import 'package:path/path.dart' as path;
import 'package:flat_buffers/flat_buffers.dart'; import 'package:flat_buffers/flat_buffers.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart';
import './monster_test_my_game.example_generated.dart' as example;
import './monster_test_my_game.example2_generated.dart' as example2;
import 'enums_generated.dart' as example3;
import './bool_structs_generated.dart' as example4; import './bool_structs_generated.dart' as example4;
import './monster_test_my_game.example2_generated.dart' as example2;
import './monster_test_my_game.example_generated.dart' as example;
import 'enums_generated.dart' as example3;
main() { main() {
defineReflectiveSuite(() { defineReflectiveSuite(() {
@@ -29,11 +28,9 @@ int indexToField(int index) {
@reflectiveTest @reflectiveTest
class CheckOtherLangaugesData { class CheckOtherLangaugesData {
test_cppData() async { test_cppData() async {
List<int> data = await io.File(path.join( List<int> data = await io.File(
path.context.current, path.join(path.context.current, 'test', 'monsterdata_test.mon'),
'test', ).readAsBytes();
'monsterdata_test.mon',
)).readAsBytes();
example.Monster mon = example.Monster(data); example.Monster mon = example.Monster(data);
expect(mon.hp, 80); expect(mon.hp, 80);
expect(mon.mana, 150); expect(mon.mana, 150);
@@ -145,7 +142,8 @@ class CheckOtherLangaugesData {
'longEnumNormalDefault: LongEnum.LongOne, nanDefault: NaN, ' 'longEnumNormalDefault: LongEnum.LongOne, nanDefault: NaN, '
'infDefault: Infinity, positiveInfDefault: Infinity, infinityDefault: ' 'infDefault: Infinity, positiveInfDefault: Infinity, infinityDefault: '
'Infinity, positiveInfinityDefault: Infinity, negativeInfDefault: ' 'Infinity, positiveInfinityDefault: Infinity, negativeInfDefault: '
'-Infinity, negativeInfinityDefault: -Infinity, doubleInfDefault: Infinity}'); '-Infinity, negativeInfinityDefault: -Infinity, doubleInfDefault: Infinity}',
);
} }
} }
@@ -298,20 +296,72 @@ class BuilderTest {
expect(allocator.buffer(builder.size()), [2, 0, 0, 0, 0, 0, 0, 1]); expect(allocator.buffer(builder.size()), [2, 0, 0, 0, 0, 0, 0, 1]);
builder.putUint8(3); builder.putUint8(3);
expect( expect(allocator.buffer(builder.size()), [
allocator.buffer(builder.size()), [0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 1]); 0,
0,
0,
3,
2,
0,
0,
0,
0,
0,
0,
1,
]);
builder.putUint8(4); builder.putUint8(4);
expect( expect(allocator.buffer(builder.size()), [
allocator.buffer(builder.size()), [0, 0, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); 0,
0,
4,
3,
2,
0,
0,
0,
0,
0,
0,
1,
]);
builder.putUint8(5); builder.putUint8(5);
expect( expect(allocator.buffer(builder.size()), [
allocator.buffer(builder.size()), [0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); 0,
5,
4,
3,
2,
0,
0,
0,
0,
0,
0,
1,
]);
builder.putUint32(6); builder.putUint32(6);
expect(allocator.buffer(builder.size()), expect(allocator.buffer(builder.size()), [
[6, 0, 0, 0, 0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); 6,
0,
0,
0,
0,
5,
4,
3,
2,
0,
0,
0,
0,
0,
0,
1,
]);
} }
void test_table_default() { void test_table_default() {
@@ -331,14 +381,14 @@ class BuilderTest {
int objectOffset = buffer.derefObject(0); int objectOffset = buffer.derefObject(0);
// was not written, so uses the new default value // was not written, so uses the new default value
expect( expect(
const Int32Reader() const Int32Reader().vTableGet(buffer, objectOffset, indexToField(0), 15),
.vTableGet(buffer, objectOffset, indexToField(0), 15), 15,
15); );
// has the written value // has the written value
expect( expect(
const Int32Reader() const Int32Reader().vTableGet(buffer, objectOffset, indexToField(1), 15),
.vTableGet(buffer, objectOffset, indexToField(1), 15), 20,
20); );
} }
void test_table_format([Builder? builder]) { void test_table_format([Builder? builder]) {
@@ -370,7 +420,9 @@ class BuilderTest {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
int offset = byteData.getUint16(vTableLoc + 4 + 2 * i, Endian.little); int offset = byteData.getUint16(vTableLoc + 4 + 2 * i, Endian.little);
expect( expect(
byteData.getInt32(tableDataLoc + offset, Endian.little), 10 + 10 * i); byteData.getInt32(tableDataLoc + offset, Endian.little),
10 + 10 * i,
);
} }
} }
@@ -380,10 +432,14 @@ class BuilderTest {
List<int> byteList; List<int> byteList;
{ {
Builder builder = Builder(initialSize: 0); Builder builder = Builder(initialSize: 0);
int? latinStringOffset = int? latinStringOffset = builder.writeString(
builder.writeString(latinString, asciiOptimization: true); latinString,
int? unicodeStringOffset = asciiOptimization: true,
builder.writeString(unicodeString, asciiOptimization: true); );
int? unicodeStringOffset = builder.writeString(
unicodeString,
asciiOptimization: true,
);
builder.startTable(2); builder.startTable(2);
builder.addOffset(0, latinStringOffset); builder.addOffset(0, latinStringOffset);
builder.addOffset(1, unicodeStringOffset); builder.addOffset(1, unicodeStringOffset);
@@ -395,13 +451,19 @@ class BuilderTest {
BufferContext buf = BufferContext.fromBytes(byteList); BufferContext buf = BufferContext.fromBytes(byteList);
int objectOffset = buf.derefObject(0); int objectOffset = buf.derefObject(0);
expect( expect(
const StringReader() const StringReader().vTableGetNullable(
.vTableGetNullable(buf, objectOffset, indexToField(0)), buf,
latinString); objectOffset,
indexToField(0),
),
latinString,
);
expect( expect(
const StringReader(asciiOptimization: true) const StringReader(
.vTableGetNullable(buf, objectOffset, indexToField(1)), asciiOptimization: true,
unicodeString); ).vTableGetNullable(buf, objectOffset, indexToField(1)),
unicodeString,
);
} }
void test_table_types([Builder? builder]) { void test_table_types([Builder? builder]) {
@@ -425,33 +487,41 @@ class BuilderTest {
BufferContext buf = BufferContext.fromBytes(byteList); BufferContext buf = BufferContext.fromBytes(byteList);
int objectOffset = buf.derefObject(0); int objectOffset = buf.derefObject(0);
expect( expect(
const BoolReader() const BoolReader().vTableGetNullable(buf, objectOffset, indexToField(0)),
.vTableGetNullable(buf, objectOffset, indexToField(0)), true,
true); );
expect( expect(
const Int8Reader() const Int8Reader().vTableGetNullable(buf, objectOffset, indexToField(1)),
.vTableGetNullable(buf, objectOffset, indexToField(1)), 10,
10); );
expect( expect(
const Int32Reader() const Int32Reader().vTableGetNullable(buf, objectOffset, indexToField(2)),
.vTableGetNullable(buf, objectOffset, indexToField(2)), 20,
20); );
expect( expect(
const StringReader() const StringReader().vTableGetNullable(
.vTableGetNullable(buf, objectOffset, indexToField(3)), buf,
'12345'); objectOffset,
indexToField(3),
),
'12345',
);
expect( expect(
const Int32Reader() const Int32Reader().vTableGetNullable(buf, objectOffset, indexToField(4)),
.vTableGetNullable(buf, objectOffset, indexToField(4)), 40,
40); );
expect( expect(
const Uint32Reader() const Uint32Reader().vTableGetNullable(
.vTableGetNullable(buf, objectOffset, indexToField(5)), buf,
0x9ABCDEF0); objectOffset,
indexToField(5),
),
0x9ABCDEF0,
);
expect( expect(
const Uint8Reader() const Uint8Reader().vTableGetNullable(buf, objectOffset, indexToField(6)),
.vTableGetNullable(buf, objectOffset, indexToField(6)), 0x9A,
0x9A); );
} }
void test_writeList_of_Uint32() { void test_writeList_of_Uint32() {
@@ -596,8 +666,9 @@ class BuilderTest {
} }
// read and verify // read and verify
BufferContext buf = BufferContext.fromBytes(byteList); BufferContext buf = BufferContext.fromBytes(byteList);
List<TestPointImpl> items = List<TestPointImpl> items = const ListReader<TestPointImpl>(
const ListReader<TestPointImpl>(TestPointReader()).read(buf, 0); TestPointReader(),
).read(buf, 0);
expect(items, hasLength(2)); expect(items, hasLength(2));
expect(items[0].x, 10); expect(items[0].x, 10);
expect(items[0].y, 20); expect(items[0].y, 20);
@@ -627,8 +698,10 @@ class BuilderTest {
List<int> byteList; List<int> byteList;
{ {
builder ??= Builder(initialSize: 0); builder ??= Builder(initialSize: 0);
int listOffset = builder.writeList( int listOffset = builder.writeList([
[builder.writeString('12345'), builder.writeString('ABC')]); builder.writeString('12345'),
builder.writeString('ABC'),
]);
builder.startTable(1); builder.startTable(1);
builder.addOffset(0, listOffset); builder.addOffset(0, listOffset);
int offset = builder.endTable(); int offset = builder.endTable();
@@ -707,13 +780,14 @@ class BuilderTest {
test_table_format, test_table_format,
test_table_types, test_table_types,
test_writeList_ofObjects, test_writeList_ofObjects,
test_writeList_ofStrings_inObject test_writeList_ofStrings_inObject,
]; ];
// Execute all test cases in all permutations of their order. // Execute all test cases in all permutations of their order.
// To do that, we generate permutations of test case indexes. // To do that, we generate permutations of test case indexes.
final testCasesPermutations = final testCasesPermutations = _permutationsOf(
_permutationsOf(List.generate(testCases.length, (index) => index)); List.generate(testCases.length, (index) => index),
);
expect(testCasesPermutations.length, _factorial(testCases.length)); expect(testCasesPermutations.length, _factorial(testCases.length));
for (var indexes in testCasesPermutations) { for (var indexes in testCasesPermutations) {
@@ -788,7 +862,8 @@ class ObjectAPITest {
z: 3, z: 3,
test1: 4.0, test1: 4.0,
test2: example.Color.Red, test2: example.Color.Red,
test3: example.TestT(a: 1, b: 2)) test3: example.TestT(a: 1, b: 2),
)
..mana = 2 ..mana = 2
..name = 'Monstrous' ..name = 'Monstrous'
..inventory = [24, 42] ..inventory = [24, 42]
@@ -804,7 +879,7 @@ class ObjectAPITest {
..testf = 42.24 ..testf = 42.24
..testarrayofsortedstruct = [ ..testarrayofsortedstruct = [
example.AbilityT(id: 1, distance: 5), example.AbilityT(id: 1, distance: 5),
example.AbilityT(id: 3, distance: 7) example.AbilityT(id: 3, distance: 7),
] ]
..vectorOfLongs = [5, 6, 7] ..vectorOfLongs = [5, 6, 7]
..vectorOfDoubles = [8.9, 9.0, 10.1, 11.2] ..vectorOfDoubles = [8.9, 9.0, 10.1, 11.2]
@@ -867,8 +942,9 @@ class StringListWrapperImpl {
StringListWrapperImpl(this.bp, this.offset); StringListWrapperImpl(this.bp, this.offset);
List<String>? get items => const ListReader<String>(StringReader()) List<String>? get items => const ListReader<String>(
.vTableGetNullable(bp, offset, indexToField(0)); StringReader(),
).vTableGetNullable(bp, offset, indexToField(0));
} }
class StringListWrapperReader extends TableReader<StringListWrapperImpl> { class StringListWrapperReader extends TableReader<StringListWrapperImpl> {
@@ -906,10 +982,14 @@ class GeneratorTest {
expect(example.Color.values, same(example.Color.values)); expect(example.Color.values, same(example.Color.values));
expect(example.Race.values, same(example.Race.values)); expect(example.Race.values, same(example.Race.values));
expect(example.AnyTypeId.values, same(example.AnyTypeId.values)); expect(example.AnyTypeId.values, same(example.AnyTypeId.values));
expect(example.AnyUniqueAliasesTypeId.values, expect(
same(example.AnyUniqueAliasesTypeId.values)); example.AnyUniqueAliasesTypeId.values,
expect(example.AnyAmbiguousAliasesTypeId.values, same(example.AnyUniqueAliasesTypeId.values),
same(example.AnyAmbiguousAliasesTypeId.values)); );
expect(
example.AnyAmbiguousAliasesTypeId.values,
same(example.AnyAmbiguousAliasesTypeId.values),
);
} }
} }
@@ -917,11 +997,13 @@ class GeneratorTest {
@reflectiveTest @reflectiveTest
class ListOfEnumsTest { class ListOfEnumsTest {
void test_listOfEnums() async { void test_listOfEnums() async {
var mytable = example3.MyTableObjectBuilder(options: [ var mytable = example3.MyTableObjectBuilder(
options: [
example3.OptionsEnum.A, example3.OptionsEnum.A,
example3.OptionsEnum.B, example3.OptionsEnum.B,
example3.OptionsEnum.C example3.OptionsEnum.C,
]); ],
);
var bytes = mytable.toBytes(); var bytes = mytable.toBytes();
var mytable_read = example3.MyTable(bytes); var mytable_read = example3.MyTable(bytes);
expect(mytable_read.options![0].value, example3.OptionsEnum.A.value); expect(mytable_read.options![0].value, example3.OptionsEnum.A.value);
@@ -934,7 +1016,8 @@ class ListOfEnumsTest {
class BoolInStructTest { class BoolInStructTest {
void test_boolInStruct() async { void test_boolInStruct() async {
var mystruct = example4.FooObjectBuilder( var mystruct = example4.FooObjectBuilder(
myFoo: example4.FooPropertiesObjectBuilder(a: true, b: false)); myFoo: example4.FooPropertiesObjectBuilder(a: true, b: false),
);
var bytes = mystruct.toBytes(); var bytes = mystruct.toBytes();
var mystruct_read = example4.Foo(bytes); var mystruct_read = example4.Foo(bytes);
expect(mystruct_read.myFoo!.a, true); expect(mystruct_read.myFoo!.a, true);

View File

@@ -62,8 +62,23 @@ void main() {
{ {
var flx = Builder(); var flx = Builder();
flx.addString('hello 😱'); flx.addString('hello 😱');
expect(flx.finish(), expect(flx.finish(), [
[10, 104, 101, 108, 108, 111, 32, 240, 159, 152, 177, 0, 11, 20, 1]); 10,
104,
101,
108,
108,
111,
32,
240,
159,
152,
177,
0,
11,
20,
1,
]);
} }
}); });
@@ -117,7 +132,7 @@ void main() {
192, 192,
16, 16,
75, 75,
1 1,
]); ]);
} }
{ {
@@ -177,7 +192,7 @@ void main() {
7, 7,
3, 3,
60, 60,
1 1,
]); ]);
} }
{ {
@@ -215,7 +230,7 @@ void main() {
10, 10,
6, 6,
60, 60,
1 1,
]); ]);
} }
{ {
@@ -300,7 +315,7 @@ void main() {
104, 104,
45, 45,
43, 43,
1 1,
]); ]);
} }
}); });
@@ -322,8 +337,24 @@ void main() {
..addKey('') ..addKey('')
..addInt(45) ..addInt(45)
..end(); ..end();
expect( expect(flx.finish(), [
flx.finish(), [97, 0, 0, 2, 2, 5, 2, 1, 2, 45, 12, 4, 4, 4, 36, 1]); 97,
0,
0,
2,
2,
5,
2,
1,
2,
45,
12,
4,
4,
4,
36,
1,
]);
} }
{ {
var flx = Builder() var flx = Builder()
@@ -367,7 +398,7 @@ void main() {
36, 36,
4, 4,
40, 40,
1 1,
]); ]);
} }
}); });
@@ -381,21 +412,38 @@ void main() {
test('build from object', () { test('build from object', () {
expect( expect(
Builder.buildFromObject(Uint8List.fromList([1, 2, 3]).buffer) Builder.buildFromObject(
.asUint8List(), Uint8List.fromList([1, 2, 3]).buffer,
[3, 1, 2, 3, 3, 100, 1]); ).asUint8List(),
[3, 1, 2, 3, 3, 100, 1],
);
expect(Builder.buildFromObject(null).asUint8List(), [0, 0, 1]); expect(Builder.buildFromObject(null).asUint8List(), [0, 0, 1]);
expect(Builder.buildFromObject(true).asUint8List(), [1, 104, 1]); expect(Builder.buildFromObject(true).asUint8List(), [1, 104, 1]);
expect(Builder.buildFromObject(false).asUint8List(), [0, 104, 1]); expect(Builder.buildFromObject(false).asUint8List(), [0, 104, 1]);
expect(Builder.buildFromObject(25).asUint8List(), [25, 4, 1]); expect(Builder.buildFromObject(25).asUint8List(), [25, 4, 1]);
expect(Builder.buildFromObject(-250).asUint8List(), [6, 255, 5, 2]); expect(Builder.buildFromObject(-250).asUint8List(), [6, 255, 5, 2]);
expect(Builder.buildFromObject(-2.50).asUint8List(), [
0,
0,
32,
192,
14,
4,
]);
expect(Builder.buildFromObject('Maxim').asUint8List(), [
5,
77,
97,
120,
105,
109,
0,
6,
20,
1,
]);
expect( expect(
Builder.buildFromObject(-2.50).asUint8List(), [0, 0, 32, 192, 14, 4]); Builder.buildFromObject([1, 3.3, 'max', true, null, false]).asUint8List(),
expect(Builder.buildFromObject('Maxim').asUint8List(),
[5, 77, 97, 120, 105, 109, 0, 6, 20, 1]);
expect(
Builder.buildFromObject([1, 3.3, 'max', true, null, false])
.asUint8List(),
[ [
3, 3,
109, 109,
@@ -469,12 +517,13 @@ void main() {
104, 104,
54, 54,
43, 43,
1 1,
]); ],
);
expect( expect(
Builder.buildFromObject([ Builder.buildFromObject([
{'something': 12}, {'something': 12},
{'something': 45} {'something': 45},
]).asUint8List(), ]).asUint8List(),
[ [
115, 115,
@@ -506,8 +555,9 @@ void main() {
36, 36,
4, 4,
40, 40,
1 1,
]); ],
);
}); });
test('add double indirectly', () { test('add double indirectly', () {
@@ -543,7 +593,7 @@ void main() {
35, 35,
8, 8,
40, 40,
1 1,
]); ]);
}); });
@@ -580,7 +630,7 @@ void main() {
27, 27,
8, 8,
40, 40,
1 1,
]); ]);
}); });

View File

@@ -20,70 +20,76 @@ void main() {
expect(Reference.fromBuffer(b([1, 4, 5, 2])).intValue, 1025); expect(Reference.fromBuffer(b([1, 4, 5, 2])).intValue, 1025);
expect(Reference.fromBuffer(b([255, 251, 5, 2])).intValue, -1025); expect(Reference.fromBuffer(b([255, 251, 5, 2])).intValue, -1025);
expect(Reference.fromBuffer(b([1, 4, 9, 2])).intValue, 1025); expect(Reference.fromBuffer(b([1, 4, 9, 2])).intValue, 1025);
expect(Reference.fromBuffer(b([255, 255, 255, 127, 6, 4])).intValue, expect(
2147483647); Reference.fromBuffer(b([255, 255, 255, 127, 6, 4])).intValue,
2147483647,
);
expect(Reference.fromBuffer(b([0, 0, 0, 128, 6, 4])).intValue, -2147483648); expect(Reference.fromBuffer(b([0, 0, 0, 128, 6, 4])).intValue, -2147483648);
expect( expect(
Reference.fromBuffer(b([255, 255, 255, 255, 0, 0, 0, 0, 7, 8])) Reference.fromBuffer(b([255, 255, 255, 255, 0, 0, 0, 0, 7, 8])).intValue,
.intValue, 4294967295,
4294967295); );
expect( expect(
Reference.fromBuffer(b([255, 255, 255, 255, 255, 255, 255, 127, 7, 8])) Reference.fromBuffer(
.intValue, b([255, 255, 255, 255, 255, 255, 255, 127, 7, 8]),
9223372036854775807); ).intValue,
expect(Reference.fromBuffer(b([0, 0, 0, 0, 0, 0, 0, 128, 7, 8])).intValue, 9223372036854775807,
-9223372036854775808); );
expect(
Reference.fromBuffer(b([0, 0, 0, 0, 0, 0, 0, 128, 7, 8])).intValue,
-9223372036854775808,
);
// Dart does not really support UInt64 // Dart does not really support UInt64
// expect(FlxValue.fromBuffer(b([255, 255, 255, 255, 255, 255, 255, 255, 11, 8])).intValue, 18446744073709551615); // expect(FlxValue.fromBuffer(b([255, 255, 255, 255, 255, 255, 255, 255, 11, 8])).intValue, 18446744073709551615);
}); });
test('double value', () { test('double value', () {
expect(Reference.fromBuffer(b([0, 0, 128, 63, 14, 4])).doubleValue, 1.0); expect(Reference.fromBuffer(b([0, 0, 128, 63, 14, 4])).doubleValue, 1.0);
expect(Reference.fromBuffer(b([0, 0, 144, 64, 14, 4])).doubleValue, 4.5); expect(Reference.fromBuffer(b([0, 0, 144, 64, 14, 4])).doubleValue, 4.5);
expect(Reference.fromBuffer(b([205, 204, 204, 61, 14, 4])).doubleValue,
closeTo(.1, .001));
expect( expect(
Reference.fromBuffer(b([154, 153, 153, 153, 153, 153, 185, 63, 15, 8])) Reference.fromBuffer(b([205, 204, 204, 61, 14, 4])).doubleValue,
.doubleValue, closeTo(.1, .001),
.1); );
expect(
Reference.fromBuffer(
b([154, 153, 153, 153, 153, 153, 185, 63, 15, 8]),
).doubleValue,
.1,
);
}); });
test('num value', () { test('num value', () {
expect(Reference.fromBuffer(b([0, 0, 144, 64, 14, 4])).numValue, 4.5); expect(Reference.fromBuffer(b([0, 0, 144, 64, 14, 4])).numValue, 4.5);
expect(Reference.fromBuffer(b([205, 204, 204, 61, 14, 4])).numValue,
closeTo(.1, .001));
expect( expect(
Reference.fromBuffer(b([154, 153, 153, 153, 153, 153, 185, 63, 15, 8])) Reference.fromBuffer(b([205, 204, 204, 61, 14, 4])).numValue,
.numValue, closeTo(.1, .001),
.1); );
expect(
Reference.fromBuffer(
b([154, 153, 153, 153, 153, 153, 185, 63, 15, 8]),
).numValue,
.1,
);
expect(Reference.fromBuffer(b([255, 251, 5, 2])).numValue, -1025); expect(Reference.fromBuffer(b([255, 251, 5, 2])).numValue, -1025);
}); });
test('string value', () { test('string value', () {
expect( expect(
Reference.fromBuffer(b([5, 77, 97, 120, 105, 109, 0, 6, 20, 1])) Reference.fromBuffer(
.stringValue, b([5, 77, 97, 120, 105, 109, 0, 6, 20, 1]),
'Maxim'); ).stringValue,
'Maxim',
);
expect( expect(
Reference.fromBuffer(b([ Reference.fromBuffer(
10, b([10, 104, 101, 108, 108, 111, 32, 240, 159, 152, 177, 0, 11, 20, 1]),
104, ).stringValue,
101, 'hello 😱',
108, );
108,
111,
32,
240,
159,
152,
177,
0,
11,
20,
1
])).stringValue,
'hello 😱');
}); });
test('blob value', () { test('blob value', () {
expect( expect(Reference.fromBuffer(b([3, 1, 2, 3, 3, 100, 1])).blobValue, [
Reference.fromBuffer(b([3, 1, 2, 3, 3, 100, 1])).blobValue, [1, 2, 3]); 1,
2,
3,
]);
}); });
test('bool vector', () { test('bool vector', () {
var flx = Reference.fromBuffer(b([3, 1, 0, 1, 3, 144, 1])); var flx = Reference.fromBuffer(b([3, 1, 0, 1, 3, 144, 1]));
@@ -95,9 +101,12 @@ void main() {
testNumbers([3, 1, 2, 3, 3, 44, 1], [1, 2, 3]); testNumbers([3, 1, 2, 3, 3, 44, 1], [1, 2, 3]);
testNumbers([3, 255, 2, 3, 3, 44, 1], [-1, 2, 3]); testNumbers([3, 255, 2, 3, 3, 44, 1], [-1, 2, 3]);
testNumbers([3, 0, 1, 0, 43, 2, 3, 0, 6, 45, 1], [1, 555, 3]); testNumbers([3, 0, 1, 0, 43, 2, 3, 0, 6, 45, 1], [1, 555, 3]);
testNumbers([3, 0, 0, 0, 1, 0, 0, 0, 204, 216, 0, 0, 3, 0, 0, 0, 12, 46, 1], testNumbers(
[1, 55500, 3]); [3, 0, 0, 0, 1, 0, 0, 0, 204, 216, 0, 0, 3, 0, 0, 0, 12, 46, 1],
testNumbers([ [1, 55500, 3],
);
testNumbers(
[
3, 3,
0, 0,
0, 0,
@@ -132,16 +141,16 @@ void main() {
0, 0,
24, 24,
47, 47,
1
], [
1, 1,
55555555500, ],
3 [1, 55555555500, 3],
]); );
testNumbers( testNumbers(
[3, 0, 0, 0, 0, 0, 192, 63, 0, 0, 32, 64, 0, 0, 96, 64, 12, 54, 1], [3, 0, 0, 0, 0, 0, 192, 63, 0, 0, 32, 64, 0, 0, 96, 64, 12, 54, 1],
[1.5, 2.5, 3.5]); [1.5, 2.5, 3.5],
testNumbers([ );
testNumbers(
[
3, 3,
0, 0,
0, 0,
@@ -176,18 +185,17 @@ void main() {
64, 64,
24, 24,
55, 55,
1 1,
], [ ],
1.1, [1.1, 2.2, 3.3],
2.2, );
3.3
]);
}); });
test('number vector, fixed type', () { test('number vector, fixed type', () {
testNumbers([1, 2, 2, 64, 1], [1, 2]); testNumbers([1, 2, 2, 64, 1], [1, 2]);
testNumbers([255, 255, 0, 1, 4, 65, 1], [-1, 256]); testNumbers([255, 255, 0, 1, 4, 65, 1], [-1, 256]);
testNumbers([211, 255, 255, 255, 0, 232, 3, 0, 8, 66, 1], [-45, 256000]); testNumbers([211, 255, 255, 255, 0, 232, 3, 0, 8, 66, 1], [-45, 256000]);
testNumbers([ testNumbers(
[
211, 211,
255, 255,
255, 255,
@@ -206,18 +214,18 @@ void main() {
127, 127,
16, 16,
67, 67,
1 1,
], [ ],
-45, [-45, 9223372036854775807],
9223372036854775807 );
]);
testNumbers([1, 2, 2, 68, 1], [1, 2]); testNumbers([1, 2, 2, 68, 1], [1, 2]);
testNumbers([1, 0, 0, 1, 4, 69, 1], [1, 256]); testNumbers([1, 0, 0, 1, 4, 69, 1], [1, 256]);
testNumbers([45, 0, 0, 0, 0, 232, 3, 0, 8, 70, 1], [45, 256000]); testNumbers([45, 0, 0, 0, 0, 232, 3, 0, 8, 70, 1], [45, 256000]);
testNumbers([205, 204, 140, 63, 0, 0, 0, 192, 8, 74, 1], [1.1, -2]); testNumbers([205, 204, 140, 63, 0, 0, 0, 192, 8, 74, 1], [1.1, -2]);
testNumbers([ testNumbers(
[
154, 154,
153, 153,
153, 153,
@@ -236,16 +244,18 @@ void main() {
192, 192,
16, 16,
75, 75,
1 1,
], [ ],
1.1, [1.1, -256],
-256 );
]);
testNumbers([211, 255, 255, 255, 0, 232, 3, 0, 4, 0, 0, 0, 12, 78, 1], testNumbers(
[-45, 256000, 4]); [211, 255, 255, 255, 0, 232, 3, 0, 4, 0, 0, 0, 12, 78, 1],
[-45, 256000, 4],
);
testNumbers([ testNumbers(
[
211, 211,
255, 255,
255, 255,
@@ -280,15 +290,13 @@ void main() {
0, 0,
32, 32,
91, 91,
1 1,
], [ ],
-45, [-45, 9223372036854775807, 4, 9],
9223372036854775807, );
4,
9
]);
testNumbers([ testNumbers(
[
45, 45,
0, 0,
0, 0,
@@ -323,15 +331,13 @@ void main() {
0, 0,
32, 32,
95, 95,
1 1,
], [ ],
45, [45, 9223372036854775807, 4, 9],
9223372036854775807, );
4,
9
]);
testNumbers([ testNumbers(
[
154, 154,
153, 153,
153, 153,
@@ -358,14 +364,13 @@ void main() {
64, 64,
24, 24,
87, 87,
1 1,
], [ ],
1.1, [1.1, 256, 4],
256, );
4
]);
testNumbers([ testNumbers(
[
154, 154,
153, 153,
153, 153,
@@ -400,16 +405,14 @@ void main() {
64, 64,
32, 32,
99, 99,
1 1,
], [ ],
1.1, [1.1, 256, 4, 9],
256, );
4,
9
]);
}); });
test('string vector', () { test('string vector', () {
testStrings([ testStrings(
[
3, 3,
102, 102,
111, 111,
@@ -431,13 +434,12 @@ void main() {
7, 7,
3, 3,
60, 60,
1 1,
], [ ],
'foo', ['foo', 'bar', 'baz'],
'bar', );
'baz' testStrings(
]); [
testStrings([
3, 3,
102, 102,
111, 111,
@@ -462,18 +464,14 @@ void main() {
10, 10,
6, 6,
60, 60,
1 1,
], [ ],
'foo', ['foo', 'bar', 'baz', 'foo', 'bar', 'baz'],
'bar', );
'baz',
'foo',
'bar',
'baz'
]);
}); });
test('mixed vector', () { test('mixed vector', () {
var flx = Reference.fromBuffer(b([ var flx = Reference.fromBuffer(
b([
3, 3,
102, 102,
111, 111,
@@ -537,8 +535,9 @@ void main() {
104, 104,
45, 45,
43, 43,
1 1,
])); ]),
);
expect(flx.length, 5); expect(flx.length, 5);
expect(flx[0].stringValue, 'foo'); expect(flx[0].stringValue, 'foo');
expect(flx[1].numValue, 1); expect(flx[1].numValue, 1);
@@ -554,7 +553,8 @@ void main() {
}); });
test('two value map', () { test('two value map', () {
var flx = Reference.fromBuffer( var flx = Reference.fromBuffer(
b([0, 97, 0, 2, 4, 4, 2, 1, 2, 45, 12, 4, 4, 4, 36, 1])); b([0, 97, 0, 2, 4, 4, 2, 1, 2, 45, 12, 4, 4, 4, 36, 1]),
);
expect(flx.length, 2); expect(flx.length, 2);
expect(flx['a'].numValue, 12); expect(flx['a'].numValue, 12);
expect(flx[''].numValue, 45); expect(flx[''].numValue, 45);
@@ -579,54 +579,89 @@ void main() {
expect( expect(
() => flx['address']['country'].stringValue, () => flx['address']['country'].stringValue,
throwsA(predicate((dynamic e) => throwsA(
predicate(
(dynamic e) =>
e is ArgumentError && e is ArgumentError &&
e.message == e.message ==
'Key: [country] is not applicable on: //address of: ValueType.Map'))); 'Key: [country] is not applicable on: //address of: ValueType.Map',
),
),
);
expect( expect(
() => flx['address']['countryCode'][0], () => flx['address']['countryCode'][0],
throwsA(predicate((dynamic e) => throwsA(
predicate(
(dynamic e) =>
e is ArgumentError && e is ArgumentError &&
e.message == e.message ==
'Key: [0] is not applicable on: //address/countryCode of: ValueType.String'))); 'Key: [0] is not applicable on: //address/countryCode of: ValueType.String',
),
),
);
expect( expect(
() => flx[1], () => flx[1],
throwsA(predicate((dynamic e) => throwsA(
predicate(
(dynamic e) =>
e is ArgumentError && e is ArgumentError &&
e.message == e.message == 'Key: [1] is not applicable on: / of: ValueType.Map',
'Key: [1] is not applicable on: / of: ValueType.Map'))); ),
),
);
expect( expect(
() => flx['flags'][4], () => flx['flags'][4],
throwsA(predicate((dynamic e) => throwsA(
predicate(
(dynamic e) =>
e is ArgumentError && e is ArgumentError &&
e.message == e.message ==
'Key: [4] is not applicable on: //flags of: ValueType.VectorBool length: 4'))); 'Key: [4] is not applicable on: //flags of: ValueType.VectorBool length: 4',
),
),
);
expect( expect(
() => flx['flags'][-1], () => flx['flags'][-1],
throwsA(predicate((dynamic e) => throwsA(
predicate(
(dynamic e) =>
e is ArgumentError && e is ArgumentError &&
e.message == e.message ==
'Key: [-1] is not applicable on: //flags of: ValueType.VectorBool length: 4'))); 'Key: [-1] is not applicable on: //flags of: ValueType.VectorBool length: 4',
),
),
);
}); });
test('complex map to json', () { test('complex map to json', () {
var flx = complexMap(); var flx = complexMap();
expect(flx.json, expect(
'{"address":{"city":"Bla","countryCode":"XX","zip":"12345"},"age":35,"flags":[true,false,true,true],"name":"Maxim","weight":72.5}'); flx.json,
'{"address":{"city":"Bla","countryCode":"XX","zip":"12345"},"age":35,"flags":[true,false,true,true],"name":"Maxim","weight":72.5}',
);
}); });
test('complex map iterators', () { test('complex map iterators', () {
var flx = complexMap(); var flx = complexMap();
expect(flx.mapKeyIterable.map((e) => e).toList(), expect(flx.mapKeyIterable.map((e) => e).toList(), [
['address', 'age', 'flags', 'name', 'weight']); 'address',
'age',
'flags',
'name',
'weight',
]);
expect(flx.mapValueIterable.map((e) => e.json).toList(), [ expect(flx.mapValueIterable.map((e) => e.json).toList(), [
flx['address'].json, flx['address'].json,
flx['age'].json, flx['age'].json,
flx['flags'].json, flx['flags'].json,
flx['name'].json, flx['name'].json,
flx['weight'].json flx['weight'].json,
]);
expect(flx['flags'].vectorIterable.map((e) => e.boolValue).toList(), [
true,
false,
true,
true,
]); ]);
expect(flx['flags'].vectorIterable.map((e) => e.boolValue).toList(),
[true, false, true, true]);
}); });
test('bug where offest were stored as int instead of uint', () { test('bug where offest were stored as int instead of uint', () {
@@ -790,11 +825,13 @@ void main() {
4, 4,
16, 16,
36, 36,
1 1,
]; ];
var flx = Reference.fromBuffer(b(data)); var flx = Reference.fromBuffer(b(data));
expect(flx.json, expect(
'{"channels_in":64,"dilation_height_factor":1,"dilation_width_factor":1,"fused_activation_function":1,"pad_values":1,"padding":0,"stride_height":1,"stride_width":1}'); flx.json,
'{"channels_in":64,"dilation_height_factor":1,"dilation_width_factor":1,"fused_activation_function":1,"pad_values":1,"padding":0,"stride_height":1,"stride_width":1}',
);
const object = { const object = {
"channels_in": 64, "channels_in": 64,
"dilation_height_factor": 1, "dilation_height_factor": 1,
@@ -803,13 +840,15 @@ void main() {
"pad_values": 1, "pad_values": 1,
"padding": 0, "padding": 0,
"stride_height": 1, "stride_height": 1,
"stride_width": 1 "stride_width": 1,
}; };
var data1 = Builder.buildFromObject(object).asUint8List(); var data1 = Builder.buildFromObject(object).asUint8List();
expect(data1.length, data.length); expect(data1.length, data.length);
var flx1 = Reference.fromBuffer(b(data1)); var flx1 = Reference.fromBuffer(b(data1));
expect(flx1.json, expect(
'{"channels_in":64,"dilation_height_factor":1,"dilation_width_factor":1,"fused_activation_function":1,"pad_values":1,"padding":0,"stride_height":1,"stride_width":1}'); flx1.json,
'{"channels_in":64,"dilation_height_factor":1,"dilation_width_factor":1,"fused_activation_function":1,"pad_values":1,"padding":0,"stride_height":1,"stride_width":1}',
);
}); });
} }
@@ -835,18 +874,19 @@ void testStrings(List<int> buffer, List<String> numbers) {
} }
Reference complexMap() { Reference complexMap() {
// { // {
// "age": 35, // "age": 35,
// "flags": [True, False, True, True], // "flags": [True, False, True, True],
// "weight": 72.5, // "weight": 72.5,
// "name": "Maxim", // "name": "Maxim",
// "address": { // "address": {
// "city": "Bla", // "city": "Bla",
// "zip": "12345", // "zip": "12345",
// "countryCode": "XX", // "countryCode": "XX",
// } // }
// } // }
return Reference.fromBuffer(b([ return Reference.fromBuffer(
b([
97, 97,
100, 100,
100, 100,
@@ -986,6 +1026,7 @@ Reference complexMap() {
14, 14,
25, 25,
38, 38,
1 1,
])); ]),
);
} }

View File

@@ -48,116 +48,210 @@ void main() {
expect(ValueTypeUtils.isFixedTypedVector(ValueType.VectorInt), isFalse); expect(ValueTypeUtils.isFixedTypedVector(ValueType.VectorInt), isFalse);
}); });
test('to typed vector', () { test('to typed vector', () {
expect(ValueTypeUtils.toTypedVector(ValueType.Int, 0), expect(
equals(ValueType.VectorInt)); ValueTypeUtils.toTypedVector(ValueType.Int, 0),
expect(ValueTypeUtils.toTypedVector(ValueType.UInt, 0), equals(ValueType.VectorInt),
equals(ValueType.VectorUInt)); );
expect(ValueTypeUtils.toTypedVector(ValueType.Bool, 0), expect(
equals(ValueType.VectorBool)); ValueTypeUtils.toTypedVector(ValueType.UInt, 0),
expect(ValueTypeUtils.toTypedVector(ValueType.Float, 0), equals(ValueType.VectorUInt),
equals(ValueType.VectorFloat)); );
expect(ValueTypeUtils.toTypedVector(ValueType.Key, 0), expect(
equals(ValueType.VectorKey)); ValueTypeUtils.toTypedVector(ValueType.Bool, 0),
expect(ValueTypeUtils.toTypedVector(ValueType.String, 0), equals(ValueType.VectorBool),
equals(ValueType.VectorString)); );
expect(
ValueTypeUtils.toTypedVector(ValueType.Float, 0),
equals(ValueType.VectorFloat),
);
expect(
ValueTypeUtils.toTypedVector(ValueType.Key, 0),
equals(ValueType.VectorKey),
);
expect(
ValueTypeUtils.toTypedVector(ValueType.String, 0),
equals(ValueType.VectorString),
);
expect(ValueTypeUtils.toTypedVector(ValueType.Int, 2), expect(
equals(ValueType.VectorInt2)); ValueTypeUtils.toTypedVector(ValueType.Int, 2),
expect(ValueTypeUtils.toTypedVector(ValueType.UInt, 2), equals(ValueType.VectorInt2),
equals(ValueType.VectorUInt2)); );
expect(ValueTypeUtils.toTypedVector(ValueType.Float, 2), expect(
equals(ValueType.VectorFloat2)); ValueTypeUtils.toTypedVector(ValueType.UInt, 2),
equals(ValueType.VectorUInt2),
);
expect(
ValueTypeUtils.toTypedVector(ValueType.Float, 2),
equals(ValueType.VectorFloat2),
);
expect(ValueTypeUtils.toTypedVector(ValueType.Int, 3), expect(
equals(ValueType.VectorInt3)); ValueTypeUtils.toTypedVector(ValueType.Int, 3),
expect(ValueTypeUtils.toTypedVector(ValueType.UInt, 3), equals(ValueType.VectorInt3),
equals(ValueType.VectorUInt3)); );
expect(ValueTypeUtils.toTypedVector(ValueType.Float, 3), expect(
equals(ValueType.VectorFloat3)); ValueTypeUtils.toTypedVector(ValueType.UInt, 3),
equals(ValueType.VectorUInt3),
);
expect(
ValueTypeUtils.toTypedVector(ValueType.Float, 3),
equals(ValueType.VectorFloat3),
);
expect(ValueTypeUtils.toTypedVector(ValueType.Int, 4), expect(
equals(ValueType.VectorInt4)); ValueTypeUtils.toTypedVector(ValueType.Int, 4),
expect(ValueTypeUtils.toTypedVector(ValueType.UInt, 4), equals(ValueType.VectorInt4),
equals(ValueType.VectorUInt4)); );
expect(ValueTypeUtils.toTypedVector(ValueType.Float, 4), expect(
equals(ValueType.VectorFloat4)); ValueTypeUtils.toTypedVector(ValueType.UInt, 4),
equals(ValueType.VectorUInt4),
);
expect(
ValueTypeUtils.toTypedVector(ValueType.Float, 4),
equals(ValueType.VectorFloat4),
);
}); });
test('typed vector element type', () { test('typed vector element type', () {
expect(ValueTypeUtils.typedVectorElementType(ValueType.VectorInt), expect(
equals(ValueType.Int)); ValueTypeUtils.typedVectorElementType(ValueType.VectorInt),
expect(ValueTypeUtils.typedVectorElementType(ValueType.VectorUInt), equals(ValueType.Int),
equals(ValueType.UInt)); );
expect(ValueTypeUtils.typedVectorElementType(ValueType.VectorFloat), expect(
equals(ValueType.Float)); ValueTypeUtils.typedVectorElementType(ValueType.VectorUInt),
expect(ValueTypeUtils.typedVectorElementType(ValueType.VectorString), equals(ValueType.UInt),
equals(ValueType.String)); );
expect(ValueTypeUtils.typedVectorElementType(ValueType.VectorKey), expect(
equals(ValueType.Key)); ValueTypeUtils.typedVectorElementType(ValueType.VectorFloat),
expect(ValueTypeUtils.typedVectorElementType(ValueType.VectorBool), equals(ValueType.Float),
equals(ValueType.Bool)); );
expect(
ValueTypeUtils.typedVectorElementType(ValueType.VectorString),
equals(ValueType.String),
);
expect(
ValueTypeUtils.typedVectorElementType(ValueType.VectorKey),
equals(ValueType.Key),
);
expect(
ValueTypeUtils.typedVectorElementType(ValueType.VectorBool),
equals(ValueType.Bool),
);
}); });
test('fixed typed vector element type', () { test('fixed typed vector element type', () {
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorInt2), expect(
equals(ValueType.Int)); ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorInt2),
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorInt3), equals(ValueType.Int),
equals(ValueType.Int)); );
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorInt4), expect(
equals(ValueType.Int)); ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorInt3),
equals(ValueType.Int),
);
expect(
ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorInt4),
equals(ValueType.Int),
);
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorUInt2), expect(
equals(ValueType.UInt)); ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorUInt2),
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorUInt3), equals(ValueType.UInt),
equals(ValueType.UInt)); );
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorUInt4), expect(
equals(ValueType.UInt)); ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorUInt3),
equals(ValueType.UInt),
);
expect(
ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorUInt4),
equals(ValueType.UInt),
);
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorFloat2), expect(
equals(ValueType.Float)); ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorFloat2),
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorFloat3), equals(ValueType.Float),
equals(ValueType.Float)); );
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorFloat4), expect(
equals(ValueType.Float)); ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorFloat3),
equals(ValueType.Float),
);
expect(
ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorFloat4),
equals(ValueType.Float),
);
}); });
test('fixed typed vector element size', () { test('fixed typed vector element size', () {
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorInt2), expect(
equals(2)); ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorInt2),
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorInt3), equals(2),
equals(3)); );
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorInt4), expect(
equals(4)); ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorInt3),
equals(3),
);
expect(
ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorInt4),
equals(4),
);
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorUInt2), expect(
equals(2)); ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorUInt2),
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorUInt3), equals(2),
equals(3)); );
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorUInt4), expect(
equals(4)); ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorUInt3),
equals(3),
);
expect(
ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorUInt4),
equals(4),
);
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorFloat2), expect(
equals(2)); ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorFloat2),
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorFloat3), equals(2),
equals(3)); );
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorFloat4), expect(
equals(4)); ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorFloat3),
equals(3),
);
expect(
ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorFloat4),
equals(4),
);
}); });
test('packed type', () { test('packed type', () {
expect( expect(
ValueTypeUtils.packedType(ValueType.Null, BitWidth.width8), equals(0)); ValueTypeUtils.packedType(ValueType.Null, BitWidth.width8),
equals(0),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Null, BitWidth.width16), equals(1)); ValueTypeUtils.packedType(ValueType.Null, BitWidth.width16),
equals(1),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Null, BitWidth.width32), equals(2)); ValueTypeUtils.packedType(ValueType.Null, BitWidth.width32),
equals(2),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Null, BitWidth.width64), equals(3)); ValueTypeUtils.packedType(ValueType.Null, BitWidth.width64),
equals(3),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Int, BitWidth.width8), equals(4)); ValueTypeUtils.packedType(ValueType.Int, BitWidth.width8),
equals(4),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Int, BitWidth.width16), equals(5)); ValueTypeUtils.packedType(ValueType.Int, BitWidth.width16),
equals(5),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Int, BitWidth.width32), equals(6)); ValueTypeUtils.packedType(ValueType.Int, BitWidth.width32),
equals(6),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Int, BitWidth.width64), equals(7)); ValueTypeUtils.packedType(ValueType.Int, BitWidth.width64),
equals(7),
);
}); });
test('bit width', () { test('bit width', () {
expect(BitWidthUtil.width(0), BitWidth.width8); expect(BitWidthUtil.width(0), BitWidth.width8);

View File

@@ -2,10 +2,11 @@
// ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable, constant_identifier_names // ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable, constant_identifier_names
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb; import 'package:flat_buffers/flat_buffers.dart' as fb;
import './include_test2_my_game.other_name_space_generated.dart'
import './include_test2_my_game.other_name_space_generated.dart' as my_game_other_name_space; as my_game_other_name_space;
class TableA { class TableA {
TableA._(this._bc, this._bcOffset); TableA._(this._bc, this._bcOffset);
@@ -19,15 +20,17 @@ class TableA {
final fb.BufferContext _bc; final fb.BufferContext _bc;
final int _bcOffset; final int _bcOffset;
my_game_other_name_space.TableB? get b => my_game_other_name_space.TableB.reader.vTableGetNullable(_bc, _bcOffset, 4); my_game_other_name_space.TableB? get b => my_game_other_name_space
.TableB
.reader
.vTableGetNullable(_bc, _bcOffset, 4);
@override @override
String toString() { String toString() {
return 'TableA{b: ${b}}'; return 'TableA{b: ${b}}';
} }
TableAT unpack() => TableAT( TableAT unpack() => TableAT(b: b?.unpack());
b: b?.unpack());
static int pack(fb.Builder fbBuilder, TableAT? object) { static int pack(fb.Builder fbBuilder, TableAT? object) {
if (object == null) return 0; if (object == null) return 0;
@@ -38,8 +41,7 @@ class TableA {
class TableAT implements fb.Packable { class TableAT implements fb.Packable {
my_game_other_name_space.TableBT? b; my_game_other_name_space.TableBT? b;
TableAT({ TableAT({this.b});
this.b});
@override @override
int pack(fb.Builder fbBuilder) { int pack(fb.Builder fbBuilder) {
@@ -59,8 +61,7 @@ class _TableAReader extends fb.TableReader<TableA> {
const _TableAReader(); const _TableAReader();
@override @override
TableA createObject(fb.BufferContext bc, int offset) => TableA createObject(fb.BufferContext bc, int offset) => TableA._(bc, offset);
TableA._(bc, offset);
} }
class TableABuilder { class TableABuilder {
@@ -85,9 +86,7 @@ class TableABuilder {
class TableAObjectBuilder extends fb.ObjectBuilder { class TableAObjectBuilder extends fb.ObjectBuilder {
final my_game_other_name_space.TableBObjectBuilder? _b; final my_game_other_name_space.TableBObjectBuilder? _b;
TableAObjectBuilder({ TableAObjectBuilder({my_game_other_name_space.TableBObjectBuilder? b})
my_game_other_name_space.TableBObjectBuilder? b,
})
: _b = b; : _b = b;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].

View File

@@ -4,8 +4,8 @@
library my_game.other_name_space; library my_game.other_name_space;
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb;
import 'package:flat_buffers/flat_buffers.dart' as fb;
import './include_test1_generated.dart'; import './include_test1_generated.dart';
@@ -17,8 +17,10 @@ enum FromInclude {
factory FromInclude.fromValue(int value) { factory FromInclude.fromValue(int value) {
switch (value) { switch (value) {
case 0: return FromInclude.IncludeVal; case 0:
default: throw StateError('Invalid value $value for bit flag enum'); return FromInclude.IncludeVal;
default:
throw StateError('Invalid value $value for bit flag enum');
} }
} }
@@ -56,8 +58,7 @@ class Unused {
return 'Unused{a: ${a}}'; return 'Unused{a: ${a}}';
} }
UnusedT unpack() => UnusedT( UnusedT unpack() => UnusedT(a: a);
a: a);
static int pack(fb.Builder fbBuilder, UnusedT? object) { static int pack(fb.Builder fbBuilder, UnusedT? object) {
if (object == null) return 0; if (object == null) return 0;
@@ -68,8 +69,7 @@ class Unused {
class UnusedT implements fb.Packable { class UnusedT implements fb.Packable {
int a; int a;
UnusedT({ UnusedT({required this.a});
required this.a});
@override @override
int pack(fb.Builder fbBuilder) { int pack(fb.Builder fbBuilder) {
@@ -90,8 +90,7 @@ class _UnusedReader extends fb.StructReader<Unused> {
int get size => 4; int get size => 4;
@override @override
Unused createObject(fb.BufferContext bc, int offset) => Unused createObject(fb.BufferContext bc, int offset) => Unused._(bc, offset);
Unused._(bc, offset);
} }
class UnusedBuilder { class UnusedBuilder {
@@ -103,16 +102,12 @@ class UnusedBuilder {
fbBuilder.putInt32(a); fbBuilder.putInt32(a);
return fbBuilder.offset; return fbBuilder.offset;
} }
} }
class UnusedObjectBuilder extends fb.ObjectBuilder { class UnusedObjectBuilder extends fb.ObjectBuilder {
final int _a; final int _a;
UnusedObjectBuilder({ UnusedObjectBuilder({required int a}) : _a = a;
required int a,
})
: _a = a;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override
@@ -129,6 +124,7 @@ class UnusedObjectBuilder extends fb.ObjectBuilder {
return fbBuilder.buffer; return fbBuilder.buffer;
} }
} }
class TableB { class TableB {
TableB._(this._bc, this._bcOffset); TableB._(this._bc, this._bcOffset);
factory TableB(List<int> bytes) { factory TableB(List<int> bytes) {
@@ -148,8 +144,7 @@ class TableB {
return 'TableB{a: ${a}}'; return 'TableB{a: ${a}}';
} }
TableBT unpack() => TableBT( TableBT unpack() => TableBT(a: a?.unpack());
a: a?.unpack());
static int pack(fb.Builder fbBuilder, TableBT? object) { static int pack(fb.Builder fbBuilder, TableBT? object) {
if (object == null) return 0; if (object == null) return 0;
@@ -160,8 +155,7 @@ class TableB {
class TableBT implements fb.Packable { class TableBT implements fb.Packable {
TableAT? a; TableAT? a;
TableBT({ TableBT({this.a});
this.a});
@override @override
int pack(fb.Builder fbBuilder) { int pack(fb.Builder fbBuilder) {
@@ -181,8 +175,7 @@ class _TableBReader extends fb.TableReader<TableB> {
const _TableBReader(); const _TableBReader();
@override @override
TableB createObject(fb.BufferContext bc, int offset) => TableB createObject(fb.BufferContext bc, int offset) => TableB._(bc, offset);
TableB._(bc, offset);
} }
class TableBBuilder { class TableBBuilder {
@@ -207,10 +200,7 @@ class TableBBuilder {
class TableBObjectBuilder extends fb.ObjectBuilder { class TableBObjectBuilder extends fb.ObjectBuilder {
final TableAObjectBuilder? _a; final TableAObjectBuilder? _a;
TableBObjectBuilder({ TableBObjectBuilder({TableAObjectBuilder? a}) : _a = a;
TableAObjectBuilder? a,
})
: _a = a;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override

View File

@@ -4,12 +4,12 @@
library my_game.example2; library my_game.example2;
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb; import 'package:flat_buffers/flat_buffers.dart' as fb;
import './monster_test_my_game_generated.dart' as my_game;
import './monster_test_my_game.example_generated.dart' as my_game_example;
import './include_test1_generated.dart'; import './include_test1_generated.dart';
import './monster_test_my_game.example_generated.dart' as my_game_example;
import './monster_test_my_game_generated.dart' as my_game;
class Monster { class Monster {
Monster._(this._bc, this._bcOffset); Monster._(this._bc, this._bcOffset);
@@ -23,7 +23,6 @@ class Monster {
final fb.BufferContext _bc; final fb.BufferContext _bc;
final int _bcOffset; final int _bcOffset;
@override @override
String toString() { String toString() {
return 'Monster{}'; return 'Monster{}';
@@ -59,7 +58,6 @@ class _MonsterReader extends fb.TableReader<Monster> {
} }
class MonsterObjectBuilder extends fb.ObjectBuilder { class MonsterObjectBuilder extends fb.ObjectBuilder {
MonsterObjectBuilder(); MonsterObjectBuilder();
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].

File diff suppressed because it is too large Load Diff

View File

@@ -4,12 +4,12 @@
library my_game; library my_game;
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb; import 'package:flat_buffers/flat_buffers.dart' as fb;
import './monster_test_my_game.example_generated.dart' as my_game_example;
import './monster_test_my_game.example2_generated.dart' as my_game_example2;
import './include_test1_generated.dart'; import './include_test1_generated.dart';
import './monster_test_my_game.example2_generated.dart' as my_game_example2;
import './monster_test_my_game.example_generated.dart' as my_game_example;
class InParentNamespace { class InParentNamespace {
InParentNamespace._(this._bc, this._bcOffset); InParentNamespace._(this._bc, this._bcOffset);
@@ -23,7 +23,6 @@ class InParentNamespace {
final fb.BufferContext _bc; final fb.BufferContext _bc;
final int _bcOffset; final int _bcOffset;
@override @override
String toString() { String toString() {
return 'InParentNamespace{}'; return 'InParentNamespace{}';
@@ -59,7 +58,6 @@ class _InParentNamespaceReader extends fb.TableReader<InParentNamespace> {
} }
class InParentNamespaceObjectBuilder extends fb.ObjectBuilder { class InParentNamespaceObjectBuilder extends fb.ObjectBuilder {
InParentNamespaceObjectBuilder(); InParentNamespaceObjectBuilder();
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].

View File

@@ -104,13 +104,16 @@ func (b *Builder) StartObject(numfields int) {
// logically-equal vtables will be deduplicated. // logically-equal vtables will be deduplicated.
// //
// A vtable has the following format: // A vtable has the following format:
//
// <VOffsetT: size of the vtable in bytes, including this value> // <VOffsetT: size of the vtable in bytes, including this value>
// <VOffsetT: size of the object in bytes, including the vtable offset> // <VOffsetT: size of the object in bytes, including the vtable offset>
// <VOffsetT: offset for a field> * N, where N is the number of fields in // <VOffsetT: offset for a field> * N, where N is the number of fields in
// the schema for this type. Includes deprecated fields. // the schema for this type. Includes deprecated fields.
//
// Thus, a vtable is made of 2 + N elements, each SizeVOffsetT bytes wide. // Thus, a vtable is made of 2 + N elements, each SizeVOffsetT bytes wide.
// //
// An object has the following format: // An object has the following format:
//
// <SOffsetT: offset to this object's vtable (may be negative)> // <SOffsetT: offset to this object's vtable (may be negative)>
// <byte: data>+ // <byte: data>+
func (b *Builder) WriteVtable() (n UOffsetT) { func (b *Builder) WriteVtable() (n UOffsetT) {
@@ -296,6 +299,7 @@ func (b *Builder) PrependUOffsetT(off UOffsetT) {
// StartVector initializes bookkeeping for writing a new vector. // StartVector initializes bookkeeping for writing a new vector.
// //
// A vector has the following format: // A vector has the following format:
//
// <UOffsetT: number of elements in this vector> // <UOffsetT: number of elements in this vector>
// <T: data>+, where T is the type of elements of this vector. // <T: data>+, where T is the type of elements of this vector.
func (b *Builder) StartVector(elemSize, numElems, alignment int) UOffsetT { func (b *Builder) StartVector(elemSize, numElems, alignment int) UOffsetT {

View File

@@ -1,5 +1,5 @@
import sys
from pathlib import Path from pathlib import Path
import sys
# Get the path where this script is located so we can invoke the script from # Get the path where this script is located so we can invoke the script from
# any directory and have the paths work correctly. # any directory and have the paths work correctly.

View File

@@ -2,5 +2,5 @@
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
export { Galaxy } from './galaxy.js'; export {Galaxy} from './galaxy.js';
export { Universe } from './universe.js'; export {Universe} from './universe.js';

View File

@@ -1,31 +1,36 @@
import sys
import argparse import argparse
import sys
import grpc import grpc
sys.path.insert(0, '../../../../../flatbuffers/python') sys.path.insert(0, "../../../../../flatbuffers/python")
import flatbuffers import flatbuffers
from models import HelloReply, HelloRequest, greeter_grpc_fb from models import HelloReply, HelloRequest, greeter_grpc_fb
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("port", help="server port to connect to", default=3000) parser.add_argument("port", help="server port to connect to", default=3000)
parser.add_argument("name", help="name to be sent to server", default="flatbuffers") parser.add_argument(
"name", help="name to be sent to server", default="flatbuffers"
)
def say_hello(stub, hello_request): def say_hello(stub, hello_request):
reply = stub.SayHello(hello_request) reply = stub.SayHello(hello_request)
r = HelloReply.HelloReply.GetRootAs(reply) r = HelloReply.HelloReply.GetRootAs(reply)
print(r.Message()) print(r.Message())
def say_many_hellos(stub, hello_request): def say_many_hellos(stub, hello_request):
greetings = stub.SayManyHellos(hello_request) greetings = stub.SayManyHellos(hello_request)
for greeting in greetings: for greeting in greetings:
r = HelloReply.HelloReply.GetRootAs(greeting) r = HelloReply.HelloReply.GetRootAs(greeting)
print(r.Message()) print(r.Message())
def main(): def main():
args = parser.parse_args() args = parser.parse_args()
with grpc.insecure_channel('localhost:' + args.port) as channel: with grpc.insecure_channel("localhost:" + args.port) as channel:
builder = flatbuffers.Builder() builder = flatbuffers.Builder()
ind = builder.CreateString(args.name) ind = builder.CreateString(args.name)
HelloRequest.HelloRequestStart(builder) HelloRequest.HelloRequestStart(builder)
@@ -37,4 +42,5 @@ def main():
say_hello(stub, output) say_hello(stub, output)
say_many_hellos(stub, output) say_many_hellos(stub, output)
main() main()

View File

@@ -2,30 +2,29 @@
import flatbuffers import flatbuffers
import grpc import grpc
from models.HelloReply import HelloReply from models.HelloReply import HelloReply
from models.HelloRequest import HelloRequest from models.HelloRequest import HelloRequest
class GreeterStub(object): class GreeterStub(object):
'''Interface exported by the server.''' """Interface exported by the server."""
def __init__(self, channel): def __init__(self, channel):
'''Constructor. """Constructor.
Args: Args:
channel: A grpc.Channel. channel: A grpc.Channel.
''' """
self.SayHello = channel.unary_unary( self.SayHello = channel.unary_unary(method='/models.Greeter/SayHello')
method='/models.Greeter/SayHello')
self.SayManyHellos = channel.unary_stream( self.SayManyHellos = channel.unary_stream(
method='/models.Greeter/SayManyHellos') method='/models.Greeter/SayManyHellos'
)
class GreeterServicer(object): class GreeterServicer(object):
'''Interface exported by the server.''' """Interface exported by the server."""
def SayHello(self, request, context): def SayHello(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_code(grpc.StatusCode.UNIMPLEMENTED)
@@ -40,15 +39,14 @@ class GreeterServicer(object):
def add_GreeterServicer_to_server(servicer, server): def add_GreeterServicer_to_server(servicer, server):
rpc_method_handlers = { rpc_method_handlers = {
'SayHello': grpc.unary_unary_rpc_method_handler( 'SayHello': grpc.unary_unary_rpc_method_handler(servicer.SayHello),
servicer.SayHello),
'SayManyHellos': grpc.unary_stream_rpc_method_handler( 'SayManyHellos': grpc.unary_stream_rpc_method_handler(
servicer.SayManyHellos), servicer.SayManyHellos
),
} }
generic_handler = grpc.method_handlers_generic_handler( generic_handler = grpc.method_handlers_generic_handler(
'models.Greeter', rpc_method_handlers) 'models.Greeter', rpc_method_handlers
)
server.add_generic_rpc_handlers((generic_handler,)) server.add_generic_rpc_handlers((generic_handler,))

View File

@@ -1,9 +1,9 @@
import argparse
from concurrent import futures from concurrent import futures
import sys import sys
import argparse
import grpc import grpc
sys.path.insert(0, '../../../../../flatbuffers/python') sys.path.insert(0, "../../../../../flatbuffers/python")
import flatbuffers import flatbuffers
from models import HelloReply, HelloRequest, greeter_grpc_fb from models import HelloReply, HelloRequest, greeter_grpc_fb
@@ -11,6 +11,7 @@ from models import HelloReply, HelloRequest, greeter_grpc_fb
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("port", help="server on port", default=3000) parser.add_argument("port", help="server on port", default=3000)
def build_reply(message): def build_reply(message):
builder = flatbuffers.Builder() builder = flatbuffers.Builder()
ind = builder.CreateString(message) ind = builder.CreateString(message)
@@ -20,6 +21,7 @@ def build_reply(message):
builder.Finish(root) builder.Finish(root)
return bytes(builder.Output()) return bytes(builder.Output())
class GreeterServicer(greeter_grpc_fb.GreeterServicer): class GreeterServicer(greeter_grpc_fb.GreeterServicer):
def __init__(self): def __init__(self):
@@ -30,7 +32,7 @@ class GreeterServicer(greeter_grpc_fb.GreeterServicer):
reply = "Unknown" reply = "Unknown"
if r.Name(): if r.Name():
reply = r.Name() reply = r.Name()
return build_reply("welcome " + reply.decode('UTF-8')) return build_reply("welcome " + reply.decode("UTF-8"))
def SayManyHellos(self, request, context): def SayManyHellos(self, request, context):
r = HelloRequest.HelloRequest().GetRootAs(request, 0) r = HelloRequest.HelloRequest().GetRootAs(request, 0)
@@ -40,18 +42,17 @@ class GreeterServicer(greeter_grpc_fb.GreeterServicer):
for greeting in self.greetings: for greeting in self.greetings:
print(type(reply)) print(type(reply))
yield build_reply(greeting + " " + reply.decode('UTF-8')) yield build_reply(greeting + " " + reply.decode("UTF-8"))
def serve(): def serve():
args = parser.parse_args() args = parser.parse_args()
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
greeter_grpc_fb.add_GreeterServicer_to_server( greeter_grpc_fb.add_GreeterServicer_to_server(GreeterServicer(), server)
GreeterServicer(), server server.add_insecure_port("[::]:" + args.port)
)
server.add_insecure_port('[::]:' + args.port)
server.start() server.start()
server.wait_for_termination() server.wait_for_termination()
if __name__ == '__main__':
if __name__ == "__main__":
serve() serve()

View File

@@ -37,7 +37,8 @@ func greet(name: String, client greeter: models_GreeterServiceClient) {
builder.finish(offset: root) builder.finish(offset: root)
// Make the RPC call to the server. // Make the RPC call to the server.
let sayHello = greeter let sayHello =
greeter
.SayHello(Message<models_HelloRequest>(builder: &builder)) .SayHello(Message<models_HelloRequest>(builder: &builder))
// wait() on the response to stop the program from exiting before the response is received. // wait() on the response to stop the program from exiting before the response is received.
@@ -76,7 +77,7 @@ func main(args: [String]) {
print("Usage: PORT [NAME]") print("Usage: PORT [NAME]")
exit(1) exit(1)
case let (.some(port), name): case (.some(let port), let name):
// Setup an `EventLoopGroup` for the connection to run on. // Setup an `EventLoopGroup` for the connection to run on.
// //
// See: https://github.com/apple/swift-nio#eventloops-and-eventloopgroups // See: https://github.com/apple/swift-nio#eventloops-and-eventloopgroups

View File

@@ -32,7 +32,8 @@ class Greeter: models_GreeterProvider {
func SayHello( func SayHello(
request: Message<models_HelloRequest>, request: Message<models_HelloRequest>,
context: StatusOnlyCallContext) context: StatusOnlyCallContext
)
-> EventLoopFuture<Message<models_HelloReply>> -> EventLoopFuture<Message<models_HelloReply>>
{ {
let recipient = request.object.name ?? "Stranger" let recipient = request.object.name ?? "Stranger"
@@ -47,12 +48,14 @@ class Greeter: models_GreeterProvider {
func SayManyHellos( func SayManyHellos(
request: Message<models_HelloRequest>, request: Message<models_HelloRequest>,
context: StreamingResponseCallContext<Message<models_HelloReply>>) context: StreamingResponseCallContext<Message<models_HelloReply>>
)
-> EventLoopFuture<GRPCStatus> -> EventLoopFuture<GRPCStatus>
{ {
for name in greetings { for name in greetings {
var builder = FlatBufferBuilder() var builder = FlatBufferBuilder()
let off = builder let off =
builder
.create(string: "\(name) \(request.object.name ?? "Unknown")") .create(string: "\(name) \(request.object.name ?? "Unknown")")
let root = models_HelloReply.createHelloReply( let root = models_HelloReply.createHelloReply(
&builder, &builder,

View File

@@ -1,16 +1,21 @@
import * as grpc from '@grpc/grpc-js'; import * as grpc from '@grpc/grpc-js';
import * as flatbuffers from 'flatbuffers'; import * as flatbuffers from 'flatbuffers';
import { HelloReply } from './models/hello-reply'; import {GreeterClient} from './greeter_grpc';
import { HelloRequest } from './models/hello-request'; import {HelloReply} from './models/hello-reply';
import { GreeterClient } from './greeter_grpc'; import {HelloRequest} from './models/hello-request';
async function main(PORT: Number, name: string) { async function main(PORT: Number, name: string) {
const client = new GreeterClient(`localhost:${PORT}`, grpc.credentials.createInsecure()); const client = new GreeterClient(
`localhost:${PORT}`,
grpc.credentials.createInsecure(),
);
const builder = new flatbuffers.Builder(); const builder = new flatbuffers.Builder();
const offset = builder.createString(name); const offset = builder.createString(name);
const root = HelloRequest.createHelloRequest(builder, offset); const root = HelloRequest.createHelloRequest(builder, offset);
builder.finish(root); builder.finish(root);
const buffer = HelloRequest.getRootAsHelloRequest(new flatbuffers.ByteBuffer(builder.asUint8Array())); const buffer = HelloRequest.getRootAsHelloRequest(
new flatbuffers.ByteBuffer(builder.asUint8Array()),
);
client.SayHello(buffer, (err, response) => { client.SayHello(buffer, (err, response) => {
console.log(response.message()); console.log(response.message());
@@ -23,12 +28,12 @@ async function main(PORT: Number, name: string) {
}); });
} }
const args = process.argv.slice(2) const args = process.argv.slice(2);
const PORT = Number(args[0]); const PORT = Number(args[0]);
const name: string = args[1] ?? "flatbuffers"; const name: string = args[1] ?? 'flatbuffers';
if (PORT) { if (PORT) {
main(PORT, name); main(PORT, name);
} else { } else {
throw new Error("Requires a valid port number.") throw new Error('Requires a valid port number.');
} }

View File

@@ -1,4 +1,4 @@
// automatically generated by the FlatBuffers compiler, do not modify // automatically generated by the FlatBuffers compiler, do not modify
export { HelloReply } from './models/hello-reply.js'; export {HelloReply} from './models/hello-reply.js';
export { HelloRequest } from './models/hello-request.js'; export {HelloRequest} from './models/hello-request.js';

View File

@@ -1,31 +1,45 @@
import * as grpc from '@grpc/grpc-js'; import * as grpc from '@grpc/grpc-js';
import * as flatbuffers from 'flatbuffers'; import * as flatbuffers from 'flatbuffers';
import { HelloReply } from './models/hello-reply'; import {GreeterService, IGreeterServer} from './greeter_grpc';
import { HelloRequest } from './models/hello-request'; import {HelloReply} from './models/hello-reply';
import { IGreeterServer, GreeterService } from './greeter_grpc'; import {HelloRequest} from './models/hello-request';
const greeter: IGreeterServer = { const greeter: IGreeterServer = {
SayHello(call: grpc.ServerUnaryCall<HelloRequest, HelloReply>, callback: grpc.sendUnaryData<HelloReply>): void { SayHello(
call: grpc.ServerUnaryCall<HelloRequest, HelloReply>,
callback: grpc.sendUnaryData<HelloReply>,
): void {
console.log(`SayHello ${call.request.name()}`); console.log(`SayHello ${call.request.name()}`);
const builder = new flatbuffers.Builder(); const builder = new flatbuffers.Builder();
const offset = builder.createString(`welcome ${call.request.name()}`); const offset = builder.createString(`welcome ${call.request.name()}`);
const root = HelloReply.createHelloReply(builder, offset); const root = HelloReply.createHelloReply(builder, offset);
builder.finish(root); builder.finish(root);
callback(null, HelloReply.getRootAsHelloReply(new flatbuffers.ByteBuffer(builder.asUint8Array()))); callback(
null,
HelloReply.getRootAsHelloReply(
new flatbuffers.ByteBuffer(builder.asUint8Array()),
),
);
}, },
async SayManyHellos(call: grpc.ServerWritableStream<HelloRequest, HelloReply>): Promise<void> { async SayManyHellos(
call: grpc.ServerWritableStream<HelloRequest, HelloReply>,
): Promise<void> {
const name = call.request.name(); const name = call.request.name();
console.log(`${call.request.name()} saying hi in different langagues`); console.log(`${call.request.name()} saying hi in different langagues`);
['Hi', 'Hallo', 'Ciao'].forEach(element => { ['Hi', 'Hallo', 'Ciao'].forEach((element) => {
const builder = new flatbuffers.Builder(); const builder = new flatbuffers.Builder();
const offset = builder.createString(`${element} ${name}`); const offset = builder.createString(`${element} ${name}`);
const root = HelloReply.createHelloReply(builder, offset); const root = HelloReply.createHelloReply(builder, offset);
builder.finish(root); builder.finish(root);
call.write(HelloReply.getRootAsHelloReply(new flatbuffers.ByteBuffer(builder.asUint8Array()))) call.write(
HelloReply.getRootAsHelloReply(
new flatbuffers.ByteBuffer(builder.asUint8Array()),
),
);
}); });
call.end(); call.end();
} },
} };
function serve(): void { function serve(): void {
const PORT = 3000; const PORT = 3000;
@@ -42,7 +56,7 @@ function serve(): void {
console.log(`Server bound on port: ${port}`); console.log(`Server bound on port: ${port}`);
server.start(); server.start();
} }
} },
); );
} }

View File

@@ -19,28 +19,29 @@ import com.google.flatbuffers.Table;
import io.grpc.Drainable; import io.grpc.Drainable;
import io.grpc.KnownLength; import io.grpc.KnownLength;
import io.grpc.MethodDescriptor; import io.grpc.MethodDescriptor;
import javax.annotation.Nullable;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import javax.annotation.Nullable;
public class FlatbuffersUtils { public class FlatbuffersUtils {
abstract public static class FBExtactor <T extends Table> { public abstract static class FBExtactor<T extends Table> {
T extract (InputStream stream) throws IOException { T extract(InputStream stream) throws IOException {
if (stream instanceof KnownLength) { if (stream instanceof KnownLength) {
int size = stream.available(); int size = stream.available();
ByteBuffer buffer = ByteBuffer.allocate(size); ByteBuffer buffer = ByteBuffer.allocate(size);
stream.read(buffer.array()); stream.read(buffer.array());
return extract(buffer); return extract(buffer);
} else } else
throw new RuntimeException("The class " + stream.getClass().getCanonicalName() + " does not extend from KnownLength "); throw new RuntimeException(
"The class "
+ stream.getClass().getCanonicalName()
+ " does not extend from KnownLength ");
} }
public abstract T extract(ByteBuffer buffer); public abstract T extract(ByteBuffer buffer);
} }
static class FBInputStream extends InputStream implements Drainable, KnownLength { static class FBInputStream extends InputStream implements Drainable, KnownLength {
@@ -81,18 +82,17 @@ public class FlatbuffersUtils {
makeStreamIfNotAlready(); makeStreamIfNotAlready();
return inputStream.read(b, off, len); return inputStream.read(b, off, len);
} }
} else } else return inputStream.read(b, off, len);
return inputStream.read(b, off, len);
} }
@Override @Override
public int available() throws IOException { public int available() throws IOException {
return inputStream == null ? size : inputStream.available(); return inputStream == null ? size : inputStream.available();
} }
} }
public static <T extends Table> MethodDescriptor.Marshaller<T> marshaller(final Class<T> clazz, final FBExtactor<T> extractor) { public static <T extends Table> MethodDescriptor.Marshaller<T> marshaller(
final Class<T> clazz, final FBExtactor<T> extractor) {
return new MethodDescriptor.ReflectableMarshaller<T>() { return new MethodDescriptor.ReflectableMarshaller<T>() {
@Override @Override
public Class<T> getMessageClass() { public Class<T> getMessageClass() {
@@ -101,7 +101,7 @@ public class FlatbuffersUtils {
@Override @Override
public InputStream stream(T value) { public InputStream stream(T value) {
return new FBInputStream (value.getByteBuffer()); return new FBInputStream(value.getByteBuffer());
} }
@Override @Override

View File

@@ -8,21 +8,22 @@
namespace grpc_cpp_generator { namespace grpc_cpp_generator {
namespace { namespace {
template<class T> static grpc::string as_string(T x) { template <class T>
static grpc::string as_string(T x) {
std::ostringstream out; std::ostringstream out;
out << x; out << x;
return out.str(); return out.str();
} }
static inline bool ClientOnlyStreaming(const grpc_generator::Method *method) { static inline bool ClientOnlyStreaming(const grpc_generator::Method* method) {
return method->ClientStreaming() && !method->ServerStreaming(); return method->ClientStreaming() && !method->ServerStreaming();
} }
static inline bool ServerOnlyStreaming(const grpc_generator::Method *method) { static inline bool ServerOnlyStreaming(const grpc_generator::Method* method) {
return !method->ClientStreaming() && method->ServerStreaming(); return !method->ClientStreaming() && method->ServerStreaming();
} }
static grpc::string FilenameIdentifier(const grpc::string &filename) { static grpc::string FilenameIdentifier(const grpc::string& filename) {
grpc::string result; grpc::string result;
for (unsigned i = 0; i < filename.size(); i++) { for (unsigned i = 0; i < filename.size(); i++) {
char c = filename[i]; char c = filename[i];
@@ -38,22 +39,25 @@ static grpc::string FilenameIdentifier(const grpc::string &filename) {
return result; return result;
} }
template<class T, size_t N> static T *array_end(T (&array)[N]) { template <class T, size_t N>
static T* array_end(T (&array)[N]) {
return array + N; return array + N;
} }
static void PrintIncludes(grpc_generator::Printer *printer, static void PrintIncludes(grpc_generator::Printer* printer,
const std::vector<grpc::string> &headers, const std::vector<grpc::string>& headers,
const Parameters &params) { const Parameters& params) {
std::map<grpc::string, grpc::string> vars; std::map<grpc::string, grpc::string> vars;
vars["l"] = params.use_system_headers ? '<' : '"'; vars["l"] = params.use_system_headers ? '<' : '"';
vars["r"] = params.use_system_headers ? '>' : '"'; vars["r"] = params.use_system_headers ? '>' : '"';
auto &s = params.grpc_search_path; auto& s = params.grpc_search_path;
if (!s.empty()) { if (!s.empty()) {
vars["l"] += s; vars["l"] += s;
if (s[s.size() - 1] != '/') { vars["l"] += '/'; } if (s[s.size() - 1] != '/') {
vars["l"] += '/';
}
} }
for (auto i = headers.begin(); i != headers.end(); i++) { for (auto i = headers.begin(); i != headers.end(); i++) {
@@ -62,12 +66,11 @@ static void PrintIncludes(grpc_generator::Printer *printer,
} }
if (params.generate_callback_api) { if (params.generate_callback_api) {
// Callback API headers (guarded later by feature macro in emitted code). // Callback API headers (guarded later by feature macro in emitted code).
static const char *cb_headers[] = { static const char* cb_headers[] = {
"grpcpp/impl/codegen/callback_common.h", "grpcpp/impl/codegen/callback_common.h",
"grpcpp/impl/codegen/server_callback_handlers.h", "grpcpp/impl/codegen/server_callback_handlers.h",
"grpcpp/support/client_callback.h" "grpcpp/support/client_callback.h"};
}; for (auto& h : cb_headers) {
for (auto &h : cb_headers) {
vars["h"] = h; vars["h"] = h;
printer->Print(vars, "#include $l$$h$$r$\n"); printer->Print(vars, "#include $l$$h$$r$\n");
} }
@@ -76,8 +79,8 @@ static void PrintIncludes(grpc_generator::Printer *printer,
} // namespace } // namespace
grpc::string GetHeaderPrologue(grpc_generator::File *file, grpc::string GetHeaderPrologue(grpc_generator::File* file,
const Parameters &params) { const Parameters& params) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
@@ -108,15 +111,15 @@ grpc::string GetHeaderPrologue(grpc_generator::File *file,
return output; return output;
} }
grpc::string GetHeaderIncludes(grpc_generator::File *file, grpc::string GetHeaderIncludes(grpc_generator::File* file,
const Parameters &params) { const Parameters& params) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
auto printer = file->CreatePrinter(&output); auto printer = file->CreatePrinter(&output);
std::map<grpc::string, grpc::string> vars; std::map<grpc::string, grpc::string> vars;
static const char *headers_strs[] = { static const char* headers_strs[] = {
"grpcpp/impl/codegen/async_stream.h", "grpcpp/impl/codegen/async_stream.h",
"grpcpp/impl/codegen/async_unary_call.h", "grpcpp/impl/codegen/async_unary_call.h",
"grpcpp/impl/codegen/method_handler.h", "grpcpp/impl/codegen/method_handler.h",
@@ -125,8 +128,7 @@ grpc::string GetHeaderIncludes(grpc_generator::File *file,
"grpcpp/impl/codegen/service_type.h", "grpcpp/impl/codegen/service_type.h",
"grpcpp/impl/codegen/status.h", "grpcpp/impl/codegen/status.h",
"grpcpp/impl/codegen/stub_options.h", "grpcpp/impl/codegen/stub_options.h",
"grpcpp/impl/codegen/sync_stream.h" "grpcpp/impl/codegen/sync_stream.h"};
};
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs)); std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
PrintIncludes(printer.get(), headers, params); PrintIncludes(printer.get(), headers, params);
printer->Print(vars, "\n"); printer->Print(vars, "\n");
@@ -153,8 +155,8 @@ grpc::string GetHeaderIncludes(grpc_generator::File *file,
namespace { namespace {
static void PrintHeaderClientMethodInterfaces( static void PrintHeaderClientMethodInterfaces(
grpc_generator::Printer *printer, const grpc_generator::Method *method, grpc_generator::Printer* printer, const grpc_generator::Method* method,
std::map<grpc::string, grpc::string> *vars, bool is_public) { std::map<grpc::string, grpc::string>* vars, bool is_public) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name(); (*vars)["Response"] = method->output_type_name();
@@ -163,8 +165,8 @@ static void PrintHeaderClientMethodInterfaces(
grpc::string prefix; grpc::string prefix;
grpc::string method_params; // extra arguments to method grpc::string method_params; // extra arguments to method
grpc::string raw_args; // extra arguments to raw version of method grpc::string raw_args; // extra arguments to raw version of method
} async_prefixes[] = { { "Async", ", void* tag", ", tag" }, } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
{ "PrepareAsync", "", "" } }; {"PrepareAsync", "", ""}};
if (is_public) { if (is_public) {
if (method->NoStreaming()) { if (method->NoStreaming()) {
@@ -174,7 +176,7 @@ static void PrintHeaderClientMethodInterfaces(
"const $Request$& request, $Response$* response) = 0;\n"); "const $Request$& request, $Response$* response) = 0;\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
printer->Print( printer->Print(
*vars, *vars,
@@ -207,7 +209,7 @@ static void PrintHeaderClientMethodInterfaces(
printer->Print("}\n"); printer->Print("}\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args; (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -242,7 +244,7 @@ static void PrintHeaderClientMethodInterfaces(
printer->Print("}\n"); printer->Print("}\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args; (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -276,7 +278,7 @@ static void PrintHeaderClientMethodInterfaces(
printer->Print("}\n"); printer->Print("}\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args; (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -300,7 +302,7 @@ static void PrintHeaderClientMethodInterfaces(
if (method->NoStreaming()) { if (method->NoStreaming()) {
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
printer->Print( printer->Print(
*vars, *vars,
@@ -317,7 +319,7 @@ static void PrintHeaderClientMethodInterfaces(
"::grpc::ClientContext* context, $Response$* response) = 0;\n"); "::grpc::ClientContext* context, $Response$* response) = 0;\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
printer->Print( printer->Print(
@@ -335,7 +337,7 @@ static void PrintHeaderClientMethodInterfaces(
"::grpc::ClientContext* context, const $Request$& request) = 0;\n"); "::grpc::ClientContext* context, const $Request$& request) = 0;\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
printer->Print( printer->Print(
@@ -352,7 +354,7 @@ static void PrintHeaderClientMethodInterfaces(
"$Method$Raw(::grpc::ClientContext* context) = 0;\n"); "$Method$Raw(::grpc::ClientContext* context) = 0;\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
printer->Print( printer->Print(
@@ -366,9 +368,9 @@ static void PrintHeaderClientMethodInterfaces(
} }
} }
static void PrintHeaderClientMethod(grpc_generator::Printer *printer, static void PrintHeaderClientMethod(grpc_generator::Printer* printer,
const grpc_generator::Method *method, const grpc_generator::Method* method,
std::map<grpc::string, grpc::string> *vars, std::map<grpc::string, grpc::string>* vars,
bool is_public) { bool is_public) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
@@ -377,8 +379,8 @@ static void PrintHeaderClientMethod(grpc_generator::Printer *printer,
grpc::string prefix; grpc::string prefix;
grpc::string method_params; // extra arguments to method grpc::string method_params; // extra arguments to method
grpc::string raw_args; // extra arguments to raw version of method grpc::string raw_args; // extra arguments to raw version of method
} async_prefixes[] = { { "Async", ", void* tag", ", tag" }, } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
{ "PrepareAsync", "", "" } }; {"PrepareAsync", "", ""}};
if (is_public) { if (is_public) {
if (method->NoStreaming()) { if (method->NoStreaming()) {
@@ -404,7 +406,7 @@ static void PrintHeaderClientMethod(grpc_generator::Printer *printer,
} }
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
printer->Print( printer->Print(
*vars, *vars,
@@ -436,11 +438,12 @@ static void PrintHeaderClientMethod(grpc_generator::Printer *printer,
printer->Print(*vars, "// Client streaming callback reactor entry.\n"); printer->Print(*vars, "// Client streaming callback reactor entry.\n");
printer->Print( printer->Print(
*vars, *vars,
"void async_$Method$(::grpc::ClientContext* context, $Response$* response, ::grpc::ClientWriteReactor< $Request$ >* reactor);\n"); "void async_$Method$(::grpc::ClientContext* context, $Response$* "
"response, ::grpc::ClientWriteReactor< $Request$ >* reactor);\n");
} }
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args; (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -474,11 +477,13 @@ static void PrintHeaderClientMethod(grpc_generator::Printer *printer,
if ((*vars)["generate_callback_api"] == "1") { if ((*vars)["generate_callback_api"] == "1") {
printer->Print(*vars, "// Server streaming callback reactor entry.\n"); printer->Print(*vars, "// Server streaming callback reactor entry.\n");
printer->Print(*vars, printer->Print(*vars,
"void async_$Method$(::grpc::ClientContext* context, const $Request$& request, ::grpc::ClientReadReactor< $Response$ >* reactor);\n"); "void async_$Method$(::grpc::ClientContext* context, "
"const $Request$& request, ::grpc::ClientReadReactor< "
"$Response$ >* reactor);\n");
} }
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args; (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -509,14 +514,16 @@ static void PrintHeaderClientMethod(grpc_generator::Printer *printer,
printer->Outdent(); printer->Outdent();
printer->Print("}\n"); printer->Print("}\n");
if ((*vars)["generate_callback_api"] == "1") { if ((*vars)["generate_callback_api"] == "1") {
printer->Print(*vars, "// Bidirectional streaming callback reactor entry.\n"); printer->Print(*vars,
"// Bidirectional streaming callback reactor entry.\n");
printer->Print( printer->Print(
*vars, *vars,
"void async_$Method$(::grpc::ClientContext* context, ::grpc::ClientBidiReactor< $Request$, $Response$ >* reactor);\n"); "void async_$Method$(::grpc::ClientContext* context, "
"::grpc::ClientBidiReactor< $Request$, $Response$ >* reactor);\n");
} }
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args; (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -539,7 +546,7 @@ static void PrintHeaderClientMethod(grpc_generator::Printer *printer,
if (method->NoStreaming()) { if (method->NoStreaming()) {
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
printer->Print( printer->Print(
*vars, *vars,
@@ -559,7 +566,7 @@ static void PrintHeaderClientMethod(grpc_generator::Printer *printer,
"override;\n"); "override;\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args; (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -576,7 +583,7 @@ static void PrintHeaderClientMethod(grpc_generator::Printer *printer,
" override;\n"); " override;\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args; (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -592,7 +599,7 @@ static void PrintHeaderClientMethod(grpc_generator::Printer *printer,
"$Method$Raw(::grpc::ClientContext* context) override;\n"); "$Method$Raw(::grpc::ClientContext* context) override;\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args; (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -607,16 +614,16 @@ static void PrintHeaderClientMethod(grpc_generator::Printer *printer,
} }
static void PrintHeaderClientMethodData( static void PrintHeaderClientMethodData(
grpc_generator::Printer *printer, const grpc_generator::Method *method, grpc_generator::Printer* printer, const grpc_generator::Method* method,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string>* vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
printer->Print(*vars, printer->Print(*vars,
"const ::grpc::internal::RpcMethod rpcmethod_$Method$_;\n"); "const ::grpc::internal::RpcMethod rpcmethod_$Method$_;\n");
} }
static void PrintHeaderServerMethodSync( static void PrintHeaderServerMethodSync(
grpc_generator::Printer *printer, const grpc_generator::Method *method, grpc_generator::Printer* printer, const grpc_generator::Method* method,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string>* vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name(); (*vars)["Response"] = method->output_type_name();
@@ -649,8 +656,8 @@ static void PrintHeaderServerMethodSync(
} }
static void PrintHeaderServerMethodAsync( static void PrintHeaderServerMethodAsync(
grpc_generator::Printer *printer, const grpc_generator::Method *method, grpc_generator::Printer* printer, const grpc_generator::Method* method,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string>* vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name(); (*vars)["Response"] = method->output_type_name();
@@ -765,8 +772,8 @@ static void PrintHeaderServerMethodAsync(
} }
static void PrintHeaderServerMethodStreamedUnary( static void PrintHeaderServerMethodStreamedUnary(
grpc_generator::Printer *printer, const grpc_generator::Method *method, grpc_generator::Printer* printer, const grpc_generator::Method* method,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string>* vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name(); (*vars)["Response"] = method->output_type_name();
@@ -816,8 +823,8 @@ static void PrintHeaderServerMethodStreamedUnary(
} }
static void PrintHeaderServerMethodSplitStreaming( static void PrintHeaderServerMethodSplitStreaming(
grpc_generator::Printer *printer, const grpc_generator::Method *method, grpc_generator::Printer* printer, const grpc_generator::Method* method,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string>* vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name(); (*vars)["Response"] = method->output_type_name();
@@ -869,8 +876,8 @@ static void PrintHeaderServerMethodSplitStreaming(
} }
static void PrintHeaderServerMethodGeneric( static void PrintHeaderServerMethodGeneric(
grpc_generator::Printer *printer, const grpc_generator::Method *method, grpc_generator::Printer* printer, const grpc_generator::Method* method,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string>* vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name(); (*vars)["Response"] = method->output_type_name();
@@ -939,9 +946,9 @@ static void PrintHeaderServerMethodGeneric(
printer->Print(*vars, "};\n"); printer->Print(*vars, "};\n");
} }
static void PrintHeaderService(grpc_generator::Printer *printer, static void PrintHeaderService(grpc_generator::Printer* printer,
const grpc_generator::Service *service, const grpc_generator::Service* service,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string>* vars) {
(*vars)["Service"] = service->name(); (*vars)["Service"] = service->name();
printer->Print(service->GetLeadingComments("//").c_str()); printer->Print(service->GetLeadingComments("//").c_str());
@@ -1036,7 +1043,9 @@ static void PrintHeaderService(grpc_generator::Printer *printer,
printer->Print(*vars, "WithAsyncMethod_$method_name$<"); printer->Print(*vars, "WithAsyncMethod_$method_name$<");
} }
printer->Print("Service"); printer->Print("Service");
for (int i = 0; i < service->method_count(); ++i) { printer->Print(" >"); } for (int i = 0; i < service->method_count(); ++i) {
printer->Print(" >");
}
printer->Print(" AsyncService;\n"); printer->Print(" AsyncService;\n");
// Server side - Generic // Server side - Generic
@@ -1061,7 +1070,9 @@ static void PrintHeaderService(grpc_generator::Printer *printer,
} }
printer->Print("Service"); printer->Print("Service");
for (int i = 0; i < service->method_count(); ++i) { for (int i = 0; i < service->method_count(); ++i) {
if (service->method(i)->NoStreaming()) { printer->Print(" >"); } if (service->method(i)->NoStreaming()) {
printer->Print(" >");
}
} }
printer->Print(" StreamedUnaryService;\n"); printer->Print(" StreamedUnaryService;\n");
@@ -1083,7 +1094,9 @@ static void PrintHeaderService(grpc_generator::Printer *printer,
printer->Print("Service"); printer->Print("Service");
for (int i = 0; i < service->method_count(); ++i) { for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i); auto method = service->method(i);
if (ServerOnlyStreaming(method.get())) { printer->Print(" >"); } if (ServerOnlyStreaming(method.get())) {
printer->Print(" >");
}
} }
printer->Print(" SplitStreamedService;\n"); printer->Print(" SplitStreamedService;\n");
@@ -1158,8 +1171,8 @@ static void PrintHeaderService(grpc_generator::Printer *printer,
} // namespace } // namespace
grpc::string GetHeaderServices(grpc_generator::File *file, grpc::string GetHeaderServices(grpc_generator::File* file,
const Parameters &params) { const Parameters& params) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
@@ -1168,7 +1181,9 @@ grpc::string GetHeaderServices(grpc_generator::File *file,
// Package string is empty or ends with a dot. It is used to fully qualify // Package string is empty or ends with a dot. It is used to fully qualify
// method names. // method names.
vars["Package"] = file->package(); vars["Package"] = file->package();
if (!file->package().empty()) { vars["Package"].append("."); } if (!file->package().empty()) {
vars["Package"].append(".");
}
if (!params.services_namespace.empty()) { if (!params.services_namespace.empty()) {
vars["services_namespace"] = params.services_namespace; vars["services_namespace"] = params.services_namespace;
@@ -1192,8 +1207,8 @@ grpc::string GetHeaderServices(grpc_generator::File *file,
return output; return output;
} }
grpc::string GetHeaderEpilogue(grpc_generator::File *file, grpc::string GetHeaderEpilogue(grpc_generator::File* file,
const Parameters & /*params*/) { const Parameters& /*params*/) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
@@ -1221,8 +1236,8 @@ grpc::string GetHeaderEpilogue(grpc_generator::File *file,
return output; return output;
} }
grpc::string GetSourcePrologue(grpc_generator::File *file, grpc::string GetSourcePrologue(grpc_generator::File* file,
const Parameters &params) { const Parameters& params) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
@@ -1247,15 +1262,15 @@ grpc::string GetSourcePrologue(grpc_generator::File *file,
return output; return output;
} }
grpc::string GetSourceIncludes(grpc_generator::File *file, grpc::string GetSourceIncludes(grpc_generator::File* file,
const Parameters &params) { const Parameters& params) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
auto printer = file->CreatePrinter(&output); auto printer = file->CreatePrinter(&output);
std::map<grpc::string, grpc::string> vars; std::map<grpc::string, grpc::string> vars;
static const char *headers_strs[] = { static const char* headers_strs[] = {
"grpcpp/impl/codegen/async_stream.h", "grpcpp/impl/codegen/async_stream.h",
"grpcpp/impl/codegen/async_unary_call.h", "grpcpp/impl/codegen/async_unary_call.h",
"grpcpp/impl/codegen/channel_interface.h", "grpcpp/impl/codegen/channel_interface.h",
@@ -1263,8 +1278,7 @@ grpc::string GetSourceIncludes(grpc_generator::File *file,
"grpcpp/impl/codegen/method_handler.h", "grpcpp/impl/codegen/method_handler.h",
"grpcpp/impl/codegen/rpc_service_method.h", "grpcpp/impl/codegen/rpc_service_method.h",
"grpcpp/impl/codegen/service_type.h", "grpcpp/impl/codegen/service_type.h",
"grpcpp/impl/codegen/sync_stream.h" "grpcpp/impl/codegen/sync_stream.h"};
};
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs)); std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
PrintIncludes(printer.get(), headers, params); PrintIncludes(printer.get(), headers, params);
@@ -1285,8 +1299,8 @@ grpc::string GetSourceIncludes(grpc_generator::File *file,
namespace { namespace {
static void PrintSourceClientMethod( static void PrintSourceClientMethod(
grpc_generator::Printer *printer, const grpc_generator::Method *method, grpc_generator::Printer* printer, const grpc_generator::Method* method,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string>* vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name(); (*vars)["Response"] = method->output_type_name();
@@ -1295,8 +1309,8 @@ static void PrintSourceClientMethod(
grpc::string start; // bool literal expressed as string grpc::string start; // bool literal expressed as string
grpc::string method_params; // extra arguments to method grpc::string method_params; // extra arguments to method
grpc::string create_args; // extra arguments to creator grpc::string create_args; // extra arguments to creator
} async_prefixes[] = { { "Async", "true", ", void* tag", ", tag" }, } async_prefixes[] = {{"Async", "true", ", void* tag", ", tag"},
{ "PrepareAsync", "false", "", ", nullptr" } }; {"PrepareAsync", "false", "", ", nullptr"}};
if (method->NoStreaming()) { if (method->NoStreaming()) {
printer->Print(*vars, printer->Print(*vars,
"::grpc::Status $ns$$Service$::Stub::$Method$(" "::grpc::Status $ns$$Service$::Stub::$Method$("
@@ -1325,11 +1339,12 @@ static void PrintSourceClientMethod(
*vars, *vars,
" " " "
"::grpc::internal::ClientCallbackUnaryFactory::Create(channel_.get()," "::grpc::internal::ClientCallbackUnaryFactory::Create(channel_.get(),"
" rpcmethod_$Method$_, context, &request, response, reactor);\n}\n\n"); " rpcmethod_$Method$_, context, &request, response, "
"reactor);\n}\n\n");
} }
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start; (*vars)["AsyncStart"] = async_prefix.start;
printer->Print(*vars, printer->Print(*vars,
@@ -1372,7 +1387,7 @@ static void PrintSourceClientMethod(
} }
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start; (*vars)["AsyncStart"] = async_prefix.start;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
@@ -1409,14 +1424,15 @@ static void PrintSourceClientMethod(
"void $ns$$Service$::Stub::async_$Method$(::grpc::ClientContext* " "void $ns$$Service$::Stub::async_$Method$(::grpc::ClientContext* "
"context, const $Request$& request, ::grpc::ClientReadReactor< " "context, const $Request$& request, ::grpc::ClientReadReactor< "
"$Response$ >* reactor) {\n"); "$Response$ >* reactor) {\n");
printer->Print(*vars, printer->Print(
*vars,
" ::grpc::internal::ClientCallbackReaderFactory< " " ::grpc::internal::ClientCallbackReaderFactory< "
"$Response$ >::Create(channel_.get(), " "$Response$ >::Create(channel_.get(), "
"rpcmethod_$Method$_, context, &request, reactor);\n}\n\n"); "rpcmethod_$Method$_, context, &request, reactor);\n}\n\n");
} }
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start; (*vars)["AsyncStart"] = async_prefix.start;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
@@ -1460,7 +1476,7 @@ static void PrintSourceClientMethod(
} }
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start; (*vars)["AsyncStart"] = async_prefix.start;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
@@ -1483,8 +1499,8 @@ static void PrintSourceClientMethod(
} }
static void PrintSourceServerMethod( static void PrintSourceServerMethod(
grpc_generator::Printer *printer, const grpc_generator::Method *method, grpc_generator::Printer* printer, const grpc_generator::Method* method,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string>* vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name(); (*vars)["Response"] = method->output_type_name();
@@ -1531,9 +1547,9 @@ static void PrintSourceServerMethod(
} }
} }
static void PrintSourceService(grpc_generator::Printer *printer, static void PrintSourceService(grpc_generator::Printer* printer,
const grpc_generator::Service *service, const grpc_generator::Service* service,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string>* vars) {
(*vars)["Service"] = service->name(); (*vars)["Service"] = service->name();
if (service->method_count() > 0) { if (service->method_count() > 0) {
@@ -1666,28 +1682,34 @@ static void PrintSourceService(grpc_generator::Printer *printer,
"AddMethod(new ::grpc::internal::RpcServiceMethod(\n" "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
" $prefix$$Service$_method_names[$Idx$],\n" " $prefix$$Service$_method_names[$Idx$],\n"
" ::grpc::internal::RpcMethod::NORMAL_RPC,\n" " ::grpc::internal::RpcMethod::NORMAL_RPC,\n"
" new ::grpc::internal::CallbackUnaryHandler<$Request$, $Response$>(\n" " new ::grpc::internal::CallbackUnaryHandler<$Request$, "
" [this](::grpc::CallbackServerContext* ctx, const $Request$* req, $Response$* resp) {\n" "$Response$>(\n"
" [this](::grpc::CallbackServerContext* ctx, const $Request$* "
"req, $Response$* resp) {\n"
" return this->$Method$(ctx, req, resp);\n" " return this->$Method$(ctx, req, resp);\n"
" })));\n"); " })));\n");
} else if (ClientOnlyStreaming(method.get())) { } else if (ClientOnlyStreaming(method.get())) {
printer->Print( printer->Print(*vars,
*vars,
"AddMethod(new ::grpc::internal::RpcServiceMethod(\n" "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
" $prefix$$Service$_method_names[$Idx$],\n" " $prefix$$Service$_method_names[$Idx$],\n"
" ::grpc::internal::RpcMethod::CLIENT_STREAMING,\n" " ::grpc::internal::RpcMethod::CLIENT_STREAMING,\n"
" new ::grpc::internal::CallbackClientStreamingHandler<$Request$, $Response$>(\n" " new "
" [this](::grpc::CallbackServerContext* ctx, $Response$* resp) {\n" "::grpc::internal::CallbackClientStreamingHandler<$"
"Request$, $Response$>(\n"
" [this](::grpc::CallbackServerContext* ctx, "
"$Response$* resp) {\n"
" return this->$Method$(ctx, resp);\n" " return this->$Method$(ctx, resp);\n"
" })));\n"); " })));\n");
} else if (ServerOnlyStreaming(method.get())) { } else if (ServerOnlyStreaming(method.get())) {
printer->Print( printer->Print(*vars,
*vars,
"AddMethod(new ::grpc::internal::RpcServiceMethod(\n" "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
" $prefix$$Service$_method_names[$Idx$],\n" " $prefix$$Service$_method_names[$Idx$],\n"
" ::grpc::internal::RpcMethod::SERVER_STREAMING,\n" " ::grpc::internal::RpcMethod::SERVER_STREAMING,\n"
" new ::grpc::internal::CallbackServerStreamingHandler<$Request$, $Response$>(\n" " new "
" [this](::grpc::CallbackServerContext* ctx, const $Request$* req) {\n" "::grpc::internal::CallbackServerStreamingHandler<$"
"Request$, $Response$>(\n"
" [this](::grpc::CallbackServerContext* ctx, const "
"$Request$* req) {\n"
" return this->$Method$(ctx, req);\n" " return this->$Method$(ctx, req);\n"
" })));\n"); " })));\n");
} else if (method->BidiStreaming()) { } else if (method->BidiStreaming()) {
@@ -1696,7 +1718,8 @@ static void PrintSourceService(grpc_generator::Printer *printer,
"AddMethod(new ::grpc::internal::RpcServiceMethod(\n" "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
" $prefix$$Service$_method_names[$Idx$],\n" " $prefix$$Service$_method_names[$Idx$],\n"
" ::grpc::internal::RpcMethod::BIDI_STREAMING,\n" " ::grpc::internal::RpcMethod::BIDI_STREAMING,\n"
" new ::grpc::internal::CallbackBidiHandler<$Request$, $Response$>(\n" " new ::grpc::internal::CallbackBidiHandler<$Request$, "
"$Response$>(\n"
" [this](::grpc::CallbackServerContext* ctx) {\n" " [this](::grpc::CallbackServerContext* ctx) {\n"
" return this->$Method$(ctx);\n" " return this->$Method$(ctx);\n"
" })));\n"); " })));\n");
@@ -1751,8 +1774,8 @@ static void PrintSourceService(grpc_generator::Printer *printer,
} // namespace } // namespace
grpc::string GetSourceServices(grpc_generator::File *file, grpc::string GetSourceServices(grpc_generator::File* file,
const Parameters &params) { const Parameters& params) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
@@ -1761,7 +1784,9 @@ grpc::string GetSourceServices(grpc_generator::File *file,
// Package string is empty or ends with a dot. It is used to fully qualify // Package string is empty or ends with a dot. It is used to fully qualify
// method names. // method names.
vars["Package"] = file->package(); vars["Package"] = file->package();
if (!file->package().empty()) { vars["Package"].append("."); } if (!file->package().empty()) {
vars["Package"].append(".");
}
if (!params.services_namespace.empty()) { if (!params.services_namespace.empty()) {
vars["ns"] = params.services_namespace + "::"; vars["ns"] = params.services_namespace + "::";
vars["prefix"] = params.services_namespace; vars["prefix"] = params.services_namespace;
@@ -1779,8 +1804,8 @@ grpc::string GetSourceServices(grpc_generator::File *file,
return output; return output;
} }
grpc::string GetSourceEpilogue(grpc_generator::File *file, grpc::string GetSourceEpilogue(grpc_generator::File* file,
const Parameters & /*params*/) { const Parameters& /*params*/) {
grpc::string temp; grpc::string temp;
if (!file->package().empty()) { if (!file->package().empty()) {
@@ -1797,8 +1822,8 @@ grpc::string GetSourceEpilogue(grpc_generator::File *file,
return temp; return temp;
} }
grpc::string GetMockPrologue(grpc_generator::File *file, grpc::string GetMockPrologue(grpc_generator::File* file,
const Parameters &params) { const Parameters& params) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
@@ -1824,15 +1849,15 @@ grpc::string GetMockPrologue(grpc_generator::File *file,
} }
// TODO(mmukhi): Add client-stream and completion-queue headers. // TODO(mmukhi): Add client-stream and completion-queue headers.
grpc::string GetMockIncludes(grpc_generator::File *file, grpc::string GetMockIncludes(grpc_generator::File* file,
const Parameters &params) { const Parameters& params) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
auto printer = file->CreatePrinter(&output); auto printer = file->CreatePrinter(&output);
std::map<grpc::string, grpc::string> vars; std::map<grpc::string, grpc::string> vars;
static const char *headers_strs[] = { static const char* headers_strs[] = {
"grpcpp/impl/codegen/async_stream.h", "grpcpp/impl/codegen/async_stream.h",
"grpcpp/impl/codegen/sync_stream.h", "grpcpp/impl/codegen/sync_stream.h",
"gmock/gmock.h", "gmock/gmock.h",
@@ -1856,9 +1881,9 @@ grpc::string GetMockIncludes(grpc_generator::File *file,
namespace { namespace {
static void PrintMockClientMethods(grpc_generator::Printer *printer, static void PrintMockClientMethods(grpc_generator::Printer* printer,
const grpc_generator::Method *method, const grpc_generator::Method* method,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string>* vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name(); (*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name(); (*vars)["Response"] = method->output_type_name();
@@ -1867,8 +1892,7 @@ static void PrintMockClientMethods(grpc_generator::Printer *printer,
grpc::string prefix; grpc::string prefix;
grpc::string method_params; // extra arguments to method grpc::string method_params; // extra arguments to method
int extra_method_param_count; int extra_method_param_count;
} async_prefixes[] = { { "Async", ", void* tag", 1 }, } async_prefixes[] = {{"Async", ", void* tag", 1}, {"PrepareAsync", "", 0}};
{ "PrepareAsync", "", 0 } };
if (method->NoStreaming()) { if (method->NoStreaming()) {
printer->Print( printer->Print(
@@ -1877,7 +1901,7 @@ static void PrintMockClientMethods(grpc_generator::Printer *printer,
"const $Request$& request, $Response$* response));\n"); "const $Request$& request, $Response$* response));\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
printer->Print( printer->Print(
*vars, *vars,
@@ -1894,7 +1918,7 @@ static void PrintMockClientMethods(grpc_generator::Printer *printer,
"(::grpc::ClientContext* context, $Response$* response));\n"); "(::grpc::ClientContext* context, $Response$* response));\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["MockArgs"] = (*vars)["MockArgs"] =
@@ -1913,7 +1937,7 @@ static void PrintMockClientMethods(grpc_generator::Printer *printer,
"(::grpc::ClientContext* context, const $Request$& request));\n"); "(::grpc::ClientContext* context, const $Request$& request));\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["MockArgs"] = (*vars)["MockArgs"] =
@@ -1933,7 +1957,7 @@ static void PrintMockClientMethods(grpc_generator::Printer *printer,
"(::grpc::ClientContext* context));\n"); "(::grpc::ClientContext* context));\n");
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]); for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) { i++) {
auto &async_prefix = async_prefixes[i]; auto& async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params; (*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["MockArgs"] = (*vars)["MockArgs"] =
@@ -1948,9 +1972,9 @@ static void PrintMockClientMethods(grpc_generator::Printer *printer,
} }
} }
static void PrintMockService(grpc_generator::Printer *printer, static void PrintMockService(grpc_generator::Printer* printer,
const grpc_generator::Service *service, const grpc_generator::Service* service,
std::map<grpc::string, grpc::string> *vars) { std::map<grpc::string, grpc::string>* vars) {
(*vars)["Service"] = service->name(); (*vars)["Service"] = service->name();
printer->Print(*vars, printer->Print(*vars,
@@ -1966,8 +1990,8 @@ static void PrintMockService(grpc_generator::Printer *printer,
} // namespace } // namespace
grpc::string GetMockServices(grpc_generator::File *file, grpc::string GetMockServices(grpc_generator::File* file,
const Parameters &params) { const Parameters& params) {
grpc::string output; grpc::string output;
{ {
// Scope the output stream so it closes and finalizes output to the string. // Scope the output stream so it closes and finalizes output to the string.
@@ -1976,7 +2000,9 @@ grpc::string GetMockServices(grpc_generator::File *file,
// Package string is empty or ends with a dot. It is used to fully qualify // Package string is empty or ends with a dot. It is used to fully qualify
// method names. // method names.
vars["Package"] = file->package(); vars["Package"] = file->package();
if (!file->package().empty()) { vars["Package"].append("."); } if (!file->package().empty()) {
vars["Package"].append(".");
}
if (!params.services_namespace.empty()) { if (!params.services_namespace.empty()) {
vars["services_namespace"] = params.services_namespace; vars["services_namespace"] = params.services_namespace;
@@ -1995,8 +2021,8 @@ grpc::string GetMockServices(grpc_generator::File *file,
return output; return output;
} }
grpc::string GetMockEpilogue(grpc_generator::File *file, grpc::string GetMockEpilogue(grpc_generator::File* file,
const Parameters & /*params*/) { const Parameters& /*params*/) {
grpc::string temp; grpc::string temp;
if (!file->package().empty()) { if (!file->package().empty()) {

View File

@@ -11,8 +11,8 @@
#include "src/compiler/schema_interface.h" #include "src/compiler/schema_interface.h"
#ifndef GRPC_CUSTOM_STRING #ifndef GRPC_CUSTOM_STRING
# include <string> #include <string>
# define GRPC_CUSTOM_STRING std::string #define GRPC_CUSTOM_STRING std::string
#endif #endif
namespace grpc { namespace grpc {
@@ -42,68 +42,68 @@ struct Parameters {
}; };
// Return the prologue of the generated header file. // Return the prologue of the generated header file.
grpc::string GetHeaderPrologue(grpc_generator::File *file, grpc::string GetHeaderPrologue(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the includes needed for generated header file. // Return the includes needed for generated header file.
grpc::string GetHeaderIncludes(grpc_generator::File *file, grpc::string GetHeaderIncludes(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the includes needed for generated source file. // Return the includes needed for generated source file.
grpc::string GetSourceIncludes(grpc_generator::File *file, grpc::string GetSourceIncludes(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the epilogue of the generated header file. // Return the epilogue of the generated header file.
grpc::string GetHeaderEpilogue(grpc_generator::File *file, grpc::string GetHeaderEpilogue(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the prologue of the generated source file. // Return the prologue of the generated source file.
grpc::string GetSourcePrologue(grpc_generator::File *file, grpc::string GetSourcePrologue(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the services for generated header file. // Return the services for generated header file.
grpc::string GetHeaderServices(grpc_generator::File *file, grpc::string GetHeaderServices(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the services for generated source file. // Return the services for generated source file.
grpc::string GetSourceServices(grpc_generator::File *file, grpc::string GetSourceServices(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the epilogue of the generated source file. // Return the epilogue of the generated source file.
grpc::string GetSourceEpilogue(grpc_generator::File *file, grpc::string GetSourceEpilogue(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the prologue of the generated mock file. // Return the prologue of the generated mock file.
grpc::string GetMockPrologue(grpc_generator::File *file, grpc::string GetMockPrologue(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the includes needed for generated mock file. // Return the includes needed for generated mock file.
grpc::string GetMockIncludes(grpc_generator::File *file, grpc::string GetMockIncludes(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the services for generated mock file. // Return the services for generated mock file.
grpc::string GetMockServices(grpc_generator::File *file, grpc::string GetMockServices(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the epilogue of generated mock file. // Return the epilogue of generated mock file.
grpc::string GetMockEpilogue(grpc_generator::File *file, grpc::string GetMockEpilogue(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the prologue of the generated mock file. // Return the prologue of the generated mock file.
grpc::string GetMockPrologue(grpc_generator::File *file, grpc::string GetMockPrologue(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the includes needed for generated mock file. // Return the includes needed for generated mock file.
grpc::string GetMockIncludes(grpc_generator::File *file, grpc::string GetMockIncludes(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the services for generated mock file. // Return the services for generated mock file.
grpc::string GetMockServices(grpc_generator::File *file, grpc::string GetMockServices(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
// Return the epilogue of generated mock file. // Return the epilogue of generated mock file.
grpc::string GetMockEpilogue(grpc_generator::File *file, grpc::string GetMockEpilogue(grpc_generator::File* file,
const Parameters &params); const Parameters& params);
} // namespace grpc_cpp_generator } // namespace grpc_cpp_generator

View File

@@ -4,17 +4,18 @@
#include <map> #include <map>
#include <sstream> #include <sstream>
template<class T> grpc::string as_string(T x) { template <class T>
grpc::string as_string(T x) {
std::ostringstream out; std::ostringstream out;
out << x; out << x;
return out.str(); return out.str();
} }
inline bool ClientOnlyStreaming(const grpc_generator::Method *method) { inline bool ClientOnlyStreaming(const grpc_generator::Method* method) {
return method->ClientStreaming() && !method->ServerStreaming(); return method->ClientStreaming() && !method->ServerStreaming();
} }
inline bool ServerOnlyStreaming(const grpc_generator::Method *method) { inline bool ServerOnlyStreaming(const grpc_generator::Method* method) {
return !method->ClientStreaming() && method->ServerStreaming(); return !method->ClientStreaming() && method->ServerStreaming();
} }
@@ -35,7 +36,7 @@ static grpc::string exportName(grpc::string s) {
return s; return s;
} }
static void GenerateError(grpc_generator::Printer *printer, static void GenerateError(grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> vars, std::map<grpc::string, grpc::string> vars,
const bool multiple_return = true) { const bool multiple_return = true) {
printer->Print(vars, "if $Error_Check$ {\n"); printer->Print(vars, "if $Error_Check$ {\n");
@@ -47,8 +48,8 @@ static void GenerateError(grpc_generator::Printer *printer,
} }
// Generates imports for the service // Generates imports for the service
static void GenerateImports(grpc_generator::File *file, static void GenerateImports(grpc_generator::File* file,
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> vars) { std::map<grpc::string, grpc::string> vars) {
vars["filename"] = file->filename(); vars["filename"] = file->filename();
printer->Print("//Generated by gRPC Go plugin\n"); printer->Print("//Generated by gRPC Go plugin\n");
@@ -67,8 +68,8 @@ static void GenerateImports(grpc_generator::File *file,
} }
// Generates Server method signature source // Generates Server method signature source
static void GenerateServerMethodSignature(const grpc_generator::Method *method, static void GenerateServerMethodSignature(
grpc_generator::Printer *printer, const grpc_generator::Method* method, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> vars) { std::map<grpc::string, grpc::string> vars) {
vars["Method"] = exportName(method->name()); vars["Method"] = exportName(method->name());
vars["Request"] = method->get_input_type_name(); vars["Request"] = method->get_input_type_name();
@@ -87,8 +88,8 @@ static void GenerateServerMethodSignature(const grpc_generator::Method *method,
} }
} }
static void GenerateServerMethod(const grpc_generator::Method *method, static void GenerateServerMethod(const grpc_generator::Method* method,
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> vars) { std::map<grpc::string, grpc::string> vars) {
vars["Method"] = exportName(method->name()); vars["Method"] = exportName(method->name());
vars["Request"] = method->get_input_type_name(); vars["Request"] = method->get_input_type_name();
@@ -160,8 +161,12 @@ static void GenerateServerMethod(const grpc_generator::Method *method,
printer->Print(vars, "type $Service$_$Method$Server interface {\n"); printer->Print(vars, "type $Service$_$Method$Server interface {\n");
printer->Indent(); printer->Indent();
if (genSend) { printer->Print(vars, "Send(*$Response$) error\n"); } if (genSend) {
if (genRecv) { printer->Print(vars, "Recv() (*$Request$, error)\n"); } printer->Print(vars, "Send(*$Response$) error\n");
}
if (genRecv) {
printer->Print(vars, "Recv() (*$Request$, error)\n");
}
if (genSendAndClose) { if (genSendAndClose) {
printer->Print(vars, "SendAndClose(*$Response$) error\n"); printer->Print(vars, "SendAndClose(*$Response$) error\n");
} }
@@ -205,8 +210,8 @@ static void GenerateServerMethod(const grpc_generator::Method *method,
} }
// Generates Client method signature source // Generates Client method signature source
static void GenerateClientMethodSignature(const grpc_generator::Method *method, static void GenerateClientMethodSignature(
grpc_generator::Printer *printer, const grpc_generator::Method* method, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> vars) { std::map<grpc::string, grpc::string> vars) {
vars["Method"] = exportName(method->name()); vars["Method"] = exportName(method->name());
vars["Request"] = vars["Request"] =
@@ -226,8 +231,8 @@ static void GenerateClientMethodSignature(const grpc_generator::Method *method,
} }
// Generates Client method source // Generates Client method source
static void GenerateClientMethod(const grpc_generator::Method *method, static void GenerateClientMethod(const grpc_generator::Method* method,
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> vars) { std::map<grpc::string, grpc::string> vars) {
printer->Print(vars, "func (c *$ServiceUnexported$Client) "); printer->Print(vars, "func (c *$ServiceUnexported$Client) ");
vars["Ending"] = " {\n"; vars["Ending"] = " {\n";
@@ -277,8 +282,12 @@ static void GenerateClientMethod(const grpc_generator::Method *method,
// Stream interface // Stream interface
printer->Print(vars, "type $Service$_$Method$Client interface {\n"); printer->Print(vars, "type $Service$_$Method$Client interface {\n");
printer->Indent(); printer->Indent();
if (genSend) { printer->Print(vars, "Send(*$Request$) error\n"); } if (genSend) {
if (genRecv) { printer->Print(vars, "Recv() (*$Response$, error)\n"); } printer->Print(vars, "Send(*$Request$) error\n");
}
if (genRecv) {
printer->Print(vars, "Recv() (*$Response$, error)\n");
}
if (genCloseAndRecv) { if (genCloseAndRecv) {
printer->Print(vars, "CloseAndRecv() (*$Response$, error)\n"); printer->Print(vars, "CloseAndRecv() (*$Response$, error)\n");
} }
@@ -329,8 +338,8 @@ static void GenerateClientMethod(const grpc_generator::Method *method,
} }
// Generates client API for the service // Generates client API for the service
void GenerateService(const grpc_generator::Service *service, void GenerateService(const grpc_generator::Service* service,
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> vars) { std::map<grpc::string, grpc::string> vars) {
vars["Service"] = exportName(service->name()); vars["Service"] = exportName(service->name());
// Client Interface // Client Interface
@@ -484,9 +493,9 @@ void GenerateService(const grpc_generator::Service *service,
} // namespace } // namespace
// Returns source for the service // Returns source for the service
grpc::string GenerateServiceSource(grpc_generator::File *file, grpc::string GenerateServiceSource(grpc_generator::File* file,
const grpc_generator::Service *service, const grpc_generator::Service* service,
grpc_go_generator::Parameters *parameters) { grpc_go_generator::Parameters* parameters) {
grpc::string out; grpc::string out;
auto p = file->CreatePrinter(&out, '\t'); auto p = file->CreatePrinter(&out, '\t');
p->SetIndentationSize(1); p->SetIndentationSize(1);

View File

@@ -24,9 +24,9 @@ struct Parameters {
}; };
// Return the source of the generated service file. // Return the source of the generated service file.
grpc::string GenerateServiceSource(grpc_generator::File *file, grpc::string GenerateServiceSource(grpc_generator::File* file,
const grpc_generator::Service *service, const grpc_generator::Service* service,
grpc_go_generator::Parameters *parameters); grpc_go_generator::Parameters* parameters);
} // namespace grpc_go_generator } // namespace grpc_go_generator

View File

@@ -28,11 +28,11 @@
// Stringify helpers used solely to cast GRPC_VERSION // Stringify helpers used solely to cast GRPC_VERSION
#ifndef STR #ifndef STR
# define STR(s) # s #define STR(s) #s
#endif #endif
#ifndef XSTR #ifndef XSTR
# define XSTR(s) STR(s) #define XSTR(s) STR(s)
#endif #endif
typedef grpc_generator::Printer Printer; typedef grpc_generator::Printer Printer;
@@ -46,8 +46,8 @@ namespace grpc_java_generator {
typedef std::string string; typedef std::string string;
namespace { namespace {
// Generates imports for the service // Generates imports for the service
static void GenerateImports(grpc_generator::File *file, static void GenerateImports(grpc_generator::File* file,
grpc_generator::Printer *printer, VARS &vars) { grpc_generator::Printer* printer, VARS& vars) {
vars["filename"] = file->filename(); vars["filename"] = file->filename();
printer->Print(vars, printer->Print(vars,
"//Generated by flatc compiler (version $flatc_version$)\n"); "//Generated by flatc compiler (version $flatc_version$)\n");
@@ -64,7 +64,7 @@ static void GenerateImports(grpc_generator::File *file,
// Adjust a method name prefix identifier to follow the JavaBean spec: // Adjust a method name prefix identifier to follow the JavaBean spec:
// - decapitalize the first letter // - decapitalize the first letter
// - remove embedded underscores & capitalize the following letter // - remove embedded underscores & capitalize the following letter
static string MixedLower(const string &word) { static string MixedLower(const string& word) {
string w; string w;
w += static_cast<string::value_type>(tolower(word[0])); w += static_cast<string::value_type>(tolower(word[0]));
bool after_underscore = false; bool after_underscore = false;
@@ -84,7 +84,7 @@ static string MixedLower(const string &word) {
// - An underscore is inserted where a lower case letter is followed by an // - An underscore is inserted where a lower case letter is followed by an
// upper case letter. // upper case letter.
// - All letters are converted to upper case // - All letters are converted to upper case
static string ToAllUpperCase(const string &word) { static string ToAllUpperCase(const string& word) {
string w; string w;
for (size_t i = 0; i < word.length(); ++i) { for (size_t i = 0; i < word.length(); ++i) {
w += static_cast<string::value_type>(toupper(word[i])); w += static_cast<string::value_type>(toupper(word[i]));
@@ -95,49 +95,48 @@ static string ToAllUpperCase(const string &word) {
return w; return w;
} }
static inline string LowerMethodName(const MethodDescriptor *method) { static inline string LowerMethodName(const MethodDescriptor* method) {
return MixedLower(method->name()); return MixedLower(method->name());
} }
static inline string MethodPropertiesFieldName(const MethodDescriptor *method) { static inline string MethodPropertiesFieldName(const MethodDescriptor* method) {
return "METHOD_" + ToAllUpperCase(method->name()); return "METHOD_" + ToAllUpperCase(method->name());
} }
static inline string MethodPropertiesGetterName( static inline string MethodPropertiesGetterName(
const MethodDescriptor *method) { const MethodDescriptor* method) {
return MixedLower("get_" + method->name() + "_method"); return MixedLower("get_" + method->name() + "_method");
} }
static inline string MethodIdFieldName(const MethodDescriptor *method) { static inline string MethodIdFieldName(const MethodDescriptor* method) {
return "METHODID_" + ToAllUpperCase(method->name()); return "METHODID_" + ToAllUpperCase(method->name());
} }
static inline string JavaClassName(VARS &vars, const string &name) { static inline string JavaClassName(VARS& vars, const string& name) {
// string name = google::protobuf::compiler::java::ClassName(desc); // string name = google::protobuf::compiler::java::ClassName(desc);
return vars["Package"] + name; return vars["Package"] + name;
} }
static inline string ServiceClassName(const string &service_name) { static inline string ServiceClassName(const string& service_name) {
return service_name + "Grpc"; return service_name + "Grpc";
} }
// TODO(nmittler): Remove once protobuf includes javadoc methods in // TODO(nmittler): Remove once protobuf includes javadoc methods in
// distribution. // distribution.
template<typename ITR> template <typename ITR>
static void GrpcSplitStringToIteratorUsing(const string &full, static void GrpcSplitStringToIteratorUsing(const string& full,
const char *delim, ITR &result) { const char* delim, ITR& result) {
// Optimize the common case where delim is a single character. // Optimize the common case where delim is a single character.
if (delim[0] != '\0' && delim[1] == '\0') { if (delim[0] != '\0' && delim[1] == '\0') {
char c = delim[0]; char c = delim[0];
const char *p = full.data(); const char* p = full.data();
const char *end = p + full.size(); const char* end = p + full.size();
while (p != end) { while (p != end) {
if (*p == c) { if (*p == c) {
++p; ++p;
} else { } else {
const char *start = p; const char* start = p;
while (++p != end && *p != c) while (++p != end && *p != c);
;
*result++ = string(start, p - start); *result++ = string(start, p - start);
} }
} }
@@ -157,13 +156,13 @@ static void GrpcSplitStringToIteratorUsing(const string &full,
} }
} }
static void GrpcSplitStringUsing(const string &full, const char *delim, static void GrpcSplitStringUsing(const string& full, const char* delim,
std::vector<string> *result) { std::vector<string>* result) {
std::back_insert_iterator<std::vector<string>> it(*result); std::back_insert_iterator<std::vector<string>> it(*result);
GrpcSplitStringToIteratorUsing(full, delim, it); GrpcSplitStringToIteratorUsing(full, delim, it);
} }
static std::vector<string> GrpcSplit(const string &full, const char *delim) { static std::vector<string> GrpcSplit(const string& full, const char* delim) {
std::vector<string> result; std::vector<string> result;
GrpcSplitStringUsing(full, delim, &result); GrpcSplitStringUsing(full, delim, &result);
return result; return result;
@@ -171,7 +170,7 @@ static std::vector<string> GrpcSplit(const string &full, const char *delim) {
// TODO(nmittler): Remove once protobuf includes javadoc methods in // TODO(nmittler): Remove once protobuf includes javadoc methods in
// distribution. // distribution.
static string GrpcEscapeJavadoc(const string &input) { static string GrpcEscapeJavadoc(const string& input) {
string result; string result;
result.reserve(input.size() * 2); result.reserve(input.size() * 2);
@@ -218,7 +217,9 @@ static string GrpcEscapeJavadoc(const string &input) {
// Java interprets Unicode escape sequences anywhere! // Java interprets Unicode escape sequences anywhere!
result.append("&#92;"); result.append("&#92;");
break; break;
default: result.push_back(c); break; default:
result.push_back(c);
break;
} }
prev = c; prev = c;
@@ -227,7 +228,7 @@ static string GrpcEscapeJavadoc(const string &input) {
return result; return result;
} }
static std::vector<string> GrpcGetDocLines(const string &comments) { static std::vector<string> GrpcGetDocLines(const string& comments) {
if (!comments.empty()) { if (!comments.empty()) {
// TODO(kenton): Ideally we should parse the comment text as Markdown and // TODO(kenton): Ideally we should parse the comment text as Markdown and
// write it back as HTML, but this requires a Markdown parser. For now // write it back as HTML, but this requires a Markdown parser. For now
@@ -238,23 +239,27 @@ static std::vector<string> GrpcGetDocLines(const string &comments) {
string escapedComments = GrpcEscapeJavadoc(comments); string escapedComments = GrpcEscapeJavadoc(comments);
std::vector<string> lines = GrpcSplit(escapedComments, "\n"); std::vector<string> lines = GrpcSplit(escapedComments, "\n");
while (!lines.empty() && lines.back().empty()) { lines.pop_back(); } while (!lines.empty() && lines.back().empty()) {
lines.pop_back();
}
return lines; return lines;
} }
return std::vector<string>(); return std::vector<string>();
} }
static std::vector<string> GrpcGetDocLinesForDescriptor( static std::vector<string> GrpcGetDocLinesForDescriptor(
const DescriptorType *descriptor) { const DescriptorType* descriptor) {
return descriptor->GetAllComments(); return descriptor->GetAllComments();
// return GrpcGetDocLines(descriptor->GetLeadingComments("///")); // return GrpcGetDocLines(descriptor->GetLeadingComments("///"));
} }
static void GrpcWriteDocCommentBody(Printer *printer, VARS &vars, static void GrpcWriteDocCommentBody(Printer* printer, VARS& vars,
const std::vector<string> &lines, const std::vector<string>& lines,
bool surroundWithPreTag) { bool surroundWithPreTag) {
if (!lines.empty()) { if (!lines.empty()) {
if (surroundWithPreTag) { printer->Print(" * <pre>\n"); } if (surroundWithPreTag) {
printer->Print(" * <pre>\n");
}
for (size_t i = 0; i < lines.size(); i++) { for (size_t i = 0; i < lines.size(); i++) {
// Most lines should start with a space. Watch out for lines that start // Most lines should start with a space. Watch out for lines that start
@@ -268,28 +273,30 @@ static void GrpcWriteDocCommentBody(Printer *printer, VARS &vars,
} }
} }
if (surroundWithPreTag) { printer->Print(" * </pre>\n"); } if (surroundWithPreTag) {
printer->Print(" * </pre>\n");
}
} }
} }
static void GrpcWriteDocComment(Printer *printer, VARS &vars, static void GrpcWriteDocComment(Printer* printer, VARS& vars,
const string &comments) { const string& comments) {
printer->Print("/**\n"); printer->Print("/**\n");
std::vector<string> lines = GrpcGetDocLines(comments); std::vector<string> lines = GrpcGetDocLines(comments);
GrpcWriteDocCommentBody(printer, vars, lines, false); GrpcWriteDocCommentBody(printer, vars, lines, false);
printer->Print(" */\n"); printer->Print(" */\n");
} }
static void GrpcWriteServiceDocComment(Printer *printer, VARS &vars, static void GrpcWriteServiceDocComment(Printer* printer, VARS& vars,
const ServiceDescriptor *service) { const ServiceDescriptor* service) {
printer->Print("/**\n"); printer->Print("/**\n");
std::vector<string> lines = GrpcGetDocLinesForDescriptor(service); std::vector<string> lines = GrpcGetDocLinesForDescriptor(service);
GrpcWriteDocCommentBody(printer, vars, lines, true); GrpcWriteDocCommentBody(printer, vars, lines, true);
printer->Print(" */\n"); printer->Print(" */\n");
} }
static void GrpcWriteMethodDocComment(Printer *printer, VARS &vars, static void GrpcWriteMethodDocComment(Printer* printer, VARS& vars,
const MethodDescriptor *method) { const MethodDescriptor* method) {
printer->Print("/**\n"); printer->Print("/**\n");
std::vector<string> lines = GrpcGetDocLinesForDescriptor(method); std::vector<string> lines = GrpcGetDocLinesForDescriptor(method);
GrpcWriteDocCommentBody(printer, vars, lines, true); GrpcWriteDocCommentBody(printer, vars, lines, true);
@@ -298,7 +305,7 @@ static void GrpcWriteMethodDocComment(Printer *printer, VARS &vars,
// outputs static singleton extractor for type stored in "extr_type" and // outputs static singleton extractor for type stored in "extr_type" and
// "extr_type_name" vars // "extr_type_name" vars
static void PrintTypeExtractor(Printer *p, VARS &vars) { static void PrintTypeExtractor(Printer* p, VARS& vars) {
p->Print(vars, p->Print(vars,
"private static volatile FlatbuffersUtils.FBExtactor<$extr_type$> " "private static volatile FlatbuffersUtils.FBExtactor<$extr_type$> "
"extractorOf$extr_type_name$;\n" "extractorOf$extr_type_name$;\n"
@@ -320,8 +327,8 @@ static void PrintTypeExtractor(Printer *p, VARS &vars) {
" }\n" " }\n"
"}\n\n"); "}\n\n");
} }
static void PrintMethodFields(Printer *p, VARS &vars, static void PrintMethodFields(Printer* p, VARS& vars,
const ServiceDescriptor *service) { const ServiceDescriptor* service) {
p->Print("// Static method descriptors that strictly reflect the proto.\n"); p->Print("// Static method descriptors that strictly reflect the proto.\n");
vars["service_name"] = service->name(); vars["service_name"] = service->name();
@@ -443,11 +450,11 @@ enum StubType {
enum CallType { ASYNC_CALL = 0, BLOCKING_CALL = 1, FUTURE_CALL = 2 }; enum CallType { ASYNC_CALL = 0, BLOCKING_CALL = 1, FUTURE_CALL = 2 };
static void PrintBindServiceMethodBody(Printer *p, VARS &vars, static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
const ServiceDescriptor *service); const ServiceDescriptor* service);
// Prints a client interface or implementation class, or a server interface. // Prints a client interface or implementation class, or a server interface.
static void PrintStub(Printer *p, VARS &vars, const ServiceDescriptor *service, static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
StubType type) { StubType type) {
const string service_name = service->name(); const string service_name = service->name();
vars["service_name"] = service_name; vars["service_name"] = service_name;
@@ -493,7 +500,9 @@ static void PrintStub(Printer *p, VARS &vars, const ServiceDescriptor *service,
vars["client_name"] = client_name; vars["client_name"] = client_name;
// Class head // Class head
if (!interface) { GrpcWriteServiceDocComment(p, vars, service); } if (!interface) {
GrpcWriteServiceDocComment(p, vars, service);
}
if (impl_base) { if (impl_base) {
p->Print(vars, p->Print(vars,
"public static abstract class $abstract_name$ implements " "public static abstract class $abstract_name$ implements "
@@ -555,7 +564,9 @@ static void PrintStub(Printer *p, VARS &vars, const ServiceDescriptor *service,
p->Print("\n"); p->Print("\n");
// TODO(nmittler): Replace with WriteMethodDocComment once included by the // TODO(nmittler): Replace with WriteMethodDocComment once included by the
// protobuf distro. // protobuf distro.
if (!interface) { GrpcWriteMethodDocComment(p, vars, &*method); } if (!interface) {
GrpcWriteMethodDocComment(p, vars, &*method);
}
p->Print("public "); p->Print("public ");
switch (call_type) { switch (call_type) {
case BLOCKING_CALL: case BLOCKING_CALL:
@@ -620,7 +631,8 @@ static void PrintStub(Printer *p, VARS &vars, const ServiceDescriptor *service,
"responseObserver);\n"); "responseObserver);\n");
} }
break; break;
default: break; default:
break;
} }
} else if (!interface) { } else if (!interface) {
switch (call_type) { switch (call_type) {
@@ -695,15 +707,15 @@ static void PrintStub(Printer *p, VARS &vars, const ServiceDescriptor *service,
} }
static bool CompareMethodClientStreaming( static bool CompareMethodClientStreaming(
const std::unique_ptr<const grpc_generator::Method> &method1, const std::unique_ptr<const grpc_generator::Method>& method1,
const std::unique_ptr<const grpc_generator::Method> &method2) { const std::unique_ptr<const grpc_generator::Method>& method2) {
return method1->ClientStreaming() < method2->ClientStreaming(); return method1->ClientStreaming() < method2->ClientStreaming();
} }
// Place all method invocations into a single class to reduce memory footprint // Place all method invocations into a single class to reduce memory footprint
// on Android. // on Android.
static void PrintMethodHandlerClass(Printer *p, VARS &vars, static void PrintMethodHandlerClass(Printer* p, VARS& vars,
const ServiceDescriptor *service) { const ServiceDescriptor* service) {
// Sort method ids based on ClientStreaming() so switch tables are compact. // Sort method ids based on ClientStreaming() so switch tables are compact.
std::vector<std::unique_ptr<const grpc_generator::Method>> sorted_methods( std::vector<std::unique_ptr<const grpc_generator::Method>> sorted_methods(
service->method_count()); service->method_count());
@@ -713,7 +725,7 @@ static void PrintMethodHandlerClass(Printer *p, VARS &vars,
stable_sort(sorted_methods.begin(), sorted_methods.end(), stable_sort(sorted_methods.begin(), sorted_methods.end(),
CompareMethodClientStreaming); CompareMethodClientStreaming);
for (size_t i = 0; i < sorted_methods.size(); i++) { for (size_t i = 0; i < sorted_methods.size(); i++) {
auto &method = sorted_methods[i]; auto& method = sorted_methods[i];
vars["method_id"] = to_string(i); vars["method_id"] = to_string(i);
vars["method_id_name"] = MethodIdFieldName(&*method); vars["method_id_name"] = MethodIdFieldName(&*method);
p->Print(vars, p->Print(vars,
@@ -746,7 +758,9 @@ static void PrintMethodHandlerClass(Printer *p, VARS &vars,
for (int i = 0; i < service->method_count(); ++i) { for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i); auto method = service->method(i);
if (method->ClientStreaming() || method->BidiStreaming()) { continue; } if (method->ClientStreaming() || method->BidiStreaming()) {
continue;
}
vars["method_id_name"] = MethodIdFieldName(&*method); vars["method_id_name"] = MethodIdFieldName(&*method);
vars["lower_method_name"] = LowerMethodName(&*method); vars["lower_method_name"] = LowerMethodName(&*method);
vars["input_type"] = JavaClassName(vars, method->get_input_type_name()); vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
@@ -778,7 +792,9 @@ static void PrintMethodHandlerClass(Printer *p, VARS &vars,
for (int i = 0; i < service->method_count(); ++i) { for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i); auto method = service->method(i);
if (!(method->ClientStreaming() || method->BidiStreaming())) { continue; } if (!(method->ClientStreaming() || method->BidiStreaming())) {
continue;
}
vars["method_id_name"] = MethodIdFieldName(&*method); vars["method_id_name"] = MethodIdFieldName(&*method);
vars["lower_method_name"] = LowerMethodName(&*method); vars["lower_method_name"] = LowerMethodName(&*method);
vars["input_type"] = JavaClassName(vars, method->get_input_type_name()); vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
@@ -803,8 +819,8 @@ static void PrintMethodHandlerClass(Printer *p, VARS &vars,
p->Print("}\n\n"); p->Print("}\n\n");
} }
static void PrintGetServiceDescriptorMethod(Printer *p, VARS &vars, static void PrintGetServiceDescriptorMethod(Printer* p, VARS& vars,
const ServiceDescriptor *service) { const ServiceDescriptor* service) {
vars["service_name"] = service->name(); vars["service_name"] = service->name();
// vars["proto_base_descriptor_supplier"] = service->name() + // vars["proto_base_descriptor_supplier"] = service->name() +
// "BaseDescriptorSupplier"; vars["proto_file_descriptor_supplier"] = // "BaseDescriptorSupplier"; vars["proto_file_descriptor_supplier"] =
@@ -896,8 +912,8 @@ static void PrintGetServiceDescriptorMethod(Printer *p, VARS &vars,
p->Print("}\n"); p->Print("}\n");
} }
static void PrintBindServiceMethodBody(Printer *p, VARS &vars, static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
const ServiceDescriptor *service) { const ServiceDescriptor* service) {
vars["service_name"] = service->name(); vars["service_name"] = service->name();
p->Indent(); p->Indent();
p->Print(vars, p->Print(vars,
@@ -949,8 +965,8 @@ static void PrintBindServiceMethodBody(Printer *p, VARS &vars,
p->Outdent(); p->Outdent();
} }
static void PrintService(Printer *p, VARS &vars, static void PrintService(Printer* p, VARS& vars,
const ServiceDescriptor *service, const ServiceDescriptor* service,
bool disable_version) { bool disable_version) {
vars["service_name"] = service->name(); vars["service_name"] = service->name();
vars["service_class_name"] = ServiceClassName(service->name()); vars["service_class_name"] = ServiceClassName(service->name());
@@ -1030,7 +1046,7 @@ static void PrintService(Printer *p, VARS &vars,
p->Print("}\n"); p->Print("}\n");
} }
static void PrintStaticImports(Printer *p) { static void PrintStaticImports(Printer* p) {
p->Print( p->Print(
"import java.nio.ByteBuffer;\n" "import java.nio.ByteBuffer;\n"
"import static " "import static "
@@ -1063,8 +1079,8 @@ static void PrintStaticImports(Printer *p) {
"io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n\n"); "io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n\n");
} }
static void GenerateService(const grpc_generator::Service *service, static void GenerateService(const grpc_generator::Service* service,
grpc_generator::Printer *printer, VARS &vars, grpc_generator::Printer* printer, VARS& vars,
bool disable_version) { bool disable_version) {
// All non-generated classes must be referred by fully qualified names to // All non-generated classes must be referred by fully qualified names to
// avoid collision with generated classes. // avoid collision with generated classes.
@@ -1101,8 +1117,8 @@ static void GenerateService(const grpc_generator::Service *service,
} // namespace } // namespace
grpc::string GenerateServiceSource( grpc::string GenerateServiceSource(
grpc_generator::File *file, const grpc_generator::Service *service, grpc_generator::File* file, const grpc_generator::Service* service,
grpc_java_generator::Parameters *parameters) { grpc_java_generator::Parameters* parameters) {
grpc::string out; grpc::string out;
auto printer = file->CreatePrinter(&out); auto printer = file->CreatePrinter(&out);
VARS vars; VARS vars;

View File

@@ -18,6 +18,7 @@
#define NET_GRPC_COMPILER_JAVA_GENERATOR_H_ #define NET_GRPC_COMPILER_JAVA_GENERATOR_H_
#include <stdlib.h> // for abort() #include <stdlib.h> // for abort()
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <string> #include <string>
@@ -39,8 +40,8 @@ class LogHelper {
LogHelper(std::ostream* os) : os_(os) {} LogHelper(std::ostream* os) : os_(os) {}
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning(push) #pragma warning(push)
#pragma warning( \ #pragma warning(disable \
disable : 4722) // the flow of control terminates in a destructor : 4722) // the flow of control terminates in a destructor
// (needed to compile ~LogHelper where destructor emits abort intentionally - // (needed to compile ~LogHelper where destructor emits abort intentionally -
// inherited from grpc/java code generator). // inherited from grpc/java code generator).
#endif #endif

View File

@@ -35,22 +35,22 @@ namespace flatbuffers {
namespace python { namespace python {
namespace grpc { namespace grpc {
namespace { namespace {
bool ClientStreaming(const RPCCall *method) { bool ClientStreaming(const RPCCall* method) {
const Value *val = method->attributes.Lookup("streaming"); const Value* val = method->attributes.Lookup("streaming");
return val != nullptr && return val != nullptr &&
(val->constant == "client" || val->constant == "bidi"); (val->constant == "client" || val->constant == "bidi");
} }
bool ServerStreaming(const RPCCall *method) { bool ServerStreaming(const RPCCall* method) {
const Value *val = method->attributes.Lookup("streaming"); const Value* val = method->attributes.Lookup("streaming");
return val != nullptr && return val != nullptr &&
(val->constant == "server" || val->constant == "bidi"); (val->constant == "server" || val->constant == "bidi");
} }
void FormatImports(std::stringstream &ss, const Imports &imports) { void FormatImports(std::stringstream& ss, const Imports& imports) {
std::set<std::string> modules; std::set<std::string> modules;
std::map<std::string, std::set<std::string>> names_by_module; std::map<std::string, std::set<std::string>> names_by_module;
for (const Import &import : imports.imports) { for (const Import& import : imports.imports) {
if (import.IsLocal()) continue; // skip all local imports if (import.IsLocal()) continue; // skip all local imports
if (import.name == "") { if (import.name == "") {
modules.insert(import.module); modules.insert(import.module);
@@ -59,14 +59,14 @@ void FormatImports(std::stringstream &ss, const Imports &imports) {
} }
} }
for (const std::string &module : modules) { for (const std::string& module : modules) {
ss << "import " << module << '\n'; ss << "import " << module << '\n';
} }
ss << '\n'; ss << '\n';
for (const auto &import : names_by_module) { for (const auto& import : names_by_module) {
ss << "from " << import.first << " import "; ss << "from " << import.first << " import ";
size_t i = 0; size_t i = 0;
for (const std::string &name : import.second) { for (const std::string& name : import.second) {
if (i > 0) ss << ", "; if (i > 0) ss << ", ";
ss << name; ss << name;
++i; ++i;
@@ -76,8 +76,8 @@ void FormatImports(std::stringstream &ss, const Imports &imports) {
ss << "\n\n"; ss << "\n\n";
} }
bool SaveStub(const std::string &filename, const Imports &imports, bool SaveStub(const std::string& filename, const Imports& imports,
const std::string &content) { const std::string& content) {
std::stringstream ss; std::stringstream ss;
ss << "# Generated by the gRPC FlatBuffers compiler. DO NOT EDIT!\n" ss << "# Generated by the gRPC FlatBuffers compiler. DO NOT EDIT!\n"
<< '\n' << '\n'
@@ -90,8 +90,8 @@ bool SaveStub(const std::string &filename, const Imports &imports,
return flatbuffers::SaveFile(filename.c_str(), ss.str(), false); return flatbuffers::SaveFile(filename.c_str(), ss.str(), false);
} }
bool SaveService(const std::string &filename, const Imports &imports, bool SaveService(const std::string& filename, const Imports& imports,
const std::string &content) { const std::string& content) {
std::stringstream ss; std::stringstream ss;
ss << "# Generated by the gRPC FlatBuffers compiler. DO NOT EDIT!\n" << '\n'; ss << "# Generated by the gRPC FlatBuffers compiler. DO NOT EDIT!\n" << '\n';
FormatImports(ss, imports); FormatImports(ss, imports);
@@ -103,32 +103,33 @@ bool SaveService(const std::string &filename, const Imports &imports,
class BaseGenerator { class BaseGenerator {
protected: protected:
BaseGenerator(const Parser &parser, const Namer::Config &config, BaseGenerator(const Parser& parser, const Namer::Config& config,
const std::string &path, const Version &version) const std::string& path, const Version& version)
: parser_{ parser }, : parser_{parser},
namer_{ WithFlagOptions(config, parser.opts, path), Keywords(version) }, namer_{WithFlagOptions(config, parser.opts, path), Keywords(version)},
version_{ version }, version_{version},
path_(path) {} path_(path) {}
protected: protected:
std::string ModuleForFile(const std::string &file) const { std::string ModuleForFile(const std::string& file) const {
std::string module = parser_.opts.include_prefix + StripExtension(file) + std::string module = parser_.opts.include_prefix + StripExtension(file) +
parser_.opts.filename_suffix; parser_.opts.filename_suffix;
std::replace(module.begin(), module.end(), '/', '.'); std::replace(module.begin(), module.end(), '/', '.');
return module; return module;
} }
template<typename T> std::string ModuleFor(const T *def) const { template <typename T>
std::string ModuleFor(const T* def) const {
if (parser_.opts.one_file) return ModuleForFile(def->file); if (parser_.opts.one_file) return ModuleForFile(def->file);
return namer_.NamespacedType(*def); return namer_.NamespacedType(*def);
} }
std::string NamespaceDir(const Parser &parser, const std::string &path, std::string NamespaceDir(const Parser& parser, const std::string& path,
const Namespace &ns, const bool dasherize) { const Namespace& ns, const bool dasherize) {
EnsureDirExists(path); EnsureDirExists(path);
if (parser.opts.one_file) return path; if (parser.opts.one_file) return path;
std::string namespace_dir = path; // Either empty or ends in separator. std::string namespace_dir = path; // Either empty or ends in separator.
auto &namespaces = ns.components; auto& namespaces = ns.components;
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
namespace_dir += namespace_dir +=
!dasherize ? *it : ConvertCase(*it, Case::kDasher, Case::kUpperCamel); !dasherize ? *it : ConvertCase(*it, Case::kDasher, Case::kUpperCamel);
@@ -138,32 +139,32 @@ class BaseGenerator {
return namespace_dir; return namespace_dir;
} }
std::string NamespaceDir(const Namespace &ns, const bool dasherize) { std::string NamespaceDir(const Namespace& ns, const bool dasherize) {
return NamespaceDir(parser_, path_, ns, dasherize); return NamespaceDir(parser_, path_, ns, dasherize);
} }
const Parser &parser_; const Parser& parser_;
const IdlNamer namer_; const IdlNamer namer_;
const Version version_; const Version version_;
const std::string &path_; const std::string& path_;
}; };
class StubGenerator : public BaseGenerator { class StubGenerator : public BaseGenerator {
public: public:
StubGenerator(const Parser &parser, const std::string &path, StubGenerator(const Parser& parser, const std::string& path,
const Version &version) const Version& version)
: BaseGenerator(parser, kStubConfig, path, version) {} : BaseGenerator(parser, kStubConfig, path, version) {}
bool Generate() { bool Generate() {
Imports imports; Imports imports;
std::stringstream stub; std::stringstream stub;
std::string ns_name{}; std::string ns_name{};
for (const ServiceDef *service : parser_.services_.vec) { for (const ServiceDef* service : parser_.services_.vec) {
Generate(stub, service, &imports); Generate(stub, service, &imports);
ns_name = NamespaceDir(*service->defined_namespace, false); ns_name = NamespaceDir(*service->defined_namespace, false);
} }
std::string sanitized_suffix{ parser_.opts.grpc_filename_suffix }; std::string sanitized_suffix{parser_.opts.grpc_filename_suffix};
std::replace(sanitized_suffix.begin(), sanitized_suffix.end(), '.', '_'); std::replace(sanitized_suffix.begin(), sanitized_suffix.end(), '.', '_');
std::string filename = std::string filename =
ns_name + kPathSeparator + ns_name + kPathSeparator +
@@ -174,14 +175,14 @@ class StubGenerator : public BaseGenerator {
} }
private: private:
void Generate(std::stringstream &ss, const ServiceDef *service, void Generate(std::stringstream& ss, const ServiceDef* service,
Imports *imports) { Imports* imports) {
imports->Import("grpc"); imports->Import("grpc");
ss << "class " << service->name << "Stub(object):\n" ss << "class " << service->name << "Stub(object):\n"
<< " def __init__(self, channel: grpc.Channel) -> None: ...\n"; << " def __init__(self, channel: grpc.Channel) -> None: ...\n";
for (const RPCCall *method : service->calls.vec) { for (const RPCCall* method : service->calls.vec) {
std::string request = "bytes"; std::string request = "bytes";
std::string response = "bytes"; std::string response = "bytes";
@@ -213,7 +214,7 @@ class StubGenerator : public BaseGenerator {
ss << "\n\n"; ss << "\n\n";
ss << "class " << service->name << "Servicer(object):\n"; ss << "class " << service->name << "Servicer(object):\n";
for (const RPCCall *method : service->calls.vec) { for (const RPCCall* method : service->calls.vec) {
std::string request = "bytes"; std::string request = "bytes";
std::string response = "bytes"; std::string response = "bytes";
@@ -252,8 +253,8 @@ class StubGenerator : public BaseGenerator {
class ServiceGenerator : public BaseGenerator { class ServiceGenerator : public BaseGenerator {
public: public:
ServiceGenerator(const Parser &parser, const std::string &path, ServiceGenerator(const Parser& parser, const std::string& path,
const Version &version) const Version& version)
: BaseGenerator(parser, kConfig, path, version) {} : BaseGenerator(parser, kConfig, path, version) {}
bool Generate() { bool Generate() {
@@ -274,14 +275,14 @@ class ServiceGenerator : public BaseGenerator {
} }
std::string ns_name{}; std::string ns_name{};
for (const ServiceDef *service : parser_.services_.vec) { for (const ServiceDef* service : parser_.services_.vec) {
GenerateStub(ss, service, &imports); GenerateStub(ss, service, &imports);
GenerateServicer(ss, service, &imports); GenerateServicer(ss, service, &imports);
GenerateRegister(ss, service, &imports); GenerateRegister(ss, service, &imports);
ns_name = NamespaceDir(*service->defined_namespace, false); ns_name = NamespaceDir(*service->defined_namespace, false);
} }
std::string sanitized_suffix{ parser_.opts.grpc_filename_suffix }; std::string sanitized_suffix{parser_.opts.grpc_filename_suffix};
std::replace(sanitized_suffix.begin(), sanitized_suffix.end(), '.', '_'); std::replace(sanitized_suffix.begin(), sanitized_suffix.end(), '.', '_');
std::string filename = std::string filename =
ns_name + kPathSeparator + ns_name + kPathSeparator +
@@ -292,8 +293,8 @@ class ServiceGenerator : public BaseGenerator {
} }
private: private:
void GenerateStub(std::stringstream &ss, const ServiceDef *service, void GenerateStub(std::stringstream& ss, const ServiceDef* service,
Imports *imports) { Imports* imports) {
ss << "class " << service->name << "Stub"; ss << "class " << service->name << "Stub";
if (version_.major != 3) ss << "(object)"; if (version_.major != 3) ss << "(object)";
ss << ":\n" ss << ":\n"
@@ -307,7 +308,7 @@ class ServiceGenerator : public BaseGenerator {
<< " '''\n" << " '''\n"
<< '\n'; << '\n';
for (const RPCCall *method : service->calls.vec) { for (const RPCCall* method : service->calls.vec) {
std::string response = namer_.Type(*method->response); std::string response = namer_.Type(*method->response);
imports->Import(ModuleFor(method->response), response); imports->Import(ModuleFor(method->response), response);
@@ -330,8 +331,8 @@ class ServiceGenerator : public BaseGenerator {
ss << '\n'; ss << '\n';
} }
void GenerateServicer(std::stringstream &ss, const ServiceDef *service, void GenerateServicer(std::stringstream& ss, const ServiceDef* service,
Imports *imports) { Imports* imports) {
imports->Import("grpc"); imports->Import("grpc");
ss << "class " << service->name << "Servicer"; ss << "class " << service->name << "Servicer";
@@ -340,7 +341,7 @@ class ServiceGenerator : public BaseGenerator {
<< " '''Interface exported by the server.'''\n" << " '''Interface exported by the server.'''\n"
<< '\n'; << '\n';
for (const RPCCall *method : service->calls.vec) { for (const RPCCall* method : service->calls.vec) {
const std::string request_param = const std::string request_param =
ClientStreaming(method) ? "request_iterator" : "request"; ClientStreaming(method) ? "request_iterator" : "request";
ss << " def " << method->name << "(self, " << request_param ss << " def " << method->name << "(self, " << request_param
@@ -354,15 +355,15 @@ class ServiceGenerator : public BaseGenerator {
ss << '\n'; ss << '\n';
} }
void GenerateRegister(std::stringstream &ss, const ServiceDef *service, void GenerateRegister(std::stringstream& ss, const ServiceDef* service,
Imports *imports) { Imports* imports) {
imports->Import("grpc"); imports->Import("grpc");
ss << "def add_" << service->name ss << "def add_" << service->name
<< "Servicer_to_server(servicer, server):\n" << "Servicer_to_server(servicer, server):\n"
<< " rpc_method_handlers = {\n"; << " rpc_method_handlers = {\n";
for (const RPCCall *method : service->calls.vec) { for (const RPCCall* method : service->calls.vec) {
std::string request = namer_.Type(*method->request); std::string request = namer_.Type(*method->request);
imports->Import(ModuleFor(method->request), request); imports->Import(ModuleFor(method->request), request);
@@ -393,15 +394,15 @@ class ServiceGenerator : public BaseGenerator {
}; };
} // namespace } // namespace
bool Generate(const Parser &parser, const std::string &path, bool Generate(const Parser& parser, const std::string& path,
const Version &version) { const Version& version) {
ServiceGenerator generator{ parser, path, version }; ServiceGenerator generator{parser, path, version};
return generator.Generate(); return generator.Generate();
} }
bool GenerateStub(const Parser &parser, const std::string &path, bool GenerateStub(const Parser& parser, const std::string& path,
const Version &version) { const Version& version) {
StubGenerator generator{ parser, path, version }; StubGenerator generator{parser, path, version};
return generator.Generate(); return generator.Generate();
} }

View File

@@ -27,11 +27,11 @@
namespace flatbuffers { namespace flatbuffers {
namespace python { namespace python {
namespace grpc { namespace grpc {
bool Generate(const Parser &parser, const std::string &path, bool Generate(const Parser& parser, const std::string& path,
const Version &version); const Version& version);
bool GenerateStub(const Parser &parser, const std::string &path, bool GenerateStub(const Parser& parser, const std::string& path,
const Version &version); const Version& version);
} // namespace grpc } // namespace grpc
} // namespace python } // namespace python
} // namespace flatbuffers } // namespace flatbuffers

View File

@@ -20,34 +20,35 @@
* please open an issue in the flatbuffers repository. This file should always * please open an issue in the flatbuffers repository. This file should always
* be maintained according to the Swift-grpc repository * be maintained according to the Swift-grpc repository
*/ */
#include "src/compiler/swift_generator.h"
#include <map> #include <map>
#include <sstream> #include <sstream>
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include "src/compiler/schema_interface.h" #include "src/compiler/schema_interface.h"
#include "src/compiler/swift_generator.h"
namespace grpc_swift_generator { namespace grpc_swift_generator {
namespace { namespace {
static std::string WrapInNameSpace(const std::vector<std::string> &components, static std::string WrapInNameSpace(const std::vector<std::string>& components,
const grpc::string &name) { const grpc::string& name) {
std::string qualified_name; std::string qualified_name;
for (auto it = components.begin(); it != components.end(); ++it) for (auto it = components.begin(); it != components.end(); ++it)
qualified_name += *it + "_"; qualified_name += *it + "_";
return qualified_name + name; return qualified_name + name;
} }
static grpc::string GenerateMessage(const std::vector<std::string> &components, static grpc::string GenerateMessage(const std::vector<std::string>& components,
const grpc::string &name) { const grpc::string& name) {
return "Message<" + WrapInNameSpace(components, name) + ">"; return "Message<" + WrapInNameSpace(components, name) + ">";
} }
// MARK: - Client // MARK: - Client
static void GenerateClientFuncName(const grpc_generator::Method *method, static void GenerateClientFuncName(
grpc_generator::Printer *printer, const grpc_generator::Method* method, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
if (method->NoStreaming()) { if (method->NoStreaming()) {
printer->Print(vars, printer->Print(vars,
@@ -83,9 +84,9 @@ static void GenerateClientFuncName(const grpc_generator::Method *method,
" ) -> BidirectionalStreamingCall<$Input$, $Output$>"); " ) -> BidirectionalStreamingCall<$Input$, $Output$>");
} }
static void GenerateClientFuncBody(const grpc_generator::Method *method, static void GenerateClientFuncBody(
grpc_generator::Printer *printer, const grpc_generator::Method* method, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
vars["Interceptor"] = vars["Interceptor"] =
"interceptors: self.interceptors?.make$MethodName$Interceptors() ?? []"; "interceptors: self.interceptors?.make$MethodName$Interceptors() ?? []";
@@ -133,9 +134,9 @@ static void GenerateClientFuncBody(const grpc_generator::Method *method,
" )\n"); " )\n");
} }
void GenerateClientProtocol(const grpc_generator::Service *service, void GenerateClientProtocol(const grpc_generator::Service* service,
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
printer->Print( printer->Print(
vars, vars,
@@ -207,8 +208,8 @@ void GenerateClientProtocol(const grpc_generator::Service *service,
printer->Print("}\n\n"); printer->Print("}\n\n");
} }
void GenerateClientClass(grpc_generator::Printer *printer, void GenerateClientClass(grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
printer->Print(vars, printer->Print(vars,
"$ACCESS$ final class $ServiceQualifiedName$ServiceClient: " "$ACCESS$ final class $ServiceQualifiedName$ServiceClient: "
@@ -237,7 +238,7 @@ void GenerateClientClass(grpc_generator::Printer *printer,
// MARK: - Server // MARK: - Server
grpc::string GenerateServerFuncName(const grpc_generator::Method *method) { grpc::string GenerateServerFuncName(const grpc_generator::Method* method) {
if (method->NoStreaming()) { if (method->NoStreaming()) {
return "func $MethodName$(request: $Input$" return "func $MethodName$(request: $Input$"
", context: StatusOnlyCallContext) -> EventLoopFuture<$Output$>"; ", context: StatusOnlyCallContext) -> EventLoopFuture<$Output$>";
@@ -258,7 +259,7 @@ grpc::string GenerateServerFuncName(const grpc_generator::Method *method) {
"-> EventLoopFuture<(StreamEvent<$Input$>) -> Void>"; "-> EventLoopFuture<(StreamEvent<$Input$>) -> Void>";
} }
grpc::string GenerateServerExtensionBody(const grpc_generator::Method *method) { grpc::string GenerateServerExtensionBody(const grpc_generator::Method* method) {
grpc::string start = " case \"$MethodName$\":\n "; grpc::string start = " case \"$MethodName$\":\n ";
grpc::string interceptors = grpc::string interceptors =
" interceptors: self.interceptors?.make$MethodName$Interceptors() " " interceptors: self.interceptors?.make$MethodName$Interceptors() "
@@ -302,9 +303,9 @@ grpc::string GenerateServerExtensionBody(const grpc_generator::Method *method) {
return ""; return "";
} }
void GenerateServerProtocol(const grpc_generator::Service *service, void GenerateServerProtocol(const grpc_generator::Service* service,
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
printer->Print(vars, printer->Print(vars,
"$ACCESS$ protocol $ServiceQualifiedName$Provider: " "$ACCESS$ protocol $ServiceQualifiedName$Provider: "
@@ -375,12 +376,14 @@ void GenerateServerProtocol(const grpc_generator::Service *service,
} }
} // namespace } // namespace
grpc::string Generate(grpc_generator::File *file, grpc::string Generate(grpc_generator::File* file,
const grpc_generator::Service *service) { const grpc_generator::Service* service) {
grpc::string output; grpc::string output;
std::map<grpc::string, grpc::string> vars; std::map<grpc::string, grpc::string> vars;
vars["PATH"] = file->package(); vars["PATH"] = file->package();
if (!file->package().empty()) { vars["PATH"].append("."); } if (!file->package().empty()) {
vars["PATH"].append(".");
}
vars["ServiceQualifiedName"] = vars["ServiceQualifiedName"] =
WrapInNameSpace(service->namespace_parts(), service->name()); WrapInNameSpace(service->namespace_parts(), service->name());
vars["ServiceName"] = service->name(); vars["ServiceName"] = service->name();

View File

@@ -20,8 +20,8 @@
#include "src/compiler/schema_interface.h" #include "src/compiler/schema_interface.h"
#ifndef GRPC_CUSTOM_STRING #ifndef GRPC_CUSTOM_STRING
# include <string> #include <string>
# define GRPC_CUSTOM_STRING std::string #define GRPC_CUSTOM_STRING std::string
#endif #endif
namespace grpc { namespace grpc {
@@ -31,7 +31,7 @@ typedef GRPC_CUSTOM_STRING string;
} // namespace grpc } // namespace grpc
namespace grpc_swift_generator { namespace grpc_swift_generator {
grpc::string Generate(grpc_generator::File *file, grpc::string Generate(grpc_generator::File* file,
const grpc_generator::Service *service); const grpc_generator::Service* service);
grpc::string GenerateHeader(); grpc::string GenerateHeader();
} // namespace grpc_swift_generator } // namespace grpc_swift_generator

View File

@@ -56,9 +56,9 @@ static grpc::string GenerateNamespace(const std::vector<std::string> ns,
// MARK: - Shared code // MARK: - Shared code
static void GenerateImports(const grpc_generator::Service *service, static void GenerateImports(const grpc_generator::Service* service,
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary, std::map<grpc::string, grpc::string>* dictonary,
const bool grpc_var_import) { const bool grpc_var_import) {
auto vars = *dictonary; auto vars = *dictonary;
printer->Print( printer->Print(
@@ -105,9 +105,9 @@ static void GenerateImports(const grpc_generator::Service *service,
// MARK: - Generate Main GRPC Code // MARK: - Generate Main GRPC Code
static void GetStreamType(grpc_generator::Printer *printer, static void GetStreamType(grpc_generator::Printer* printer,
const grpc_generator::Method *method, const grpc_generator::Method* method,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
auto client_streaming = method->ClientStreaming() || method->BidiStreaming(); auto client_streaming = method->ClientStreaming() || method->BidiStreaming();
auto server_streaming = method->ServerStreaming() || method->BidiStreaming(); auto server_streaming = method->ServerStreaming() || method->BidiStreaming();
@@ -117,8 +117,9 @@ static void GetStreamType(grpc_generator::Printer *printer,
printer->Print(vars, "responseStream: $ServerStreaming$,\n"); printer->Print(vars, "responseStream: $ServerStreaming$,\n");
} }
static void GenerateSerializeMethod(grpc_generator::Printer *printer, static void GenerateSerializeMethod(
std::map<grpc::string, grpc::string> *dictonary) { grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
printer->Print(vars, "function serialize_$Type$(buffer_args) {\n"); printer->Print(vars, "function serialize_$Type$(buffer_args) {\n");
printer->Indent(); printer->Indent();
@@ -134,8 +135,8 @@ static void GenerateSerializeMethod(grpc_generator::Printer *printer,
} }
static void GenerateDeserializeMethod( static void GenerateDeserializeMethod(
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
printer->Print(vars, "function deserialize_$Type$(buffer) {\n"); printer->Print(vars, "function deserialize_$Type$(buffer) {\n");
printer->Indent(); printer->Indent();
@@ -146,9 +147,9 @@ static void GenerateDeserializeMethod(
printer->Print("}\n\n"); printer->Print("}\n\n");
} }
static void GenerateMethods(const grpc_generator::Service *service, static void GenerateMethods(const grpc_generator::Service* service,
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
std::set<grpc::string> generated_functions; std::set<grpc::string> generated_functions;
@@ -178,9 +179,9 @@ static void GenerateMethods(const grpc_generator::Service *service,
} }
} }
static void GenerateService(const grpc_generator::Service *service, static void GenerateService(const grpc_generator::Service* service,
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
vars["NAME"] = service->name() + "Service"; vars["NAME"] = service->name() + "Service";
@@ -215,15 +216,17 @@ static void GenerateService(const grpc_generator::Service *service,
} // namespace } // namespace
grpc::string Generate(grpc_generator::File *file, grpc::string Generate(grpc_generator::File* file,
const grpc_generator::Service *service, const grpc_generator::Service* service,
const grpc::string &filename) { const grpc::string& filename) {
grpc::string output; grpc::string output;
std::map<grpc::string, grpc::string> vars; std::map<grpc::string, grpc::string> vars;
vars["PATH"] = file->package(); vars["PATH"] = file->package();
if (!file->package().empty()) { vars["PATH"].append("."); } if (!file->package().empty()) {
vars["PATH"].append(".");
}
vars["ServiceName"] = service->name(); vars["ServiceName"] = service->name();
vars["FBSFile"] = service->name() + "_fbs"; vars["FBSFile"] = service->name() + "_fbs";
@@ -240,8 +243,8 @@ namespace {
// MARK: - Generate Interface // MARK: - Generate Interface
static void FillInterface(grpc_generator::Printer *printer, static void FillInterface(grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
printer->Print(vars, printer->Print(vars,
"interface I$ServiceName$Service_I$MethodName$ extends " "interface I$ServiceName$Service_I$MethodName$ extends "
@@ -258,9 +261,9 @@ static void FillInterface(grpc_generator::Printer *printer,
printer->Print("}\n"); printer->Print("}\n");
} }
static void GenerateInterfaces(const grpc_generator::Service *service, static void GenerateInterfaces(
grpc_generator::Printer *printer, const grpc_generator::Service* service, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
for (auto it = 0; it < service->method_count(); it++) { for (auto it = 0; it < service->method_count(); it++) {
auto method = service->method(it); auto method = service->method(it);
@@ -281,8 +284,8 @@ static void GenerateInterfaces(const grpc_generator::Service *service,
} }
static void GenerateExportedInterface( static void GenerateExportedInterface(
const grpc_generator::Service *service, grpc_generator::Printer *printer, const grpc_generator::Service* service, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
printer->Print(vars, printer->Print(vars,
"export interface I$ServiceName$Server extends " "export interface I$ServiceName$Server extends "
@@ -324,9 +327,9 @@ static void GenerateExportedInterface(
printer->Print("}\n"); printer->Print("}\n");
} }
static void GenerateMainInterface(const grpc_generator::Service *service, static void GenerateMainInterface(
grpc_generator::Printer *printer, const grpc_generator::Service* service, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
printer->Print( printer->Print(
vars, vars,
@@ -351,11 +354,13 @@ static void GenerateMainInterface(const grpc_generator::Service *service,
static grpc::string GenerateMetaData() { return "metadata: grpc.Metadata"; } static grpc::string GenerateMetaData() { return "metadata: grpc.Metadata"; }
static grpc::string GenerateOptions() { return "options: Partial<grpc.CallOptions>"; } static grpc::string GenerateOptions() {
return "options: Partial<grpc.CallOptions>";
}
static void GenerateUnaryClientInterface( static void GenerateUnaryClientInterface(
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
grpc::string main = "$ISPUBLIC$$MethodName$(request: $INPUT$, "; grpc::string main = "$ISPUBLIC$$MethodName$(request: $INPUT$, ";
grpc::string callback = grpc::string callback =
@@ -369,8 +374,8 @@ static void GenerateUnaryClientInterface(
} }
static void GenerateClientWriteStreamInterface( static void GenerateClientWriteStreamInterface(
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
grpc::string main = "$ISPUBLIC$$MethodName$("; grpc::string main = "$ISPUBLIC$$MethodName$(";
grpc::string callback = grpc::string callback =
@@ -386,8 +391,8 @@ static void GenerateClientWriteStreamInterface(
} }
static void GenerateClientReadableStreamInterface( static void GenerateClientReadableStreamInterface(
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
grpc::string main = "$ISPUBLIC$$MethodName$(request: $INPUT$, "; grpc::string main = "$ISPUBLIC$$MethodName$(request: $INPUT$, ";
grpc::string end_function = "): grpc.ClientReadableStream<$OUTPUT$>;\n"; grpc::string end_function = "): grpc.ClientReadableStream<$OUTPUT$>;\n";
@@ -398,8 +403,8 @@ static void GenerateClientReadableStreamInterface(
} }
static void GenerateDepluxStreamInterface( static void GenerateDepluxStreamInterface(
grpc_generator::Printer *printer, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
grpc::string main = "$ISPUBLIC$$MethodName$("; grpc::string main = "$ISPUBLIC$$MethodName$(";
grpc::string end_function = grpc::string end_function =
@@ -413,9 +418,9 @@ static void GenerateDepluxStreamInterface(
.c_str()); .c_str());
} }
static void GenerateClientInterface(const grpc_generator::Service *service, static void GenerateClientInterface(
grpc_generator::Printer *printer, const grpc_generator::Service* service, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
printer->Print(vars, "export interface I$ServiceName$Client {\n"); printer->Print(vars, "export interface I$ServiceName$Client {\n");
printer->Indent(); printer->Indent();
@@ -452,8 +457,8 @@ static void GenerateClientInterface(const grpc_generator::Service *service,
} }
static void GenerateClientClassInterface( static void GenerateClientClassInterface(
const grpc_generator::Service *service, grpc_generator::Printer *printer, const grpc_generator::Service* service, grpc_generator::Printer* printer,
std::map<grpc::string, grpc::string> *dictonary) { std::map<grpc::string, grpc::string>* dictonary) {
auto vars = *dictonary; auto vars = *dictonary;
printer->Print(vars, printer->Print(vars,
"export class $ServiceName$Client extends grpc.Client " "export class $ServiceName$Client extends grpc.Client "
@@ -494,10 +499,9 @@ static void GenerateClientClassInterface(
} }
} // namespace } // namespace
grpc::string GenerateInterface(grpc_generator::File* file,
grpc::string GenerateInterface(grpc_generator::File *file, const grpc_generator::Service* service,
const grpc_generator::Service *service, const grpc::string& filename) {
const grpc::string &filename) {
grpc::string output; grpc::string output;
std::set<grpc::string> generated_functions; std::set<grpc::string> generated_functions;
@@ -505,7 +509,9 @@ grpc::string GenerateInterface(grpc_generator::File *file,
vars["PATH"] = file->package(); vars["PATH"] = file->package();
if (!file->package().empty()) { vars["PATH"].append("."); } if (!file->package().empty()) {
vars["PATH"].append(".");
}
vars["ServiceName"] = service->name(); vars["ServiceName"] = service->name();
vars["FBSFile"] = service->name() + "_fbs"; vars["FBSFile"] = service->name() + "_fbs";

View File

@@ -5,8 +5,8 @@
#include "src/compiler/schema_interface.h" #include "src/compiler/schema_interface.h"
#ifndef GRPC_CUSTOM_STRING #ifndef GRPC_CUSTOM_STRING
# include <string> #include <string>
# define GRPC_CUSTOM_STRING std::string #define GRPC_CUSTOM_STRING std::string
#endif #endif
namespace grpc { namespace grpc {
@@ -16,11 +16,11 @@ typedef GRPC_CUSTOM_STRING string;
} // namespace grpc } // namespace grpc
namespace grpc_ts_generator { namespace grpc_ts_generator {
grpc::string Generate(grpc_generator::File *file, grpc::string Generate(grpc_generator::File* file,
const grpc_generator::Service *service, const grpc_generator::Service* service,
const grpc::string &filename); const grpc::string& filename);
grpc::string GenerateInterface(grpc_generator::File *file, grpc::string GenerateInterface(grpc_generator::File* file,
const grpc_generator::Service *service, const grpc_generator::Service* service,
const grpc::string &filename); const grpc::string& filename);
} // namespace grpc_ts_generator } // namespace grpc_ts_generator

View File

@@ -1,10 +1,11 @@
import java.nio.ByteBuffer;
import MyGame.Example.Monster; import MyGame.Example.Monster;
import MyGame.Example.Stat; import MyGame.Example.Stat;
import com.google.flatbuffers.FlatBufferBuilder; import com.google.flatbuffers.FlatBufferBuilder;
import java.nio.ByteBuffer;
class GameFactory { class GameFactory {
public static Monster createMonster(String monsterName, short nestedMonsterHp, short nestedMonsterMana) { public static Monster createMonster(
String monsterName, short nestedMonsterHp, short nestedMonsterMana) {
FlatBufferBuilder builder = new FlatBufferBuilder(); FlatBufferBuilder builder = new FlatBufferBuilder();
int name_offset = builder.createString(monsterName); int name_offset = builder.createString(monsterName);
@@ -38,5 +39,4 @@ class GameFactory {
Stat stat = Stat.getRootAsStat(builder.dataBuffer()); Stat stat = Stat.getRootAsStat(builder.dataBuffer());
return stat; return stat;
} }
} }

View File

@@ -17,27 +17,20 @@
import MyGame.Example.Monster; import MyGame.Example.Monster;
import MyGame.Example.MonsterStorageGrpc; import MyGame.Example.MonsterStorageGrpc;
import MyGame.Example.Stat; import MyGame.Example.Stat;
import com.google.flatbuffers.FlatBufferBuilder;
import io.grpc.ManagedChannel; import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder; import io.grpc.ManagedChannelBuilder;
import io.grpc.Server; import io.grpc.Server;
import io.grpc.ServerBuilder; import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver; import io.grpc.stub.StreamObserver;
import java.io.IOException;
import java.util.Iterator;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Assert; import org.junit.Assert;
import java.io.IOException; /** Demonstrates basic client-server interaction using grpc-java over netty. */
import java.lang.InterruptedException;
import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.CountDownLatch;
/**
* Demonstrates basic client-server interaction using grpc-java over netty.
*/
public class JavaGrpcTest { public class JavaGrpcTest {
static final String BIG_MONSTER_NAME = "Cyberdemon"; static final String BIG_MONSTER_NAME = "Cyberdemon";
static final short nestedMonsterHp = 600; static final short nestedMonsterHp = 600;
@@ -65,7 +58,7 @@ public class JavaGrpcTest {
@Override @Override
public void retrieve(Stat request, io.grpc.stub.StreamObserver<Monster> responseObserver) { public void retrieve(Stat request, io.grpc.stub.StreamObserver<Monster> responseObserver) {
// Create 10 monsters for streaming response. // Create 10 monsters for streaming response.
for (int i=0; i<numStreamedMsgs; i++) { for (int i = 0; i < numStreamedMsgs; i++) {
Monster monster = GameFactory.createMonsterFromStat(request, i); Monster monster = GameFactory.createMonsterFromStat(request, i);
responseObserver.onNext(monster); responseObserver.onNext(monster);
} }
@@ -82,7 +75,8 @@ public class JavaGrpcTest {
return computeMinMax(responseObserver, true); return computeMinMax(responseObserver, true);
} }
private StreamObserver<Monster> computeMinMax(final StreamObserver<Stat> responseObserver, final boolean includeMin) { private StreamObserver<Monster> computeMinMax(
final StreamObserver<Stat> responseObserver, final boolean includeMin) {
final AtomicInteger maxHp = new AtomicInteger(Integer.MIN_VALUE); final AtomicInteger maxHp = new AtomicInteger(Integer.MIN_VALUE);
final AtomicReference<String> maxHpMonsterName = new AtomicReference<String>(); final AtomicReference<String> maxHpMonsterName = new AtomicReference<String>();
final AtomicInteger maxHpCount = new AtomicInteger(); final AtomicInteger maxHpCount = new AtomicInteger();
@@ -98,8 +92,7 @@ public class JavaGrpcTest {
maxHp.set(monster.hp()); maxHp.set(monster.hp());
maxHpMonsterName.set(monster.name()); maxHpMonsterName.set(monster.name());
maxHpCount.set(1); maxHpCount.set(1);
} } else if (monster.hp() == maxHp.get()) {
else if (monster.hp() == maxHp.get()) {
// Count how many times we saw a monster of current max hit points. // Count how many times we saw a monster of current max hit points.
maxHpCount.getAndIncrement(); maxHpCount.getAndIncrement();
} }
@@ -109,27 +102,31 @@ public class JavaGrpcTest {
minHp.set(monster.hp()); minHp.set(monster.hp());
minHpMonsterName.set(monster.name()); minHpMonsterName.set(monster.name());
minHpCount.set(1); minHpCount.set(1);
} } else if (monster.hp() == minHp.get()) {
else if (monster.hp() == minHp.get()) {
// Count how many times we saw a monster of current min hit points. // Count how many times we saw a monster of current min hit points.
minHpCount.getAndIncrement(); minHpCount.getAndIncrement();
} }
} }
public void onCompleted() { public void onCompleted() {
Stat maxHpStat = GameFactory.createStat(maxHpMonsterName.get(), maxHp.get(), maxHpCount.get()); Stat maxHpStat =
GameFactory.createStat(maxHpMonsterName.get(), maxHp.get(), maxHpCount.get());
// Send max hit points first. // Send max hit points first.
responseObserver.onNext(maxHpStat); responseObserver.onNext(maxHpStat);
if (includeMin) { if (includeMin) {
// Send min hit points. // Send min hit points.
Stat minHpStat = GameFactory.createStat(minHpMonsterName.get(), minHp.get(), minHpCount.get()); Stat minHpStat =
GameFactory.createStat(minHpMonsterName.get(), minHp.get(), minHpCount.get());
responseObserver.onNext(minHpStat); responseObserver.onNext(minHpStat);
} }
responseObserver.onCompleted(); responseObserver.onCompleted();
} }
public void onError(Throwable t) { public void onError(Throwable t) {
// Not expected // Not expected
Assert.fail(); Assert.fail();
}; }
;
}; };
} }
} }
@@ -138,7 +135,8 @@ public class JavaGrpcTest {
public static void startServer() throws IOException { public static void startServer() throws IOException {
server = ServerBuilder.forPort(0).addService(new MyService()).build().start(); server = ServerBuilder.forPort(0).addService(new MyService()).build().start();
int port = server.getPort(); int port = server.getPort();
channel = ManagedChannelBuilder.forAddress("localhost", port) channel =
ManagedChannelBuilder.forAddress("localhost", port)
// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
// needing certificates. // needing certificates.
.usePlaintext() .usePlaintext()
@@ -150,7 +148,8 @@ public class JavaGrpcTest {
@org.junit.Test @org.junit.Test
public void testUnary() throws IOException { public void testUnary() throws IOException {
Monster monsterRequest = GameFactory.createMonster(BIG_MONSTER_NAME, nestedMonsterHp, nestedMonsterMana); Monster monsterRequest =
GameFactory.createMonster(BIG_MONSTER_NAME, nestedMonsterHp, nestedMonsterMana);
Stat stat = blockingStub.store(monsterRequest); Stat stat = blockingStub.store(monsterRequest);
Assert.assertEquals(stat.id(), "Hello " + BIG_MONSTER_NAME); Assert.assertEquals(stat.id(), "Hello " + BIG_MONSTER_NAME);
System.out.println("Received stat response from service: " + stat.id()); System.out.println("Received stat response from service: " + stat.id());
@@ -158,14 +157,15 @@ public class JavaGrpcTest {
@org.junit.Test @org.junit.Test
public void testServerStreaming() throws IOException { public void testServerStreaming() throws IOException {
Monster monsterRequest = GameFactory.createMonster(BIG_MONSTER_NAME, nestedMonsterHp, nestedMonsterMana); Monster monsterRequest =
GameFactory.createMonster(BIG_MONSTER_NAME, nestedMonsterHp, nestedMonsterMana);
Stat stat = blockingStub.store(monsterRequest); Stat stat = blockingStub.store(monsterRequest);
Iterator<Monster> iterator = blockingStub.retrieve(stat); Iterator<Monster> iterator = blockingStub.retrieve(stat);
int counter = 0; int counter = 0;
while(iterator.hasNext()) { while (iterator.hasNext()) {
Monster m = iterator.next(); Monster m = iterator.next();
System.out.println("Received monster " + m.name()); System.out.println("Received monster " + m.name());
counter ++; counter++;
} }
Assert.assertEquals(counter, numStreamedMsgs); Assert.assertEquals(counter, numStreamedMsgs);
System.out.println("FlatBuffers GRPC client/server test: completed successfully"); System.out.println("FlatBuffers GRPC client/server test: completed successfully");
@@ -176,19 +176,24 @@ public class JavaGrpcTest {
final AtomicReference<Stat> maxHitStat = new AtomicReference<Stat>(); final AtomicReference<Stat> maxHitStat = new AtomicReference<Stat>();
final CountDownLatch streamAlive = new CountDownLatch(1); final CountDownLatch streamAlive = new CountDownLatch(1);
StreamObserver<Stat> statObserver = new StreamObserver<Stat>() { StreamObserver<Stat> statObserver =
new StreamObserver<Stat>() {
public void onCompleted() { public void onCompleted() {
streamAlive.countDown(); streamAlive.countDown();
} }
public void onError(Throwable ex) { }
public void onError(Throwable ex) {}
public void onNext(Stat stat) { public void onNext(Stat stat) {
maxHitStat.set(stat); maxHitStat.set(stat);
} }
}; };
StreamObserver<Monster> monsterStream = asyncStub.getMaxHitPoint(statObserver); StreamObserver<Monster> monsterStream = asyncStub.getMaxHitPoint(statObserver);
short count = 10; short count = 10;
for (short i = 0;i < count; ++i) { for (short i = 0; i < count; ++i) {
Monster monster = GameFactory.createMonster(BIG_MONSTER_NAME + i, (short) (nestedMonsterHp * i), nestedMonsterMana); Monster monster =
GameFactory.createMonster(
BIG_MONSTER_NAME + i, (short) (nestedMonsterHp * i), nestedMonsterMana);
monsterStream.onNext(monster); monsterStream.onNext(monster);
} }
monsterStream.onCompleted(); monsterStream.onCompleted();
@@ -205,30 +210,35 @@ public class JavaGrpcTest {
final AtomicReference<Stat> minHitStat = new AtomicReference<Stat>(); final AtomicReference<Stat> minHitStat = new AtomicReference<Stat>();
final CountDownLatch streamAlive = new CountDownLatch(1); final CountDownLatch streamAlive = new CountDownLatch(1);
StreamObserver<Stat> statObserver = new StreamObserver<Stat>() { StreamObserver<Stat> statObserver =
new StreamObserver<Stat>() {
public void onCompleted() { public void onCompleted() {
streamAlive.countDown(); streamAlive.countDown();
} }
public void onError(Throwable ex) { }
public void onError(Throwable ex) {}
public void onNext(Stat stat) { public void onNext(Stat stat) {
// We expect the server to send the max stat first and then the min stat. // We expect the server to send the max stat first and then the min stat.
if (maxHitStat.get() == null) { if (maxHitStat.get() == null) {
maxHitStat.set(stat); maxHitStat.set(stat);
} } else {
else {
minHitStat.set(stat); minHitStat.set(stat);
} }
} }
}; };
StreamObserver<Monster> monsterStream = asyncStub.getMinMaxHitPoints(statObserver); StreamObserver<Monster> monsterStream = asyncStub.getMinMaxHitPoints(statObserver);
short count = 10; short count = 10;
for (short i = 0;i < count; ++i) { for (short i = 0; i < count; ++i) {
Monster monster = GameFactory.createMonster(BIG_MONSTER_NAME + i, (short) (nestedMonsterHp * i), nestedMonsterMana); Monster monster =
GameFactory.createMonster(
BIG_MONSTER_NAME + i, (short) (nestedMonsterHp * i), nestedMonsterMana);
monsterStream.onNext(monster); monsterStream.onNext(monster);
} }
monsterStream.onCompleted(); monsterStream.onCompleted();
// Wait a little bit for the server to send the stats of the monster with the max and min hit-points. // Wait a little bit for the server to send the stats of the monster with the max and min
// hit-points.
streamAlive.await(timeoutMs, TimeUnit.MILLISECONDS); streamAlive.await(timeoutMs, TimeUnit.MILLISECONDS);
Assert.assertEquals(maxHitStat.get().id(), BIG_MONSTER_NAME + (count - 1)); Assert.assertEquals(maxHitStat.get().id(), BIG_MONSTER_NAME + (count - 1));

View File

@@ -1,13 +1,13 @@
from __future__ import print_function from __future__ import print_function
from concurrent import futures
import os import os
import sys import sys
import grpc
import flatbuffers import flatbuffers
import grpc
from concurrent import futures sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "tests"))
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'tests'))
import MyGame.Example.Monster as Monster import MyGame.Example.Monster as Monster
import MyGame.Example.Stat as Stat import MyGame.Example.Stat as Stat
import MyGame.Example.Vec3 as Vec3 import MyGame.Example.Vec3 as Vec3
@@ -60,7 +60,7 @@ class MonsterStorage(monster_grpc_fb.MonsterStorageServicer):
assert m.InventoryLength() == len(test_inventory) assert m.InventoryLength() == len(test_inventory)
for i in range(0, len(test_inventory)): for i in range(0, len(test_inventory)):
assert m.Inventory(i) == test_inventory[len(test_inventory)-i -1] assert m.Inventory(i) == test_inventory[len(test_inventory) - i - 1]
assert m.TestType() == test_testtype assert m.TestType() == test_testtype
@@ -103,7 +103,7 @@ def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
monster_grpc_fb.add_MonsterStorageServicer_to_server(MonsterStorage(), server) monster_grpc_fb.add_MonsterStorageServicer_to_server(MonsterStorage(), server)
server.add_insecure_port('[::]:50051') server.add_insecure_port("[::]:50051")
server.start() server.start()
@@ -112,7 +112,7 @@ def serve():
def run(): def run():
channel = grpc.insecure_channel('127.0.0.1:50051') channel = grpc.insecure_channel("127.0.0.1:50051")
stub = monster_grpc_fb.MonsterStorageStub(channel) stub = monster_grpc_fb.MonsterStorageStub(channel)
b = flatbuffers.Builder(0) b = flatbuffers.Builder(0)
@@ -142,7 +142,9 @@ def run():
Monster.MonsterAddHp(b, test_hp) Monster.MonsterAddHp(b, test_hp)
Monster.MonsterAddName(b, name1) Monster.MonsterAddName(b, name1)
Monster.MonsterAddColor(b, test_color) Monster.MonsterAddColor(b, test_color)
pos = Vec3.CreateVec3(b, test_X, test_Y, test_Z, test_test1, test_color, test_a, test_b) pos = Vec3.CreateVec3(
b, test_X, test_Y, test_Z, test_test1, test_color, test_a, test_b
)
Monster.MonsterAddPos(b, pos) Monster.MonsterAddPos(b, pos)
Monster.MonsterAddInventory(b, inv) Monster.MonsterAddInventory(b, inv)
Monster.MonsterAddTestType(b, test_testtype) Monster.MonsterAddTestType(b, test_testtype)
@@ -170,5 +172,5 @@ def run():
count = count + 1 count = count + 1
if __name__ == '__main__': if __name__ == "__main__":
serve() serve()

View File

@@ -25,69 +25,69 @@ class IdlNamer : public Namer {
using Namer::Variable; using Namer::Variable;
using Namer::Variant; using Namer::Variant;
std::string Constant(const FieldDef &d) const { return Constant(d.name); } std::string Constant(const FieldDef& d) const { return Constant(d.name); }
// Types are always structs or enums so we can only expose these two // Types are always structs or enums so we can only expose these two
// overloads. // overloads.
std::string Type(const StructDef &d) const { return Type(d.name); } std::string Type(const StructDef& d) const { return Type(d.name); }
std::string Type(const EnumDef &d) const { return Type(d.name); } std::string Type(const EnumDef& d) const { return Type(d.name); }
std::string Function(const Definition &s) const { return Function(s.name); } std::string Function(const Definition& s) const { return Function(s.name); }
std::string Function(const std::string& prefix, const Definition &s) const { std::string Function(const std::string& prefix, const Definition& s) const {
return Function(prefix + s.name); return Function(prefix + s.name);
} }
std::string Field(const FieldDef &s) const { return Field(s.name); } std::string Field(const FieldDef& s) const { return Field(s.name); }
std::string Field(const FieldDef &d, const std::string &s) const { std::string Field(const FieldDef& d, const std::string& s) const {
return Field(d.name + "_" + s); return Field(d.name + "_" + s);
} }
std::string Variable(const FieldDef &s) const { return Variable(s.name); } std::string Variable(const FieldDef& s) const { return Variable(s.name); }
std::string Variable(const StructDef &s) const { return Variable(s.name); } std::string Variable(const StructDef& s) const { return Variable(s.name); }
std::string Variant(const EnumVal &s) const { return Variant(s.name); } std::string Variant(const EnumVal& s) const { return Variant(s.name); }
std::string EnumVariant(const EnumDef &e, const EnumVal &v) const { std::string EnumVariant(const EnumDef& e, const EnumVal& v) const {
return Type(e) + config_.enum_variant_seperator + Variant(v); return Type(e) + config_.enum_variant_seperator + Variant(v);
} }
std::string ObjectType(const StructDef &d) const { std::string ObjectType(const StructDef& d) const {
return ObjectType(d.name); return ObjectType(d.name);
} }
std::string ObjectType(const EnumDef &d) const { return ObjectType(d.name); } std::string ObjectType(const EnumDef& d) const { return ObjectType(d.name); }
std::string Method(const FieldDef &d, const std::string &suffix) const { std::string Method(const FieldDef& d, const std::string& suffix) const {
return Method(d.name, suffix); return Method(d.name, suffix);
} }
std::string Method(const std::string &prefix, const StructDef &d) const { std::string Method(const std::string& prefix, const StructDef& d) const {
return Method(prefix, d.name); return Method(prefix, d.name);
} }
std::string Method(const std::string &prefix, const FieldDef &d) const { std::string Method(const std::string& prefix, const FieldDef& d) const {
return Method(prefix, d.name); return Method(prefix, d.name);
} }
std::string Method(const std::string &prefix, const FieldDef &d, std::string Method(const std::string& prefix, const FieldDef& d,
const std::string &suffix) const { const std::string& suffix) const {
return Method(prefix, d.name, suffix); return Method(prefix, d.name, suffix);
} }
std::string Namespace(const struct Namespace &ns) const { std::string Namespace(const struct Namespace& ns) const {
return Namespace(ns.components); return Namespace(ns.components);
} }
std::string NamespacedEnumVariant(const EnumDef &e, const EnumVal &v) const { std::string NamespacedEnumVariant(const EnumDef& e, const EnumVal& v) const {
return NamespacedString(e.defined_namespace, EnumVariant(e, v)); return NamespacedString(e.defined_namespace, EnumVariant(e, v));
} }
std::string NamespacedType(const Definition &def) const { std::string NamespacedType(const Definition& def) const {
return NamespacedString(def.defined_namespace, Type(def.name)); return NamespacedString(def.defined_namespace, Type(def.name));
} }
std::string NamespacedObjectType(const Definition &def) const { std::string NamespacedObjectType(const Definition& def) const {
return NamespacedString(def.defined_namespace, ObjectType(def.name)); return NamespacedString(def.defined_namespace, ObjectType(def.name));
} }
std::string Directories(const struct Namespace &ns, std::string Directories(const struct Namespace& ns,
SkipDir skips = SkipDir::None, SkipDir skips = SkipDir::None,
Case input_case = Case::kUpperCamel) const { Case input_case = Case::kUpperCamel) const {
return Directories(ns.components, skips, input_case); return Directories(ns.components, skips, input_case);
@@ -96,19 +96,19 @@ class IdlNamer : public Namer {
// Legacy fields do not really follow the usual config and should be // Legacy fields do not really follow the usual config and should be
// considered for deprecation. // considered for deprecation.
std::string LegacyRustNativeVariant(const EnumVal &v) const { std::string LegacyRustNativeVariant(const EnumVal& v) const {
return ConvertCase(EscapeKeyword(v.name), Case::kUpperCamel); return ConvertCase(EscapeKeyword(v.name), Case::kUpperCamel);
} }
std::string LegacyRustFieldOffsetName(const FieldDef &field) const { std::string LegacyRustFieldOffsetName(const FieldDef& field) const {
return "VT_" + ConvertCase(EscapeKeyword(field.name), Case::kAllUpper); return "VT_" + ConvertCase(EscapeKeyword(field.name), Case::kAllUpper);
} }
std::string LegacyRustUnionTypeOffsetName(const FieldDef &field) const { std::string LegacyRustUnionTypeOffsetName(const FieldDef& field) const {
return "VT_" + ConvertCase(EscapeKeyword(field.name + "_type"), Case::kAllUpper); return "VT_" +
ConvertCase(EscapeKeyword(field.name + "_type"), Case::kAllUpper);
} }
std::string LegacySwiftVariant(const EnumVal& ev) const {
std::string LegacySwiftVariant(const EnumVal &ev) const {
auto name = ev.name; auto name = ev.name;
if (isupper(name.front())) { if (isupper(name.front())) {
std::transform(name.begin(), name.end(), name.begin(), CharToLower); std::transform(name.begin(), name.end(), name.begin(), CharToLower);
@@ -117,24 +117,24 @@ class IdlNamer : public Namer {
} }
// Also used by Kotlin, lol. // Also used by Kotlin, lol.
std::string LegacyJavaMethod2(const std::string &prefix, const StructDef &sd, std::string LegacyJavaMethod2(const std::string& prefix, const StructDef& sd,
const std::string &suffix) const { const std::string& suffix) const {
return prefix + sd.name + suffix; return prefix + sd.name + suffix;
} }
std::string LegacyKotlinVariant(EnumVal &ev) const { std::string LegacyKotlinVariant(EnumVal& ev) const {
// Namer assumes the input case is snake case which is wrong... // Namer assumes the input case is snake case which is wrong...
return ConvertCase(EscapeKeyword(ev.name), Case::kLowerCamel); return ConvertCase(EscapeKeyword(ev.name), Case::kLowerCamel);
} }
// Kotlin methods escapes keywords after case conversion but before // Kotlin methods escapes keywords after case conversion but before
// prefixing and suffixing. // prefixing and suffixing.
std::string LegacyKotlinMethod(const std::string &prefix, const FieldDef &d, std::string LegacyKotlinMethod(const std::string& prefix, const FieldDef& d,
const std::string &suffix) const { const std::string& suffix) const {
return prefix + ConvertCase(EscapeKeyword(d.name), Case::kUpperCamel) + return prefix + ConvertCase(EscapeKeyword(d.name), Case::kUpperCamel) +
suffix; suffix;
} }
std::string LegacyKotlinMethod(const std::string &prefix, const StructDef &d, std::string LegacyKotlinMethod(const std::string& prefix, const StructDef& d,
const std::string &suffix) const { const std::string& suffix) const {
return prefix + ConvertCase(EscapeKeyword(d.name), Case::kUpperCamel) + return prefix + ConvertCase(EscapeKeyword(d.name), Case::kUpperCamel) +
suffix; suffix;
} }
@@ -145,17 +145,19 @@ class IdlNamer : public Namer {
return "mutate_" + d.name; return "mutate_" + d.name;
} }
std::string LegacyRustUnionTypeMethod(const FieldDef &d) { std::string LegacyRustUnionTypeMethod(const FieldDef& d) {
// assert d is a union // assert d is a union
// d should convert case but not escape keywords due to historical reasons // d should convert case but not escape keywords due to historical reasons
return ConvertCase(d.name, config_.fields, Case::kLowerCamel) + "_type"; return ConvertCase(d.name, config_.fields, Case::kLowerCamel) + "_type";
} }
private: private:
std::string NamespacedString(const struct Namespace *ns, std::string NamespacedString(const struct Namespace* ns,
const std::string &str) const { const std::string& str) const {
std::string ret; std::string ret;
if (ns != nullptr) { ret += Namespace(ns->components); } if (ns != nullptr) {
ret += Namespace(ns->components);
}
if (!ret.empty()) ret += config_.namespace_seperator; if (!ret.empty()) ret += config_.namespace_seperator;
return ret + str; return ret + str;
} }
@@ -163,9 +165,9 @@ class IdlNamer : public Namer {
// This is a temporary helper function for code generators to call until all // This is a temporary helper function for code generators to call until all
// flag-overriding logic into flatc.cpp // flag-overriding logic into flatc.cpp
inline Namer::Config WithFlagOptions(const Namer::Config &input, inline Namer::Config WithFlagOptions(const Namer::Config& input,
const IDLOptions &opts, const IDLOptions& opts,
const std::string &path) { const std::string& path) {
Namer::Config result = input; Namer::Config result = input;
result.object_prefix = opts.object_prefix; result.object_prefix = opts.object_prefix;
result.object_suffix = opts.object_suffix; result.object_suffix = opts.object_suffix;

View File

@@ -110,49 +110,49 @@ class Namer {
virtual ~Namer() {} virtual ~Namer() {}
template<typename T> std::string Method(const T &s) const { template <typename T>
std::string Method(const T& s) const {
return Method(s.name); return Method(s.name);
} }
virtual std::string Method(const std::string &pre, virtual std::string Method(const std::string& pre, const std::string& mid,
const std::string &mid, const std::string& suf) const {
const std::string &suf) const {
return Format(pre + "_" + mid + "_" + suf, config_.methods); return Format(pre + "_" + mid + "_" + suf, config_.methods);
} }
virtual std::string Method(const std::string &pre, virtual std::string Method(const std::string& pre,
const std::string &suf) const { const std::string& suf) const {
return Format(pre + "_" + suf, config_.methods); return Format(pre + "_" + suf, config_.methods);
} }
virtual std::string Method(const std::string &s) const { virtual std::string Method(const std::string& s) const {
return Format(s, config_.methods); return Format(s, config_.methods);
} }
virtual std::string Constant(const std::string &s) const { virtual std::string Constant(const std::string& s) const {
return Format(s, config_.constants); return Format(s, config_.constants);
} }
virtual std::string Function(const std::string &s) const { virtual std::string Function(const std::string& s) const {
return Format(s, config_.functions); return Format(s, config_.functions);
} }
virtual std::string Variable(const std::string &s) const { virtual std::string Variable(const std::string& s) const {
return Format(s, config_.variables); return Format(s, config_.variables);
} }
template<typename T> template <typename T>
std::string Variable(const std::string &p, const T &s) const { std::string Variable(const std::string& p, const T& s) const {
return Format(p + "_" + s.name, config_.variables); return Format(p + "_" + s.name, config_.variables);
} }
virtual std::string Variable(const std::string &p, virtual std::string Variable(const std::string& p,
const std::string &s) const { const std::string& s) const {
return Format(p + "_" + s, config_.variables); return Format(p + "_" + s, config_.variables);
} }
virtual std::string Namespace(const std::string &s) const { virtual std::string Namespace(const std::string& s) const {
return Format(s, config_.namespaces); return Format(s, config_.namespaces);
} }
virtual std::string Namespace(const std::vector<std::string> &ns) const { virtual std::string Namespace(const std::vector<std::string>& ns) const {
std::string result; std::string result;
for (auto it = ns.begin(); it != ns.end(); it++) { for (auto it = ns.begin(); it != ns.end(); it++) {
if (it != ns.begin()) result += config_.namespace_seperator; if (it != ns.begin()) result += config_.namespace_seperator;
@@ -161,14 +161,14 @@ class Namer {
return result; return result;
} }
virtual std::string NamespacedType(const std::vector<std::string> &ns, virtual std::string NamespacedType(const std::vector<std::string>& ns,
const std::string &s) const { const std::string& s) const {
return (ns.empty() ? "" : (Namespace(ns) + config_.namespace_seperator)) + return (ns.empty() ? "" : (Namespace(ns) + config_.namespace_seperator)) +
Type(s); Type(s);
} }
// Returns `filename` with the right casing, suffix, and extension. // Returns `filename` with the right casing, suffix, and extension.
virtual std::string File(const std::string &filename, virtual std::string File(const std::string& filename,
SkipFile skips = SkipFile::None) const { SkipFile skips = SkipFile::None) const {
const bool skip_suffix = (skips & SkipFile::Suffix) != SkipFile::None; const bool skip_suffix = (skips & SkipFile::Suffix) != SkipFile::None;
const bool skip_ext = (skips & SkipFile::Extension) != SkipFile::None; const bool skip_ext = (skips & SkipFile::Extension) != SkipFile::None;
@@ -176,8 +176,8 @@ class Namer {
(skip_suffix ? "" : config_.filename_suffix) + (skip_suffix ? "" : config_.filename_suffix) +
(skip_ext ? "" : config_.filename_extension); (skip_ext ? "" : config_.filename_extension);
} }
template<typename T> template <typename T>
std::string File(const T &f, SkipFile skips = SkipFile::None) const { std::string File(const T& f, SkipFile skips = SkipFile::None) const {
return File(f.name, skips); return File(f.name, skips);
} }
@@ -188,7 +188,7 @@ class Namer {
// input_case is used to tell how to modify namespace. e.g. kUpperCamel will // input_case is used to tell how to modify namespace. e.g. kUpperCamel will
// add a underscode between case changes, so MyGame turns into My_Game // add a underscode between case changes, so MyGame turns into My_Game
// (depending also on the output_case). // (depending also on the output_case).
virtual std::string Directories(const std::vector<std::string> &directories, virtual std::string Directories(const std::vector<std::string>& directories,
SkipDir skips = SkipDir::None, SkipDir skips = SkipDir::None,
Case input_case = Case::kUpperCamel) const { Case input_case = Case::kUpperCamel) const {
const bool skip_output_path = const bool skip_output_path =
@@ -204,7 +204,7 @@ class Namer {
return result; return result;
} }
virtual std::string EscapeKeyword(const std::string &name) const { virtual std::string EscapeKeyword(const std::string& name) const {
if (keywords_.find(name) == keywords_.end()) { if (keywords_.find(name) == keywords_.end()) {
return name; return name;
} else { } else {
@@ -212,26 +212,26 @@ class Namer {
} }
} }
virtual std::string Type(const std::string &s) const { virtual std::string Type(const std::string& s) const {
return Format(s, config_.types); return Format(s, config_.types);
} }
virtual std::string Type(const std::string &t, const std::string &s) const { virtual std::string Type(const std::string& t, const std::string& s) const {
return Format(t + "_" + s, config_.types); return Format(t + "_" + s, config_.types);
} }
virtual std::string ObjectType(const std::string &s) const { virtual std::string ObjectType(const std::string& s) const {
return config_.object_prefix + Type(s) + config_.object_suffix; return config_.object_prefix + Type(s) + config_.object_suffix;
} }
virtual std::string Field(const std::string &s) const { virtual std::string Field(const std::string& s) const {
return Format(s, config_.fields); return Format(s, config_.fields);
} }
virtual std::string Variant(const std::string &s) const { virtual std::string Variant(const std::string& s) const {
return Format(s, config_.variants); return Format(s, config_.variants);
} }
virtual std::string Format(const std::string &s, Case casing) const { virtual std::string Format(const std::string& s, Case casing) const {
if (config_.escape_keywords == Config::Escape::BeforeConvertingCase) { if (config_.escape_keywords == Config::Escape::BeforeConvertingCase) {
return ConvertCase(EscapeKeyword(s), casing, Case::kLowerCamel); return ConvertCase(EscapeKeyword(s), casing, Case::kLowerCamel);
} else { } else {
@@ -242,8 +242,8 @@ class Namer {
// Denamespaces a string (e.g. The.Quick.Brown.Fox) by returning the last part // Denamespaces a string (e.g. The.Quick.Brown.Fox) by returning the last part
// after the `delimiter` (Fox) and placing the rest in `namespace_prefix` // after the `delimiter` (Fox) and placing the rest in `namespace_prefix`
// (The.Quick.Brown). // (The.Quick.Brown).
virtual std::string Denamespace(const std::string &s, virtual std::string Denamespace(const std::string& s,
std::string &namespace_prefix, std::string& namespace_prefix,
const char delimiter = '.') const { const char delimiter = '.') const {
const size_t pos = s.find_last_of(delimiter); const size_t pos = s.find_last_of(delimiter);
if (pos == std::string::npos) { if (pos == std::string::npos) {
@@ -255,7 +255,7 @@ class Namer {
} }
// Same as above, but disregards the prefix. // Same as above, but disregards the prefix.
virtual std::string Denamespace(const std::string &s, virtual std::string Denamespace(const std::string& s,
const char delimiter = '.') const { const char delimiter = '.') const {
std::string prefix; std::string prefix;
return Denamespace(s, prefix, delimiter); return Denamespace(s, prefix, delimiter);

View File

@@ -7,7 +7,7 @@
namespace flatbuffers { namespace flatbuffers {
namespace python { namespace python {
Version::Version(const std::string &version) { Version::Version(const std::string& version) {
std::stringstream ss(version); std::stringstream ss(version);
char dot; char dot;
ss >> major >> dot >> minor >> dot >> micro; ss >> major >> dot >> minor >> dot >> micro;
@@ -17,7 +17,7 @@ bool Version::IsValid() const {
return (major == 0 || major == 2 || major == 3) && minor >= 0 && micro >= 0; return (major == 0 || major == 2 || major == 3) && minor >= 0 && micro >= 0;
} }
std::set<std::string> Keywords(const Version &version) { std::set<std::string> Keywords(const Version& version) {
switch (version.major) { switch (version.major) {
case 2: case 2:
// https://docs.python.org/2/reference/lexical_analysis.html#keywords // https://docs.python.org/2/reference/lexical_analysis.html#keywords
@@ -44,15 +44,15 @@ std::set<std::string> Keywords(const Version &version) {
} }
} }
const python::Import &python::Imports::Import(const std::string &module) { const python::Import& python::Imports::Import(const std::string& module) {
python::Import import; python::Import import;
import.module = module; import.module = module;
imports.push_back(std::move(import)); imports.push_back(std::move(import));
return imports.back(); return imports.back();
} }
const python::Import &python::Imports::Import(const std::string &module, const python::Import& python::Imports::Import(const std::string& module,
const std::string &name) { const std::string& name) {
python::Import import; python::Import import;
import.module = module; import.module = module;
import.name = name; import.name = name;
@@ -60,15 +60,15 @@ const python::Import &python::Imports::Import(const std::string &module,
return imports.back(); return imports.back();
} }
const python::Import &python::Imports::Export(const std::string &module) { const python::Import& python::Imports::Export(const std::string& module) {
python::Import import; python::Import import;
import.module = module; import.module = module;
exports.push_back(std::move(import)); exports.push_back(std::move(import));
return exports.back(); return exports.back();
} }
const python::Import &python::Imports::Export(const std::string &module, const python::Import& python::Imports::Export(const std::string& module,
const std::string &name) { const std::string& name) {
python::Import import; python::Import import;
import.module = module; import.module = module;
import.name = name; import.name = name;

View File

@@ -62,7 +62,7 @@ static const Namer::Config kStubConfig = {
// //
// https://docs.python.org/3/faq/general.html#how-does-the-python-version-numbering-scheme-work // https://docs.python.org/3/faq/general.html#how-does-the-python-version-numbering-scheme-work
struct Version { struct Version {
explicit Version(const std::string &version); explicit Version(const std::string& version);
bool IsValid() const; bool IsValid() const;
@@ -71,7 +71,7 @@ struct Version {
int16_t micro = 0; int16_t micro = 0;
}; };
std::set<std::string> Keywords(const Version &version); std::set<std::string> Keywords(const Version& version);
struct Import { struct Import {
bool IsLocal() const { return module == "."; } bool IsLocal() const { return module == "."; }
@@ -81,13 +81,13 @@ struct Import {
}; };
struct Imports { struct Imports {
const python::Import &Import(const std::string &module); const python::Import& Import(const std::string& module);
const python::Import &Import(const std::string &module, const python::Import& Import(const std::string& module,
const std::string &name); const std::string& name);
const python::Import &Export(const std::string &module); const python::Import& Export(const std::string& module);
const python::Import &Export(const std::string &module, const python::Import& Export(const std::string& module,
const std::string &name); const std::string& name);
std::vector<python::Import> imports; std::vector<python::Import> imports;
std::vector<python::Import> exports; std::vector<python::Import> exports;

View File

@@ -18,22 +18,22 @@
#define FLATBUFFERS_FLATC_PCH_H_ #define FLATBUFFERS_FLATC_PCH_H_
// stl // stl
#include <cmath>
#include <sstream>
#include <cassert> #include <cassert>
#include <unordered_set> #include <cmath>
#include <unordered_map>
#include <iostream>
#include <functional> #include <functional>
#include <set> #include <iostream>
#include <iterator> #include <iterator>
#include <set>
#include <sstream>
#include <tuple> #include <tuple>
#include <unordered_map>
#include <unordered_set>
// flatbuffers // flatbuffers
#include "flatbuffers/pch/pch.h"
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/flexbuffers.h" #include "flatbuffers/flexbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/pch/pch.h"
#endif // FLATBUFFERS_FLATC_PCH_H_ #endif // FLATBUFFERS_FLATC_PCH_H_

View File

@@ -18,19 +18,19 @@
#define FLATBUFFERS_PCH_H_ #define FLATBUFFERS_PCH_H_
// stl // stl
#include <algorithm>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <algorithm>
#include <list>
#include <string>
#include <utility>
#include <iomanip> #include <iomanip>
#include <limits>
#include <list>
#include <map> #include <map>
#include <memory> #include <memory>
#include <limits>
#include <stack> #include <stack>
#include <vector> #include <string>
#include <type_traits> #include <type_traits>
#include <utility>
#include <vector>
// flatbuffers // flatbuffers
#include "flatbuffers/util.h" #include "flatbuffers/util.h"

View File

@@ -3,12 +3,10 @@ package com.google.flatbuffers;
import java.util.Arrays; import java.util.Arrays;
/** /**
* Implements {@code ReadBuf} using an array of bytes * Implements {@code ReadBuf} using an array of bytes as a backing storage. Using array of bytes are
* as a backing storage. Using array of bytes are
* usually faster than {@code ByteBuffer}. * usually faster than {@code ByteBuffer}.
* *
* This class is not thread-safe, meaning that * <p>This class is not thread-safe, meaning that it must operate on a single thread. Operating from
* it must operate on a single thread. Operating from
* multiple thread leads into a undefined behavior * multiple thread leads into a undefined behavior
*/ */
public class ArrayReadWriteBuf implements ReadWriteBuf { public class ArrayReadWriteBuf implements ReadWriteBuf {
@@ -51,27 +49,27 @@ public class ArrayReadWriteBuf implements ReadWriteBuf {
@Override @Override
public short getShort(int index) { public short getShort(int index) {
return (short) ((buffer[index+ 1] << 8) | (buffer[index] & 0xff)); return (short) ((buffer[index + 1] << 8) | (buffer[index] & 0xff));
} }
@Override @Override
public int getInt(int index) { public int getInt(int index) {
return (((buffer[index + 3]) << 24) | return (((buffer[index + 3]) << 24)
((buffer[index + 2] & 0xff) << 16) | | ((buffer[index + 2] & 0xff) << 16)
((buffer[index + 1] & 0xff) << 8) | | ((buffer[index + 1] & 0xff) << 8)
((buffer[index] & 0xff))); | ((buffer[index] & 0xff)));
} }
@Override @Override
public long getLong(int index) { public long getLong(int index) {
return ((((long) buffer[index++] & 0xff)) | return ((((long) buffer[index++] & 0xff))
(((long) buffer[index++] & 0xff) << 8) | | (((long) buffer[index++] & 0xff) << 8)
(((long) buffer[index++] & 0xff) << 16) | | (((long) buffer[index++] & 0xff) << 16)
(((long) buffer[index++] & 0xff) << 24) | | (((long) buffer[index++] & 0xff) << 24)
(((long) buffer[index++] & 0xff) << 32) | | (((long) buffer[index++] & 0xff) << 32)
(((long) buffer[index++] & 0xff) << 40) | | (((long) buffer[index++] & 0xff) << 40)
(((long) buffer[index++] & 0xff) << 48) | | (((long) buffer[index++] & 0xff) << 48)
(((long) buffer[index]) << 56)); | (((long) buffer[index]) << 56));
} }
@Override @Override
@@ -94,7 +92,6 @@ public class ArrayReadWriteBuf implements ReadWriteBuf {
return buffer; return buffer;
} }
@Override @Override
public void putBoolean(boolean value) { public void putBoolean(boolean value) {
setBoolean(writePos, value); setBoolean(writePos, value);
@@ -104,7 +101,7 @@ public class ArrayReadWriteBuf implements ReadWriteBuf {
@Override @Override
public void put(byte[] value, int start, int length) { public void put(byte[] value, int start, int length) {
set(writePos, value, start, length); set(writePos, value, start, length);
writePos+=length; writePos += length;
} }
@Override @Override
@@ -116,36 +113,36 @@ public class ArrayReadWriteBuf implements ReadWriteBuf {
@Override @Override
public void putShort(short value) { public void putShort(short value) {
setShort(writePos, value); setShort(writePos, value);
writePos +=2; writePos += 2;
} }
@Override @Override
public void putInt(int value) { public void putInt(int value) {
setInt(writePos, value); setInt(writePos, value);
writePos +=4; writePos += 4;
} }
@Override @Override
public void putLong(long value) { public void putLong(long value) {
setLong(writePos, value); setLong(writePos, value);
writePos +=8; writePos += 8;
} }
@Override @Override
public void putFloat(float value) { public void putFloat(float value) {
setFloat(writePos, value); setFloat(writePos, value);
writePos +=4; writePos += 4;
} }
@Override @Override
public void putDouble(double value) { public void putDouble(double value) {
setDouble(writePos, value); setDouble(writePos, value);
writePos +=8; writePos += 8;
} }
@Override @Override
public void setBoolean(int index, boolean value) { public void setBoolean(int index, boolean value) {
set(index, value ? (byte)1 : (byte)0); set(index, value ? (byte) 1 : (byte) 0);
} }
@Override @Override
@@ -165,7 +162,7 @@ public class ArrayReadWriteBuf implements ReadWriteBuf {
requestCapacity(index + 2); requestCapacity(index + 2);
buffer[index++] = (byte) ((value) & 0xff); buffer[index++] = (byte) ((value) & 0xff);
buffer[index ] = (byte) ((value >> 8) & 0xff); buffer[index] = (byte) ((value >> 8) & 0xff);
} }
@Override @Override
@@ -175,7 +172,7 @@ public class ArrayReadWriteBuf implements ReadWriteBuf {
buffer[index++] = (byte) ((value) & 0xff); buffer[index++] = (byte) ((value) & 0xff);
buffer[index++] = (byte) ((value >> 8) & 0xff); buffer[index++] = (byte) ((value >> 8) & 0xff);
buffer[index++] = (byte) ((value >> 16) & 0xff); buffer[index++] = (byte) ((value >> 16) & 0xff);
buffer[index ] = (byte) ((value >> 24) & 0xff); buffer[index] = (byte) ((value >> 24) & 0xff);
} }
@Override @Override
@@ -191,7 +188,7 @@ public class ArrayReadWriteBuf implements ReadWriteBuf {
buffer[index++] = (byte) ((i) & 0xff); buffer[index++] = (byte) ((i) & 0xff);
buffer[index++] = (byte) ((i >> 8) & 0xff); buffer[index++] = (byte) ((i >> 8) & 0xff);
buffer[index++] = (byte) ((i >> 16) & 0xff); buffer[index++] = (byte) ((i >> 16) & 0xff);
buffer[index ] = (byte) ((i >> 24) & 0xff); buffer[index] = (byte) ((i >> 24) & 0xff);
} }
@Override @Override
@@ -202,7 +199,7 @@ public class ArrayReadWriteBuf implements ReadWriteBuf {
buffer[index++] = (byte) ((iValue) & 0xff); buffer[index++] = (byte) ((iValue) & 0xff);
buffer[index++] = (byte) ((iValue >> 8) & 0xff); buffer[index++] = (byte) ((iValue >> 8) & 0xff);
buffer[index++] = (byte) ((iValue >> 16) & 0xff); buffer[index++] = (byte) ((iValue >> 16) & 0xff);
buffer[index ] = (byte) ((iValue >> 24) & 0xff); buffer[index] = (byte) ((iValue >> 24) & 0xff);
} }
@Override @Override
@@ -219,7 +216,7 @@ public class ArrayReadWriteBuf implements ReadWriteBuf {
buffer[index++] = (byte) ((i) & 0xff); buffer[index++] = (byte) ((i) & 0xff);
buffer[index++] = (byte) ((i >> 8) & 0xff); buffer[index++] = (byte) ((i >> 8) & 0xff);
buffer[index++] = (byte) ((i >> 16) & 0xff); buffer[index++] = (byte) ((i >> 16) & 0xff);
buffer[index ] = (byte) ((i >> 24) & 0xff); buffer[index] = (byte) ((i >> 24) & 0xff);
} }
@Override @Override
@@ -235,7 +232,8 @@ public class ArrayReadWriteBuf implements ReadWriteBuf {
@Override @Override
public boolean requestCapacity(int capacity) { public boolean requestCapacity(int capacity) {
if (capacity < 0) { if (capacity < 0) {
throw new IllegalArgumentException("Capacity may not be negative (likely a previous int overflow)"); throw new IllegalArgumentException(
"Capacity may not be negative (likely a previous int overflow)");
} }
if (buffer.length >= capacity) { if (buffer.length >= capacity) {
return true; return true;

View File

@@ -20,16 +20,17 @@ import java.nio.ByteBuffer;
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
/** /** All vector access objects derive from this class, and add their own accessors. */
* All vector access objects derive from this class, and add their own accessors.
*/
public class BaseVector { public class BaseVector {
/** Used to hold the vector data position. */ /** Used to hold the vector data position. */
private int vector; private int vector;
/** Used to hold the vector size. */ /** Used to hold the vector size. */
private int length; private int length;
/** Used to hold the vector element size in table. */ /** Used to hold the vector element size in table. */
private int element_size; private int element_size;
/** The underlying ByteBuffer to hold the data of the vector. */ /** The underlying ByteBuffer to hold the data of the vector. */
protected ByteBuffer bb; protected ByteBuffer bb;
@@ -56,8 +57,8 @@ public class BaseVector {
* Re-init the internal state with an external buffer {@code ByteBuffer}, an offset within and * Re-init the internal state with an external buffer {@code ByteBuffer}, an offset within and
* element size. * element size.
* *
* This method exists primarily to allow recycling vector instances without risking memory leaks * <p>This method exists primarily to allow recycling vector instances without risking memory
* due to {@code ByteBuffer} references. * leaks due to {@code ByteBuffer} references.
*/ */
protected void __reset(int _vector, int _element_size, ByteBuffer _bb) { protected void __reset(int _vector, int _element_size, ByteBuffer _bb) {
bb = _bb; bb = _bb;
@@ -75,8 +76,8 @@ public class BaseVector {
/** /**
* Resets the internal state with a null {@code ByteBuffer} and a zero position. * Resets the internal state with a null {@code ByteBuffer} and a zero position.
* *
* This method exists primarily to allow recycling vector instances without risking memory leaks * <p>This method exists primarily to allow recycling vector instances without risking memory
* due to {@code ByteBuffer} references. The instance will be unusable until it is assigned * leaks due to {@code ByteBuffer} references. The instance will be unusable until it is assigned
* again to a {@code ByteBuffer}. * again to a {@code ByteBuffer}.
*/ */
public void reset() { public void reset() {

View File

@@ -17,13 +17,10 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*; import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/** import java.nio.ByteBuffer;
* Helper type for accessing vector of booleans.
*/ /** Helper type for accessing vector of booleans. */
public final class BooleanVector extends BaseVector { public final class BooleanVector extends BaseVector {
/** /**
* Assigns vector access object to vector data. * Assigns vector access object to vector data.
@@ -34,7 +31,8 @@ public final class BooleanVector extends BaseVector {
* `vector`. * `vector`.
*/ */
public BooleanVector __assign(int _vector, ByteBuffer _bb) { public BooleanVector __assign(int _vector, ByteBuffer _bb) {
__reset(_vector, Constants.SIZEOF_BYTE, _bb); return this; __reset(_vector, Constants.SIZEOF_BYTE, _bb);
return this;
} }
/** /**

View File

@@ -64,7 +64,7 @@ public class ByteBufferReadWriteBuf implements ReadWriteBuf {
@Override @Override
public void putBoolean(boolean value) { public void putBoolean(boolean value) {
buffer.put(value ? (byte)1 : (byte)0); buffer.put(value ? (byte) 1 : (byte) 0);
} }
@Override @Override
@@ -104,7 +104,7 @@ public class ByteBufferReadWriteBuf implements ReadWriteBuf {
@Override @Override
public void setBoolean(int index, boolean value) { public void setBoolean(int index, boolean value) {
set(index, value ? (byte)1 : (byte)0); set(index, value ? (byte) 1 : (byte) 0);
} }
@Override @Override
@@ -166,5 +166,4 @@ public class ByteBufferReadWriteBuf implements ReadWriteBuf {
public boolean requestCapacity(int capacity) { public boolean requestCapacity(int capacity) {
return capacity <= buffer.limit(); return capacity <= buffer.limit();
} }
} }

View File

@@ -24,9 +24,7 @@ import java.nio.ByteBuffer;
/// @addtogroup flatbuffers_java_api /// @addtogroup flatbuffers_java_api
/// @{ /// @{
/** /** Class that collects utility functions around `ByteBuffer`. */
* Class that collects utility functions around `ByteBuffer`.
*/
public class ByteBufferUtil { public class ByteBufferUtil {
/** /**
@@ -40,19 +38,17 @@ public class ByteBufferUtil {
} }
/** /**
* Create a duplicate of a size-prefixed `ByteBuffer` that has its position * Create a duplicate of a size-prefixed `ByteBuffer` that has its position advanced just past the
* advanced just past the size prefix. * size prefix.
* *
* @param bb a size-prefixed buffer * @param bb a size-prefixed buffer
* @return a new buffer on the same underlying data that has skipped the * @return a new buffer on the same underlying data that has skipped the size prefix
* size prefix
*/ */
public static ByteBuffer removeSizePrefix(ByteBuffer bb) { public static ByteBuffer removeSizePrefix(ByteBuffer bb) {
ByteBuffer s = bb.duplicate(); ByteBuffer s = bb.duplicate();
s.position(s.position() + SIZE_PREFIX_LENGTH); s.position(s.position() + SIZE_PREFIX_LENGTH);
return s; return s;
} }
} }
/// @} /// @}

View File

@@ -17,13 +17,10 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*; import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/** import java.nio.ByteBuffer;
* Helper type for accessing vector of signed or unsigned 8-bit values.
*/ /** Helper type for accessing vector of signed or unsigned 8-bit values. */
public final class ByteVector extends BaseVector { public final class ByteVector extends BaseVector {
/** /**
* Assigns vector access object to vector data. * Assigns vector access object to vector data.
@@ -34,7 +31,8 @@ public final class ByteVector extends BaseVector {
* `vector`. * `vector`.
*/ */
public ByteVector __assign(int vector, ByteBuffer bb) { public ByteVector __assign(int vector, ByteBuffer bb) {
__reset(vector, Constants.SIZEOF_BYTE, bb); return this; __reset(vector, Constants.SIZEOF_BYTE, bb);
return this;
} }
/** /**
@@ -48,8 +46,8 @@ public final class ByteVector extends BaseVector {
} }
/** /**
* Reads the byte at the given index, zero-extends it to type int, and returns the result, * Reads the byte at the given index, zero-extends it to type int, and returns the result, which
* which is therefore in the range 0 through 255. * is therefore in the range 0 through 255.
* *
* @param j The index from which the byte will be read. * @param j The index from which the byte will be read.
* @return the unsigned 8-bit at the given index. * @return the unsigned 8-bit at the given index.

View File

@@ -18,34 +18,39 @@ package com.google.flatbuffers;
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
/** /** Class that holds shared constants */
* Class that holds shared constants
*/
public class Constants { public class Constants {
// Java doesn't seem to have these. // Java doesn't seem to have these.
/** The number of bytes in an `byte`. */ /** The number of bytes in an `byte`. */
static final int SIZEOF_BYTE = 1; static final int SIZEOF_BYTE = 1;
/** The number of bytes in a `short`. */ /** The number of bytes in a `short`. */
static final int SIZEOF_SHORT = 2; static final int SIZEOF_SHORT = 2;
/** The number of bytes in an `int`. */ /** The number of bytes in an `int`. */
static final int SIZEOF_INT = 4; static final int SIZEOF_INT = 4;
/** The number of bytes in an `float`. */ /** The number of bytes in an `float`. */
static final int SIZEOF_FLOAT = 4; static final int SIZEOF_FLOAT = 4;
/** The number of bytes in an `long`. */ /** The number of bytes in an `long`. */
static final int SIZEOF_LONG = 8; static final int SIZEOF_LONG = 8;
/** The number of bytes in an `double`. */ /** The number of bytes in an `double`. */
static final int SIZEOF_DOUBLE = 8; static final int SIZEOF_DOUBLE = 8;
/** The number of bytes in a file identifier. */ /** The number of bytes in a file identifier. */
static final int FILE_IDENTIFIER_LENGTH = 4; static final int FILE_IDENTIFIER_LENGTH = 4;
/** The number of bytes in a size prefix. */ /** The number of bytes in a size prefix. */
public static final int SIZE_PREFIX_LENGTH = 4; public static final int SIZE_PREFIX_LENGTH = 4;
/** A version identifier to force a compile error if someone
accidentally tries to build generated code with a runtime of /**
two mismatched version. Versions need to always match, as * A version identifier to force a compile error if someone accidentally tries to build generated
the runtime and generated code are modified in sync. * code with a runtime of two mismatched version. Versions need to always match, as the runtime
Changes to the Java implementation need to be sure to change * and generated code are modified in sync. Changes to the Java implementation need to be sure to
the version here and in the code generator on every possible * change the version here and in the code generator on every possible incompatible change
incompatible change */ */
public static void FLATBUFFERS_25_2_10() {} public static void FLATBUFFERS_25_2_10() {}
} }

View File

@@ -17,13 +17,10 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*; import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/** import java.nio.ByteBuffer;
* Helper type for accessing vector of double values.
*/ /** Helper type for accessing vector of double values. */
public final class DoubleVector extends BaseVector { public final class DoubleVector extends BaseVector {
/** /**
* Assigns vector access object to vector data. * Assigns vector access object to vector data.
@@ -34,7 +31,8 @@ public final class DoubleVector extends BaseVector {
* `vector`. * `vector`.
*/ */
public DoubleVector __assign(int _vector, ByteBuffer _bb) { public DoubleVector __assign(int _vector, ByteBuffer _bb) {
__reset(_vector, Constants.SIZEOF_DOUBLE, _bb); return this; __reset(_vector, Constants.SIZEOF_DOUBLE, _bb);
return this;
} }
/** /**

View File

@@ -24,15 +24,14 @@ import java.nio.*;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.lang.Integer;
/// @file /// @file
/// @addtogroup flatbuffers_java_api /// @addtogroup flatbuffers_java_api
/// @{ /// @{
/** /**
* Class that helps you build a FlatBuffer. See the section * Class that helps you build a FlatBuffer. See the section "Use in Java/C#" in the main FlatBuffers
* "Use in Java/C#" in the main FlatBuffers documentation. * documentation.
*/ */
public class FlatBufferBuilder { public class FlatBufferBuilder {
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
@@ -51,19 +50,16 @@ public class FlatBufferBuilder {
ByteBufferFactory bb_factory; // Factory for allocating the internal buffer ByteBufferFactory bb_factory; // Factory for allocating the internal buffer
final Utf8 utf8; // UTF-8 encoder to use final Utf8 utf8; // UTF-8 encoder to use
Map<String, Integer> string_pool; // map used to cache shared strings. Map<String, Integer> string_pool; // map used to cache shared strings.
/// @endcond /// @endcond
/** /**
* Maximum size of buffer to allocate. If we're allocating arrays on the heap, * Maximum size of buffer to allocate. If we're allocating arrays on the heap, the header size of
* the header size of the array counts towards its maximum size. * the array counts towards its maximum size.
*/ */
private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
/** /** Default buffer size that is allocated if an initial size is not given, or is non positive. */
* Default buffer size that is allocated if an initial size is not given, or is
* non positive.
*/
private static final int DEFAULT_BUFFER_SIZE = 1024; private static final int DEFAULT_BUFFER_SIZE = 1024;
/** /**
@@ -84,8 +80,8 @@ public class FlatBufferBuilder {
* @param existing_bb The byte buffer to reuse. * @param existing_bb The byte buffer to reuse.
* @param utf8 The Utf8 codec * @param utf8 The Utf8 codec
*/ */
public FlatBufferBuilder(int initial_size, ByteBufferFactory bb_factory, public FlatBufferBuilder(
ByteBuffer existing_bb, Utf8 utf8) { int initial_size, ByteBufferFactory bb_factory, ByteBuffer existing_bb, Utf8 utf8) {
if (initial_size <= 0) { if (initial_size <= 0) {
initial_size = DEFAULT_BUFFER_SIZE; initial_size = DEFAULT_BUFFER_SIZE;
} }
@@ -110,30 +106,28 @@ public class FlatBufferBuilder {
this(initial_size, HeapByteBufferFactory.INSTANCE, null, Utf8.getDefault()); this(initial_size, HeapByteBufferFactory.INSTANCE, null, Utf8.getDefault());
} }
/** /** Start with a buffer of 1KiB, then grow as required. */
* Start with a buffer of 1KiB, then grow as required.
*/
public FlatBufferBuilder() { public FlatBufferBuilder() {
this(DEFAULT_BUFFER_SIZE); this(DEFAULT_BUFFER_SIZE);
} }
/** /**
* Alternative constructor allowing reuse of {@link ByteBuffer}s. The builder * Alternative constructor allowing reuse of {@link ByteBuffer}s. The builder can still grow the
* can still grow the buffer as necessary. User classes should make sure * buffer as necessary. User classes should make sure to call {@link #dataBuffer()} to obtain the
* to call {@link #dataBuffer()} to obtain the resulting encoded message. * resulting encoded message.
* *
* @param existing_bb The byte buffer to reuse. * @param existing_bb The byte buffer to reuse.
* @param bb_factory The factory to be used for allocating a new internal buffer if * @param bb_factory The factory to be used for allocating a new internal buffer if the existing
* the existing buffer needs to grow * buffer needs to grow
*/ */
public FlatBufferBuilder(ByteBuffer existing_bb, ByteBufferFactory bb_factory) { public FlatBufferBuilder(ByteBuffer existing_bb, ByteBufferFactory bb_factory) {
this(existing_bb.capacity(), bb_factory, existing_bb, Utf8.getDefault()); this(existing_bb.capacity(), bb_factory, existing_bb, Utf8.getDefault());
} }
/** /**
* Alternative constructor allowing reuse of {@link ByteBuffer}s. The builder * Alternative constructor allowing reuse of {@link ByteBuffer}s. The builder can still grow the
* can still grow the buffer as necessary. User classes should make sure * buffer as necessary. User classes should make sure to call {@link #dataBuffer()} to obtain the
* to call {@link #dataBuffer()} to obtain the resulting encoded message. * resulting encoded message.
* *
* @param existing_bb The byte buffer to reuse. * @param existing_bb The byte buffer to reuse.
*/ */
@@ -142,16 +136,16 @@ public class FlatBufferBuilder {
} }
/** /**
* Alternative initializer that allows reusing this object on an existing * Alternative initializer that allows reusing this object on an existing `ByteBuffer`. This
* `ByteBuffer`. This method resets the builder's internal state, but keeps * method resets the builder's internal state, but keeps objects that have been allocated for
* objects that have been allocated for temporary storage. * temporary storage.
* *
* @param existing_bb The byte buffer to reuse. * @param existing_bb The byte buffer to reuse.
* @param bb_factory The factory to be used for allocating a new internal buffer if * @param bb_factory The factory to be used for allocating a new internal buffer if the existing
* the existing buffer needs to grow * buffer needs to grow
* @return Returns `this`. * @return Returns `this`.
*/ */
public FlatBufferBuilder init(ByteBuffer existing_bb, ByteBufferFactory bb_factory){ public FlatBufferBuilder init(ByteBuffer existing_bb, ByteBufferFactory bb_factory) {
this.bb_factory = bb_factory; this.bb_factory = bb_factory;
bb = existing_bb; bb = existing_bb;
bb.clear(); bb.clear();
@@ -171,19 +165,19 @@ public class FlatBufferBuilder {
} }
/** /**
* An interface that provides a user of the FlatBufferBuilder class the ability to specify * An interface that provides a user of the FlatBufferBuilder class the ability to specify the
* the method in which the internal buffer gets allocated. This allows for alternatives * method in which the internal buffer gets allocated. This allows for alternatives to the default
* to the default behavior, which is to allocate memory for a new byte-array * behavior, which is to allocate memory for a new byte-array backed `ByteBuffer` array inside the
* backed `ByteBuffer` array inside the JVM. * JVM.
* *
* The FlatBufferBuilder class contains the HeapByteBufferFactory class to * <p>The FlatBufferBuilder class contains the HeapByteBufferFactory class to preserve the default
* preserve the default behavior in the event that the user does not provide * behavior in the event that the user does not provide their own implementation of this
* their own implementation of this interface. * interface.
*/ */
public static abstract class ByteBufferFactory { public abstract static class ByteBufferFactory {
/** /**
* Create a `ByteBuffer` with a given capacity. * Create a `ByteBuffer` with a given capacity. The returned ByteBuf must have a
* The returned ByteBuf must have a ByteOrder.LITTLE_ENDIAN ByteOrder. * ByteOrder.LITTLE_ENDIAN ByteOrder.
* *
* @param capacity The size of the `ByteBuffer` to allocate. * @param capacity The size of the `ByteBuffer` to allocate.
* @return Returns the new `ByteBuffer` that was allocated. * @return Returns the new `ByteBuffer` that was allocated.
@@ -191,23 +185,20 @@ public class FlatBufferBuilder {
public abstract ByteBuffer newByteBuffer(int capacity); public abstract ByteBuffer newByteBuffer(int capacity);
/** /**
* Release a ByteBuffer. Current {@link FlatBufferBuilder} * Release a ByteBuffer. Current {@link FlatBufferBuilder} released any reference to it, so it
* released any reference to it, so it is safe to dispose the buffer * is safe to dispose the buffer or return it to a pool. It is not guaranteed that the buffer
* or return it to a pool. * has been created with {@link #newByteBuffer(int) }.
* It is not guaranteed that the buffer has been created
* with {@link #newByteBuffer(int) }.
* *
* @param bb the buffer to release * @param bb the buffer to release
*/ */
public void releaseByteBuffer(ByteBuffer bb) { public void releaseByteBuffer(ByteBuffer bb) {}
}
} }
/** /**
* An implementation of the ByteBufferFactory interface that is used when * An implementation of the ByteBufferFactory interface that is used when one is not provided by
* one is not provided by the user. * the user.
* *
* Allocate memory for a new byte-array backed `ByteBuffer` array inside the JVM. * <p>Allocate memory for a new byte-array backed `ByteBuffer` array inside the JVM.
*/ */
public static final class HeapByteBufferFactory extends ByteBufferFactory { public static final class HeapByteBufferFactory extends ByteBufferFactory {
@@ -230,14 +221,12 @@ public class FlatBufferBuilder {
return table.__offset(offset) != 0; return table.__offset(offset) != 0;
} }
/** /** Reset the FlatBufferBuilder by purging all data that it holds. */
* Reset the FlatBufferBuilder by purging all data that it holds. public void clear() {
*/
public void clear(){
space = bb.capacity(); space = bb.capacity();
bb.clear(); bb.clear();
minalign = 1; minalign = 1;
while(vtable_in_use > 0) vtable[--vtable_in_use] = 0; while (vtable_in_use > 0) vtable[--vtable_in_use] = 0;
vtable_in_use = 0; vtable_in_use = 0;
nested = false; nested = false;
finished = false; finished = false;
@@ -250,13 +239,13 @@ public class FlatBufferBuilder {
} }
/** /**
* Doubles the size of the backing {@link ByteBuffer} and copies the old data towards the * Doubles the size of the backing {@link ByteBuffer} and copies the old data towards the end of
* end of the new buffer (since we build the buffer backwards). * the new buffer (since we build the buffer backwards).
* *
* @param bb The current buffer with the existing data. * @param bb The current buffer with the existing data.
* @param bb_factory The factory to be used for allocating the new internal buffer * @param bb_factory The factory to be used for allocating the new internal buffer
* @return A new byte buffer with the old data copied copied to it. The data is * @return A new byte buffer with the old data copied copied to it. The data is located at the end
* located at the end of the buffer. * of the buffer.
*/ */
static ByteBuffer growByteBuffer(ByteBuffer bb, ByteBufferFactory bb_factory) { static ByteBuffer growByteBuffer(ByteBuffer bb, ByteBufferFactory bb_factory) {
int old_buf_size = bb.capacity(); int old_buf_size = bb.capacity();
@@ -265,8 +254,7 @@ public class FlatBufferBuilder {
if (old_buf_size == 0) { if (old_buf_size == 0) {
new_buf_size = DEFAULT_BUFFER_SIZE; new_buf_size = DEFAULT_BUFFER_SIZE;
} } else {
else {
if (old_buf_size == MAX_BUFFER_SIZE) { // Ensure we don't grow beyond what fits in an int. if (old_buf_size == MAX_BUFFER_SIZE) { // Ensure we don't grow beyond what fits in an int.
throw new AssertionError("FlatBuffers: cannot grow buffer beyond 2 gigabytes."); throw new AssertionError("FlatBuffers: cannot grow buffer beyond 2 gigabytes.");
} }
@@ -296,15 +284,14 @@ public class FlatBufferBuilder {
* @param byte_size Number of bytes to add. * @param byte_size Number of bytes to add.
*/ */
public void pad(int byte_size) { public void pad(int byte_size) {
for (int i = 0; i < byte_size; i++) bb.put(--space, (byte)0); for (int i = 0; i < byte_size; i++) bb.put(--space, (byte) 0);
} }
/** /**
* Prepare to write an element of `size` after `additional_bytes` * Prepare to write an element of `size` after `additional_bytes` have been written, e.g. if you
* have been written, e.g. if you write a string, you need to align such * write a string, you need to align such the int length field is aligned to {@link
* the int length field is aligned to {@link com.google.flatbuffers.Constants#SIZEOF_INT}, and * com.google.flatbuffers.Constants#SIZEOF_INT}, and the string data follows it directly. If all
* the string data follows it directly. If all you need to do is alignment, `additional_bytes` * you need to do is alignment, `additional_bytes` will be 0.
* will be 0.
* *
* @param size This is the of the new element to write. * @param size This is the of the new element to write.
* @param additional_bytes The padding size. * @param additional_bytes The padding size.
@@ -329,60 +316,75 @@ public class FlatBufferBuilder {
} }
/** /**
* Add a `boolean` to the buffer, backwards from the current location. Doesn't align nor * Add a `boolean` to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A `boolean` to put into the buffer. * @param x A `boolean` to put into the buffer.
*/ */
public void putBoolean(boolean x) { bb.put (space -= Constants.SIZEOF_BYTE, (byte)(x ? 1 : 0)); } public void putBoolean(boolean x) {
bb.put(space -= Constants.SIZEOF_BYTE, (byte) (x ? 1 : 0));
}
/** /**
* Add a `byte` to the buffer, backwards from the current location. Doesn't align nor * Add a `byte` to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A `byte` to put into the buffer. * @param x A `byte` to put into the buffer.
*/ */
public void putByte (byte x) { bb.put (space -= Constants.SIZEOF_BYTE, x); } public void putByte(byte x) {
bb.put(space -= Constants.SIZEOF_BYTE, x);
}
/** /**
* Add a `short` to the buffer, backwards from the current location. Doesn't align nor * Add a `short` to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A `short` to put into the buffer. * @param x A `short` to put into the buffer.
*/ */
public void putShort (short x) { bb.putShort (space -= Constants.SIZEOF_SHORT, x); } public void putShort(short x) {
bb.putShort(space -= Constants.SIZEOF_SHORT, x);
}
/** /**
* Add an `int` to the buffer, backwards from the current location. Doesn't align nor * Add an `int` to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x An `int` to put into the buffer. * @param x An `int` to put into the buffer.
*/ */
public void putInt (int x) { bb.putInt (space -= Constants.SIZEOF_INT, x); } public void putInt(int x) {
bb.putInt(space -= Constants.SIZEOF_INT, x);
}
/** /**
* Add a `long` to the buffer, backwards from the current location. Doesn't align nor * Add a `long` to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A `long` to put into the buffer. * @param x A `long` to put into the buffer.
*/ */
public void putLong (long x) { bb.putLong (space -= Constants.SIZEOF_LONG, x); } public void putLong(long x) {
bb.putLong(space -= Constants.SIZEOF_LONG, x);
}
/** /**
* Add a `float` to the buffer, backwards from the current location. Doesn't align nor * Add a `float` to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A `float` to put into the buffer. * @param x A `float` to put into the buffer.
*/ */
public void putFloat (float x) { bb.putFloat (space -= Constants.SIZEOF_FLOAT, x); } public void putFloat(float x) {
bb.putFloat(space -= Constants.SIZEOF_FLOAT, x);
}
/** /**
* Add a `double` to the buffer, backwards from the current location. Doesn't align nor * Add a `double` to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A `double` to put into the buffer. * @param x A `double` to put into the buffer.
*/ */
public void putDouble (double x) { bb.putDouble(space -= Constants.SIZEOF_DOUBLE, x); } public void putDouble(double x) {
bb.putDouble(space -= Constants.SIZEOF_DOUBLE, x);
}
/// @endcond /// @endcond
/** /**
@@ -390,49 +392,70 @@ public class FlatBufferBuilder {
* *
* @param x A `boolean` to put into the buffer. * @param x A `boolean` to put into the buffer.
*/ */
public void addBoolean(boolean x) { prep(Constants.SIZEOF_BYTE, 0); putBoolean(x); } public void addBoolean(boolean x) {
prep(Constants.SIZEOF_BYTE, 0);
putBoolean(x);
}
/** /**
* Add a `byte` to the buffer, properly aligned, and grows the buffer (if necessary). * Add a `byte` to the buffer, properly aligned, and grows the buffer (if necessary).
* *
* @param x A `byte` to put into the buffer. * @param x A `byte` to put into the buffer.
*/ */
public void addByte (byte x) { prep(Constants.SIZEOF_BYTE, 0); putByte (x); } public void addByte(byte x) {
prep(Constants.SIZEOF_BYTE, 0);
putByte(x);
}
/** /**
* Add a `short` to the buffer, properly aligned, and grows the buffer (if necessary). * Add a `short` to the buffer, properly aligned, and grows the buffer (if necessary).
* *
* @param x A `short` to put into the buffer. * @param x A `short` to put into the buffer.
*/ */
public void addShort (short x) { prep(Constants.SIZEOF_SHORT, 0); putShort (x); } public void addShort(short x) {
prep(Constants.SIZEOF_SHORT, 0);
putShort(x);
}
/** /**
* Add an `int` to the buffer, properly aligned, and grows the buffer (if necessary). * Add an `int` to the buffer, properly aligned, and grows the buffer (if necessary).
* *
* @param x An `int` to put into the buffer. * @param x An `int` to put into the buffer.
*/ */
public void addInt (int x) { prep(Constants.SIZEOF_INT, 0); putInt (x); } public void addInt(int x) {
prep(Constants.SIZEOF_INT, 0);
putInt(x);
}
/** /**
* Add a `long` to the buffer, properly aligned, and grows the buffer (if necessary). * Add a `long` to the buffer, properly aligned, and grows the buffer (if necessary).
* *
* @param x A `long` to put into the buffer. * @param x A `long` to put into the buffer.
*/ */
public void addLong (long x) { prep(Constants.SIZEOF_LONG, 0); putLong (x); } public void addLong(long x) {
prep(Constants.SIZEOF_LONG, 0);
putLong(x);
}
/** /**
* Add a `float` to the buffer, properly aligned, and grows the buffer (if necessary). * Add a `float` to the buffer, properly aligned, and grows the buffer (if necessary).
* *
* @param x A `float` to put into the buffer. * @param x A `float` to put into the buffer.
*/ */
public void addFloat (float x) { prep(Constants.SIZEOF_FLOAT, 0); putFloat (x); } public void addFloat(float x) {
prep(Constants.SIZEOF_FLOAT, 0);
putFloat(x);
}
/** /**
* Add a `double` to the buffer, properly aligned, and grows the buffer (if necessary). * Add a `double` to the buffer, properly aligned, and grows the buffer (if necessary).
* *
* @param x A `double` to put into the buffer. * @param x A `double` to put into the buffer.
*/ */
public void addDouble (double x) { prep(Constants.SIZEOF_DOUBLE, 0); putDouble (x); } public void addDouble(double x) {
prep(Constants.SIZEOF_DOUBLE, 0);
putDouble(x);
}
/** /**
* Adds on offset, relative to where it will be written. * Adds on offset, relative to where it will be written.
@@ -448,19 +471,20 @@ public class FlatBufferBuilder {
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
/** /**
* Start a new array/vector of objects. Users usually will not call * Start a new array/vector of objects. Users usually will not call this directly. The
* this directly. The `FlatBuffers` compiler will create a start/end * `FlatBuffers` compiler will create a start/end method for vector types in generated code.
* method for vector types in generated code. *
* <p> * <p>The expected sequence of calls is:
* The expected sequence of calls is: *
* <ol> * <ol>
* <li>Start the array using this method.</li> * <li>Start the array using this method.
* <li>Call {@link #addOffset(int)} `num_elems` number of times to set * <li>Call {@link #addOffset(int)} `num_elems` number of times to set the offset of each
* the offset of each element in the array.</li> * element in the array.
* <li>Call {@link #endVector()} to retrieve the offset of the array.</li> * <li>Call {@link #endVector()} to retrieve the offset of the array.
* </ol> * </ol>
* <p> *
* For example, to create an array of strings, do: * <p>For example, to create an array of strings, do:
*
* <pre>{@code * <pre>{@code
* // Need 10 strings * // Need 10 strings
* FlatBufferBuilder builder = new FlatBufferBuilder(existingBuffer); * FlatBufferBuilder builder = new FlatBufferBuilder(existingBuffer);
@@ -498,25 +522,24 @@ public class FlatBufferBuilder {
} }
/** /**
* Finish off the creation of an array and all its elements. The array * Finish off the creation of an array and all its elements. The array must be created with {@link
* must be created with {@link #startVector(int, int, int)}. * #startVector(int, int, int)}.
* *
* @return The offset at which the newly created array starts. * @return The offset at which the newly created array starts.
* @see #startVector(int, int, int) * @see #startVector(int, int, int)
*/ */
public int endVector() { public int endVector() {
if (!nested) if (!nested) throw new AssertionError("FlatBuffers: endVector called without startVector");
throw new AssertionError("FlatBuffers: endVector called without startVector");
nested = false; nested = false;
putInt(vector_num_elems); putInt(vector_num_elems);
return offset(); return offset();
} }
/// @endcond /// @endcond
/** /**
* Create a new array/vector and return a ByteBuffer to be filled later. * Create a new array/vector and return a ByteBuffer to be filled later. Call {@link #endVector}
* Call {@link #endVector} after this method to get an offset to the beginning * after this method to get an offset to the beginning of vector.
* of vector.
* *
* @param elem_size the size of each element in bytes. * @param elem_size the size of each element in bytes.
* @param num_elems number of elements in the vector. * @param num_elems number of elements in the vector.
@@ -544,7 +567,7 @@ public class FlatBufferBuilder {
public int createVectorOfTables(int[] offsets) { public int createVectorOfTables(int[] offsets) {
notNested(); notNested();
startVector(Constants.SIZEOF_INT, offsets.length, Constants.SIZEOF_INT); startVector(Constants.SIZEOF_INT, offsets.length, Constants.SIZEOF_INT);
for(int i = offsets.length - 1; i >= 0; i--) addOffset(offsets[i]); for (int i = offsets.length - 1; i >= 0; i--) addOffset(offsets[i]);
return endVector(); return endVector();
} }
@@ -561,13 +584,12 @@ public class FlatBufferBuilder {
} }
/** /**
* Encode the String `s` in the buffer using UTF-8. If a String with * Encode the String `s` in the buffer using UTF-8. If a String with this exact contents has
* this exact contents has already been serialized using this method, * already been serialized using this method, instead simply returns the offset of the existing
* instead simply returns the offset of the existing String. * String.
* *
* Usage of the method will incur into additional allocations, * <p>Usage of the method will incur into additional allocations, so it is advisable to use it
* so it is advisable to use it only when it is known upfront that * only when it is known upfront that your message will have several repeated strings.
* your message will have several repeated strings.
* *
* @param s The String to encode. * @param s The String to encode.
* @return The offset in the buffer where the encoded String starts. * @return The offset in the buffer where the encoded String starts.
@@ -579,12 +601,11 @@ public class FlatBufferBuilder {
int offset = createString(s); int offset = createString(s);
string_pool.put(s, offset); string_pool.put(s, offset);
return offset; return offset;
} }
Integer offset = string_pool.get(s); Integer offset = string_pool.get(s);
if(offset == null) { if (offset == null) {
offset = createString(s); offset = createString(s);
string_pool.put(s, offset); string_pool.put(s, offset);
} }
@@ -592,15 +613,15 @@ public class FlatBufferBuilder {
} }
/** /**
* Encode the string `s` in the buffer using UTF-8. If {@code s} is * Encode the string `s` in the buffer using UTF-8. If {@code s} is already a {@link CharBuffer},
* already a {@link CharBuffer}, this method is allocation free. * this method is allocation free.
* *
* @param s The string to encode. * @param s The string to encode.
* @return The offset in the buffer where the encoded string starts. * @return The offset in the buffer where the encoded string starts.
*/ */
public int createString(CharSequence s) { public int createString(CharSequence s) {
int length = utf8.encodedLength(s); int length = utf8.encodedLength(s);
addByte((byte)0); addByte((byte) 0);
startVector(1, length, 1); startVector(1, length, 1);
bb.position(space -= length); bb.position(space -= length);
utf8.encodeUtf8(s, bb); utf8.encodeUtf8(s, bb);
@@ -615,7 +636,7 @@ public class FlatBufferBuilder {
*/ */
public int createString(ByteBuffer s) { public int createString(ByteBuffer s) {
int length = s.remaining(); int length = s.remaining();
addByte((byte)0); addByte((byte) 0);
startVector(1, length, 1); startVector(1, length, 1);
bb.position(space -= length); bb.position(space -= length);
bb.put(s); bb.put(s);
@@ -654,7 +675,7 @@ public class FlatBufferBuilder {
/** /**
* Create a byte array in the buffer. * Create a byte array in the buffer.
* *
* The source {@link ByteBuffer} position is advanced by {@link ByteBuffer#remaining()} places * <p>The source {@link ByteBuffer} position is advanced by {@link ByteBuffer#remaining()} places
* after this call. * after this call.
* *
* @param byteBuffer A source {@link ByteBuffer} with data. * @param byteBuffer A source {@link ByteBuffer} with data.
@@ -669,44 +690,37 @@ public class FlatBufferBuilder {
} }
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
/** /** Should not be accessing the final buffer before it is finished. */
* Should not be accessing the final buffer before it is finished.
*/
public void finished() { public void finished() {
if (!finished) if (!finished)
throw new AssertionError( throw new AssertionError(
"FlatBuffers: you can only access the serialized buffer after it has been" + "FlatBuffers: you can only access the serialized buffer after it has been"
" finished by FlatBufferBuilder.finish()."); + " finished by FlatBufferBuilder.finish().");
} }
/** /**
* Should not be creating any other object, string or vector * Should not be creating any other object, string or vector while an object is being constructed.
* while an object is being constructed.
*/ */
public void notNested() { public void notNested() {
if (nested) if (nested) throw new AssertionError("FlatBuffers: object serialization must not be nested.");
throw new AssertionError("FlatBuffers: object serialization must not be nested.");
} }
/** /**
* Structures are always stored inline, they need to be created right * Structures are always stored inline, they need to be created right where they're used. You'll
* where they're used. You'll get this assertion failure if you * get this assertion failure if you created it elsewhere.
* created it elsewhere.
* *
* @param obj The offset of the created object. * @param obj The offset of the created object.
*/ */
public void Nested(int obj) { public void Nested(int obj) {
if (obj != offset()) if (obj != offset()) throw new AssertionError("FlatBuffers: struct must be serialized inline.");
throw new AssertionError("FlatBuffers: struct must be serialized inline.");
} }
/** /**
* Start encoding a new object in the buffer. Users will not usually need to * Start encoding a new object in the buffer. Users will not usually need to call this directly.
* call this directly. The `FlatBuffers` compiler will generate helper methods * The `FlatBuffers` compiler will generate helper methods that call this method internally.
* that call this method internally. *
* <p> * <p>For example, using the "Monster" code found on the "landing page". An object of type
* For example, using the "Monster" code found on the "landing page". An * `Monster` can be created using the following code:
* object of type `Monster` can be created using the following code:
* *
* <pre>{@code * <pre>{@code
* int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] { * int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] {
@@ -726,15 +740,16 @@ public class FlatBufferBuilder {
* Monster.addTestarrayofstring(fbb, testArrayOfString); * Monster.addTestarrayofstring(fbb, testArrayOfString);
* int mon = Monster.endMonster(fbb); * int mon = Monster.endMonster(fbb);
* }</pre> * }</pre>
* <p> *
* Here: * <p>Here:
*
* <ul> * <ul>
* <li>The call to `Monster#startMonster(FlatBufferBuilder)` will call this * <li>The call to `Monster#startMonster(FlatBufferBuilder)` will call this method with the
* method with the right number of fields set.</li> * right number of fields set.
* <li>`Monster#endMonster(FlatBufferBuilder)` will ensure {@link #endObject()} is called.</li> * <li>`Monster#endMonster(FlatBufferBuilder)` will ensure {@link #endObject()} is called.
* </ul> * </ul>
* <p> *
* It's not recommended to call this method directly. If it's called manually, you must ensure * <p>It's not recommended to call this method directly. If it's called manually, you must ensure
* to audit all calls to it whenever fields are added or removed from your schema. This is * to audit all calls to it whenever fields are added or removed from your schema. This is
* automatically done by the code generated by the `FlatBuffers` compiler. * automatically done by the code generated by the `FlatBuffers` compiler.
* *
@@ -758,7 +773,12 @@ public class FlatBufferBuilder {
* default value, it can be skipped. * default value, it can be skipped.
* @param d A `boolean` default value to compare against when `force_defaults` is `false`. * @param d A `boolean` default value to compare against when `force_defaults` is `false`.
*/ */
public void addBoolean(int o, boolean x, boolean d) { if(force_defaults || x != d) { addBoolean(x); slot(o); } } public void addBoolean(int o, boolean x, boolean d) {
if (force_defaults || x != d) {
addBoolean(x);
slot(o);
}
}
/** /**
* Add a `byte` to a table at `o` into its vtable, with value `x` and default `d`. * Add a `byte` to a table at `o` into its vtable, with value `x` and default `d`.
@@ -769,7 +789,12 @@ public class FlatBufferBuilder {
* default value, it can be skipped. * default value, it can be skipped.
* @param d A `byte` default value to compare against when `force_defaults` is `false`. * @param d A `byte` default value to compare against when `force_defaults` is `false`.
*/ */
public void addByte (int o, byte x, int d) { if(force_defaults || x != d) { addByte (x); slot(o); } } public void addByte(int o, byte x, int d) {
if (force_defaults || x != d) {
addByte(x);
slot(o);
}
}
/** /**
* Add a `short` to a table at `o` into its vtable, with value `x` and default `d`. * Add a `short` to a table at `o` into its vtable, with value `x` and default `d`.
@@ -780,7 +805,12 @@ public class FlatBufferBuilder {
* default value, it can be skipped. * default value, it can be skipped.
* @param d A `short` default value to compare against when `force_defaults` is `false`. * @param d A `short` default value to compare against when `force_defaults` is `false`.
*/ */
public void addShort (int o, short x, int d) { if(force_defaults || x != d) { addShort (x); slot(o); } } public void addShort(int o, short x, int d) {
if (force_defaults || x != d) {
addShort(x);
slot(o);
}
}
/** /**
* Add an `int` to a table at `o` into its vtable, with value `x` and default `d`. * Add an `int` to a table at `o` into its vtable, with value `x` and default `d`.
@@ -791,7 +821,12 @@ public class FlatBufferBuilder {
* default value, it can be skipped. * default value, it can be skipped.
* @param d An `int` default value to compare against when `force_defaults` is `false`. * @param d An `int` default value to compare against when `force_defaults` is `false`.
*/ */
public void addInt (int o, int x, int d) { if(force_defaults || x != d) { addInt (x); slot(o); } } public void addInt(int o, int x, int d) {
if (force_defaults || x != d) {
addInt(x);
slot(o);
}
}
/** /**
* Add a `long` to a table at `o` into its vtable, with value `x` and default `d`. * Add a `long` to a table at `o` into its vtable, with value `x` and default `d`.
@@ -802,7 +837,12 @@ public class FlatBufferBuilder {
* default value, it can be skipped. * default value, it can be skipped.
* @param d A `long` default value to compare against when `force_defaults` is `false`. * @param d A `long` default value to compare against when `force_defaults` is `false`.
*/ */
public void addLong (int o, long x, long d) { if(force_defaults || x != d) { addLong (x); slot(o); } } public void addLong(int o, long x, long d) {
if (force_defaults || x != d) {
addLong(x);
slot(o);
}
}
/** /**
* Add a `float` to a table at `o` into its vtable, with value `x` and default `d`. * Add a `float` to a table at `o` into its vtable, with value `x` and default `d`.
@@ -813,7 +853,12 @@ public class FlatBufferBuilder {
* default value, it can be skipped. * default value, it can be skipped.
* @param d A `float` default value to compare against when `force_defaults` is `false`. * @param d A `float` default value to compare against when `force_defaults` is `false`.
*/ */
public void addFloat (int o, float x, double d) { if(force_defaults || x != d) { addFloat (x); slot(o); } } public void addFloat(int o, float x, double d) {
if (force_defaults || x != d) {
addFloat(x);
slot(o);
}
}
/** /**
* Add a `double` to a table at `o` into its vtable, with value `x` and default `d`. * Add a `double` to a table at `o` into its vtable, with value `x` and default `d`.
@@ -824,7 +869,12 @@ public class FlatBufferBuilder {
* default value, it can be skipped. * default value, it can be skipped.
* @param d A `double` default value to compare against when `force_defaults` is `false`. * @param d A `double` default value to compare against when `force_defaults` is `false`.
*/ */
public void addDouble (int o, double x, double d) { if(force_defaults || x != d) { addDouble (x); slot(o); } } public void addDouble(int o, double x, double d) {
if (force_defaults || x != d) {
addDouble(x);
slot(o);
}
}
/** /**
* Add an `offset` to a table at `o` into its vtable, with value `x` and default `d`. * Add an `offset` to a table at `o` into its vtable, with value `x` and default `d`.
@@ -835,7 +885,12 @@ public class FlatBufferBuilder {
* default value, it can be skipped. * default value, it can be skipped.
* @param d An `offset` default value to compare against when `force_defaults` is `false`. * @param d An `offset` default value to compare against when `force_defaults` is `false`.
*/ */
public void addOffset (int o, int x, int d) { if(force_defaults || x != d) { addOffset (x); slot(o); } } public void addOffset(int o, int x, int d) {
if (force_defaults || x != d) {
addOffset(x);
slot(o);
}
}
/** /**
* Add a struct to the table. Structs are stored inline, so nothing additional is being added. * Add a struct to the table. Structs are stored inline, so nothing additional is being added.
@@ -845,7 +900,7 @@ public class FlatBufferBuilder {
* @param d The default value is always `0`. * @param d The default value is always `0`.
*/ */
public void addStruct(int voffset, int x, int d) { public void addStruct(int voffset, int x, int d) {
if(x != d) { if (x != d) {
Nested(x); Nested(x);
slot(voffset); slot(voffset);
} }
@@ -854,8 +909,7 @@ public class FlatBufferBuilder {
/** /**
* Set the current vtable at `voffset` to the current location in the buffer. * Set the current vtable at `voffset` to the current location in the buffer.
* *
* @param voffset The index into the vtable to store the offset relative to the end of the * @param voffset The index into the vtable to store the offset relative to the end of the buffer.
* buffer.
*/ */
public void slot(int voffset) { public void slot(int voffset) {
vtable[voffset] = offset(); vtable[voffset] = offset();
@@ -877,15 +931,15 @@ public class FlatBufferBuilder {
// Trim trailing zeroes. // Trim trailing zeroes.
for (; i >= 0 && vtable[i] == 0; i--) {} for (; i >= 0 && vtable[i] == 0; i--) {}
int trimmed_size = i + 1; int trimmed_size = i + 1;
for (; i >= 0 ; i--) { for (; i >= 0; i--) {
// Offset relative to the start of the table. // Offset relative to the start of the table.
short off = (short)(vtable[i] != 0 ? vtableloc - vtable[i] : 0); short off = (short) (vtable[i] != 0 ? vtableloc - vtable[i] : 0);
addShort(off); addShort(off);
} }
final int standard_fields = 2; // The fields below: final int standard_fields = 2; // The fields below:
addShort((short)(vtableloc - object_start)); addShort((short) (vtableloc - object_start));
addShort((short)((trimmed_size + standard_fields) * SIZEOF_SHORT)); addShort((short) ((trimmed_size + standard_fields) * SIZEOF_SHORT));
// Search for an existing vtable that matches the current one. // Search for an existing vtable that matches the current one.
int existing_vtable = 0; int existing_vtable = 0;
@@ -925,8 +979,7 @@ public class FlatBufferBuilder {
} }
/** /**
* Checks that a required field has been set in a given table that has * Checks that a required field has been set in a given table that has just been constructed.
* just been constructed.
* *
* @param table The offset to the start of the table from the `ByteBuffer` capacity. * @param table The offset to the start of the table from the `ByteBuffer` capacity.
* @param field The offset to the field in the vtable. * @param field The offset to the field in the vtable.
@@ -936,9 +989,9 @@ public class FlatBufferBuilder {
int vtable_start = table_start - bb.getInt(table_start); int vtable_start = table_start - bb.getInt(table_start);
boolean ok = bb.getShort(vtable_start + field) != 0; boolean ok = bb.getShort(vtable_start + field) != 0;
// If this fails, the caller will show what field needs to be set. // If this fails, the caller will show what field needs to be set.
if (!ok) if (!ok) throw new AssertionError("FlatBuffers: field " + field + " must be set");
throw new AssertionError("FlatBuffers: field " + field + " must be set");
} }
/// @endcond /// @endcond
/** /**
@@ -986,10 +1039,10 @@ public class FlatBufferBuilder {
protected void finish(int root_table, String file_identifier, boolean size_prefix) { protected void finish(int root_table, String file_identifier, boolean size_prefix) {
prep(minalign, SIZEOF_INT + FILE_IDENTIFIER_LENGTH + (size_prefix ? SIZEOF_INT : 0)); prep(minalign, SIZEOF_INT + FILE_IDENTIFIER_LENGTH + (size_prefix ? SIZEOF_INT : 0));
if (file_identifier.length() != FILE_IDENTIFIER_LENGTH) if (file_identifier.length() != FILE_IDENTIFIER_LENGTH)
throw new AssertionError("FlatBuffers: file identifier must be length " + throw new AssertionError(
FILE_IDENTIFIER_LENGTH); "FlatBuffers: file identifier must be length " + FILE_IDENTIFIER_LENGTH);
for (int i = FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) { for (int i = FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) {
addByte((byte)file_identifier.charAt(i)); addByte((byte) file_identifier.charAt(i));
} }
finish(root_table, size_prefix); finish(root_table, size_prefix);
} }
@@ -1017,22 +1070,20 @@ public class FlatBufferBuilder {
} }
/** /**
* In order to save space, fields that are set to their default value * In order to save space, fields that are set to their default value don't get serialized into
* don't get serialized into the buffer. Forcing defaults provides a * the buffer. Forcing defaults provides a way to manually disable this optimization.
* way to manually disable this optimization.
* *
* @param forceDefaults When set to `true`, always serializes default values. * @param forceDefaults When set to `true`, always serializes default values.
* @return Returns `this`. * @return Returns `this`.
*/ */
public FlatBufferBuilder forceDefaults(boolean forceDefaults){ public FlatBufferBuilder forceDefaults(boolean forceDefaults) {
this.force_defaults = forceDefaults; this.force_defaults = forceDefaults;
return this; return this;
} }
/** /**
* Get the ByteBuffer representing the FlatBuffer. Only call this after you've * Get the ByteBuffer representing the FlatBuffer. Only call this after you've called `finish()`.
* called `finish()`. The actual data starts at the ByteBuffer's current position, * The actual data starts at the ByteBuffer's current position, not necessarily at `0`.
* not necessarily at `0`.
* *
* @return The {@link ByteBuffer} representing the FlatBuffer * @return The {@link ByteBuffer} representing the FlatBuffer
*/ */
@@ -1042,12 +1093,12 @@ public class FlatBufferBuilder {
} }
/** /**
* The FlatBuffer data doesn't start at offset 0 in the {@link ByteBuffer}, but * The FlatBuffer data doesn't start at offset 0 in the {@link ByteBuffer}, but now the {@code
* now the {@code ByteBuffer}'s position is set to that location upon {@link #finish(int)}. * ByteBuffer}'s position is set to that location upon {@link #finish(int)}.
* *
* @return The {@link ByteBuffer#position() position} the data starts in {@link #dataBuffer()} * @return The {@link ByteBuffer#position() position} the data starts in {@link #dataBuffer()}
* @deprecated This method should not be needed anymore, but is left * @deprecated This method should not be needed anymore, but is left here for the moment to
* here for the moment to document this API change. It will be removed in the future. * document this API change. It will be removed in the future.
*/ */
@Deprecated @Deprecated
private int dataStart() { private int dataStart() {
@@ -1056,15 +1107,15 @@ public class FlatBufferBuilder {
} }
/** /**
* A utility function to copy and return the ByteBuffer data from `start` to * A utility function to copy and return the ByteBuffer data from `start` to `start` + `length` as
* `start` + `length` as a `byte[]`. * a `byte[]`.
* *
* @param start Start copying at this offset. * @param start Start copying at this offset.
* @param length How many bytes to copy. * @param length How many bytes to copy.
* @return A range copy of the {@link #dataBuffer() data buffer}. * @return A range copy of the {@link #dataBuffer() data buffer}.
* @throws IndexOutOfBoundsException If the range of bytes is ouf of bound. * @throws IndexOutOfBoundsException If the range of bytes is ouf of bound.
*/ */
public byte[] sizedByteArray(int start, int length){ public byte[] sizedByteArray(int start, int length) {
finished(); finished();
byte[] array = new byte[length]; byte[] array = new byte[length];
bb.position(start); bb.position(start);
@@ -1084,8 +1135,8 @@ public class FlatBufferBuilder {
/** /**
* A utility function to return an InputStream to the ByteBuffer data * A utility function to return an InputStream to the ByteBuffer data
* *
* @return An InputStream that starts at the beginning of the ByteBuffer data * @return An InputStream that starts at the beginning of the ByteBuffer data and can read to the
* and can read to the end of it. * end of it.
*/ */
public InputStream sizedInputStream() { public InputStream sizedInputStream() {
finished(); finished();
@@ -1095,9 +1146,7 @@ public class FlatBufferBuilder {
return new ByteBufferBackedInputStream(duplicate); return new ByteBufferBackedInputStream(duplicate);
} }
/** /** A class that allows a user to create an InputStream from a ByteBuffer. */
* A class that allows a user to create an InputStream from a ByteBuffer.
*/
static class ByteBufferBackedInputStream extends InputStream { static class ByteBufferBackedInputStream extends InputStream {
ByteBuffer buf; ByteBuffer buf;
@@ -1109,12 +1158,11 @@ public class FlatBufferBuilder {
public int read() throws IOException { public int read() throws IOException {
try { try {
return buf.get() & 0xFF; return buf.get() & 0xFF;
} catch(BufferUnderflowException e) { } catch (BufferUnderflowException e) {
return -1; return -1;
} }
} }
} }
} }
/// @} /// @}

View File

@@ -16,14 +16,11 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import static com.google.flatbuffers.FlexBuffers.Unsigned.byteToUnsignedInt; import static com.google.flatbuffers.FlexBuffers.Unsigned.byteToUnsignedInt;
import static com.google.flatbuffers.FlexBuffers.Unsigned.intToUnsignedLong; import static com.google.flatbuffers.FlexBuffers.Unsigned.intToUnsignedLong;
import static com.google.flatbuffers.FlexBuffers.Unsigned.shortToUnsignedInt; import static com.google.flatbuffers.FlexBuffers.Unsigned.shortToUnsignedInt;
import java.math.BigInteger;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
/// @file /// @file
/// @addtogroup flatbuffers_java_api /// @addtogroup flatbuffers_java_api
@@ -31,10 +28,11 @@ import java.nio.charset.StandardCharsets;
/** /**
* This class can be used to parse FlexBuffer messages. * This class can be used to parse FlexBuffer messages.
* <p> *
* For generating FlexBuffer messages, use {@link FlexBuffersBuilder}. * <p>For generating FlexBuffer messages, use {@link FlexBuffersBuilder}.
* <p> *
* Example of usage: * <p>Example of usage:
*
* <pre> * <pre>
* ReadBuf bb = ... // load message from file or network * ReadBuf bb = ... // load message from file or network
* FlexBuffers.Reference r = FlexBuffers.getRoot(bb); // Reads the root element * FlexBuffers.Reference r = FlexBuffers.getRoot(bb); // Reads the root element
@@ -48,34 +46,49 @@ public class FlexBuffers {
// type. // type.
/** Represent a null type */ /** Represent a null type */
public static final int FBT_NULL = 0; public static final int FBT_NULL = 0;
/** Represent a signed integer type */ /** Represent a signed integer type */
public static final int FBT_INT = 1; public static final int FBT_INT = 1;
/** Represent a unsigned type */ /** Represent a unsigned type */
public static final int FBT_UINT = 2; public static final int FBT_UINT = 2;
/** Represent a float type */ /** Represent a float type */
public static final int FBT_FLOAT = 3; // Types above stored inline, types below store an offset. public static final int FBT_FLOAT = 3; // Types above stored inline, types below store an offset.
/** Represent a key to a map type */ /** Represent a key to a map type */
public static final int FBT_KEY = 4; public static final int FBT_KEY = 4;
/** Represent a string type */ /** Represent a string type */
public static final int FBT_STRING = 5; public static final int FBT_STRING = 5;
/** Represent a indirect signed integer type */ /** Represent a indirect signed integer type */
public static final int FBT_INDIRECT_INT = 6; public static final int FBT_INDIRECT_INT = 6;
/** Represent a indirect unsigned integer type */ /** Represent a indirect unsigned integer type */
public static final int FBT_INDIRECT_UINT = 7; public static final int FBT_INDIRECT_UINT = 7;
/** Represent a indirect float type */ /** Represent a indirect float type */
public static final int FBT_INDIRECT_FLOAT = 8; public static final int FBT_INDIRECT_FLOAT = 8;
/** Represent a map type */ /** Represent a map type */
public static final int FBT_MAP = 9; public static final int FBT_MAP = 9;
/** Represent a vector type */ /** Represent a vector type */
public static final int FBT_VECTOR = 10; // Untyped. public static final int FBT_VECTOR = 10; // Untyped.
/** Represent a vector of signed integers type */ /** Represent a vector of signed integers type */
public static final int FBT_VECTOR_INT = 11; // Typed any size = stores no type table). public static final int FBT_VECTOR_INT = 11; // Typed any size = stores no type table).
/** Represent a vector of unsigned integers type */ /** Represent a vector of unsigned integers type */
public static final int FBT_VECTOR_UINT = 12; public static final int FBT_VECTOR_UINT = 12;
/** Represent a vector of floats type */ /** Represent a vector of floats type */
public static final int FBT_VECTOR_FLOAT = 13; public static final int FBT_VECTOR_FLOAT = 13;
/** Represent a vector of keys type */ /** Represent a vector of keys type */
public static final int FBT_VECTOR_KEY = 14; public static final int FBT_VECTOR_KEY = 14;
/** Represent a vector of strings type */ /** Represent a vector of strings type */
// DEPRECATED, use FBT_VECTOR or FBT_VECTOR_KEY instead. // DEPRECATED, use FBT_VECTOR or FBT_VECTOR_KEY instead.
// more info on thttps://github.com/google/flatbuffers/issues/5627. // more info on thttps://github.com/google/flatbuffers/issues/5627.
@@ -91,14 +104,18 @@ public class FlexBuffers {
public static final int FBT_VECTOR_INT4 = 22; // Typed quad = no type table; no size field). public static final int FBT_VECTOR_INT4 = 22; // Typed quad = no type table; no size field).
public static final int FBT_VECTOR_UINT4 = 23; public static final int FBT_VECTOR_UINT4 = 23;
public static final int FBT_VECTOR_FLOAT4 = 24; public static final int FBT_VECTOR_FLOAT4 = 24;
/// @endcond FLATBUFFERS_INTERNAL /// @endcond FLATBUFFERS_INTERNAL
/** Represent a blob type */ /** Represent a blob type */
public static final int FBT_BLOB = 25; public static final int FBT_BLOB = 25;
/** Represent a boolean type */ /** Represent a boolean type */
public static final int FBT_BOOL = 26; public static final int FBT_BOOL = 26;
/** Represent a vector of booleans type */ /** Represent a vector of booleans type */
public static final int FBT_VECTOR_BOOL = 36; // To Allow the same type of conversion of type to vector type public static final int FBT_VECTOR_BOOL =
36; // To Allow the same type of conversion of type to vector type
private static final ReadBuf EMPTY_BB = new ArrayReadWriteBuf(new byte[] {0}, 1); private static final ReadBuf EMPTY_BB = new ArrayReadWriteBuf(new byte[] {0}, 1);
@@ -109,7 +126,8 @@ public class FlexBuffers {
* @return true if typed vector * @return true if typed vector
*/ */
static boolean isTypedVector(int type) { static boolean isTypedVector(int type) {
return (type >= FBT_VECTOR_INT && type <= FBT_VECTOR_STRING_DEPRECATED) || type == FBT_VECTOR_BOOL; return (type >= FBT_VECTOR_INT && type <= FBT_VECTOR_STRING_DEPRECATED)
|| type == FBT_VECTOR_BOOL;
} }
/** /**
@@ -136,10 +154,14 @@ public class FlexBuffers {
static int toTypedVector(int type, int fixedLength) { static int toTypedVector(int type, int fixedLength) {
assert (isTypedVectorElementType(type)); assert (isTypedVectorElementType(type));
switch (fixedLength) { switch (fixedLength) {
case 0: return type - FBT_INT + FBT_VECTOR_INT; case 0:
case 2: return type - FBT_INT + FBT_VECTOR_INT2; return type - FBT_INT + FBT_VECTOR_INT;
case 3: return type - FBT_INT + FBT_VECTOR_INT3; case 2:
case 4: return type - FBT_INT + FBT_VECTOR_INT4; return type - FBT_INT + FBT_VECTOR_INT2;
case 3:
return type - FBT_INT + FBT_VECTOR_INT3;
case 4:
return type - FBT_INT + FBT_VECTOR_INT4;
default: default:
assert (false); assert (false);
return FBT_NULL; return FBT_NULL;
@@ -159,11 +181,17 @@ public class FlexBuffers {
// read unsigned int with size byteWidth and return as a 64-bit integer // read unsigned int with size byteWidth and return as a 64-bit integer
private static long readUInt(ReadBuf buff, int end, int byteWidth) { private static long readUInt(ReadBuf buff, int end, int byteWidth) {
switch (byteWidth) { switch (byteWidth) {
case 1: return byteToUnsignedInt(buff.get(end)); case 1:
case 2: return shortToUnsignedInt(buff.getShort(end)); return byteToUnsignedInt(buff.get(end));
case 4: return intToUnsignedLong(buff.getInt(end)); case 2:
case 8: return buff.getLong(end); // We are passing signed long here. Losing information (user should know) return shortToUnsignedInt(buff.getShort(end));
default: return -1; // we should never reach here case 4:
return intToUnsignedLong(buff.getInt(end));
case 8:
return buff.getLong(
end); // We are passing signed long here. Losing information (user should know)
default:
return -1; // we should never reach here
} }
} }
@@ -175,36 +203,47 @@ public class FlexBuffers {
// read signed int of size byteWidth and return as 64-bit int // read signed int of size byteWidth and return as 64-bit int
private static long readLong(ReadBuf buff, int end, int byteWidth) { private static long readLong(ReadBuf buff, int end, int byteWidth) {
switch (byteWidth) { switch (byteWidth) {
case 1: return buff.get(end); case 1:
case 2: return buff.getShort(end); return buff.get(end);
case 4: return buff.getInt(end); case 2:
case 8: return buff.getLong(end); return buff.getShort(end);
default: return -1; // we should never reach here case 4:
return buff.getInt(end);
case 8:
return buff.getLong(end);
default:
return -1; // we should never reach here
} }
} }
private static double readDouble(ReadBuf buff, int end, int byteWidth) { private static double readDouble(ReadBuf buff, int end, int byteWidth) {
switch (byteWidth) { switch (byteWidth) {
case 4: return buff.getFloat(end); case 4:
case 8: return buff.getDouble(end); return buff.getFloat(end);
default: return -1; // we should never reach here case 8:
return buff.getDouble(end);
default:
return -1; // we should never reach here
} }
} }
/** /**
* Reads a FlexBuffer message in ReadBuf and returns {@link Reference} to * Reads a FlexBuffer message in ReadBuf and returns {@link Reference} to the root element.
* the root element. *
* @param buffer ReadBuf containing FlexBuffer message * @param buffer ReadBuf containing FlexBuffer message
* @return {@link Reference} to the root object * @return {@link Reference} to the root object
*/ */
@Deprecated @Deprecated
public static Reference getRoot(ByteBuffer buffer) { public static Reference getRoot(ByteBuffer buffer) {
return getRoot( buffer.hasArray() ? new ArrayReadWriteBuf(buffer.array(), buffer.limit()) : new ByteBufferReadWriteBuf(buffer)); return getRoot(
buffer.hasArray()
? new ArrayReadWriteBuf(buffer.array(), buffer.limit())
: new ByteBufferReadWriteBuf(buffer));
} }
/** /**
* Reads a FlexBuffer message in ReadBuf and returns {@link Reference} to * Reads a FlexBuffer message in ReadBuf and returns {@link Reference} to the root element.
* the root element. *
* @param buffer ReadBuf containing FlexBuffer message * @param buffer ReadBuf containing FlexBuffer message
* @return {@link Reference} to the root object * @return {@link Reference} to the root object
*/ */
@@ -218,9 +257,7 @@ public class FlexBuffers {
return new Reference(buffer, end, byteWidth, packetType); return new Reference(buffer, end, byteWidth, packetType);
} }
/** /** Represents an generic element in the buffer. */
* Represents an generic element in the buffer.
*/
public static class Reference { public static class Reference {
private static final Reference NULL_REFERENCE = new Reference(EMPTY_BB, 0, 1, 0); private static final Reference NULL_REFERENCE = new Reference(EMPTY_BB, 0, 1, 0);
@@ -244,6 +281,7 @@ public class FlexBuffers {
/** /**
* Return element type * Return element type
*
* @return element type as integer * @return element type as integer
*/ */
public int getType() { public int getType() {
@@ -252,6 +290,7 @@ public class FlexBuffers {
/** /**
* Checks whether the element is null type * Checks whether the element is null type
*
* @return true if null type * @return true if null type
*/ */
public boolean isNull() { public boolean isNull() {
@@ -260,6 +299,7 @@ public class FlexBuffers {
/** /**
* Checks whether the element is boolean type * Checks whether the element is boolean type
*
* @return true if boolean type * @return true if boolean type
*/ */
public boolean isBoolean() { public boolean isBoolean() {
@@ -268,6 +308,7 @@ public class FlexBuffers {
/** /**
* Checks whether the element type is numeric (signed/unsigned integers and floats) * Checks whether the element type is numeric (signed/unsigned integers and floats)
*
* @return true if numeric type * @return true if numeric type
*/ */
public boolean isNumeric() { public boolean isNumeric() {
@@ -276,6 +317,7 @@ public class FlexBuffers {
/** /**
* Checks whether the element type is signed or unsigned integers * Checks whether the element type is signed or unsigned integers
*
* @return true if an integer type * @return true if an integer type
*/ */
public boolean isIntOrUInt() { public boolean isIntOrUInt() {
@@ -284,6 +326,7 @@ public class FlexBuffers {
/** /**
* Checks whether the element type is float * Checks whether the element type is float
*
* @return true if a float type * @return true if a float type
*/ */
public boolean isFloat() { public boolean isFloat() {
@@ -292,6 +335,7 @@ public class FlexBuffers {
/** /**
* Checks whether the element type is signed integer * Checks whether the element type is signed integer
*
* @return true if a signed integer type * @return true if a signed integer type
*/ */
public boolean isInt() { public boolean isInt() {
@@ -300,6 +344,7 @@ public class FlexBuffers {
/** /**
* Checks whether the element type is signed integer * Checks whether the element type is signed integer
*
* @return true if a signed integer type * @return true if a signed integer type
*/ */
public boolean isUInt() { public boolean isUInt() {
@@ -308,6 +353,7 @@ public class FlexBuffers {
/** /**
* Checks whether the element type is string * Checks whether the element type is string
*
* @return true if a string type * @return true if a string type
*/ */
public boolean isString() { public boolean isString() {
@@ -316,6 +362,7 @@ public class FlexBuffers {
/** /**
* Checks whether the element type is key * Checks whether the element type is key
*
* @return true if a key type * @return true if a key type
*/ */
public boolean isKey() { public boolean isKey() {
@@ -324,6 +371,7 @@ public class FlexBuffers {
/** /**
* Checks whether the element type is vector * Checks whether the element type is vector
*
* @return true if a vector type * @return true if a vector type
*/ */
public boolean isVector() { public boolean isVector() {
@@ -332,6 +380,7 @@ public class FlexBuffers {
/** /**
* Checks whether the element type is typed vector * Checks whether the element type is typed vector
*
* @return true if a typed vector type * @return true if a typed vector type
*/ */
public boolean isTypedVector() { public boolean isTypedVector() {
@@ -340,6 +389,7 @@ public class FlexBuffers {
/** /**
* Checks whether the element type is a map * Checks whether the element type is a map
*
* @return true if a map type * @return true if a map type
*/ */
public boolean isMap() { public boolean isMap() {
@@ -348,6 +398,7 @@ public class FlexBuffers {
/** /**
* Checks whether the element type is a blob * Checks whether the element type is a blob
*
* @return true if a blob type * @return true if a blob type
*/ */
public boolean isBlob() { public boolean isBlob() {
@@ -356,10 +407,15 @@ public class FlexBuffers {
/** /**
* Returns element as 32-bit integer. * Returns element as 32-bit integer.
* <p> For vector element, it will return size of the vector</p> *
* <p> For String element, it will type to be parsed as integer</p> * <p>For vector element, it will return size of the vector
* <p> Unsigned elements will become negative</p> *
* <p> Float elements will be casted to integer </p> * <p>For String element, it will type to be parsed as integer
*
* <p>Unsigned elements will become negative
*
* <p>Float elements will be casted to integer
*
* @return 32-bit integer or 0 if fail to convert element to integer. * @return 32-bit integer or 0 if fail to convert element to integer.
*/ */
public int asInt() { public int asInt() {
@@ -368,15 +424,24 @@ public class FlexBuffers {
return readInt(bb, end, parentWidth); return readInt(bb, end, parentWidth);
} else } else
switch (type) { switch (type) {
case FBT_INDIRECT_INT: return readInt(bb, indirect(bb, end, parentWidth), byteWidth); case FBT_INDIRECT_INT:
case FBT_UINT: return (int) readUInt(bb, end, parentWidth); return readInt(bb, indirect(bb, end, parentWidth), byteWidth);
case FBT_INDIRECT_UINT: return (int) readUInt(bb, indirect(bb, end, parentWidth), parentWidth); case FBT_UINT:
case FBT_FLOAT: return (int) readDouble(bb, end, parentWidth); return (int) readUInt(bb, end, parentWidth);
case FBT_INDIRECT_FLOAT: return (int) readDouble(bb, indirect(bb, end, parentWidth), byteWidth); case FBT_INDIRECT_UINT:
case FBT_NULL: return 0; return (int) readUInt(bb, indirect(bb, end, parentWidth), parentWidth);
case FBT_STRING: return Integer.parseInt(asString()); case FBT_FLOAT:
case FBT_VECTOR: return asVector().size(); return (int) readDouble(bb, end, parentWidth);
case FBT_BOOL: return readInt(bb, end, parentWidth); case FBT_INDIRECT_FLOAT:
return (int) readDouble(bb, indirect(bb, end, parentWidth), byteWidth);
case FBT_NULL:
return 0;
case FBT_STRING:
return Integer.parseInt(asString());
case FBT_VECTOR:
return asVector().size();
case FBT_BOOL:
return readInt(bb, end, parentWidth);
default: default:
// Convert other things to int. // Convert other things to int.
return 0; return 0;
@@ -385,10 +450,15 @@ public class FlexBuffers {
/** /**
* Returns element as unsigned 64-bit integer. * Returns element as unsigned 64-bit integer.
* <p> For vector element, it will return size of the vector</p> *
* <p> For String element, it will type to be parsed as integer</p> * <p>For vector element, it will return size of the vector
* <p> Negative signed elements will become unsigned counterpart</p> *
* <p> Float elements will be casted to integer </p> * <p>For String element, it will type to be parsed as integer
*
* <p>Negative signed elements will become unsigned counterpart
*
* <p>Float elements will be casted to integer
*
* @return 64-bit integer or 0 if fail to convert element to integer. * @return 64-bit integer or 0 if fail to convert element to integer.
*/ */
public long asUInt() { public long asUInt() {
@@ -397,15 +467,24 @@ public class FlexBuffers {
return readUInt(bb, end, parentWidth); return readUInt(bb, end, parentWidth);
} else } else
switch (type) { switch (type) {
case FBT_INDIRECT_UINT: return readUInt(bb, indirect(bb, end, parentWidth), byteWidth); case FBT_INDIRECT_UINT:
case FBT_INT: return readLong(bb, end, parentWidth); return readUInt(bb, indirect(bb, end, parentWidth), byteWidth);
case FBT_INDIRECT_INT: return readLong(bb, indirect(bb, end, parentWidth), byteWidth); case FBT_INT:
case FBT_FLOAT: return (long) readDouble(bb, end, parentWidth); return readLong(bb, end, parentWidth);
case FBT_INDIRECT_FLOAT: return (long) readDouble(bb, indirect(bb, end, parentWidth), parentWidth); case FBT_INDIRECT_INT:
case FBT_NULL: return 0; return readLong(bb, indirect(bb, end, parentWidth), byteWidth);
case FBT_STRING: return Long.parseLong(asString()); case FBT_FLOAT:
case FBT_VECTOR: return asVector().size(); return (long) readDouble(bb, end, parentWidth);
case FBT_BOOL: return readInt(bb, end, parentWidth); case FBT_INDIRECT_FLOAT:
return (long) readDouble(bb, indirect(bb, end, parentWidth), parentWidth);
case FBT_NULL:
return 0;
case FBT_STRING:
return Long.parseLong(asString());
case FBT_VECTOR:
return asVector().size();
case FBT_BOOL:
return readInt(bb, end, parentWidth);
default: default:
// Convert other things to uint. // Convert other things to uint.
return 0; return 0;
@@ -414,10 +493,15 @@ public class FlexBuffers {
/** /**
* Returns element as 64-bit integer. * Returns element as 64-bit integer.
* <p> For vector element, it will return size of the vector</p> *
* <p> For String element, it will type to be parsed as integer</p> * <p>For vector element, it will return size of the vector
* <p> Unsigned elements will become negative</p> *
* <p> Float elements will be casted to integer </p> * <p>For String element, it will type to be parsed as integer
*
* <p>Unsigned elements will become negative
*
* <p>Float elements will be casted to integer
*
* @return 64-bit integer or 0 if fail to convert element to long. * @return 64-bit integer or 0 if fail to convert element to long.
*/ */
public long asLong() { public long asLong() {
@@ -426,21 +510,30 @@ public class FlexBuffers {
return readLong(bb, end, parentWidth); return readLong(bb, end, parentWidth);
} else } else
switch (type) { switch (type) {
case FBT_INDIRECT_INT: return readLong(bb, indirect(bb, end, parentWidth), byteWidth); case FBT_INDIRECT_INT:
case FBT_UINT: return readUInt(bb, end, parentWidth); return readLong(bb, indirect(bb, end, parentWidth), byteWidth);
case FBT_INDIRECT_UINT: return readUInt(bb, indirect(bb, end, parentWidth), parentWidth); case FBT_UINT:
case FBT_FLOAT: return (long) readDouble(bb, end, parentWidth); return readUInt(bb, end, parentWidth);
case FBT_INDIRECT_FLOAT: return (long) readDouble(bb, indirect(bb, end, parentWidth), byteWidth); case FBT_INDIRECT_UINT:
case FBT_NULL: return 0; return readUInt(bb, indirect(bb, end, parentWidth), parentWidth);
case FBT_STRING: { case FBT_FLOAT:
return (long) readDouble(bb, end, parentWidth);
case FBT_INDIRECT_FLOAT:
return (long) readDouble(bb, indirect(bb, end, parentWidth), byteWidth);
case FBT_NULL:
return 0;
case FBT_STRING:
{
try { try {
return Long.parseLong(asString()); return Long.parseLong(asString());
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
return 0; //same as C++ implementation return 0; // same as C++ implementation
} }
} }
case FBT_VECTOR: return asVector().size(); case FBT_VECTOR:
case FBT_BOOL: return readInt(bb, end, parentWidth); return asVector().size();
case FBT_BOOL:
return readInt(bb, end, parentWidth);
default: default:
// Convert other things to int. // Convert other things to int.
return 0; return 0;
@@ -449,8 +542,11 @@ public class FlexBuffers {
/** /**
* Returns element as 64-bit integer. * Returns element as 64-bit integer.
* <p> For vector element, it will return size of the vector</p> *
* <p> For String element, it will type to be parsed as integer</p> * <p>For vector element, it will return size of the vector
*
* <p>For String element, it will type to be parsed as integer
*
* @return 64-bit integer or 0 if fail to convert element to long. * @return 64-bit integer or 0 if fail to convert element to long.
*/ */
public double asFloat() { public double asFloat() {
@@ -459,16 +555,23 @@ public class FlexBuffers {
return readDouble(bb, end, parentWidth); return readDouble(bb, end, parentWidth);
} else } else
switch (type) { switch (type) {
case FBT_INDIRECT_FLOAT: return readDouble(bb, indirect(bb, end, parentWidth), byteWidth); case FBT_INDIRECT_FLOAT:
case FBT_INT: return readInt(bb, end, parentWidth); return readDouble(bb, indirect(bb, end, parentWidth), byteWidth);
case FBT_INT:
return readInt(bb, end, parentWidth);
case FBT_UINT: case FBT_UINT:
case FBT_BOOL: case FBT_BOOL:
return readUInt(bb, end, parentWidth); return readUInt(bb, end, parentWidth);
case FBT_INDIRECT_INT: return readInt(bb, indirect(bb, end, parentWidth), byteWidth); case FBT_INDIRECT_INT:
case FBT_INDIRECT_UINT: return readUInt(bb, indirect(bb, end, parentWidth), byteWidth); return readInt(bb, indirect(bb, end, parentWidth), byteWidth);
case FBT_NULL: return 0.0; case FBT_INDIRECT_UINT:
case FBT_STRING: return Double.parseDouble(asString()); return readUInt(bb, indirect(bb, end, parentWidth), byteWidth);
case FBT_VECTOR: return asVector().size(); case FBT_NULL:
return 0.0;
case FBT_STRING:
return Double.parseDouble(asString());
case FBT_VECTOR:
return asVector().size();
default: default:
// Convert strings and other things to float. // Convert strings and other things to float.
return 0; return 0;
@@ -477,6 +580,7 @@ public class FlexBuffers {
/** /**
* Returns element as a {@link Key} * Returns element as a {@link Key}
*
* @return key or {@link Key#empty()} if element is not a key * @return key or {@link Key#empty()} if element is not a key
*/ */
public Key asKey() { public Key asKey() {
@@ -489,6 +593,7 @@ public class FlexBuffers {
/** /**
* Returns element as a `String` * Returns element as a `String`
*
* @return element as `String` or empty `String` if fail * @return element as `String` or empty `String` if fail
*/ */
public String asString() { public String asString() {
@@ -496,8 +601,7 @@ public class FlexBuffers {
int start = indirect(bb, end, parentWidth); int start = indirect(bb, end, parentWidth);
int size = (int) readUInt(bb, start - byteWidth, byteWidth); int size = (int) readUInt(bb, start - byteWidth, byteWidth);
return bb.getString(start, size); return bb.getString(start, size);
} } else if (isKey()) {
else if (isKey()){
int start = indirect(bb, end, byteWidth); int start = indirect(bb, end, byteWidth);
for (int i = start; ; i++) { for (int i = start; ; i++) {
if (bb.get(i) == 0) { if (bb.get(i) == 0) {
@@ -511,6 +615,7 @@ public class FlexBuffers {
/** /**
* Returns element as a {@link Map} * Returns element as a {@link Map}
*
* @return element as {@link Map} or empty {@link Map} if fail * @return element as {@link Map} or empty {@link Map} if fail
*/ */
public Map asMap() { public Map asMap() {
@@ -523,16 +628,21 @@ public class FlexBuffers {
/** /**
* Returns element as a {@link Vector} * Returns element as a {@link Vector}
*
* @return element as {@link Vector} or empty {@link Vector} if fail * @return element as {@link Vector} or empty {@link Vector} if fail
*/ */
public Vector asVector() { public Vector asVector() {
if (isVector()) { if (isVector()) {
return new Vector(bb, indirect(bb, end, parentWidth), byteWidth); return new Vector(bb, indirect(bb, end, parentWidth), byteWidth);
} else if(type == FlexBuffers.FBT_VECTOR_STRING_DEPRECATED) { } else if (type == FlexBuffers.FBT_VECTOR_STRING_DEPRECATED) {
// deprecated. Should be treated as key vector // deprecated. Should be treated as key vector
return new TypedVector(bb, indirect(bb, end, parentWidth), byteWidth, FlexBuffers.FBT_KEY); return new TypedVector(bb, indirect(bb, end, parentWidth), byteWidth, FlexBuffers.FBT_KEY);
} else if (FlexBuffers.isTypedVector(type)) { } else if (FlexBuffers.isTypedVector(type)) {
return new TypedVector(bb, indirect(bb, end, parentWidth), byteWidth, FlexBuffers.toTypedVectorElementType(type)); return new TypedVector(
bb,
indirect(bb, end, parentWidth),
byteWidth,
FlexBuffers.toTypedVectorElementType(type));
} else { } else {
return Vector.empty(); return Vector.empty();
} }
@@ -540,6 +650,7 @@ public class FlexBuffers {
/** /**
* Returns element as a {@link Blob} * Returns element as a {@link Blob}
*
* @return element as {@link Blob} or empty {@link Blob} if fail * @return element as {@link Blob} or empty {@link Blob} if fail
*/ */
public Blob asBlob() { public Blob asBlob() {
@@ -552,7 +663,9 @@ public class FlexBuffers {
/** /**
* Returns element as a boolean * Returns element as a boolean
* <p>If element type is not boolean, it will be casted to integer and compared against 0</p> *
* <p>If element type is not boolean, it will be casted to integer and compared against 0
*
* @return element as boolean * @return element as boolean
*/ */
public boolean asBoolean() { public boolean asBoolean() {
@@ -564,6 +677,7 @@ public class FlexBuffers {
/** /**
* Returns text representation of the element (JSON) * Returns text representation of the element (JSON)
*
* @return String containing text representation of the element * @return String containing text representation of the element
*/ */
@Override @Override
@@ -571,11 +685,9 @@ public class FlexBuffers {
return toString(new StringBuilder(128)).toString(); return toString(new StringBuilder(128)).toString();
} }
/** /** Appends a text(JSON) representation to a `StringBuilder` */
* Appends a text(JSON) representation to a `StringBuilder`
*/
StringBuilder toString(StringBuilder sb) { StringBuilder toString(StringBuilder sb) {
//TODO: Original C++ implementation escape strings. // TODO: Original C++ implementation escape strings.
// probably we should do it as well. // probably we should do it as well.
switch (type) { switch (type) {
case FBT_NULL: case FBT_NULL:
@@ -617,7 +729,6 @@ public class FlexBuffers {
case FBT_VECTOR_INT4: case FBT_VECTOR_INT4:
case FBT_VECTOR_UINT4: case FBT_VECTOR_UINT4:
case FBT_VECTOR_FLOAT4: case FBT_VECTOR_FLOAT4:
throw new FlexBufferException("not_implemented:" + type); throw new FlexBufferException("not_implemented:" + type);
default: default:
return sb; return sb;
@@ -625,11 +736,8 @@ public class FlexBuffers {
} }
} }
/** /** Base class of all types below. Points into the data buffer and allows access to one type. */
* Base class of all types below. private abstract static class Object {
* Points into the data buffer and allows access to one type.
*/
private static abstract class Object {
ReadBuf bb; ReadBuf bb;
int end; int end;
int byteWidth; int byteWidth;
@@ -649,7 +757,7 @@ public class FlexBuffers {
} }
// Stores size in `byte_width_` bytes before end position. // Stores size in `byte_width_` bytes before end position.
private static abstract class Sized extends Object { private abstract static class Sized extends Object {
protected final int size; protected final int size;
@@ -666,9 +774,8 @@ public class FlexBuffers {
/** /**
* Represents a array of bytes element in the buffer * Represents a array of bytes element in the buffer
* *
* <p>It can be converted to `ReadBuf` using {@link data()}, * <p>It can be converted to `ReadBuf` using {@link data()}, copied into a byte[] using {@link
* copied into a byte[] using {@link getBytes()} or * getBytes()} or have individual bytes accessed individually using {@link get(int)}
* have individual bytes accessed individually using {@link get(int)}</p>
*/ */
public static class Blob extends Sized { public static class Blob extends Sized {
static final Blob EMPTY = new Blob(EMPTY_BB, 1, 1); static final Blob EMPTY = new Blob(EMPTY_BB, 1, 1);
@@ -684,6 +791,7 @@ public class FlexBuffers {
/** /**
* Return {@link Blob} as `ReadBuf` * Return {@link Blob} as `ReadBuf`
*
* @return blob as `ReadBuf` * @return blob as `ReadBuf`
*/ */
public ByteBuffer data() { public ByteBuffer data() {
@@ -695,6 +803,7 @@ public class FlexBuffers {
/** /**
* Copy blob into a byte[] * Copy blob into a byte[]
*
* @return blob as a byte[] * @return blob as a byte[]
*/ */
public byte[] getBytes() { public byte[] getBytes() {
@@ -708,24 +817,21 @@ public class FlexBuffers {
/** /**
* Return individual byte at a given position * Return individual byte at a given position
*
* @param pos position of the byte to be read * @param pos position of the byte to be read
*/ */
public byte get(int pos) { public byte get(int pos) {
assert pos >=0 && pos <= size(); assert pos >= 0 && pos <= size();
return bb.get(end + pos); return bb.get(end + pos);
} }
/** /** Returns a text(JSON) representation of the {@link Blob} */
* Returns a text(JSON) representation of the {@link Blob}
*/
@Override @Override
public String toString() { public String toString() {
return bb.getString(end, size()); return bb.getString(end, size());
} }
/** /** Append a text(JSON) representation of the {@link Blob} into a `StringBuilder` */
* Append a text(JSON) representation of the {@link Blob} into a `StringBuilder`
*/
@Override @Override
public StringBuilder toString(StringBuilder sb) { public StringBuilder toString(StringBuilder sb) {
sb.append('"'); sb.append('"');
@@ -734,10 +840,7 @@ public class FlexBuffers {
} }
} }
/** /** Represents a key element in the buffer. Keys are used to reference objects in a {@link Map} */
* Represents a key element in the buffer. Keys are
* used to reference objects in a {@link Map}
*/
public static class Key extends Object { public static class Key extends Object {
private static final Key EMPTY = new Key(EMPTY_BB, 0, 0); private static final Key EMPTY = new Key(EMPTY_BB, 0, 0);
@@ -748,15 +851,14 @@ public class FlexBuffers {
/** /**
* Return an empty {@link Key} * Return an empty {@link Key}
*
* @return empty {@link Key} * @return empty {@link Key}
* */ */
public static Key empty() { public static Key empty() {
return Key.EMPTY; return Key.EMPTY;
} }
/** /** Appends a text(JSON) representation to a `StringBuilder` */
* Appends a text(JSON) representation to a `StringBuilder`
*/
@Override @Override
public StringBuilder toString(StringBuilder sb) { public StringBuilder toString(StringBuilder sb) {
return sb.append(toString()); return sb.append(toString());
@@ -781,8 +883,7 @@ public class FlexBuffers {
do { do {
c1 = bb.get(ia); c1 = bb.get(ia);
c2 = other[io]; c2 = other[io];
if (c1 == '\0') if (c1 == '\0') return c1 - c2;
return c1 - c2;
ia++; ia++;
io++; io++;
if (io == other.length) { if (io == other.length) {
@@ -795,20 +896,19 @@ public class FlexBuffers {
return 1; return 1;
} }
} }
} } while (c1 == c2);
while (c1 == c2);
return c1 - c2; return c1 - c2;
} }
/** /**
* Compare keys * Compare keys
*
* @param obj other key to compare * @param obj other key to compare
* @return true if keys are the same * @return true if keys are the same
*/ */
@Override @Override
public boolean equals(java.lang.Object obj) { public boolean equals(java.lang.Object obj) {
if (!(obj instanceof Key)) if (!(obj instanceof Key)) return false;
return false;
return ((Key) obj).end == end && ((Key) obj).byteWidth == byteWidth; return ((Key) obj).end == end && ((Key) obj).byteWidth == byteWidth;
} }
@@ -818,9 +918,7 @@ public class FlexBuffers {
} }
} }
/** /** Map object representing a set of key-value pairs. */
* Map object representing a set of key-value pairs.
*/
public static class Map extends Vector { public static class Map extends Vector {
private static final Map EMPTY_MAP = new Map(EMPTY_BB, 1, 1); private static final Map EMPTY_MAP = new Map(EMPTY_BB, 1, 1);
// cache for converting UTF-8 codepoints into // cache for converting UTF-8 codepoints into
@@ -833,6 +931,7 @@ public class FlexBuffers {
/** /**
* Returns an empty {@link Map} * Returns an empty {@link Map}
*
* @return an empty {@link Map} * @return an empty {@link Map}
*/ */
public static Map empty() { public static Map empty() {
@@ -871,7 +970,9 @@ public class FlexBuffers {
public KeyVector keys() { public KeyVector keys() {
final int num_prefixed_fields = 3; final int num_prefixed_fields = 3;
int keysOffset = end - (byteWidth * num_prefixed_fields); int keysOffset = end - (byteWidth * num_prefixed_fields);
return new KeyVector(new TypedVector(bb, return new KeyVector(
new TypedVector(
bb,
indirect(bb, keysOffset, byteWidth), indirect(bb, keysOffset, byteWidth),
readInt(bb, keysOffset + byteWidth, byteWidth), readInt(bb, keysOffset + byteWidth, byteWidth),
FBT_KEY)); FBT_KEY));
@@ -896,12 +997,9 @@ public class FlexBuffers {
int size = size(); int size = size();
Vector vals = values(); Vector vals = values();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
builder.append('"') builder.append('"').append(keys.get(i).toString()).append("\" : ");
.append(keys.get(i).toString())
.append("\" : ");
builder.append(vals.get(i).toString()); builder.append(vals.get(i).toString());
if (i != size - 1) if (i != size - 1) builder.append(", ");
builder.append(", ");
} }
builder.append(" }"); builder.append(" }");
return builder; return builder;
@@ -919,12 +1017,9 @@ public class FlexBuffers {
int mid = (low + high) >>> 1; int mid = (low + high) >>> 1;
int keyPos = indirect(bb, keysStart + mid * keyByteWidth, keyByteWidth); int keyPos = indirect(bb, keysStart + mid * keyByteWidth, keyByteWidth);
int cmp = compareCharSequence(keyPos, searchedKey); int cmp = compareCharSequence(keyPos, searchedKey);
if (cmp < 0) if (cmp < 0) low = mid + 1;
low = mid + 1; else if (cmp > 0) high = mid - 1;
else if (cmp > 0) else return mid; // key found
high = mid - 1;
else
return mid; // key found
} }
return -(low + 1); // key not found return -(low + 1); // key not found
} }
@@ -941,12 +1036,9 @@ public class FlexBuffers {
int mid = (low + high) >>> 1; int mid = (low + high) >>> 1;
int keyPos = indirect(bb, keysStart + mid * keyByteWidth, keyByteWidth); int keyPos = indirect(bb, keysStart + mid * keyByteWidth, keyByteWidth);
int cmp = compareBytes(bb, keyPos, searchedKey); int cmp = compareBytes(bb, keyPos, searchedKey);
if (cmp < 0) if (cmp < 0) low = mid + 1;
low = mid + 1; else if (cmp > 0) high = mid - 1;
else if (cmp > 0) else return mid; // key found
high = mid - 1;
else
return mid; // key found
} }
return -(low + 1); // key not found return -(low + 1); // key not found
} }
@@ -959,8 +1051,7 @@ public class FlexBuffers {
do { do {
c1 = bb.get(l1); c1 = bb.get(l1);
c2 = other[l2]; c2 = other[l2];
if (c1 == '\0') if (c1 == '\0') return c1 - c2;
return c1 - c2;
l1++; l1++;
l2++; l2++;
if (l2 == other.length) { if (l2 == other.length) {
@@ -973,8 +1064,7 @@ public class FlexBuffers {
return 1; return 1;
} }
} }
} } while (c1 == c2);
while (c1 == c2);
return c1 - c2; return c1 - c2;
} }
@@ -1036,9 +1126,7 @@ public class FlexBuffers {
} }
} }
/** /** Object that represents a set of elements in the buffer */
* Object that represents a set of elements in the buffer
*/
public static class Vector extends Sized { public static class Vector extends Sized {
private static final Vector EMPTY_VECTOR = new Vector(EMPTY_BB, 1, 1); private static final Vector EMPTY_VECTOR = new Vector(EMPTY_BB, 1, 1);
@@ -1049,6 +1137,7 @@ public class FlexBuffers {
/** /**
* Returns an empty {@link Map} * Returns an empty {@link Map}
*
* @return an empty {@link Map} * @return an empty {@link Map}
*/ */
public static Vector empty() { public static Vector empty() {
@@ -1057,15 +1146,14 @@ public class FlexBuffers {
/** /**
* Checks if the vector is empty * Checks if the vector is empty
*
* @return true if vector is empty * @return true if vector is empty
*/ */
public boolean isEmpty() { public boolean isEmpty() {
return this == EMPTY_VECTOR; return this == EMPTY_VECTOR;
} }
/** /** Appends a text(JSON) representation to a `StringBuilder` */
* Appends a text(JSON) representation to a `StringBuilder`
*/
@Override @Override
public StringBuilder toString(StringBuilder sb) { public StringBuilder toString(StringBuilder sb) {
sb.append("[ "); sb.append("[ ");
@@ -1097,9 +1185,7 @@ public class FlexBuffers {
} }
} }
/** /** Object that represents a set of elements with the same type */
* Object that represents a set of elements with the same type
*/
public static class TypedVector extends Vector { public static class TypedVector extends Vector {
private static final TypedVector EMPTY_VECTOR = new TypedVector(EMPTY_BB, 1, 1, FBT_INT); private static final TypedVector EMPTY_VECTOR = new TypedVector(EMPTY_BB, 1, 1, FBT_INT);
@@ -1148,9 +1234,7 @@ public class FlexBuffers {
} }
} }
/** /** Represent a vector of keys in a map */
* Represent a vector of keys in a map
*/
public static class KeyVector { public static class KeyVector {
private final TypedVector vec; private final TypedVector vec;
@@ -1181,9 +1265,7 @@ public class FlexBuffers {
return vec.size(); return vec.size();
} }
/** /** Returns a text(JSON) representation */
* Returns a text(JSON) representation
*/
public String toString() { public String toString() {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
b.append('['); b.append('[');

View File

@@ -16,66 +16,66 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import static com.google.flatbuffers.FlexBuffers.*;
import static com.google.flatbuffers.FlexBuffers.Unsigned.byteToUnsignedInt;
import static com.google.flatbuffers.FlexBuffers.Unsigned.intToUnsignedLong;
import static com.google.flatbuffers.FlexBuffers.Unsigned.shortToUnsignedInt;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import static com.google.flatbuffers.FlexBuffers.*;
import static com.google.flatbuffers.FlexBuffers.Unsigned.byteToUnsignedInt;
import static com.google.flatbuffers.FlexBuffers.Unsigned.intToUnsignedLong;
import static com.google.flatbuffers.FlexBuffers.Unsigned.shortToUnsignedInt;
/// @file /// @file
/// @addtogroup flatbuffers_java_api /// @addtogroup flatbuffers_java_api
/// @{ /// @{
/** /**
* Helper class that builds FlexBuffers * Helper class that builds FlexBuffers
* <p> This class presents all necessary APIs to create FlexBuffers. A `ByteBuffer` will be used to store the *
* data. It can be created internally, or passed down in the constructor.</p> * <p>This class presents all necessary APIs to create FlexBuffers. A `ByteBuffer` will be used to
* store the data. It can be created internally, or passed down in the constructor.
* *
* <p>There are some limitations when compared to original implementation in C++. Most notably: * <p>There are some limitations when compared to original implementation in C++. Most notably:
*
* <ul> * <ul>
* <li><p> No support for mutations (might change in the future).</p></li> * <li>
* <li><p> Buffer size limited to {@link Integer#MAX_VALUE}</p></li> * <p>No support for mutations (might change in the future).
* <li><p> Since Java does not support unsigned type, all unsigned operations accepts an immediate higher representation * <li>
* of similar type.</p></li> * <p>Buffer size limited to {@link Integer#MAX_VALUE}
* <li>
* <p>Since Java does not support unsigned type, all unsigned operations accepts an immediate
* higher representation of similar type.
* </ul> * </ul>
* </p>
*/ */
public class FlexBuffersBuilder { public class FlexBuffersBuilder {
/** /** No keys or strings will be shared */
* No keys or strings will be shared
*/
public static final int BUILDER_FLAG_NONE = 0; public static final int BUILDER_FLAG_NONE = 0;
/** /**
* Keys will be shared between elements. Identical keys will only be serialized once, thus possibly saving space. * Keys will be shared between elements. Identical keys will only be serialized once, thus
* But serialization performance might be slower and consumes more memory. * possibly saving space. But serialization performance might be slower and consumes more memory.
*/ */
public static final int BUILDER_FLAG_SHARE_KEYS = 1; public static final int BUILDER_FLAG_SHARE_KEYS = 1;
/** /**
* Strings will be shared between elements. Identical strings will only be serialized once, thus possibly saving space. * Strings will be shared between elements. Identical strings will only be serialized once, thus
* But serialization performance might be slower and consumes more memory. This is ideal if you expect many repeated * possibly saving space. But serialization performance might be slower and consumes more memory.
* strings on the message. * This is ideal if you expect many repeated strings on the message.
*/ */
public static final int BUILDER_FLAG_SHARE_STRINGS = 2; public static final int BUILDER_FLAG_SHARE_STRINGS = 2;
/**
* Strings and keys will be shared between elements. /** Strings and keys will be shared between elements. */
*/
public static final int BUILDER_FLAG_SHARE_KEYS_AND_STRINGS = 3; public static final int BUILDER_FLAG_SHARE_KEYS_AND_STRINGS = 3;
/**
* Reserved for the future. /** Reserved for the future. */
*/
public static final int BUILDER_FLAG_SHARE_KEY_VECTORS = 4; public static final int BUILDER_FLAG_SHARE_KEY_VECTORS = 4;
/**
* Reserved for the future. /** Reserved for the future. */
*/
public static final int BUILDER_FLAG_SHARE_ALL = 7; public static final int BUILDER_FLAG_SHARE_ALL = 7;
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
@@ -91,7 +91,8 @@ public class FlexBuffersBuilder {
private boolean finished = false; private boolean finished = false;
// A lambda to sort map keys // A lambda to sort map keys
private Comparator<Value> keyComparator = new Comparator<Value>() { private Comparator<Value> keyComparator =
new Comparator<Value>() {
@Override @Override
public int compare(Value o1, Value o2) { public int compare(Value o1, Value o2) {
int ia = o1.key; int ia = o1.key;
@@ -100,19 +101,20 @@ public class FlexBuffersBuilder {
do { do {
c1 = bb.get(ia); c1 = bb.get(ia);
c2 = bb.get(io); c2 = bb.get(io);
if (c1 == 0) if (c1 == 0) return c1 - c2;
return c1 - c2;
ia++; ia++;
io++; io++;
} } while (c1 == c2);
while (c1 == c2);
return c1 - c2; return c1 - c2;
} }
}; };
/// @endcond /// @endcond
/** /**
* Constructs a newly allocated {@code FlexBuffersBuilder} with {@link #BUILDER_FLAG_SHARE_KEYS} set. * Constructs a newly allocated {@code FlexBuffersBuilder} with {@link #BUILDER_FLAG_SHARE_KEYS}
* set.
*
* @param bufSize size of buffer in bytes. * @param bufSize size of buffer in bytes.
*/ */
public FlexBuffersBuilder(int bufSize) { public FlexBuffersBuilder(int bufSize) {
@@ -120,7 +122,8 @@ public class FlexBuffersBuilder {
} }
/** /**
* Constructs a newly allocated {@code FlexBuffersBuilder} with {@link #BUILDER_FLAG_SHARE_KEYS} set. * Constructs a newly allocated {@code FlexBuffersBuilder} with {@link #BUILDER_FLAG_SHARE_KEYS}
* set.
*/ */
public FlexBuffersBuilder() { public FlexBuffersBuilder() {
this(256); this(256);
@@ -143,18 +146,17 @@ public class FlexBuffersBuilder {
} }
/** /**
* Constructs a newly allocated {@code FlexBuffersBuilder}. * Constructs a newly allocated {@code FlexBuffersBuilder}. By default same keys will be
* By default same keys will be serialized only once * serialized only once
*
* @param bb `ByteBuffer` that will hold the message * @param bb `ByteBuffer` that will hold the message
*/ */
public FlexBuffersBuilder(ByteBuffer bb) { public FlexBuffersBuilder(ByteBuffer bb) {
this(bb, BUILDER_FLAG_SHARE_KEYS); this(bb, BUILDER_FLAG_SHARE_KEYS);
} }
/** /** Reset the FlexBuffersBuilder by purging all data that it holds. */
* Reset the FlexBuffersBuilder by purging all data that it holds. public void clear() {
*/
public void clear(){
bb.clear(); bb.clear();
stack.clear(); stack.clear();
keyPool.clear(); keyPool.clear();
@@ -163,8 +165,8 @@ public class FlexBuffersBuilder {
} }
/** /**
* Return `ByteBuffer` containing FlexBuffer message. {@code #finish()} must be called before calling this * Return `ByteBuffer` containing FlexBuffer message. {@code #finish()} must be called before
* function otherwise an assert will trigger. * calling this function otherwise an assert will trigger.
* *
* @return `ByteBuffer` with finished message * @return `ByteBuffer` with finished message
*/ */
@@ -173,15 +175,14 @@ public class FlexBuffersBuilder {
return bb; return bb;
} }
/** /** Insert a null value into the buffer */
* Insert a null value into the buffer
*/
public void putNull() { public void putNull() {
putNull(null); putNull(null);
} }
/** /**
* Insert a null value into the buffer * Insert a null value into the buffer
*
* @param key key used to store element in map * @param key key used to store element in map
*/ */
public void putNull(String key) { public void putNull(String key) {
@@ -190,6 +191,7 @@ public class FlexBuffersBuilder {
/** /**
* Insert a single boolean into the buffer * Insert a single boolean into the buffer
*
* @param val true or false * @param val true or false
*/ */
public void putBoolean(boolean val) { public void putBoolean(boolean val) {
@@ -198,6 +200,7 @@ public class FlexBuffersBuilder {
/** /**
* Insert a single boolean into the buffer * Insert a single boolean into the buffer
*
* @param key key used to store element in map * @param key key used to store element in map
* @param val true or false * @param val true or false
*/ */
@@ -231,6 +234,7 @@ public class FlexBuffersBuilder {
/** /**
* Adds a integer into the buff * Adds a integer into the buff
*
* @param val integer * @param val integer
*/ */
public void putInt(int val) { public void putInt(int val) {
@@ -239,6 +243,7 @@ public class FlexBuffersBuilder {
/** /**
* Adds a integer into the buff * Adds a integer into the buff
*
* @param key key used to store element in map * @param key key used to store element in map
* @param val integer * @param val integer
*/ */
@@ -248,6 +253,7 @@ public class FlexBuffersBuilder {
/** /**
* Adds a integer into the buff * Adds a integer into the buff
*
* @param key key used to store element in map * @param key key used to store element in map
* @param val 64-bit integer * @param val 64-bit integer
*/ */
@@ -266,6 +272,7 @@ public class FlexBuffersBuilder {
/** /**
* Adds a 64-bit integer into the buff * Adds a 64-bit integer into the buff
*
* @param value integer * @param value integer
*/ */
public void putInt(long value) { public void putInt(long value) {
@@ -274,6 +281,7 @@ public class FlexBuffersBuilder {
/** /**
* Adds a unsigned integer into the buff. * Adds a unsigned integer into the buff.
*
* @param value integer representing unsigned value * @param value integer representing unsigned value
*/ */
public void putUInt(int value) { public void putUInt(int value) {
@@ -282,6 +290,7 @@ public class FlexBuffersBuilder {
/** /**
* Adds a unsigned integer (stored in a signed 64-bit integer) into the buff. * Adds a unsigned integer (stored in a signed 64-bit integer) into the buff.
*
* @param value integer representing unsigned value * @param value integer representing unsigned value
*/ */
public void putUInt(long value) { public void putUInt(long value) {
@@ -289,8 +298,9 @@ public class FlexBuffersBuilder {
} }
/** /**
* Adds a 64-bit unsigned integer (stored as {@link BigInteger}) into the buff. * Adds a 64-bit unsigned integer (stored as {@link BigInteger}) into the buff. Warning: This
* Warning: This operation might be very slow. * operation might be very slow.
*
* @param value integer representing unsigned value * @param value integer representing unsigned value
*/ */
public void putUInt64(BigInteger value) { public void putUInt64(BigInteger value) {
@@ -308,11 +318,11 @@ public class FlexBuffersBuilder {
int width = widthUInBits(value); int width = widthUInBits(value);
if (width == WIDTH_8) { if (width == WIDTH_8) {
vVal = Value.uInt8(iKey, (int)value); vVal = Value.uInt8(iKey, (int) value);
} else if (width == WIDTH_16) { } else if (width == WIDTH_16) {
vVal = Value.uInt16(iKey, (int)value); vVal = Value.uInt16(iKey, (int) value);
} else if (width == WIDTH_32) { } else if (width == WIDTH_32) {
vVal = Value.uInt32(iKey, (int)value); vVal = Value.uInt32(iKey, (int) value);
} else { } else {
vVal = Value.uInt64(iKey, value); vVal = Value.uInt64(iKey, value);
} }
@@ -321,6 +331,7 @@ public class FlexBuffersBuilder {
/** /**
* Adds a 32-bit float into the buff. * Adds a 32-bit float into the buff.
*
* @param value float representing value * @param value float representing value
*/ */
public void putFloat(float value) { public void putFloat(float value) {
@@ -329,6 +340,7 @@ public class FlexBuffersBuilder {
/** /**
* Adds a 32-bit float into the buff. * Adds a 32-bit float into the buff.
*
* @param key key used to store element in map * @param key key used to store element in map
* @param value float representing value * @param value float representing value
*/ */
@@ -338,6 +350,7 @@ public class FlexBuffersBuilder {
/** /**
* Adds a 64-bit float into the buff. * Adds a 64-bit float into the buff.
*
* @param value float representing value * @param value float representing value
*/ */
public void putFloat(double value) { public void putFloat(double value) {
@@ -346,6 +359,7 @@ public class FlexBuffersBuilder {
/** /**
* Adds a 64-bit float into the buff. * Adds a 64-bit float into the buff.
*
* @param key key used to store element in map * @param key key used to store element in map
* @param value float representing value * @param value float representing value
*/ */
@@ -355,6 +369,7 @@ public class FlexBuffersBuilder {
/** /**
* Adds a String into the buffer * Adds a String into the buffer
*
* @param value string * @param value string
* @return start position of string in the buffer * @return start position of string in the buffer
*/ */
@@ -364,6 +379,7 @@ public class FlexBuffersBuilder {
/** /**
* Adds a String into the buffer * Adds a String into the buffer
*
* @param key key used to store element in map * @param key key used to store element in map
* @param value string * @param value string
* @return start position of string in the buffer * @return start position of string in the buffer
@@ -395,8 +411,8 @@ public class FlexBuffersBuilder {
// in bits to fit a unsigned int // in bits to fit a unsigned int
static int widthUInBits(long len) { static int widthUInBits(long len) {
if (len <= byteToUnsignedInt((byte)0xff)) return WIDTH_8; if (len <= byteToUnsignedInt((byte) 0xff)) return WIDTH_8;
if (len <= shortToUnsignedInt((short)0xffff)) return WIDTH_16; if (len <= shortToUnsignedInt((short) 0xffff)) return WIDTH_16;
if (len <= intToUnsignedLong(0xffff_ffff)) return WIDTH_32; if (len <= intToUnsignedLong(0xffff_ffff)) return WIDTH_32;
return WIDTH_64; return WIDTH_64;
} }
@@ -425,15 +441,24 @@ public class FlexBuffersBuilder {
private void writeInt(long value, int byteWidth) { private void writeInt(long value, int byteWidth) {
switch (byteWidth) { switch (byteWidth) {
case 1: bb.put((byte) value); break; case 1:
case 2: bb.putShort((short) value); break; bb.put((byte) value);
case 4: bb.putInt((int) value); break; break;
case 8: bb.putLong(value); break; case 2:
bb.putShort((short) value);
break;
case 4:
bb.putInt((int) value);
break;
case 8:
bb.putLong(value);
break;
} }
} }
/** /**
* Adds a byte array into the message * Adds a byte array into the message
*
* @param value byte array * @param value byte array
* @return position in buffer as the start of byte array * @return position in buffer as the start of byte array
*/ */
@@ -443,6 +468,7 @@ public class FlexBuffersBuilder {
/** /**
* Adds a byte array into the message * Adds a byte array into the message
*
* @param key key used to store element in map * @param key key used to store element in map
* @param value byte array * @param value byte array
* @return position in buffer as the start of byte array * @return position in buffer as the start of byte array
@@ -456,8 +482,9 @@ public class FlexBuffersBuilder {
/** /**
* Start a new vector in the buffer. * Start a new vector in the buffer.
* @return a reference indicating position of the vector in buffer. This *
* reference must be passed along when the vector is finished using endVector() * @return a reference indicating position of the vector in buffer. This reference must be passed
* along when the vector is finished using endVector()
*/ */
public int startVector() { public int startVector() {
return stack.size(); return stack.size();
@@ -465,6 +492,7 @@ public class FlexBuffersBuilder {
/** /**
* Finishes a vector, but writing the information in the buffer * Finishes a vector, but writing the information in the buffer
*
* @param key key used to store element in map * @param key key used to store element in map
* @param start reference for beginning of the vector. Returned by {@link startVector()} * @param start reference for beginning of the vector. Returned by {@link startVector()}
* @param typed boolean indicating whether vector is typed * @param typed boolean indicating whether vector is typed
@@ -483,9 +511,9 @@ public class FlexBuffersBuilder {
} }
/** /**
* Finish writing the message into the buffer. After that no other element must * Finish writing the message into the buffer. After that no other element must be inserted into
* be inserted into the buffer. Also, you must call this function before start using the * the buffer. Also, you must call this function before start using the FlexBuffer message
* FlexBuffer message *
* @return `ByteBuffer` containing the FlexBuffer message * @return `ByteBuffer` containing the FlexBuffer message
*/ */
public ByteBuffer finish() { public ByteBuffer finish() {
@@ -516,7 +544,8 @@ public class FlexBuffersBuilder {
* @param keys Value representing key vector * @param keys Value representing key vector
* @return Value representing the created vector * @return Value representing the created vector
*/ */
private Value createVector(int key, int start, int length, boolean typed, boolean fixed, Value keys) { private Value createVector(
int key, int start, int length, boolean typed, boolean fixed, Value keys) {
if (fixed & !typed) if (fixed & !typed)
throw new UnsupportedOperationException("Untyped fixed vector is not supported"); throw new UnsupportedOperationException("Untyped fixed vector is not supported");
@@ -571,9 +600,13 @@ public class FlexBuffersBuilder {
bb.put(stack.get(i).storedPackedType(bitWidth)); bb.put(stack.get(i).storedPackedType(bitWidth));
} }
} }
return new Value(key, keys != null ? FBT_MAP return new Value(
: (typed ? FlexBuffers.toTypedVector(vectorType, fixed ? length : 0) key,
: FBT_VECTOR), bitWidth, vloc); keys != null
? FBT_MAP
: (typed ? FlexBuffers.toTypedVector(vectorType, fixed ? length : 0) : FBT_VECTOR),
bitWidth,
vloc);
} }
private void writeOffset(long val, int byteWidth) { private void writeOffset(long val, int byteWidth) {
@@ -609,8 +642,9 @@ public class FlexBuffersBuilder {
/** /**
* Start a new map in the buffer. * Start a new map in the buffer.
* @return a reference indicating position of the map in buffer. This *
* reference must be passed along when the map is finished using endMap() * @return a reference indicating position of the map in buffer. This reference must be passed
* along when the map is finished using endMap()
*/ */
public int startMap() { public int startMap() {
return stack.size(); return stack.size();
@@ -618,6 +652,7 @@ public class FlexBuffersBuilder {
/** /**
* Finishes a map, but writing the information in the buffer * Finishes a map, but writing the information in the buffer
*
* @param key key used to store element in map * @param key key used to store element in map
* @param start reference for beginning of the map. Returned by {@link startMap()} * @param start reference for beginning of the map. Returned by {@link startMap()}
* @return Reference to the map * @return Reference to the map
@@ -643,7 +678,8 @@ public class FlexBuffersBuilder {
int prefixElems = 1; int prefixElems = 1;
// Check bit widths and types for all elements. // Check bit widths and types for all elements.
for (int i = start; i < stack.size(); i++) { for (int i = start; i < stack.size(); i++) {
int elemWidth = Value.elemWidth(FBT_KEY, WIDTH_8, stack.get(i).key, bb.writePosition(), i + prefixElems); int elemWidth =
Value.elemWidth(FBT_KEY, WIDTH_8, stack.get(i).key, bb.writePosition(), i + prefixElems);
bitWidth = Math.max(bitWidth, elemWidth); bitWidth = Math.max(bitWidth, elemWidth);
} }
@@ -654,11 +690,11 @@ public class FlexBuffersBuilder {
int vloc = bb.writePosition(); int vloc = bb.writePosition();
for (int i = start; i < stack.size(); i++) { for (int i = start; i < stack.size(); i++) {
int pos = stack.get(i).key; int pos = stack.get(i).key;
assert(pos != -1); assert (pos != -1);
writeOffset(stack.get(i).key, byteWidth); writeOffset(stack.get(i).key, byteWidth);
} }
// Then the types. // Then the types.
return new Value(-1, FlexBuffers.toTypedVector(FBT_KEY,0), bitWidth, vloc); return new Value(-1, FlexBuffers.toTypedVector(FBT_KEY, 0), bitWidth, vloc);
} }
private static class Value { private static class Value {
@@ -766,7 +802,8 @@ public class FlexBuffersBuilder {
return elemWidth(type, minBitWidth, iValue, bufSize, elemIndex); return elemWidth(type, minBitWidth, iValue, bufSize, elemIndex);
} }
private static int elemWidth(int type, int minBitWidth, long iValue, int bufSize, int elemIndex) { private static int elemWidth(
int type, int minBitWidth, long iValue, int bufSize, int elemIndex) {
if (FlexBuffers.isTypeInline(type)) { if (FlexBuffers.isTypeInline(type)) {
return minBitWidth; return minBitWidth;
} else { } else {
@@ -785,8 +822,7 @@ public class FlexBuffersBuilder {
long offset = offsetLoc - iValue; long offset = offsetLoc - iValue;
// Does it fit? // Does it fit?
int bitWidth = widthUInBits(offset); int bitWidth = widthUInBits(offset);
if (((1L) << bitWidth) == byteWidth) if (((1L) << bitWidth) == byteWidth) return bitWidth;
return bitWidth;
} }
assert (false); // Must match one of the sizes above. assert (false); // Must match one of the sizes above.
return WIDTH_64; return WIDTH_64;

View File

@@ -17,13 +17,10 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*; import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/** import java.nio.ByteBuffer;
* Helper type for accessing vector of float values.
*/ /** Helper type for accessing vector of float values. */
public final class FloatVector extends BaseVector { public final class FloatVector extends BaseVector {
/** /**
* Assigns vector access object to vector data. * Assigns vector access object to vector data.
@@ -34,7 +31,8 @@ public final class FloatVector extends BaseVector {
* `vector`. * `vector`.
*/ */
public FloatVector __assign(int _vector, ByteBuffer _bb) { public FloatVector __assign(int _vector, ByteBuffer _bb) {
__reset(_vector, Constants.SIZEOF_FLOAT, _bb); return this; __reset(_vector, Constants.SIZEOF_FLOAT, _bb);
return this;
} }
/** /**

View File

@@ -17,13 +17,10 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*; import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/** import java.nio.ByteBuffer;
* Helper type for accessing vector of signed or unsigned 32-bit values.
*/ /** Helper type for accessing vector of signed or unsigned 32-bit values. */
public final class IntVector extends BaseVector { public final class IntVector extends BaseVector {
/** /**
* Assigns vector access object to vector data. * Assigns vector access object to vector data.
@@ -34,7 +31,8 @@ public final class IntVector extends BaseVector {
* `vector`. * `vector`.
*/ */
public IntVector __assign(int _vector, ByteBuffer _bb) { public IntVector __assign(int _vector, ByteBuffer _bb) {
__reset(_vector, Constants.SIZEOF_INT, _bb); return this; __reset(_vector, Constants.SIZEOF_INT, _bb);
return this;
} }
/** /**

View File

@@ -17,13 +17,10 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*; import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/** import java.nio.ByteBuffer;
* Helper type for accessing vector of long values.
*/ /** Helper type for accessing vector of long values. */
public final class LongVector extends BaseVector { public final class LongVector extends BaseVector {
/** /**
* Assigns vector access object to vector data. * Assigns vector access object to vector data.
@@ -34,7 +31,8 @@ public final class LongVector extends BaseVector {
* `vector`. * `vector`.
*/ */
public LongVector __assign(int _vector, ByteBuffer _bb) { public LongVector __assign(int _vector, ByteBuffer _bb) {
__reset(_vector, Constants.SIZEOF_LONG, _bb); return this; __reset(_vector, Constants.SIZEOF_LONG, _bb);
return this;
} }
/** /**

View File

@@ -1,12 +1,11 @@
package com.google.flatbuffers; package com.google.flatbuffers;
/** /** Represent a chunk of data, where FlexBuffers will read from. */
* Represent a chunk of data, where FlexBuffers will read from.
*/
public interface ReadBuf { public interface ReadBuf {
/** /**
* Read boolean from data. Booleans as stored as single byte * Read boolean from data. Booleans as stored as single byte
*
* @param index position of the element in ReadBuf * @param index position of the element in ReadBuf
* @return boolean element * @return boolean element
*/ */
@@ -14,6 +13,7 @@ public interface ReadBuf {
/** /**
* Read a byte from data. * Read a byte from data.
*
* @param index position of the element in ReadBuf * @param index position of the element in ReadBuf
* @return a byte * @return a byte
*/ */
@@ -21,6 +21,7 @@ public interface ReadBuf {
/** /**
* Read a short from data. * Read a short from data.
*
* @param index position of the element in ReadBuf * @param index position of the element in ReadBuf
* @return a short * @return a short
*/ */
@@ -28,6 +29,7 @@ public interface ReadBuf {
/** /**
* Read a 32-bit int from data. * Read a 32-bit int from data.
*
* @param index position of the element in ReadBuf * @param index position of the element in ReadBuf
* @return an int * @return an int
*/ */
@@ -35,6 +37,7 @@ public interface ReadBuf {
/** /**
* Read a 64-bit long from data. * Read a 64-bit long from data.
*
* @param index position of the element in ReadBuf * @param index position of the element in ReadBuf
* @return a long * @return a long
*/ */
@@ -42,6 +45,7 @@ public interface ReadBuf {
/** /**
* Read a 32-bit float from data. * Read a 32-bit float from data.
*
* @param index position of the element in ReadBuf * @param index position of the element in ReadBuf
* @return a float * @return a float
*/ */
@@ -49,6 +53,7 @@ public interface ReadBuf {
/** /**
* Read a 64-bit float from data. * Read a 64-bit float from data.
*
* @param index position of the element in ReadBuf * @param index position of the element in ReadBuf
* @return a double * @return a double
*/ */
@@ -56,6 +61,7 @@ public interface ReadBuf {
/** /**
* Read an UTF-8 string from data. * Read an UTF-8 string from data.
*
* @param start initial element of the string * @param start initial element of the string
* @param size size of the string in bytes. * @param size size of the string in bytes.
* @return a {@code String} * @return a {@code String}
@@ -63,19 +69,19 @@ public interface ReadBuf {
String getString(int start, int size); String getString(int start, int size);
/** /**
* Expose ReadBuf as an array of bytes. * Expose ReadBuf as an array of bytes. This method is meant to be as efficient as possible, so
* This method is meant to be as efficient as possible, so for a array-backed ReadBuf, it should * for a array-backed ReadBuf, it should return its own internal data. In case access to internal
* return its own internal data. In case access to internal data is not possible, * data is not possible, a copy of the data into an array of bytes might occur.
* a copy of the data into an array of bytes might occur. *
* @return ReadBuf as an array of bytes * @return ReadBuf as an array of bytes
*/ */
byte[] data(); byte[] data();
/** /**
* Defines the size of the message in the buffer. It also determines last position that buffer * Defines the size of the message in the buffer. It also determines last position that buffer can
* can be read. Last byte to be accessed is in position {@code limit() -1}. * be read. Last byte to be accessed is in position {@code limit() -1}.
*
* @return indicate last position * @return indicate last position
*/ */
int limit(); int limit();
} }

View File

@@ -7,14 +7,14 @@ package com.google.flatbuffers;
public interface ReadWriteBuf extends ReadBuf { public interface ReadWriteBuf extends ReadBuf {
/** /**
* Clears (resets) the buffer so that it can be reused. Write position will be set to the * Clears (resets) the buffer so that it can be reused. Write position will be set to the start.
* start.
*/ */
void clear(); void clear();
/** /**
* Put a boolean into the buffer at {@code writePosition()} . Booleans as stored as single * Put a boolean into the buffer at {@code writePosition()} . Booleans as stored as single byte.
* byte. Write position will be incremented. * Write position will be incremented.
*
* @return boolean element * @return boolean element
*/ */
void putBoolean(boolean value); void putBoolean(boolean value);
@@ -22,15 +22,15 @@ public interface ReadWriteBuf extends ReadBuf {
/** /**
* Put an array of bytes into the buffer at {@code writePosition()}. Write position will be * Put an array of bytes into the buffer at {@code writePosition()}. Write position will be
* incremented. * incremented.
*
* @param value the data to be copied * @param value the data to be copied
* @param start initial position on value to be copied * @param start initial position on value to be copied
* @param length amount of bytes to be copied * @param length amount of bytes to be copied
*/ */
void put (byte[] value, int start, int length); void put(byte[] value, int start, int length);
/** /**
* Write a byte into the buffer at {@code writePosition()}. Write position will be * Write a byte into the buffer at {@code writePosition()}. Write position will be incremented.
* incremented.
*/ */
void put(byte value); void put(byte value);
@@ -66,12 +66,14 @@ public interface ReadWriteBuf extends ReadBuf {
/** /**
* Write boolean into a given position on the buffer. Booleans as stored as single byte. * Write boolean into a given position on the buffer. Booleans as stored as single byte.
*
* @param index position of the element in buffer * @param index position of the element in buffer
*/ */
void setBoolean(int index, boolean value); void setBoolean(int index, boolean value);
/** /**
* Read a byte from data. * Read a byte from data.
*
* @param index position of the element in the buffer * @param index position of the element in the buffer
* @return a byte * @return a byte
*/ */
@@ -79,6 +81,7 @@ public interface ReadWriteBuf extends ReadBuf {
/** /**
* Write an array of bytes into the buffer. * Write an array of bytes into the buffer.
*
* @param index initial position of the buffer to be written * @param index initial position of the buffer to be written
* @param value the data to be copied * @param value the data to be copied
* @param start initial position on value to be copied * @param start initial position on value to be copied
@@ -88,6 +91,7 @@ public interface ReadWriteBuf extends ReadBuf {
/** /**
* Read a short from data. * Read a short from data.
*
* @param index position of the element in ReadBuf * @param index position of the element in ReadBuf
* @return a short * @return a short
*/ */
@@ -95,6 +99,7 @@ public interface ReadWriteBuf extends ReadBuf {
/** /**
* Read a 32-bit int from data. * Read a 32-bit int from data.
*
* @param index position of the element in ReadBuf * @param index position of the element in ReadBuf
* @return an int * @return an int
*/ */
@@ -102,6 +107,7 @@ public interface ReadWriteBuf extends ReadBuf {
/** /**
* Read a 64-bit long from data. * Read a 64-bit long from data.
*
* @param index position of the element in ReadBuf * @param index position of the element in ReadBuf
* @return a long * @return a long
*/ */
@@ -109,6 +115,7 @@ public interface ReadWriteBuf extends ReadBuf {
/** /**
* Read a 32-bit float from data. * Read a 32-bit float from data.
*
* @param index position of the element in ReadBuf * @param index position of the element in ReadBuf
* @return a float * @return a float
*/ */
@@ -116,27 +123,27 @@ public interface ReadWriteBuf extends ReadBuf {
/** /**
* Read a 64-bit float from data. * Read a 64-bit float from data.
*
* @param index position of the element in ReadBuf * @param index position of the element in ReadBuf
* @return a double * @return a double
*/ */
void setDouble(int index, double value); void setDouble(int index, double value);
int writePosition(); int writePosition();
/** /**
* Defines the size of the message in the buffer. It also determines last position that buffer * Defines the size of the message in the buffer. It also determines last position that buffer can
* can be read or write. Last byte to be accessed is in position {@code limit() -1}. * be read or write. Last byte to be accessed is in position {@code limit() -1}.
*
* @return indicate last position * @return indicate last position
*/ */
int limit(); int limit();
/** /**
* Request capacity of the buffer. In case buffer is already larger * Request capacity of the buffer. In case buffer is already larger than the requested, this
* than the requested, this method will just return true. Otherwise * method will just return true. Otherwise It might try to resize the buffer.
* It might try to resize the buffer.
* *
* @return true if buffer is able to offer * @return true if buffer is able to offer the requested capacity
* the requested capacity
*/ */
boolean requestCapacity(int capacity); boolean requestCapacity(int capacity);
} }

View File

@@ -17,13 +17,10 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*; import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/** import java.nio.ByteBuffer;
* Helper type for accessing vector of signed or unsigned 16-bit values.
*/ /** Helper type for accessing vector of signed or unsigned 16-bit values. */
public final class ShortVector extends BaseVector { public final class ShortVector extends BaseVector {
/** /**
* Assigns vector access object to vector data. * Assigns vector access object to vector data.
@@ -34,7 +31,8 @@ public final class ShortVector extends BaseVector {
* `vector`. * `vector`.
*/ */
public ShortVector __assign(int _vector, ByteBuffer _bb) { public ShortVector __assign(int _vector, ByteBuffer _bb) {
__reset(_vector, Constants.SIZEOF_SHORT, _bb); return this; __reset(_vector, Constants.SIZEOF_SHORT, _bb);
return this;
} }
/** /**
@@ -48,8 +46,8 @@ public final class ShortVector extends BaseVector {
} }
/** /**
* Reads the short at the given index, zero-extends it to type int, and returns the result, * Reads the short at the given index, zero-extends it to type int, and returns the result, which
* which is therefore in the range 0 through 65535. * is therefore in the range 0 through 65535.
* *
* @param j The index from which the short value will be read. * @param j The index from which the short value will be read.
* @return the unsigned 16-bit at the given index. * @return the unsigned 16-bit at the given index.

View File

@@ -17,13 +17,10 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*; import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/** import java.nio.ByteBuffer;
* Helper type for accessing vector of String.
*/ /** Helper type for accessing vector of String. */
public final class StringVector extends BaseVector { public final class StringVector extends BaseVector {
private Utf8 utf8 = Utf8.getDefault(); private Utf8 utf8 = Utf8.getDefault();
@@ -37,7 +34,8 @@ public final class StringVector extends BaseVector {
* `vector`. * `vector`.
*/ */
public StringVector __assign(int _vector, int _element_size, ByteBuffer _bb) { public StringVector __assign(int _vector, int _element_size, ByteBuffer _bb) {
__reset(_vector, _element_size, _bb); return this; __reset(_vector, _element_size, _bb);
return this;
} }
/** /**

View File

@@ -20,19 +20,18 @@ import java.nio.ByteBuffer;
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
/** /** All structs in the generated code derive from this class, and add their own accessors. */
* All structs in the generated code derive from this class, and add their own accessors.
*/
public class Struct { public class Struct {
/** 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;
/** The underlying ByteBuffer to hold the data of the Struct. */ /** The underlying ByteBuffer to hold the data of the Struct. */
protected ByteBuffer bb; protected ByteBuffer bb;
/** /**
* Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within. * Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
* *
* This method exists primarily to allow recycling Table instances without risking memory leaks * <p>This method exists primarily to allow recycling Table instances without risking memory leaks
* due to {@code ByteBuffer} references. * due to {@code ByteBuffer} references.
*/ */
protected void __reset(int _i, ByteBuffer _bb) { protected void __reset(int _i, ByteBuffer _bb) {
@@ -47,8 +46,8 @@ public class Struct {
/** /**
* Resets internal state with a null {@code ByteBuffer} and a zero position. * Resets internal state with a null {@code ByteBuffer} and a zero position.
* *
* This method exists primarily to allow recycling Struct instances without risking memory leaks * <p>This method exists primarily to allow recycling Struct instances without risking memory
* due to {@code ByteBuffer} references. The instance will be unusable until it is assigned * leaks due to {@code ByteBuffer} references. The instance will be unusable until it is assigned
* again to a {@code ByteBuffer}. * again to a {@code ByteBuffer}.
* *
* @param struct the instance to reset to initial state * @param struct the instance to reset to initial state

View File

@@ -17,23 +17,26 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*; import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
/** /** All tables in the generated code derive from this class, and add their own accessors. */
* All tables in the generated code derive from this class, and add their own accessors.
*/
public class Table { public class Table {
/** 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;
/** The underlying ByteBuffer to hold the data of the Table. */ /** The underlying ByteBuffer to hold the data of the Table. */
protected ByteBuffer bb; protected ByteBuffer bb;
/** Used to hold the vtable position. */ /** Used to hold the vtable position. */
private int vtable_start; private int vtable_start;
/** Used to hold the vtable size. */ /** Used to hold the vtable size. */
private int vtable_size; private int vtable_size;
Utf8 utf8 = Utf8.getDefault(); Utf8 utf8 = Utf8.getDefault();
/** /**
@@ -41,7 +44,9 @@ public class Table {
* *
* @return Returns the Table's ByteBuffer. * @return Returns the Table's ByteBuffer.
*/ */
public ByteBuffer getByteBuffer() { return bb; } public ByteBuffer getByteBuffer() {
return bb;
}
/** /**
* Look up a field in the vtable. * Look up a field in the vtable.
@@ -82,10 +87,10 @@ public class Table {
/** /**
* Create a Java `String` from UTF-8 data stored inside the FlatBuffer. * Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
* *
* This allocates a new string and converts to wide chars upon each access, * <p>This allocates a new string and converts to wide chars upon each access, which is not very
* which is not very efficient. Instead, each FlatBuffer string also comes with an * efficient. Instead, each FlatBuffer string also comes with an accessor based on
* accessor based on __vector_as_bytebuffer below, which is much more efficient, * __vector_as_bytebuffer below, which is much more efficient, assuming your Java program can
* assuming your Java program can handle UTF-8 data directly. * handle UTF-8 data directly.
* *
* @param offset An `int` index into the Table's ByteBuffer. * @param offset An `int` index into the Table's ByteBuffer.
* @return Returns a `String` from the data stored inside the FlatBuffer at `offset`. * @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
@@ -97,10 +102,10 @@ public class Table {
/** /**
* Create a Java `String` from UTF-8 data stored inside the FlatBuffer. * Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
* *
* This allocates a new string and converts to wide chars upon each access, * <p>This allocates a new string and converts to wide chars upon each access, which is not very
* which is not very efficient. Instead, each FlatBuffer string also comes with an * efficient. Instead, each FlatBuffer string also comes with an accessor based on
* accessor based on __vector_as_bytebuffer below, which is much more efficient, * __vector_as_bytebuffer below, which is much more efficient, assuming your Java program can
* assuming your Java program can handle UTF-8 data directly. * handle UTF-8 data directly.
* *
* @param offset An `int` index into the Table's ByteBuffer. * @param offset An `int` index into the Table's ByteBuffer.
* @param bb Table ByteBuffer used to read a string at given offset. * @param bb Table ByteBuffer used to read a string at given offset.
@@ -139,9 +144,9 @@ public class Table {
/** /**
* Get a whole vector as a ByteBuffer. * Get a whole vector as a ByteBuffer.
* *
* This is efficient, since it only allocates a new {@link ByteBuffer} object, * <p>This is efficient, since it only allocates a new {@link ByteBuffer} object, but does not
* but does not actually copy the data, it still refers to the same bytes * actually copy the data, it still refers to the same bytes as the original ByteBuffer. Also
* as the original ByteBuffer. Also useful with nested FlatBuffers, etc. * useful with nested FlatBuffers, etc.
* *
* @param vector_offset The position of the vector in the byte buffer * @param vector_offset The position of the vector in the byte buffer
* @param elem_size The size of each element in the array * @param elem_size The size of each element in the array
@@ -160,8 +165,8 @@ public class Table {
/** /**
* Initialize vector as a ByteBuffer. * Initialize vector as a ByteBuffer.
* *
* This is more efficient than using duplicate, since it doesn't copy the data * <p>This is more efficient than using duplicate, since it doesn't copy the data nor allocattes a
* nor allocattes a new {@link ByteBuffer}, creating no garbage to be collected. * new {@link ByteBuffer}, creating no garbage to be collected.
* *
* @param bb The {@link ByteBuffer} for the array * @param bb The {@link ByteBuffer} for the array
* @param vector_offset The position of the vector in the byte buffer * @param vector_offset The position of the vector in the byte buffer
@@ -205,17 +210,16 @@ public class Table {
/** /**
* Check if a {@link ByteBuffer} contains a file identifier. * Check if a {@link ByteBuffer} contains a file identifier.
* *
* @param bb A {@code ByteBuffer} to check if it contains the identifier * @param bb A {@code ByteBuffer} to check if it contains the identifier `ident`.
* `ident`.
* @param ident A `String` identifier of the FlatBuffer file. * @param ident A `String` identifier of the FlatBuffer file.
* @return True if the buffer contains the file identifier * @return True if the buffer contains the file identifier
*/ */
protected static boolean __has_identifier(ByteBuffer bb, String ident) { protected static boolean __has_identifier(ByteBuffer bb, String ident) {
if (ident.length() != FILE_IDENTIFIER_LENGTH) if (ident.length() != FILE_IDENTIFIER_LENGTH)
throw new AssertionError("FlatBuffers: file identifier must be length " + throw new AssertionError(
FILE_IDENTIFIER_LENGTH); "FlatBuffers: file identifier must be length " + FILE_IDENTIFIER_LENGTH);
for (int i = 0; i < FILE_IDENTIFIER_LENGTH; i++) { for (int i = 0; i < FILE_IDENTIFIER_LENGTH; i++) {
if (ident.charAt(i) != (char)bb.get(bb.position() + SIZEOF_INT + i)) return false; if (ident.charAt(i) != (char) bb.get(bb.position() + SIZEOF_INT + i)) return false;
} }
return true; return true;
} }
@@ -229,7 +233,9 @@ public class Table {
protected void sortTables(int[] offsets, final 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];
java.util.Arrays.sort(off, new java.util.Comparator<Integer>() { java.util.Arrays.sort(
off,
new java.util.Comparator<Integer>() {
public int compare(Integer o1, Integer o2) { public int compare(Integer o1, Integer o2) {
return keysCompare(o1, o2, bb); return keysCompare(o1, o2, bb);
} }
@@ -244,7 +250,9 @@ public class Table {
* @param o2 An 'Integer' index of the second key into the bb. * @param o2 An 'Integer' index of the second key into the bb.
* @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.
@@ -261,7 +269,7 @@ public class Table {
int startPos_1 = offset_1 + SIZEOF_INT; int startPos_1 = offset_1 + SIZEOF_INT;
int startPos_2 = offset_2 + SIZEOF_INT; int startPos_2 = offset_2 + SIZEOF_INT;
int len = Math.min(len_1, len_2); int len = Math.min(len_1, len_2);
for(int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (bb.get(i + startPos_1) != bb.get(i + startPos_2)) if (bb.get(i + startPos_1) != bb.get(i + startPos_2))
return bb.get(i + startPos_1) - bb.get(i + startPos_2); return bb.get(i + startPos_1) - bb.get(i + startPos_2);
} }
@@ -282,8 +290,7 @@ public class Table {
int startPos_1 = offset_1 + Constants.SIZEOF_INT; int startPos_1 = offset_1 + Constants.SIZEOF_INT;
int len = Math.min(len_1, len_2); int len = Math.min(len_1, len_2);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (bb.get(i + startPos_1) != key[i]) if (bb.get(i + startPos_1) != key[i]) return bb.get(i + startPos_1) - key[i];
return bb.get(i + startPos_1) - key[i];
} }
return len_1 - len_2; return len_1 - len_2;
} }
@@ -291,7 +298,7 @@ public class Table {
/** /**
* Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within. * Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
* *
* This method exists primarily to allow recycling Table instances without risking memory leaks * <p>This method exists primarily to allow recycling Table instances without risking memory leaks
* due to {@code ByteBuffer} references. * due to {@code ByteBuffer} references.
*/ */
protected void __reset(int _i, ByteBuffer _bb) { protected void __reset(int _i, ByteBuffer _bb) {
@@ -310,9 +317,9 @@ public class Table {
/** /**
* Resets the internal state with a null {@code ByteBuffer} and a zero position. * Resets the internal state with a null {@code ByteBuffer} and a zero position.
* *
* This method exists primarily to allow recycling Table instances without risking memory leaks * <p>This method exists primarily to allow recycling Table instances without risking memory leaks
* due to {@code ByteBuffer} references. The instance will be unusable until it is assigned * due to {@code ByteBuffer} references. The instance will be unusable until it is assigned again
* again to a {@code ByteBuffer}. * to a {@code ByteBuffer}.
*/ */
public void __reset() { public void __reset() {
__reset(0, null); __reset(0, null);

View File

@@ -17,13 +17,10 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*; import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/** import java.nio.ByteBuffer;
* Helper type for accessing vector of unions.
*/ /** Helper type for accessing vector of unions. */
public final class UnionVector extends BaseVector { public final class UnionVector extends BaseVector {
/** /**
* Assigns vector access object to vector data. * Assigns vector access object to vector data.
@@ -35,10 +32,10 @@ public final class UnionVector extends BaseVector {
* `vector`. * `vector`.
*/ */
public UnionVector __assign(int _vector, int _element_size, ByteBuffer _bb) { public UnionVector __assign(int _vector, int _element_size, ByteBuffer _bb) {
__reset(_vector, _element_size, _bb); return this; __reset(_vector, _element_size, _bb);
return this;
} }
/** /**
* Initialize any Table-derived type to point to the union at the given `index`. * Initialize any Table-derived type to point to the union at the given `index`.
* *

View File

@@ -16,22 +16,22 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import java.nio.ByteBuffer;
import static java.lang.Character.MAX_SURROGATE; import static java.lang.Character.MAX_SURROGATE;
import static java.lang.Character.MIN_SURROGATE;
import static java.lang.Character.MIN_HIGH_SURROGATE; import static java.lang.Character.MIN_HIGH_SURROGATE;
import static java.lang.Character.MIN_LOW_SURROGATE; import static java.lang.Character.MIN_LOW_SURROGATE;
import static java.lang.Character.MIN_SUPPLEMENTARY_CODE_POINT; import static java.lang.Character.MIN_SUPPLEMENTARY_CODE_POINT;
import static java.lang.Character.MIN_SURROGATE;
import static java.lang.Character.isSurrogatePair; import static java.lang.Character.isSurrogatePair;
import static java.lang.Character.toCodePoint; import static java.lang.Character.toCodePoint;
import java.nio.ByteBuffer;
public abstract class Utf8 { public abstract class Utf8 {
/** /**
* Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string, * Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string, this
* this method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in * method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in both
* both time and space. * time and space.
* *
* @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
* surrogates) * surrogates)
@@ -60,6 +60,7 @@ public abstract class Utf8 {
/** /**
* Get the default UTF-8 processor. * Get the default UTF-8 processor.
*
* @return the default processor * @return the default processor
*/ */
public static Utf8 getDefault() { public static Utf8 getDefault() {
@@ -71,6 +72,7 @@ public abstract class Utf8 {
/** /**
* Set the default instance of the UTF-8 processor. * Set the default instance of the UTF-8 processor.
*
* @param instance the new instance to use * @param instance the new instance to use
*/ */
public static void setDefault(Utf8 instance) { public static void setDefault(Utf8 instance) {
@@ -79,6 +81,7 @@ public abstract class Utf8 {
/** /**
* Encode a Java's CharSequence UTF8 codepoint into a byte array. * Encode a Java's CharSequence UTF8 codepoint into a byte array.
*
* @param in CharSequence to be encoded * @param in CharSequence to be encoded
* @param start start position of the first char in the codepoint * @param start start position of the first char in the codepoint
* @param out byte array of 4 bytes to be filled * @param out byte array of 4 bytes to be filled
@@ -107,7 +110,7 @@ public abstract class Utf8 {
// Three bytes (1110 xxxx 10xx xxxx 10xx xxxx) // Three bytes (1110 xxxx 10xx xxxx 10xx xxxx)
// Maximum single-char code point is 0xFFFF, 16 bits. // Maximum single-char code point is 0xFFFF, 16 bits.
out[0] = (byte) (0xE0 | (c >>> 12)); out[0] = (byte) (0xE0 | (c >>> 12));
out[1] =(byte) (0x80 | (0x3F & (c >>> 6))); out[1] = (byte) (0x80 | (0x3F & (c >>> 6)));
out[2] = (byte) (0x80 | (0x3F & c)); out[2] = (byte) (0x80 | (0x3F & c));
return 3; return 3;
} else { } else {
@@ -115,7 +118,7 @@ public abstract class Utf8 {
// Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8 // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8
// bytes // bytes
final char low; final char low;
if (start + 1 == inLength || !isSurrogatePair(c, (low = in.charAt(start+1)))) { if (start + 1 == inLength || !isSurrogatePair(c, (low = in.charAt(start + 1)))) {
throw new UnpairedSurrogateException(start, inLength); throw new UnpairedSurrogateException(start, inLength);
} }
int codePoint = toCodePoint(c, low); int codePoint = toCodePoint(c, low);
@@ -134,23 +137,17 @@ public abstract class Utf8 {
*/ */
static class DecodeUtil { static class DecodeUtil {
/** /** Returns whether this is a single-byte codepoint (i.e., ASCII) with the form '0XXXXXXX'. */
* Returns whether this is a single-byte codepoint (i.e., ASCII) with the form '0XXXXXXX'.
*/
static boolean isOneByte(byte b) { static boolean isOneByte(byte b) {
return b >= 0; return b >= 0;
} }
/** /** Returns whether this is a two-byte codepoint with the form '10XXXXXX'. */
* Returns whether this is a two-byte codepoint with the form '10XXXXXX'.
*/
static boolean isTwoBytes(byte b) { static boolean isTwoBytes(byte b) {
return b < (byte) 0xE0; return b < (byte) 0xE0;
} }
/** /** Returns whether this is a three-byte codepoint with the form '110XXXXX'. */
* Returns whether this is a three-byte codepoint with the form '110XXXXX'.
*/
static boolean isThreeBytes(byte b) { static boolean isThreeBytes(byte b) {
return b < (byte) 0xF0; return b < (byte) 0xF0;
} }
@@ -159,8 +156,7 @@ public abstract class Utf8 {
resultArr[resultPos] = (char) byte1; resultArr[resultPos] = (char) byte1;
} }
static void handleTwoBytes( static void handleTwoBytes(byte byte1, byte byte2, char[] resultArr, int resultPos)
byte byte1, byte byte2, char[] resultArr, int resultPos)
throws IllegalArgumentException { throws IllegalArgumentException {
// Simultaneously checks for illegal trailing-byte in leading position (<= '11000000') and // Simultaneously checks for illegal trailing-byte in leading position (<= '11000000') and
// overlong 2-byte, '11000001'. // overlong 2-byte, '11000001'.
@@ -184,13 +180,14 @@ public abstract class Utf8 {
|| isNotTrailingByte(byte3)) { || isNotTrailingByte(byte3)) {
throw new IllegalArgumentException("Invalid UTF-8"); throw new IllegalArgumentException("Invalid UTF-8");
} }
resultArr[resultPos] = (char) resultArr[resultPos] =
(char)
(((byte1 & 0x0F) << 12) | (trailingByteValue(byte2) << 6) | trailingByteValue(byte3)); (((byte1 & 0x0F) << 12) | (trailingByteValue(byte2) << 6) | trailingByteValue(byte3));
} }
static void handleFourBytes( static void handleFourBytes(
byte byte1, byte byte2, byte byte3, byte byte4, char[] resultArr, int resultPos) byte byte1, byte byte2, byte byte3, byte byte4, char[] resultArr, int resultPos)
throws IllegalArgumentException{ throws IllegalArgumentException {
if (isNotTrailingByte(byte2) if (isNotTrailingByte(byte2)
// Check that 1 <= plane <= 16. Tricky optimized form of: // Check that 1 <= plane <= 16. Tricky optimized form of:
// valid 4-byte leading byte? // valid 4-byte leading byte?
@@ -204,7 +201,8 @@ public abstract class Utf8 {
|| isNotTrailingByte(byte4)) { || isNotTrailingByte(byte4)) {
throw new IllegalArgumentException("Invalid UTF-8"); throw new IllegalArgumentException("Invalid UTF-8");
} }
int codepoint = ((byte1 & 0x07) << 18) int codepoint =
((byte1 & 0x07) << 18)
| (trailingByteValue(byte2) << 12) | (trailingByteValue(byte2) << 12)
| (trailingByteValue(byte3) << 6) | (trailingByteValue(byte3) << 6)
| trailingByteValue(byte4); | trailingByteValue(byte4);
@@ -212,23 +210,19 @@ public abstract class Utf8 {
resultArr[resultPos + 1] = DecodeUtil.lowSurrogate(codepoint); resultArr[resultPos + 1] = DecodeUtil.lowSurrogate(codepoint);
} }
/** /** Returns whether the byte is not a valid continuation of the form '10XXXXXX'. */
* Returns whether the byte is not a valid continuation of the form '10XXXXXX'.
*/
private static boolean isNotTrailingByte(byte b) { private static boolean isNotTrailingByte(byte b) {
return b > (byte) 0xBF; return b > (byte) 0xBF;
} }
/** /** Returns the actual value of the trailing byte (removes the prefix '10') for composition. */
* Returns the actual value of the trailing byte (removes the prefix '10') for composition.
*/
private static int trailingByteValue(byte b) { private static int trailingByteValue(byte b) {
return b & 0x3F; return b & 0x3F;
} }
private static char highSurrogate(int codePoint) { private static char highSurrogate(int codePoint) {
return (char) ((MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT >>> 10)) return (char)
+ (codePoint >>> 10)); ((MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT >>> 10)) + (codePoint >>> 10));
} }
private static char lowSurrogate(int codePoint) { private static char lowSurrogate(int codePoint) {
@@ -236,7 +230,8 @@ public abstract class Utf8 {
} }
} }
// These UTF-8 handling methods are copied from Guava's Utf8Unsafe class with a modification to throw // These UTF-8 handling methods are copied from Guava's Utf8Unsafe class with a modification to
// throw
// a protocol buffer local exception. This exception is then caught in CodedOutputStream so it can // a protocol buffer local exception. This exception is then caught in CodedOutputStream so it can
// fallback to more lenient behavior. // fallback to more lenient behavior.
static class UnpairedSurrogateException extends IllegalArgumentException { static class UnpairedSurrogateException extends IllegalArgumentException {

View File

@@ -25,8 +25,8 @@ import java.nio.charset.CoderResult;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
/** /**
* This class implements the Utf8 API using the Java Utf8 encoder. Use * This class implements the Utf8 API using the Java Utf8 encoder. Use Utf8.setDefault(new
* Utf8.setDefault(new Utf8Old()); to use it. * Utf8Old()); to use it.
*/ */
public class Utf8Old extends Utf8 { public class Utf8Old extends Utf8 {
@@ -64,8 +64,7 @@ public class Utf8Old extends Utf8 {
} }
cache.lastOutput.clear(); cache.lastOutput.clear();
cache.lastInput = in; cache.lastInput = in;
CharBuffer wrap = (in instanceof CharBuffer) ? CharBuffer wrap = (in instanceof CharBuffer) ? (CharBuffer) in : CharBuffer.wrap(in);
(CharBuffer) in : CharBuffer.wrap(in);
CoderResult result = cache.encoder.encode(wrap, cache.lastOutput, true); CoderResult result = cache.encoder.encode(wrap, cache.lastOutput, true);
if (result.isError()) { if (result.isError()) {
try { try {

View File

@@ -1,41 +1,39 @@
package com.google.flatbuffers; package com.google.flatbuffers;
import java.nio.ByteBuffer;
import static java.lang.Character.MAX_SURROGATE; import static java.lang.Character.MAX_SURROGATE;
import static java.lang.Character.MIN_SUPPLEMENTARY_CODE_POINT; import static java.lang.Character.MIN_SUPPLEMENTARY_CODE_POINT;
import static java.lang.Character.MIN_SURROGATE; import static java.lang.Character.MIN_SURROGATE;
import static java.lang.Character.isSurrogatePair; import static java.lang.Character.isSurrogatePair;
import static java.lang.Character.toCodePoint; import static java.lang.Character.toCodePoint;
import java.nio.ByteBuffer;
/** /**
* A set of low-level, high-performance static utility methods related * A set of low-level, high-performance static utility methods related to the UTF-8 character
* to the UTF-8 character encoding. This class has no dependencies * encoding. This class has no dependencies outside of the core JDK libraries.
* outside of the core JDK libraries.
* *
* <p>There are several variants of UTF-8. The one implemented by * <p>There are several variants of UTF-8. The one implemented by this class is the restricted
* this class is the restricted definition of UTF-8 introduced in * definition of UTF-8 introduced in Unicode 3.1, which mandates the rejection of "overlong" byte
* Unicode 3.1, which mandates the rejection of "overlong" byte * sequences as well as rejection of 3-byte surrogate codepoint byte sequences. Note that the UTF-8
* sequences as well as rejection of 3-byte surrogate codepoint byte * decoder included in Oracle's JDK has been modified to also reject "overlong" byte sequences, but
* sequences. Note that the UTF-8 decoder included in Oracle's JDK * (as of 2011) still accepts 3-byte surrogate codepoint byte sequences.
* has been modified to also reject "overlong" byte sequences, but (as
* of 2011) still accepts 3-byte surrogate codepoint byte sequences.
* *
* <p>The byte sequences considered valid by this class are exactly * <p>The byte sequences considered valid by this class are exactly those that can be roundtrip
* those that can be roundtrip converted to Strings and back to bytes * converted to Strings and back to bytes using the UTF-8 charset, without loss:
* using the UTF-8 charset, without loss: <pre> {@code *
* <pre>{@code
* Arrays.equals(bytes, new String(bytes, Internal.UTF_8).getBytes(Internal.UTF_8)) * Arrays.equals(bytes, new String(bytes, Internal.UTF_8).getBytes(Internal.UTF_8))
* }</pre> * }</pre>
* *
* <p>See the Unicode Standard,</br> * <p>See the Unicode Standard,</br> Table 3-6. <em>UTF-8 Bit Distribution</em>,</br> Table 3-7.
* Table 3-6. <em>UTF-8 Bit Distribution</em>,</br> * <em>Well Formed UTF-8 Byte Sequences</em>.
* Table 3-7. <em>Well Formed UTF-8 Byte Sequences</em>.
*/ */
final public class Utf8Safe extends Utf8 { public final class Utf8Safe extends Utf8 {
/** /**
* Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string, * Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string, this
* this method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in * method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in both
* both time and space. * time and space.
* *
* @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
* surrogates) * surrogates)
@@ -64,8 +62,8 @@ final public class Utf8Safe extends Utf8 {
if (utf8Length < utf16Length) { if (utf8Length < utf16Length) {
// Necessary and sufficient condition for overflow because of maximum 3x expansion // Necessary and sufficient condition for overflow because of maximum 3x expansion
throw new IllegalArgumentException("UTF-8 length does not fit in int: " throw new IllegalArgumentException(
+ (utf8Length + (1L << 32))); "UTF-8 length does not fit in int: " + (utf8Length + (1L << 32)));
} }
return utf8Length; return utf8Length;
} }
@@ -167,13 +165,11 @@ final public class Utf8Safe extends Utf8 {
return new String(resultArr, 0, resultPos); return new String(resultArr, 0, resultPos);
} }
public static String decodeUtf8Buffer(ByteBuffer buffer, int offset, public static String decodeUtf8Buffer(ByteBuffer buffer, int offset, int length) {
int length) {
// Bitwise OR combines the sign bits so any negative value fails the check. // Bitwise OR combines the sign bits so any negative value fails the check.
if ((offset | length | buffer.limit() - offset - length) < 0) { if ((offset | length | buffer.limit() - offset - length) < 0) {
throw new ArrayIndexOutOfBoundsException( throw new ArrayIndexOutOfBoundsException(
String.format("buffer limit=%d, index=%d, limit=%d", buffer.limit(), String.format("buffer limit=%d, index=%d, limit=%d", buffer.limit(), offset, length));
offset, length));
} }
final int limit = offset + length; final int limit = offset + length;
@@ -212,8 +208,7 @@ final public class Utf8Safe extends Utf8 {
if (offset >= limit) { if (offset >= limit) {
throw new IllegalArgumentException("Invalid UTF-8"); throw new IllegalArgumentException("Invalid UTF-8");
} }
DecodeUtil.handleTwoBytes( DecodeUtil.handleTwoBytes(byte1, /* byte2 */ buffer.get(offset++), resultArr, resultPos++);
byte1, /* byte2 */ buffer.get(offset++), resultArr, resultPos++);
} else if (DecodeUtil.isThreeBytes(byte1)) { } else if (DecodeUtil.isThreeBytes(byte1)) {
if (offset >= limit - 1) { if (offset >= limit - 1) {
throw new IllegalArgumentException("Invalid UTF-8"); throw new IllegalArgumentException("Invalid UTF-8");
@@ -263,7 +258,6 @@ final public class Utf8Safe extends Utf8 {
} }
} }
private static void encodeUtf8Buffer(CharSequence in, ByteBuffer out) { private static void encodeUtf8Buffer(CharSequence in, ByteBuffer out) {
final int inLength = in.length(); final int inLength = in.length();
int outIx = out.position(); int outIx = out.position();
@@ -335,8 +329,7 @@ final public class Utf8Safe extends Utf8 {
} }
} }
private static int encodeUtf8Array(CharSequence in, byte[] out, private static int encodeUtf8Array(CharSequence in, byte[] out, int offset, int length) {
int offset, int length) {
int utf16Length = in.length(); int utf16Length = in.length();
int j = offset; int j = offset;
int i = 0; int i = 0;
@@ -366,8 +359,7 @@ final public class Utf8Safe extends Utf8 {
// Minimum code point represented by a surrogate pair is 0x10000, 17 bits, // Minimum code point represented by a surrogate pair is 0x10000, 17 bits,
// four UTF-8 bytes // four UTF-8 bytes
final char low; final char low;
if (i + 1 == in.length() if (i + 1 == in.length() || !Character.isSurrogatePair(c, (low = in.charAt(++i)))) {
|| !Character.isSurrogatePair(c, (low = in.charAt(++i)))) {
throw new UnpairedSurrogateException((i - 1), utf16Length); throw new UnpairedSurrogateException((i - 1), utf16Length);
} }
int codePoint = Character.toCodePoint(c, low); int codePoint = Character.toCodePoint(c, low);
@@ -379,8 +371,7 @@ final public class Utf8Safe extends Utf8 {
// If we are surrogates and we're not a surrogate pair, always throw an // If we are surrogates and we're not a surrogate pair, always throw an
// UnpairedSurrogateException instead of an ArrayOutOfBoundsException. // UnpairedSurrogateException instead of an ArrayOutOfBoundsException.
if ((Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE) if ((Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE)
&& (i + 1 == in.length() && (i + 1 == in.length() || !Character.isSurrogatePair(c, in.charAt(i + 1)))) {
|| !Character.isSurrogatePair(c, in.charAt(i + 1)))) {
throw new UnpairedSurrogateException(i, utf16Length); throw new UnpairedSurrogateException(i, utf16Length);
} }
throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + j); throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + j);
@@ -402,8 +393,7 @@ final public class Utf8Safe extends Utf8 {
public void encodeUtf8(CharSequence in, ByteBuffer out) { public void encodeUtf8(CharSequence in, ByteBuffer out) {
if (out.hasArray()) { if (out.hasArray()) {
int start = out.arrayOffset(); int start = out.arrayOffset();
int end = encodeUtf8Array(in, out.array(), start + out.position(), int end = encodeUtf8Array(in, out.array(), start + out.position(), out.remaining());
out.remaining());
out.position(end - start); out.position(end - start);
} else { } else {
encodeUtf8Buffer(in, out); encodeUtf8Buffer(in, out);

View File

@@ -1,28 +1,23 @@
import static com.google.flatbuffers.Constants.*;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static com.google.flatbuffers.Constants.*;
import DictionaryLookup.*; import DictionaryLookup.*;
import MyGame.Example.*; import MyGame.Example.*;
import com.google.common.io.ByteStreams;
import optional_scalars.ScalarStuff;
import optional_scalars.OptionalByte;
import NamespaceA.*; import NamespaceA.*;
import NamespaceA.NamespaceB.*; import NamespaceA.NamespaceB.*;
import com.google.common.io.ByteStreams;
import com.google.flatbuffers.ArrayReadWriteBuf;
import com.google.flatbuffers.ByteBufferUtil; import com.google.flatbuffers.ByteBufferUtil;
import com.google.flatbuffers.ByteVector; import com.google.flatbuffers.ByteVector;
import com.google.flatbuffers.FlatBufferBuilder; import com.google.flatbuffers.FlatBufferBuilder;
import com.google.flatbuffers.FlexBuffers; import com.google.flatbuffers.FlexBuffers;
import com.google.flatbuffers.FlexBuffers.FlexBufferException;
import com.google.flatbuffers.FlexBuffers.KeyVector;
import com.google.flatbuffers.FlexBuffers.Reference;
import com.google.flatbuffers.FlexBuffers.Vector;
import com.google.flatbuffers.FlexBuffersBuilder; import com.google.flatbuffers.FlexBuffersBuilder;
import com.google.flatbuffers.StringVector; import com.google.flatbuffers.StringVector;
import com.google.flatbuffers.UnionVector; import com.google.flatbuffers.UnionVector;
import com.google.flatbuffers.FlexBuffers.FlexBufferException;
import com.google.flatbuffers.FlexBuffers.Reference;
import com.google.flatbuffers.FlexBuffers.Vector;
import com.google.flatbuffers.ArrayReadWriteBuf;
import com.google.flatbuffers.FlexBuffers.KeyVector;
import java.io.*; import java.io.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
@@ -31,12 +26,13 @@ import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import optional_scalars.OptionalByte;
import optional_scalars.ScalarStuff;
import org.junit.Rule; import org.junit.Rule;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.JUnit4; import org.junit.runners.JUnit4;
/* /*
* Copyright 2014 Google Inc. All rights reserved. * Copyright 2014 Google Inc. All rights reserved.
* *
@@ -56,14 +52,14 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class) @RunWith(JUnit4.class)
public class JavaTest { public class JavaTest {
@Rule @Rule public TemporaryFolder tempFolder = new TemporaryFolder();
public TemporaryFolder tempFolder = new TemporaryFolder();
@org.junit.Test @org.junit.Test
public void mainTest() throws IOException { public void mainTest() throws IOException {
// First, let's test reading a FlatBuffer generated by C++ code: // First, let's test reading a FlatBuffer generated by C++ code:
// This file was generated from monsterdata_test.json // This file was generated from monsterdata_test.json
byte[] data = ByteStreams.toByteArray( byte[] data =
ByteStreams.toByteArray(
JavaTest.class.getClassLoader().getResourceAsStream("monsterdata_test.mon")); JavaTest.class.getClassLoader().getResourceAsStream("monsterdata_test.mon"));
// Now test it: // Now test it:
@@ -121,23 +117,20 @@ public class JavaTest {
assertThat(monster.inventoryLength()).isEqualTo(5); assertThat(monster.inventoryLength()).isEqualTo(5);
int invsum = 0; int invsum = 0;
for (int i = 0; i < monster.inventoryLength(); i++) for (int i = 0; i < monster.inventoryLength(); i++) invsum += monster.inventory(i);
invsum += monster.inventory(i);
assertThat(invsum).isEqualTo(10); assertThat(invsum).isEqualTo(10);
// Method using a vector access object: // Method using a vector access object:
ByteVector inventoryVector = monster.inventoryVector(); ByteVector inventoryVector = monster.inventoryVector();
assertThat(inventoryVector.length()).isEqualTo(5); assertThat(inventoryVector.length()).isEqualTo(5);
invsum = 0; invsum = 0;
for (int i = 0; i < inventoryVector.length(); i++) for (int i = 0; i < inventoryVector.length(); i++) invsum += inventoryVector.getAsUnsigned(i);
invsum += inventoryVector.getAsUnsigned(i);
assertThat(invsum).isEqualTo(10); assertThat(invsum).isEqualTo(10);
// Alternative way of accessing a vector: // Alternative way of accessing a vector:
ByteBuffer ibb = monster.inventoryAsByteBuffer(); ByteBuffer ibb = monster.inventoryAsByteBuffer();
invsum = 0; invsum = 0;
while (ibb.position() < ibb.limit()) while (ibb.position() < ibb.limit()) invsum += ibb.get();
invsum += ibb.get();
assertThat(invsum).isEqualTo(10); assertThat(invsum).isEqualTo(10);
Test test_0 = monster.test4(0); Test test_0 = monster.test4(0);
@@ -174,8 +167,8 @@ public class JavaTest {
assertThat(monster.testhashu32Fnv1()).isEqualTo((Integer.MAX_VALUE + 1L)); assertThat(monster.testhashu32Fnv1()).isEqualTo((Integer.MAX_VALUE + 1L));
} }
@org.junit.Test
@org.junit.Test public void TestNamespaceNesting() { public void TestNamespaceNesting() {
// reference / manipulate these to verify compilation // reference / manipulate these to verify compilation
FlatBufferBuilder fbb = new FlatBufferBuilder(1); FlatBufferBuilder fbb = new FlatBufferBuilder(1);
@@ -188,7 +181,8 @@ public class JavaTest {
int off = TableInFirstNS.endTableInFirstNS(fbb); int off = TableInFirstNS.endTableInFirstNS(fbb);
} }
@org.junit.Test public void TestNestedFlatBuffer() { @org.junit.Test
public void TestNestedFlatBuffer() {
final String nestedMonsterName = "NestedMonsterName"; final String nestedMonsterName = "NestedMonsterName";
final short nestedMonsterHp = 600; final short nestedMonsterHp = 600;
final short nestedMonsterMana = 1024; final short nestedMonsterMana = 1024;
@@ -209,8 +203,8 @@ public class JavaTest {
int nestedBuffer = Monster.createTestnestedflatbufferVector(fbb2, fbb1Bytes); int nestedBuffer = Monster.createTestnestedflatbufferVector(fbb2, fbb1Bytes);
Monster.startMonster(fbb2); Monster.startMonster(fbb2);
Monster.addName(fbb2, str2); Monster.addName(fbb2, str2);
Monster.addHp(fbb2, (short)50); Monster.addHp(fbb2, (short) 50);
Monster.addMana(fbb2, (short)32); Monster.addMana(fbb2, (short) 32);
Monster.addTestnestedflatbuffer(fbb2, nestedBuffer); Monster.addTestnestedflatbuffer(fbb2, nestedBuffer);
int monster = Monster.endMonster(fbb2); int monster = Monster.endMonster(fbb2);
Monster.finishMonsterBuffer(fbb2, monster); Monster.finishMonsterBuffer(fbb2, monster);
@@ -224,10 +218,11 @@ public class JavaTest {
assertThat(nestedMonsterName).isEqualTo(nestedMonster.name()); assertThat(nestedMonsterName).isEqualTo(nestedMonster.name());
} }
@org.junit.Test public void TestCreateByteVector() { @org.junit.Test
public void TestCreateByteVector() {
FlatBufferBuilder fbb = new FlatBufferBuilder(16); FlatBufferBuilder fbb = new FlatBufferBuilder(16);
int str = fbb.createString("MyMonster"); int str = fbb.createString("MyMonster");
byte[] inventory = new byte[] { 0, 1, 2, 3, 4 }; byte[] inventory = new byte[] {0, 1, 2, 3, 4};
int vec = fbb.createByteVector(inventory); int vec = fbb.createByteVector(inventory);
Monster.startMonster(fbb); Monster.startMonster(fbb);
Monster.addInventory(fbb, vec); Monster.addInventory(fbb, vec);
@@ -236,22 +231,22 @@ public class JavaTest {
Monster.finishMonsterBuffer(fbb, monster1); Monster.finishMonsterBuffer(fbb, monster1);
Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer()); Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
assertThat((Integer) monsterObject.inventory(1)).isEqualTo((int)inventory[1]); assertThat((Integer) monsterObject.inventory(1)).isEqualTo((int) inventory[1]);
assertThat(monsterObject.inventoryLength()).isEqualTo(inventory.length); assertThat(monsterObject.inventoryLength()).isEqualTo(inventory.length);
ByteVector inventoryVector = monsterObject.inventoryVector(); ByteVector inventoryVector = monsterObject.inventoryVector();
assertThat(inventoryVector.getAsUnsigned(1)).isEqualTo((int)inventory[1]); assertThat(inventoryVector.getAsUnsigned(1)).isEqualTo((int) inventory[1]);
assertThat(inventoryVector.length()).isEqualTo(inventory.length); assertThat(inventoryVector.length()).isEqualTo(inventory.length);
assertThat(ByteBuffer.wrap(inventory)).isEqualTo( assertThat(ByteBuffer.wrap(inventory)).isEqualTo(monsterObject.inventoryAsByteBuffer());
monsterObject.inventoryAsByteBuffer());
} }
@org.junit.Test public void TestCreateUninitializedVector() { @org.junit.Test
public void TestCreateUninitializedVector() {
FlatBufferBuilder fbb = new FlatBufferBuilder(16); FlatBufferBuilder fbb = new FlatBufferBuilder(16);
int str = fbb.createString("MyMonster"); int str = fbb.createString("MyMonster");
byte[] inventory = new byte[] { 0, 1, 2, 3, 4 }; byte[] inventory = new byte[] {0, 1, 2, 3, 4};
ByteBuffer bb = fbb.createUnintializedVector(1, inventory.length, 1); ByteBuffer bb = fbb.createUnintializedVector(1, inventory.length, 1);
for (byte i:inventory) { for (byte i : inventory) {
bb.put(i); bb.put(i);
} }
int vec = fbb.endVector(); int vec = fbb.endVector();
@@ -262,16 +257,16 @@ public class JavaTest {
Monster.finishMonsterBuffer(fbb, monster1); Monster.finishMonsterBuffer(fbb, monster1);
Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer()); Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
assertThat((Integer) monsterObject.inventory(1)).isEqualTo((int)inventory[1]); assertThat((Integer) monsterObject.inventory(1)).isEqualTo((int) inventory[1]);
assertThat(monsterObject.inventoryLength()).isEqualTo(inventory.length); assertThat(monsterObject.inventoryLength()).isEqualTo(inventory.length);
ByteVector inventoryVector = monsterObject.inventoryVector(); ByteVector inventoryVector = monsterObject.inventoryVector();
assertThat(inventoryVector.getAsUnsigned(1)).isEqualTo((int)inventory[1]); assertThat(inventoryVector.getAsUnsigned(1)).isEqualTo((int) inventory[1]);
assertThat(inventoryVector.length()).isEqualTo(inventory.length); assertThat(inventoryVector.length()).isEqualTo(inventory.length);
assertThat(ByteBuffer.wrap(inventory)).isEqualTo( assertThat(ByteBuffer.wrap(inventory)).isEqualTo(monsterObject.inventoryAsByteBuffer());
monsterObject.inventoryAsByteBuffer());
} }
@org.junit.Test public void TestByteBufferFactory() throws IOException { @org.junit.Test
public void TestByteBufferFactory() throws IOException {
File file = tempFolder.newFile("javatest.bin"); File file = tempFolder.newFile("javatest.bin");
final class MappedByteBufferFactory extends FlatBufferBuilder.ByteBufferFactory { final class MappedByteBufferFactory extends FlatBufferBuilder.ByteBufferFactory {
@Override @Override
@@ -279,9 +274,12 @@ public class JavaTest {
ByteBuffer bb; ByteBuffer bb;
try { try {
RandomAccessFile f = new RandomAccessFile(file, "rw"); RandomAccessFile f = new RandomAccessFile(file, "rw");
bb = f.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, capacity).order(ByteOrder.LITTLE_ENDIAN); bb =
f.getChannel()
.map(FileChannel.MapMode.READ_WRITE, 0, capacity)
.order(ByteOrder.LITTLE_ENDIAN);
f.close(); f.close();
} catch(Throwable e) { } catch (Throwable e) {
System.out.println("FlatBuffers test: couldn't map ByteBuffer to a file"); System.out.println("FlatBuffers test: couldn't map ByteBuffer to a file");
bb = null; bb = null;
} }
@@ -294,7 +292,8 @@ public class JavaTest {
TestBuilderBasics(fbb, false); TestBuilderBasics(fbb, false);
} }
@org.junit.Test public void TestSizedInputStream() { @org.junit.Test
public void TestSizedInputStream() {
// Test on default FlatBufferBuilder that uses HeapByteBuffer // Test on default FlatBufferBuilder that uses HeapByteBuffer
FlatBufferBuilder fbb = new FlatBufferBuilder(1); FlatBufferBuilder fbb = new FlatBufferBuilder(1);
@@ -308,18 +307,20 @@ public class JavaTest {
while (currentVal != -1 && count < array.length) { while (currentVal != -1 && count < array.length) {
try { try {
currentVal = in.read(); currentVal = in.read();
} catch(java.io.IOException e) { } catch (java.io.IOException e) {
System.out.println("FlatBuffers test: couldn't read from InputStream"); System.out.println("FlatBuffers test: couldn't read from InputStream");
return; return;
} }
assertThat((byte)currentVal).isEqualTo(array[count]); assertThat((byte) currentVal).isEqualTo(array[count]);
count++; count++;
} }
assertThat(count).isEqualTo(array.length); assertThat(count).isEqualTo(array.length);
} }
void TestBuilderBasics(FlatBufferBuilder fbb, boolean sizePrefix) { void TestBuilderBasics(FlatBufferBuilder fbb, boolean sizePrefix) {
int[] names = {fbb.createString("Frodo"), fbb.createString("Barney"), fbb.createString("Wilma")}; int[] names = {
fbb.createString("Frodo"), fbb.createString("Barney"), fbb.createString("Wilma")
};
int[] off = new int[3]; int[] off = new int[3];
Monster.startMonster(fbb); Monster.startMonster(fbb);
Monster.addName(fbb, names[0]); Monster.addName(fbb, names[0]);
@@ -336,7 +337,7 @@ public class JavaTest {
int str = fbb.createString("MyMonster"); int str = fbb.createString("MyMonster");
int inv = Monster.createInventoryVector(fbb, new byte[] { 0, 1, 2, 3, 4 }); int inv = Monster.createInventoryVector(fbb, new byte[] {0, 1, 2, 3, 4});
int fred = fbb.createString("Fred"); int fred = fbb.createString("Fred");
Monster.startMonster(fbb); Monster.startMonster(fbb);
@@ -344,22 +345,21 @@ public class JavaTest {
int mon2 = Monster.endMonster(fbb); int mon2 = Monster.endMonster(fbb);
Monster.startTest4Vector(fbb, 2); Monster.startTest4Vector(fbb, 2);
Test.createTest(fbb, (short)10, (byte)20); Test.createTest(fbb, (short) 10, (byte) 20);
Test.createTest(fbb, (short)30, (byte)40); Test.createTest(fbb, (short) 30, (byte) 40);
int test4 = fbb.endVector(); int test4 = fbb.endVector();
int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] { int testArrayOfString =
fbb.createString("test1"), Monster.createTestarrayofstringVector(
fbb.createString("test2") fbb, new int[] {fbb.createString("test1"), fbb.createString("test2")});
});
Monster.startMonster(fbb); Monster.startMonster(fbb);
Monster.addPos(fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0, Monster.addPos(
Color.Green, (short)5, (byte)6)); fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0, Color.Green, (short) 5, (byte) 6));
Monster.addHp(fbb, (short)80); Monster.addHp(fbb, (short) 80);
Monster.addName(fbb, str); Monster.addName(fbb, str);
Monster.addInventory(fbb, inv); Monster.addInventory(fbb, inv);
Monster.addTestType(fbb, (byte)Any.Monster); Monster.addTestType(fbb, (byte) Any.Monster);
Monster.addTest(fbb, mon2); Monster.addTest(fbb, mon2);
Monster.addTest4(fbb, test4); Monster.addTest4(fbb, test4);
Monster.addTestarrayofstring(fbb, testArrayOfString); Monster.addTestarrayofstring(fbb, testArrayOfString);
@@ -384,7 +384,7 @@ public class JavaTest {
FileChannel fc = new FileOutputStream(tempFolder.newFile(filename)).getChannel(); FileChannel fc = new FileOutputStream(tempFolder.newFile(filename)).getChannel();
fc.write(fbb.dataBuffer().duplicate()); fc.write(fbb.dataBuffer().duplicate());
fc.close(); fc.close();
} catch(java.io.IOException e) { } catch (java.io.IOException e) {
System.out.println("FlatBuffers test: couldn't write file"); System.out.println("FlatBuffers test: couldn't write file");
return; return;
} }
@@ -392,8 +392,8 @@ public class JavaTest {
// Test it: // Test it:
ByteBuffer dataBuffer = fbb.dataBuffer(); ByteBuffer dataBuffer = fbb.dataBuffer();
if (sizePrefix) { if (sizePrefix) {
assertThat(ByteBufferUtil.getSizePrefix(dataBuffer) + SIZE_PREFIX_LENGTH).isEqualTo( assertThat(ByteBufferUtil.getSizePrefix(dataBuffer) + SIZE_PREFIX_LENGTH)
dataBuffer.remaining()); .isEqualTo(dataBuffer.remaining());
dataBuffer = ByteBufferUtil.removeSizePrefix(dataBuffer); dataBuffer = ByteBufferUtil.removeSizePrefix(dataBuffer);
} }
TestExtendedBuffer(dataBuffer); TestExtendedBuffer(dataBuffer);
@@ -403,13 +403,13 @@ public class JavaTest {
// (see Table.__string). // (see Table.__string).
TestExtendedBuffer(dataBuffer.asReadOnlyBuffer()); TestExtendedBuffer(dataBuffer.asReadOnlyBuffer());
//Attempt to mutate Monster fields and check whether the buffer has been mutated properly // Attempt to mutate Monster fields and check whether the buffer has been mutated properly
// revert to original values after testing // revert to original values after testing
Monster monster = Monster.getRootAsMonster(dataBuffer); Monster monster = Monster.getRootAsMonster(dataBuffer);
// mana is optional and does not exist in the buffer so the mutation should fail // mana is optional and does not exist in the buffer so the mutation should fail
// the mana field should retain its default value // the mana field should retain its default value
assertThat(monster.mutateMana((short)10)).isFalse(); assertThat(monster.mutateMana((short) 10)).isFalse();
assertThat(monster.mana()).isEqualTo((short) 150); assertThat(monster.mana()).isEqualTo((short) 150);
// Accessing a vector of sorted by the key tables // Accessing a vector of sorted by the key tables
@@ -432,7 +432,7 @@ public class JavaTest {
// testType is an existing field and mutating it should succeed // testType is an existing field and mutating it should succeed
assertThat(monster.testType()).isEqualTo((byte) Any.Monster); assertThat(monster.testType()).isEqualTo((byte) Any.Monster);
//mutate the inventory vector // mutate the inventory vector
assertThat(monster.mutateInventory(0, 1)).isTrue(); assertThat(monster.mutateInventory(0, 1)).isTrue();
assertThat(monster.mutateInventory(1, 2)).isTrue(); assertThat(monster.mutateInventory(1, 2)).isTrue();
assertThat(monster.mutateInventory(2, 3)).isTrue(); assertThat(monster.mutateInventory(2, 3)).isTrue();
@@ -444,10 +444,10 @@ public class JavaTest {
} }
ByteVector inventoryVector = monster.inventoryVector(); ByteVector inventoryVector = monster.inventoryVector();
for (int i = 0; i < inventoryVector.length(); i++) { for (int i = 0; i < inventoryVector.length(); i++) {
assertThat((int)inventoryVector.get(i)).isEqualTo(i + 1); assertThat((int) inventoryVector.get(i)).isEqualTo(i + 1);
} }
//reverse mutation // reverse mutation
assertThat(monster.mutateInventory(0, 0)).isTrue(); assertThat(monster.mutateInventory(0, 0)).isTrue();
assertThat(monster.mutateInventory(1, 1)).isTrue(); assertThat(monster.mutateInventory(1, 1)).isTrue();
assertThat(monster.mutateInventory(2, 2)).isTrue(); assertThat(monster.mutateInventory(2, 2)).isTrue();
@@ -463,16 +463,19 @@ public class JavaTest {
assertThat(pos.x()).isEqualTo(1.0f); assertThat(pos.x()).isEqualTo(1.0f);
} }
@org.junit.Test public void TestVectorOfUnions() { @org.junit.Test
public void TestVectorOfUnions() {
final FlatBufferBuilder fbb = new FlatBufferBuilder(); final FlatBufferBuilder fbb = new FlatBufferBuilder();
final int swordAttackDamage = 1; final int swordAttackDamage = 1;
final int[] characterVector = new int[] { final int[] characterVector =
new int[] {
Attacker.createAttacker(fbb, swordAttackDamage), Attacker.createAttacker(fbb, swordAttackDamage),
}; };
final byte[] characterTypeVector = new byte[]{ final byte[] characterTypeVector =
new byte[] {
Character.MuLan, Character.MuLan,
}; };
@@ -480,12 +483,10 @@ public class JavaTest {
fbb, fbb,
Movie.createMovie( Movie.createMovie(
fbb, fbb,
(byte)0, (byte) 0,
(byte)0, (byte) 0,
Movie.createCharactersTypeVector(fbb, characterTypeVector), Movie.createCharactersTypeVector(fbb, characterTypeVector),
Movie.createCharactersVector(fbb, characterVector) Movie.createCharactersVector(fbb, characterVector)));
)
);
final Movie movie = Movie.getRootAsMovie(fbb.dataBuffer()); final Movie movie = Movie.getRootAsMovie(fbb.dataBuffer());
ByteVector charactersTypeByteVector = movie.charactersTypeVector(); ByteVector charactersTypeByteVector = movie.charactersTypeVector();
@@ -499,11 +500,12 @@ public class JavaTest {
assertThat((Byte) movie.charactersType(0)).isEqualTo(characterTypeVector[0]); assertThat((Byte) movie.charactersType(0)).isEqualTo(characterTypeVector[0]);
assertThat(charactersTypeByteVector.get(0)).isEqualTo(characterTypeVector[0]); assertThat(charactersTypeByteVector.get(0)).isEqualTo(characterTypeVector[0]);
assertThat(((Attacker)movie.characters(new Attacker(), 0)).swordAttackDamage()).isEqualTo( assertThat(((Attacker) movie.characters(new Attacker(), 0)).swordAttackDamage())
swordAttackDamage); .isEqualTo(swordAttackDamage);
} }
@org.junit.Test public void TestFixedLengthArrays() { @org.junit.Test
public void TestFixedLengthArrays() {
FlatBufferBuilder builder = new FlatBufferBuilder(0); FlatBufferBuilder builder = new FlatBufferBuilder(0);
float a; float a;
@@ -537,8 +539,7 @@ public class JavaTest {
f[0] = -1; f[0] = -1;
f[1] = 1; f[1] = 1;
int arrayOffset = ArrayStruct.createArrayStruct(builder, int arrayOffset = ArrayStruct.createArrayStruct(builder, a, b, c, d_a, d_b, d_c, d_d, e, f);
a, b, c, d_a, d_b, d_c, d_d, e, f);
// Create a table with the ArrayStruct. // Create a table with the ArrayStruct.
ArrayTable.startArrayTable(builder); ArrayTable.startArrayTable(builder);
@@ -551,9 +552,8 @@ public class JavaTest {
NestedStruct nested = new NestedStruct(); NestedStruct nested = new NestedStruct();
assertThat(table.a().a()).isEqualTo(0.5f); assertThat(table.a().a()).isEqualTo(0.5f);
for (int i = 0; i < 15; i++) for (int i = 0; i < 15; i++) assertThat(table.a().b(i)).isEqualTo(i);
assertThat(table.a().b(i)).isEqualTo(i); assertThat(table.a().c()).isEqualTo((byte) 1);
assertThat(table.a().c()).isEqualTo((byte)1);
assertThat(table.a().d(nested, 0).a(0)).isEqualTo(1); assertThat(table.a().d(nested, 0).a(0)).isEqualTo(1);
assertThat(table.a().d(nested, 0).a(1)).isEqualTo(2); assertThat(table.a().d(nested, 0).a(1)).isEqualTo(2);
assertThat(table.a().d(nested, 1).a(0)).isEqualTo(3); assertThat(table.a().d(nested, 1).a(0)).isEqualTo(3);
@@ -564,18 +564,20 @@ public class JavaTest {
assertThat(table.a().d(nested, 0).c(1)).isEqualTo(TestEnum.B); assertThat(table.a().d(nested, 0).c(1)).isEqualTo(TestEnum.B);
assertThat(table.a().d(nested, 1).c(0)).isEqualTo(TestEnum.C); assertThat(table.a().d(nested, 1).c(0)).isEqualTo(TestEnum.C);
assertThat(table.a().d(nested, 1).c(1)).isEqualTo(TestEnum.B); assertThat(table.a().d(nested, 1).c(1)).isEqualTo(TestEnum.B);
assertThat(table.a().d(nested, 0).d(0)).isEqualTo((long)-1); assertThat(table.a().d(nested, 0).d(0)).isEqualTo((long) -1);
assertThat(table.a().d(nested, 0).d(1)).isEqualTo((long)1); assertThat(table.a().d(nested, 0).d(1)).isEqualTo((long) 1);
assertThat(table.a().d(nested, 1).d(0)).isEqualTo((long)-2); assertThat(table.a().d(nested, 1).d(0)).isEqualTo((long) -2);
assertThat(table.a().d(nested, 1).d(1)).isEqualTo((long)2); assertThat(table.a().d(nested, 1).d(1)).isEqualTo((long) 2);
assertThat(table.a().e()).isEqualTo(2); assertThat(table.a().e()).isEqualTo(2);
assertThat(table.a().f(0)).isEqualTo((long)-1); assertThat(table.a().f(0)).isEqualTo((long) -1);
assertThat(table.a().f(1)).isEqualTo((long)1); assertThat(table.a().f(1)).isEqualTo((long) 1);
} }
@org.junit.Test public void testFlexBuffersTest() { @org.junit.Test
FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512), public void testFlexBuffersTest() {
FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS); FlexBuffersBuilder builder =
new FlexBuffersBuilder(
ByteBuffer.allocate(512), FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
testFlexBuffersTest(builder); testFlexBuffersTest(builder);
int bufferLimit1 = ((ArrayReadWriteBuf) builder.getBuffer()).limit(); int bufferLimit1 = ((ArrayReadWriteBuf) builder.getBuffer()).limit();
@@ -596,7 +598,7 @@ public class JavaTest {
int vec1 = builder.startVector(); int vec1 = builder.startVector();
builder.putInt(-100); builder.putInt(-100);
builder.putString("Fred"); builder.putString("Fred");
builder.putBlob(new byte[]{(byte) 77}); builder.putBlob(new byte[] {(byte) 77});
builder.putBoolean(false); builder.putBoolean(false);
builder.putInt(Long.MAX_VALUE); builder.putInt(Long.MAX_VALUE);
@@ -628,7 +630,7 @@ public class JavaTest {
builder.putString("bar", "Fred"); // Testing key and string reuse. builder.putString("bar", "Fred"); // Testing key and string reuse.
builder.putInt("int", -120); builder.putInt("int", -120);
builder.putFloat("float", -123.0f); builder.putFloat("float", -123.0f);
builder.putBlob("blob", new byte[]{ 65, 67 }); builder.putBlob("blob", new byte[] {65, 67});
builder.endMap("mymap", map2); builder.endMap("mymap", map2);
builder.endMap(null, map1); builder.endMap(null, map1);
@@ -649,7 +651,7 @@ public class JavaTest {
assertThat(m.get("no_key").asVector()).isEqualTo(Vector.empty()); assertThat(m.get("no_key").asVector()).isEqualTo(Vector.empty());
// empty if fail // empty if fail
assertThat(m.get("no_key").asBlob()).isEqualTo(FlexBuffers.Blob.empty()); assertThat(m.get("no_key").asBlob()).isEqualTo(FlexBuffers.Blob.empty());
assert(m.get("no_key").asVector().isEmpty()); // empty if fail assert (m.get("no_key").asVector().isEmpty()); // empty if fail
// testing "vec" field // testing "vec" field
FlexBuffers.Vector vec = m.get("vec").asVector(); FlexBuffers.Vector vec = m.get("vec").asVector();
@@ -666,10 +668,10 @@ public class JavaTest {
assertThat(vec.get(4).asLong()).isEqualTo(Long.MAX_VALUE); assertThat(vec.get(4).asLong()).isEqualTo(Long.MAX_VALUE);
assertThat(vec.get(5).isMap()).isTrue(); assertThat(vec.get(5).isMap()).isTrue();
assertThat(vec.get(5).asMap().get("test").asInt()).isEqualTo(200); assertThat(vec.get(5).asMap().get("test").asInt()).isEqualTo(200);
assertThat(Float.compare((float)vec.get(6).asFloat(), 150.9f)).isEqualTo(0); assertThat(Float.compare((float) vec.get(6).asFloat(), 150.9f)).isEqualTo(0);
assertThat(Double.compare(vec.get(7).asFloat(), 150.9999998)).isEqualTo(0); assertThat(Double.compare(vec.get(7).asFloat(), 150.9999998)).isEqualTo(0);
//conversion fail returns 0 as C++ // conversion fail returns 0 as C++
assertThat((long)0).isEqualTo((long)vec.get(1).asLong()); assertThat((long) 0).isEqualTo((long) vec.get(1).asLong());
// bar vector // bar vector
FlexBuffers.Vector tvec = m.get("bar").asVector(); FlexBuffers.Vector tvec = m.get("bar").asVector();
@@ -688,7 +690,7 @@ public class JavaTest {
assertThat(bvec.get(3).asBoolean()).isFalse(); assertThat(bvec.get(3).asBoolean()).isFalse();
assertThat(((FlexBuffers.TypedVector) bvec).getElemType()).isEqualTo(FlexBuffers.FBT_BOOL); assertThat(((FlexBuffers.TypedVector) bvec).getElemType()).isEqualTo(FlexBuffers.FBT_BOOL);
assertThat((float)m.get("foo").asFloat()).isEqualTo((float) 100); assertThat((float) m.get("foo").asFloat()).isEqualTo((float) 100);
assertThat(m.get("unknown").isNull()).isTrue(); assertThat(m.get("unknown").isNull()).isTrue();
// mymap vector // mymap vector
@@ -698,19 +700,20 @@ public class JavaTest {
assertThat(mymap.keys().get(0).toString()).isEqualTo("bar"); assertThat(mymap.keys().get(0).toString()).isEqualTo("bar");
assertThat(mymap.values().get(0).asString()).isEqualTo(vec.get(1).asString()); assertThat(mymap.values().get(0).asString()).isEqualTo(vec.get(1).asString());
assertThat(mymap.get("int").asInt()).isEqualTo(-120); assertThat(mymap.get("int").asInt()).isEqualTo(-120);
assertThat((float)mymap.get("float").asFloat()).isEqualTo(-123.0f); assertThat((float) mymap.get("float").asFloat()).isEqualTo(-123.0f);
assertThat(Arrays.equals(mymap.get("blob").asBlob().getBytes(), new byte[]{ 65, 67 })).isEqualTo( assertThat(Arrays.equals(mymap.get("blob").asBlob().getBytes(), new byte[] {65, 67}))
true); .isEqualTo(true);
assertThat(mymap.get("blob").asBlob().toString()).isEqualTo("AC"); assertThat(mymap.get("blob").asBlob().toString()).isEqualTo("AC");
assertThat(mymap.get("blob").toString()).isEqualTo("\"AC\""); assertThat(mymap.get("blob").toString()).isEqualTo("\"AC\"");
} }
@org.junit.Test public void testFlexBufferVectorStrings() { @org.junit.Test
public void testFlexBufferVectorStrings() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000000)); FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000000));
int size = 3000; int size = 3000;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i=0; i< size; i++) { for (int i = 0; i < size; i++) {
sb.append("a"); sb.append("a");
} }
@@ -719,7 +722,7 @@ public class JavaTest {
int pos = builder.startVector(); int pos = builder.startVector();
for (int i=0; i<size; i++) { for (int i = 0; i < size; i++) {
builder.putString(text); builder.putString(text);
} }
@@ -728,7 +731,7 @@ public class JavaTest {
// this should raise an exception as // this should raise an exception as
// typed vector of string was deprecated // typed vector of string was deprecated
assert false; assert false;
} catch(FlexBufferException fb) { } catch (FlexBufferException fb) {
// no op // no op
} }
// we finish the vector again as non-typed // we finish the vector again as non-typed
@@ -738,82 +741,93 @@ public class JavaTest {
Vector v = FlexBuffers.getRoot(b).asVector(); Vector v = FlexBuffers.getRoot(b).asVector();
assertThat(v.size()).isEqualTo(size); assertThat(v.size()).isEqualTo(size);
for (int i=0; i<size; i++) { for (int i = 0; i < size; i++) {
assertThat(v.get(i).asString().length()).isEqualTo(size); assertThat(v.get(i).asString().length()).isEqualTo(size);
assertThat(v.get(i).asString()).isEqualTo(text); assertThat(v.get(i).asString()).isEqualTo(text);
} }
} }
@org.junit.Test public void testDeprecatedTypedVectorString() { @org.junit.Test
public void testDeprecatedTypedVectorString() {
// tests whether we are able to support reading deprecated typed vector string // tests whether we are able to support reading deprecated typed vector string
// data is equivalent to [ "abc", "abc", "abc", "abc"] // data is equivalent to [ "abc", "abc", "abc", "abc"]
byte[] data = new byte[] {0x03, 0x61, 0x62, 0x63, 0x00, 0x03, 0x61, 0x62, 0x63, 0x00, byte[] data =
0x03, 0x61, 0x62, 0x63, 0x00, 0x03, 0x61, 0x62, 0x63, 0x00, 0x04, 0x14, 0x10, new byte[] {
0x0c, 0x08, 0x04, 0x3c, 0x01}; 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)); Reference ref = FlexBuffers.getRoot(ByteBuffer.wrap(data));
assertThat(ref.getType()).isEqualTo(FlexBuffers.FBT_VECTOR_STRING_DEPRECATED); assertThat(ref.getType()).isEqualTo(FlexBuffers.FBT_VECTOR_STRING_DEPRECATED);
assertThat(ref.isTypedVector()).isTrue(); assertThat(ref.isTypedVector()).isTrue();
Vector vec = ref.asVector(); Vector vec = ref.asVector();
for (int i=0; i< vec.size(); i++) { for (int i = 0; i < vec.size(); i++) {
assertThat("abc").isEqualTo(vec.get(i).asString()); assertThat("abc").isEqualTo(vec.get(i).asString());
} }
} }
@org.junit.Test public void testSingleElementBoolean() { @org.junit.Test
public void testSingleElementBoolean() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(100)); FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(100));
builder.putBoolean(true); builder.putBoolean(true);
ByteBuffer b = builder.finish(); ByteBuffer b = builder.finish();
assertThat(FlexBuffers.getRoot(b).asBoolean()).isTrue(); assertThat(FlexBuffers.getRoot(b).asBoolean()).isTrue();
} }
@org.junit.Test public void testSingleElementByte() { @org.junit.Test
public void testSingleElementByte() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(); FlexBuffersBuilder builder = new FlexBuffersBuilder();
builder.putInt(10); builder.putInt(10);
ByteBuffer b = builder.finish(); ByteBuffer b = builder.finish();
assertThat(10).isEqualTo(FlexBuffers.getRoot(b).asInt()); assertThat(10).isEqualTo(FlexBuffers.getRoot(b).asInt());
} }
@org.junit.Test public void testSingleElementShort() { @org.junit.Test
public void testSingleElementShort() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(); FlexBuffersBuilder builder = new FlexBuffersBuilder();
builder.putInt(Short.MAX_VALUE); builder.putInt(Short.MAX_VALUE);
ByteBuffer b = builder.finish(); ByteBuffer b = builder.finish();
assertThat(Short.MAX_VALUE).isEqualTo((short) FlexBuffers.getRoot(b).asInt()); assertThat(Short.MAX_VALUE).isEqualTo((short) FlexBuffers.getRoot(b).asInt());
} }
@org.junit.Test public void testSingleElementInt() { @org.junit.Test
public void testSingleElementInt() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(); FlexBuffersBuilder builder = new FlexBuffersBuilder();
builder.putInt(Integer.MIN_VALUE); builder.putInt(Integer.MIN_VALUE);
ByteBuffer b = builder.finish(); ByteBuffer b = builder.finish();
assertThat(Integer.MIN_VALUE).isEqualTo(FlexBuffers.getRoot(b).asInt()); assertThat(Integer.MIN_VALUE).isEqualTo(FlexBuffers.getRoot(b).asInt());
} }
@org.junit.Test public void testSingleElementLong() { @org.junit.Test
public void testSingleElementLong() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(); FlexBuffersBuilder builder = new FlexBuffersBuilder();
builder.putInt(Long.MAX_VALUE); builder.putInt(Long.MAX_VALUE);
ByteBuffer b = builder.finish(); ByteBuffer b = builder.finish();
assertThat(Long.MAX_VALUE).isEqualTo(FlexBuffers.getRoot(b).asLong()); assertThat(Long.MAX_VALUE).isEqualTo(FlexBuffers.getRoot(b).asLong());
} }
@org.junit.Test public void testSingleElementFloat() { @org.junit.Test
public void testSingleElementFloat() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(); FlexBuffersBuilder builder = new FlexBuffersBuilder();
builder.putFloat(Float.MAX_VALUE); builder.putFloat(Float.MAX_VALUE);
ByteBuffer b = builder.finish(); ByteBuffer b = builder.finish();
assertThat(Float.compare(Float.MAX_VALUE, (float) FlexBuffers.getRoot(b).asFloat())).isEqualTo( assertThat(Float.compare(Float.MAX_VALUE, (float) FlexBuffers.getRoot(b).asFloat()))
0); .isEqualTo(0);
} }
@org.junit.Test public void testSingleElementDouble() { @org.junit.Test
public void testSingleElementDouble() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(); FlexBuffersBuilder builder = new FlexBuffersBuilder();
builder.putFloat(Double.MAX_VALUE); builder.putFloat(Double.MAX_VALUE);
ByteBuffer b = builder.finish(); ByteBuffer b = builder.finish();
assertThat(Double.compare(Double.MAX_VALUE, FlexBuffers.getRoot(b).asFloat())).isEqualTo(0); assertThat(Double.compare(Double.MAX_VALUE, FlexBuffers.getRoot(b).asFloat())).isEqualTo(0);
} }
@org.junit.Test public void testSingleElementBigString() { @org.junit.Test
public void testSingleElementBigString() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000)); FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000));
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i=0; i< 3000; i++) { for (int i = 0; i < 3000; i++) {
sb.append("a"); sb.append("a");
} }
@@ -826,7 +840,8 @@ public class JavaTest {
assertThat(sb.toString()).isEqualTo(r.asString()); assertThat(sb.toString()).isEqualTo(r.asString());
} }
@org.junit.Test public void testSingleElementSmallString() { @org.junit.Test
public void testSingleElementSmallString() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000)); FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000));
builder.putString("aa"); builder.putString("aa");
@@ -837,25 +852,27 @@ public class JavaTest {
assertThat("aa").isEqualTo(r.asString()); assertThat("aa").isEqualTo(r.asString());
} }
@org.junit.Test public void testSingleElementBlob() { @org.junit.Test
public void testSingleElementBlob() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(); FlexBuffersBuilder builder = new FlexBuffersBuilder();
builder.putBlob(new byte[]{5, 124, 118, -1}); builder.putBlob(new byte[] {5, 124, 118, -1});
ByteBuffer b = builder.finish(); ByteBuffer b = builder.finish();
FlexBuffers.Reference r = FlexBuffers.getRoot(b); FlexBuffers.Reference r = FlexBuffers.getRoot(b);
byte[] result = r.asBlob().getBytes(); byte[] result = r.asBlob().getBytes();
assertThat((byte)5).isEqualTo(result[0]); assertThat((byte) 5).isEqualTo(result[0]);
assertThat((byte)124).isEqualTo(result[1]); assertThat((byte) 124).isEqualTo(result[1]);
assertThat((byte)118).isEqualTo(result[2]); assertThat((byte) 118).isEqualTo(result[2]);
assertThat((byte)-1).isEqualTo(result[3]); assertThat((byte) -1).isEqualTo(result[3]);
} }
@org.junit.Test public void testSingleElementLongBlob() { @org.junit.Test
public void testSingleElementLongBlob() {
// verifies blobs of up to 2^16 in length // verifies blobs of up to 2^16 in length
for (int i = 2; i <= 1<<16; i = i<<1) { for (int i = 2; i <= 1 << 16; i = i << 1) {
byte[] input = new byte[i-1]; byte[] input = new byte[i - 1];
for (int index = 0; index < input.length; index++) { for (int index = 0; index < input.length; index++) {
input[index] = (byte)(index % 64); input[index] = (byte) (index % 64);
} }
FlexBuffersBuilder builder = new FlexBuffersBuilder(); FlexBuffersBuilder builder = new FlexBuffersBuilder();
@@ -865,28 +882,31 @@ public class JavaTest {
byte[] result = r.asBlob().getBytes(); byte[] result = r.asBlob().getBytes();
for (int index = 0; index < input.length; index++) { for (int index = 0; index < input.length; index++) {
assertThat((byte)(index % 64)).isEqualTo(result[index]); assertThat((byte) (index % 64)).isEqualTo(result[index]);
} }
} }
} }
@org.junit.Test public void testSingleElementUByte() { @org.junit.Test
public void testSingleElementUByte() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(); FlexBuffersBuilder builder = new FlexBuffersBuilder();
builder.putUInt(0xFF); builder.putUInt(0xFF);
ByteBuffer b = builder.finish(); ByteBuffer b = builder.finish();
FlexBuffers.Reference r = FlexBuffers.getRoot(b); FlexBuffers.Reference r = FlexBuffers.getRoot(b);
assertThat(255).isEqualTo((int)r.asUInt()); assertThat(255).isEqualTo((int) r.asUInt());
} }
@org.junit.Test public void testSingleElementUShort() { @org.junit.Test
public void testSingleElementUShort() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(); FlexBuffersBuilder builder = new FlexBuffersBuilder();
builder.putUInt(0xFFFF); builder.putUInt(0xFFFF);
ByteBuffer b = builder.finish(); ByteBuffer b = builder.finish();
FlexBuffers.Reference r = FlexBuffers.getRoot(b); FlexBuffers.Reference r = FlexBuffers.getRoot(b);
assertThat(65535).isEqualTo((int)r.asUInt()); assertThat(65535).isEqualTo((int) r.asUInt());
} }
@org.junit.Test public void testSingleElementUInt() { @org.junit.Test
public void testSingleElementUInt() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(); FlexBuffersBuilder builder = new FlexBuffersBuilder();
builder.putUInt(0xFFFF_FFFFL); builder.putUInt(0xFFFF_FFFFL);
ByteBuffer b = builder.finish(); ByteBuffer b = builder.finish();
@@ -894,16 +914,16 @@ public class JavaTest {
assertThat(4294967295L).isEqualTo(r.asUInt()); assertThat(4294967295L).isEqualTo(r.asUInt());
} }
@org.junit.Test public void testSingleFixedTypeVector() { @org.junit.Test
public void testSingleFixedTypeVector() {
int[] ints = new int[]{5, 124, 118, -1}; int[] ints = new int[] {5, 124, 118, -1};
float[] floats = new float[]{5.5f, 124.124f, 118.118f, -1.1f}; float[] floats = new float[] {5.5f, 124.124f, 118.118f, -1.1f};
String[] strings = new String[]{"This", "is", "a", "typed", "array"}; String[] strings = new String[] {"This", "is", "a", "typed", "array"};
boolean[] booleans = new boolean[]{false, true, true, false}; boolean[] booleans = new boolean[] {false, true, true, false};
FlexBuffersBuilder builder =
FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512), new FlexBuffersBuilder(ByteBuffer.allocate(512), FlexBuffersBuilder.BUILDER_FLAG_NONE);
FlexBuffersBuilder.BUILDER_FLAG_NONE);
int mapPos = builder.startMap(); int mapPos = builder.startMap();
@@ -927,15 +947,15 @@ public class JavaTest {
builder.endMap(null, mapPos); builder.endMap(null, mapPos);
ByteBuffer b = builder.finish(); ByteBuffer b = builder.finish();
FlexBuffers.Reference r = FlexBuffers.getRoot(b); FlexBuffers.Reference r = FlexBuffers.getRoot(b);
assert(r.asMap().get("ints").isTypedVector()); assert (r.asMap().get("ints").isTypedVector());
assert(r.asMap().get("floats").isTypedVector()); assert (r.asMap().get("floats").isTypedVector());
assert(r.asMap().get("booleans").isTypedVector()); assert (r.asMap().get("booleans").isTypedVector());
} }
@org.junit.Test public void testSingleElementVector() { @org.junit.Test
public void testSingleElementVector() {
FlexBuffersBuilder b = new FlexBuffersBuilder(); FlexBuffersBuilder b = new FlexBuffersBuilder();
int vecPos = b.startVector(); int vecPos = b.startVector();
@@ -958,11 +978,12 @@ public class JavaTest {
assertThat("wow").isEqualTo(vec.get(1).asString()); assertThat("wow").isEqualTo(vec.get(1).asString());
assertThat(true).isEqualTo(vec.get(2).isNull()); assertThat(true).isEqualTo(vec.get(2).isNull());
assertThat("[ 99, \"wow\", null ]").isEqualTo(vec.get(3).toString()); assertThat("[ 99, \"wow\", null ]").isEqualTo(vec.get(3).toString());
assertThat("[ 99, \"wow\", null, [ 99, \"wow\", null ] ]").isEqualTo( assertThat("[ 99, \"wow\", null, [ 99, \"wow\", null ] ]")
FlexBuffers.getRoot(b.getBuffer()).toString()); .isEqualTo(FlexBuffers.getRoot(b.getBuffer()).toString());
} }
@org.junit.Test public void testSingleElementMap() { @org.junit.Test
public void testSingleElementMap() {
FlexBuffersBuilder b = new FlexBuffersBuilder(); FlexBuffersBuilder b = new FlexBuffersBuilder();
int mapPost = b.startMap(); int mapPost = b.startMap();
@@ -991,11 +1012,14 @@ public class JavaTest {
assertThat("wow").isEqualTo(map.get("myVec").asVector().get(1).asString()); assertThat("wow").isEqualTo(map.get("myVec").asVector().get(1).asString());
assertThat(Double.compare(0x1.ffffbbbffffffP+1023, map.get("double").asFloat())).isEqualTo(0); assertThat(Double.compare(0x1.ffffbbbffffffP+1023, map.get("double").asFloat())).isEqualTo(0);
assertThat( assertThat(
"{ \"double\" : 1.7976894783391937E308, \"myInt\" : 9223371743723257855, \"myNull\" : null, \"myString\" : \"wow\", \"myString2\" : \"incredible\", \"myVec\" : [ 99, \"wow\" ] }").isEqualTo( "{ \"double\" : 1.7976894783391937E308, \"myInt\" : 9223371743723257855, \"myNull\" :"
FlexBuffers.getRoot(b.getBuffer()).toString()); + " null, \"myString\" : \"wow\", \"myString2\" : \"incredible\", \"myVec\" : [ 99,"
+ " \"wow\" ] }")
.isEqualTo(FlexBuffers.getRoot(b.getBuffer()).toString());
} }
@org.junit.Test public void testFlexBuferEmpty() { @org.junit.Test
public void testFlexBuferEmpty() {
FlexBuffers.Blob blob = FlexBuffers.Blob.empty(); FlexBuffers.Blob blob = FlexBuffers.Blob.empty();
FlexBuffers.Map ary = FlexBuffers.Map.empty(); FlexBuffers.Map ary = FlexBuffers.Map.empty();
FlexBuffers.Vector map = FlexBuffers.Vector.empty(); FlexBuffers.Vector map = FlexBuffers.Vector.empty();
@@ -1006,7 +1030,8 @@ public class JavaTest {
assertThat(typedAry.size()).isEqualTo(0); assertThat(typedAry.size()).isEqualTo(0);
} }
@org.junit.Test public void testHashMapToMap() { @org.junit.Test
public void testHashMapToMap() {
int entriesCount = 12; int entriesCount = 12;
HashMap<String, String> source = new HashMap<>(); HashMap<String, String> source = new HashMap<>();
@@ -1043,7 +1068,8 @@ public class JavaTest {
assertThat(source).isEqualTo(result); assertThat(source).isEqualTo(result);
} }
@org.junit.Test public void testBuilderGrowth() { @org.junit.Test
public void testBuilderGrowth() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(); FlexBuffersBuilder builder = new FlexBuffersBuilder();
String someString = "This is a small string"; String someString = "This is a small string";
builder.putString(someString); builder.putString(someString);
@@ -1056,19 +1082,20 @@ public class JavaTest {
@org.junit.Test @org.junit.Test
public void testFlexBuffersUtf8Map() { public void testFlexBuffersUtf8Map() {
FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512), FlexBuffersBuilder builder =
FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS); new FlexBuffersBuilder(
ByteBuffer.allocate(512), FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
String key0 = "😨 face1"; String key0 = "😨 face1";
String key1 = "😩 face2"; String key1 = "😩 face2";
String key2 = "😨 face3"; String key2 = "😨 face3";
String key3 = "trademark ®"; String key3 = "trademark ®";
String key4 = "€ euro"; String key4 = "€ euro";
String utf8keys[] = { "😨 face1", "😩 face2", "😨 face3", "trademark ®", "€ euro"}; String utf8keys[] = {"😨 face1", "😩 face2", "😨 face3", "trademark ®", "€ euro"};
int map = builder.startMap(); int map = builder.startMap();
for (int i=0; i< utf8keys.length; i++) { for (int i = 0; i < utf8keys.length; i++) {
builder.putString(utf8keys[i], utf8keys[i]); // Testing key and string reuse. builder.putString(utf8keys[i], utf8keys[i]); // Testing key and string reuse.
} }
builder.endMap(null, map); builder.endMap(null, map);
@@ -1079,7 +1106,7 @@ public class JavaTest {
assertThat(m.size()).isEqualTo(5); assertThat(m.size()).isEqualTo(5);
KeyVector kv = m.keys(); KeyVector kv = m.keys();
for (int i=0; i< utf8keys.length; i++) { for (int i = 0; i < utf8keys.length; i++) {
assertThat(kv.get(i).toString()).isEqualTo(m.get(i).asString()); assertThat(kv.get(i).toString()).isEqualTo(m.get(i).asString());
} }
@@ -1090,34 +1117,37 @@ public class JavaTest {
assertThat(m.get(key4).asString()).isEqualTo(utf8keys[4]); assertThat(m.get(key4).asString()).isEqualTo(utf8keys[4]);
} }
@org.junit.Test public void testFlexBuffersMapLookup() { @org.junit.Test
FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512), public void testFlexBuffersMapLookup() {
FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS); FlexBuffersBuilder builder =
new FlexBuffersBuilder(
ByteBuffer.allocate(512), FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
String key0 = "123"; String key0 = "123";
String key1 = "1234"; String key1 = "1234";
String key2 = "12345"; String key2 = "12345";
String[] keys = new String[]{key0, key1, key2}; String[] keys = new String[] {key0, key1, key2};
int map = builder.startMap(); int map = builder.startMap();
for (int i=0; i< keys.length; i++) { for (int i = 0; i < keys.length; i++) {
builder.putString(keys[i], keys[i]); // Testing key and string reuse. builder.putString(keys[i], keys[i]); // Testing key and string reuse.
} }
builder.endMap(null, map); builder.endMap(null, map);
builder.finish(); builder.finish();
FlexBuffers.Map m = FlexBuffers.getRoot(builder.getBuffer()).asMap(); FlexBuffers.Map m = FlexBuffers.getRoot(builder.getBuffer()).asMap();
for (int i=0; i< keys.length; i++) { for (int i = 0; i < keys.length; i++) {
assertThat(m.get(keys[i]).asString()).isEqualTo(keys[i]); assertThat(m.get(keys[i]).asString()).isEqualTo(keys[i]);
assertThat(m.get(keys[i].getBytes(StandardCharsets.UTF_8)).asString()).isEqualTo(keys[i]); assertThat(m.get(keys[i].getBytes(StandardCharsets.UTF_8)).asString()).isEqualTo(keys[i]);
} }
} }
@org.junit.Test public void TestDictionaryLookup() { @org.junit.Test
public void TestDictionaryLookup() {
FlatBufferBuilder fbb = new FlatBufferBuilder(16); FlatBufferBuilder fbb = new FlatBufferBuilder(16);
int lfIndex = LongFloatEntry.createLongFloatEntry(fbb, 0, 99); int lfIndex = LongFloatEntry.createLongFloatEntry(fbb, 0, 99);
int vectorEntriesIdx = LongFloatMap.createEntriesVector(fbb, new int[] { lfIndex }); int vectorEntriesIdx = LongFloatMap.createEntriesVector(fbb, new int[] {lfIndex});
int rootIdx = LongFloatMap.createLongFloatMap(fbb, vectorEntriesIdx); int rootIdx = LongFloatMap.createLongFloatMap(fbb, vectorEntriesIdx);
LongFloatMap.finishLongFloatMapBuffer(fbb, rootIdx); LongFloatMap.finishLongFloatMapBuffer(fbb, rootIdx);
@@ -1133,7 +1163,8 @@ public class JavaTest {
assertThat(e2.value()).isEqualTo(99.0f); assertThat(e2.value()).isEqualTo(99.0f);
} }
@org.junit.Test public void TestVectorOfBytes() { @org.junit.Test
public void TestVectorOfBytes() {
FlatBufferBuilder fbb = new FlatBufferBuilder(16); FlatBufferBuilder fbb = new FlatBufferBuilder(16);
int str = fbb.createString("ByteMonster"); int str = fbb.createString("ByteMonster");
byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
@@ -1251,31 +1282,33 @@ public class JavaTest {
assertThat(monsterObject8.inventoryLength()).isEqualTo(2048); assertThat(monsterObject8.inventoryLength()).isEqualTo(2048);
} }
@org.junit.Test public void TestSharedStringPool() { @org.junit.Test
public void TestSharedStringPool() {
FlatBufferBuilder fb = new FlatBufferBuilder(1); FlatBufferBuilder fb = new FlatBufferBuilder(1);
String testString = "My string"; String testString = "My string";
int offset = fb.createSharedString(testString); int offset = fb.createSharedString(testString);
for (int i=0; i< 10; i++) { for (int i = 0; i < 10; i++) {
assertThat(offset).isEqualTo(fb.createSharedString(testString)); assertThat(offset).isEqualTo(fb.createSharedString(testString));
} }
} }
@org.junit.Test public void TestScalarOptional() { @org.junit.Test
public void TestScalarOptional() {
FlatBufferBuilder fbb = new FlatBufferBuilder(1); FlatBufferBuilder fbb = new FlatBufferBuilder(1);
ScalarStuff.startScalarStuff(fbb); ScalarStuff.startScalarStuff(fbb);
int pos = ScalarStuff.endScalarStuff(fbb); int pos = ScalarStuff.endScalarStuff(fbb);
fbb.finish(pos); fbb.finish(pos);
ScalarStuff scalarStuff = ScalarStuff.getRootAsScalarStuff(fbb.dataBuffer()); ScalarStuff scalarStuff = ScalarStuff.getRootAsScalarStuff(fbb.dataBuffer());
assertThat(scalarStuff.justI8()).isEqualTo((byte)0); assertThat(scalarStuff.justI8()).isEqualTo((byte) 0);
assertThat(scalarStuff.maybeI8()).isEqualTo((byte)0); assertThat(scalarStuff.maybeI8()).isEqualTo((byte) 0);
assertThat(scalarStuff.defaultI8()).isEqualTo((byte)42); assertThat(scalarStuff.defaultI8()).isEqualTo((byte) 42);
assertThat(scalarStuff.justU8()).isEqualTo(0); assertThat(scalarStuff.justU8()).isEqualTo(0);
assertThat(scalarStuff.maybeU8()).isEqualTo(0); assertThat(scalarStuff.maybeU8()).isEqualTo(0);
assertThat(scalarStuff.defaultU8()).isEqualTo(42); assertThat(scalarStuff.defaultU8()).isEqualTo(42);
assertThat(scalarStuff.justI16()).isEqualTo((short)0); assertThat(scalarStuff.justI16()).isEqualTo((short) 0);
assertThat(scalarStuff.maybeI16()).isEqualTo((short)0); assertThat(scalarStuff.maybeI16()).isEqualTo((short) 0);
assertThat(scalarStuff.defaultI16()).isEqualTo((short)42); assertThat(scalarStuff.defaultI16()).isEqualTo((short) 42);
assertThat(scalarStuff.justU16()).isEqualTo(0); assertThat(scalarStuff.justU16()).isEqualTo(0);
assertThat(scalarStuff.maybeU16()).isEqualTo(0); assertThat(scalarStuff.maybeU16()).isEqualTo(0);
assertThat(scalarStuff.defaultU16()).isEqualTo(42); assertThat(scalarStuff.defaultU16()).isEqualTo(42);
@@ -1320,24 +1353,24 @@ public class JavaTest {
fbb.clear(); fbb.clear();
ScalarStuff.startScalarStuff(fbb); ScalarStuff.startScalarStuff(fbb);
ScalarStuff.addJustI8(fbb, (byte)5); ScalarStuff.addJustI8(fbb, (byte) 5);
ScalarStuff.addMaybeI8(fbb, (byte)5); ScalarStuff.addMaybeI8(fbb, (byte) 5);
ScalarStuff.addDefaultI8(fbb, (byte)5); ScalarStuff.addDefaultI8(fbb, (byte) 5);
ScalarStuff.addJustU8(fbb, 6); ScalarStuff.addJustU8(fbb, 6);
ScalarStuff.addMaybeU8(fbb, 6); ScalarStuff.addMaybeU8(fbb, 6);
ScalarStuff.addDefaultU8(fbb, 6); ScalarStuff.addDefaultU8(fbb, 6);
ScalarStuff.addJustI16(fbb, (short)7); ScalarStuff.addJustI16(fbb, (short) 7);
ScalarStuff.addMaybeI16(fbb, (short)7); ScalarStuff.addMaybeI16(fbb, (short) 7);
ScalarStuff.addDefaultI16(fbb, (short)7); ScalarStuff.addDefaultI16(fbb, (short) 7);
ScalarStuff.addJustU16(fbb, 8); ScalarStuff.addJustU16(fbb, 8);
ScalarStuff.addMaybeU16(fbb, 8); ScalarStuff.addMaybeU16(fbb, 8);
ScalarStuff.addDefaultU16(fbb, 8); ScalarStuff.addDefaultU16(fbb, 8);
ScalarStuff.addJustI32(fbb, 9); ScalarStuff.addJustI32(fbb, 9);
ScalarStuff.addMaybeI32(fbb, 9); ScalarStuff.addMaybeI32(fbb, 9);
ScalarStuff.addDefaultI32(fbb, 9); ScalarStuff.addDefaultI32(fbb, 9);
ScalarStuff.addJustU32(fbb, (long)10); ScalarStuff.addJustU32(fbb, (long) 10);
ScalarStuff.addMaybeU32(fbb, (long)10); ScalarStuff.addMaybeU32(fbb, (long) 10);
ScalarStuff.addDefaultU32(fbb, (long)10); ScalarStuff.addDefaultU32(fbb, (long) 10);
ScalarStuff.addJustI64(fbb, 11L); ScalarStuff.addJustI64(fbb, 11L);
ScalarStuff.addMaybeI64(fbb, 11L); ScalarStuff.addMaybeI64(fbb, 11L);
ScalarStuff.addDefaultI64(fbb, 11L); ScalarStuff.addDefaultI64(fbb, 11L);
@@ -1363,15 +1396,15 @@ public class JavaTest {
scalarStuff = ScalarStuff.getRootAsScalarStuff(fbb.dataBuffer()); scalarStuff = ScalarStuff.getRootAsScalarStuff(fbb.dataBuffer());
assertThat(scalarStuff.justI8()).isEqualTo((byte)5); assertThat(scalarStuff.justI8()).isEqualTo((byte) 5);
assertThat(scalarStuff.maybeI8()).isEqualTo((byte)5); assertThat(scalarStuff.maybeI8()).isEqualTo((byte) 5);
assertThat(scalarStuff.defaultI8()).isEqualTo((byte)5); assertThat(scalarStuff.defaultI8()).isEqualTo((byte) 5);
assertThat(scalarStuff.justU8()).isEqualTo(6); assertThat(scalarStuff.justU8()).isEqualTo(6);
assertThat(scalarStuff.maybeU8()).isEqualTo(6); assertThat(scalarStuff.maybeU8()).isEqualTo(6);
assertThat(scalarStuff.defaultU8()).isEqualTo(6); assertThat(scalarStuff.defaultU8()).isEqualTo(6);
assertThat(scalarStuff.justI16()).isEqualTo((short)7); assertThat(scalarStuff.justI16()).isEqualTo((short) 7);
assertThat(scalarStuff.maybeI16()).isEqualTo((short)7); assertThat(scalarStuff.maybeI16()).isEqualTo((short) 7);
assertThat(scalarStuff.defaultI16()).isEqualTo((short)7); assertThat(scalarStuff.defaultI16()).isEqualTo((short) 7);
assertThat(scalarStuff.justU16()).isEqualTo(8); assertThat(scalarStuff.justU16()).isEqualTo(8);
assertThat(scalarStuff.maybeU16()).isEqualTo(8); assertThat(scalarStuff.maybeU16()).isEqualTo(8);
assertThat(scalarStuff.defaultU16()).isEqualTo(8); assertThat(scalarStuff.defaultU16()).isEqualTo(8);
@@ -1442,8 +1475,7 @@ public class JavaTest {
int[] inv = monster.getInventory(); int[] inv = monster.getInventory();
assertThat(inv.length).isEqualTo(5); assertThat(inv.length).isEqualTo(5);
int[] expInv = {0, 1, 2, 3, 4}; int[] expInv = {0, 1, 2, 3, 4};
for (int i = 0; i < inv.length; i++) for (int i = 0; i < inv.length; i++) assertThat(expInv[i]).isEqualTo(inv[i]);
assertThat(expInv[i]).isEqualTo(inv[i]);
TestT[] test4 = monster.getTest4(); TestT[] test4 = monster.getTest4();
TestT test_0 = test4[0]; TestT test_0 = test4[0];

View File

@@ -8,6 +8,7 @@ plugins {
} }
group = "com.google.flatbuffers.jmh" group = "com.google.flatbuffers.jmh"
version = "2.0.0-SNAPSHOT" version = "2.0.0-SNAPSHOT"
// Reads latest version from Java's runtime pom.xml, // Reads latest version from Java's runtime pom.xml,
@@ -15,7 +16,8 @@ version = "2.0.0-SNAPSHOT"
// runtime // runtime
fun readJavaFlatBufferVersion(): String { fun readJavaFlatBufferVersion(): String {
val pom = XmlParser().parse(File("../java/pom.xml")) val pom = XmlParser().parse(File("../java/pom.xml"))
val versionTag = pom.children().find { val versionTag =
pom.children().find {
val node = it as groovy.util.Node val node = it as groovy.util.Node
node.name().toString().contains("version") node.name().toString().contains("version")
} as groovy.util.Node } as groovy.util.Node
@@ -42,17 +44,16 @@ benchmark {
include(".*FlatbufferBenchmark.*") include(".*FlatbufferBenchmark.*")
} }
} }
targets { targets { register("jvm") }
register("jvm")
}
} }
kotlin { kotlin {
jvm { jvm {
compilations { compilations {
val main by getting { } val main by getting {}
// custom benchmark compilation // custom benchmark compilation
val benchmarks by compilations.creating { val benchmarks by
compilations.creating {
defaultSourceSet { defaultSourceSet {
dependencies { dependencies {
// Compile against the main compilation's compile classpath and outputs: // Compile against the main compilation's compile classpath and outputs:
@@ -91,17 +92,13 @@ tasks.register<de.undercouch.gradle.tasks.download.Download>("downloadMultipleFi
} }
abstract class GenerateFBTestClasses : DefaultTask() { abstract class GenerateFBTestClasses : DefaultTask() {
@get:InputFiles @get:InputFiles abstract val inputFiles: ConfigurableFileCollection
abstract val inputFiles: ConfigurableFileCollection
@get:Input @get:Input abstract val includeFolder: Property<String>
abstract val includeFolder: Property<String>
@get:Input @get:Input abstract val outputFolder: Property<String>
abstract val outputFolder: Property<String>
@get:Input @get:Input abstract val variants: ListProperty<String>
abstract val variants: ListProperty<String>
@Inject @Inject
protected open fun getExecActionFactory(): org.gradle.process.internal.ExecActionFactory? { protected open fun getExecActionFactory(): org.gradle.process.internal.ExecActionFactory? {
@@ -117,7 +114,7 @@ abstract class GenerateFBTestClasses : DefaultTask() {
val execAction = getExecActionFactory()!!.newExecAction() val execAction = getExecActionFactory()!!.newExecAction()
val sources = inputFiles.asPath.split(":") val sources = inputFiles.asPath.split(":")
val langs = variants.get().map { "--$it" } val langs = variants.get().map { "--$it" }
val args = mutableListOf("flatc","-o", outputFolder.get(), *langs.toTypedArray()) val args = mutableListOf("flatc", "-o", outputFolder.get(), *langs.toTypedArray())
if (includeFolder.get().isNotEmpty()) { if (includeFolder.get().isNotEmpty()) {
args.add("-I") args.add("-I")
args.add(includeFolder.get()) args.add(includeFolder.get())

View File

@@ -2,8 +2,8 @@
package com.google.flatbuffers.kotlin.benchmark package com.google.flatbuffers.kotlin.benchmark
import com.google.flatbuffers.kotlin.FlatBufferBuilder import com.google.flatbuffers.kotlin.FlatBufferBuilder
import java.util.concurrent.TimeUnit
import jmonster.JAllMonsters import jmonster.JAllMonsters
import jmonster.JColor import jmonster.JColor
import jmonster.JMonster import jmonster.JMonster
@@ -17,7 +17,6 @@ import monster.MonsterOffsetArray
import monster.Vec3 import monster.Vec3
import org.openjdk.jmh.annotations.* import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@State(Scope.Benchmark) @State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime) @BenchmarkMode(Mode.AverageTime)
@@ -35,13 +34,15 @@ open class FlatbufferBenchmark {
populateMosterKotlin(fbDeserializationKotlin) populateMosterKotlin(fbDeserializationKotlin)
populateMosterJava(fbDeserializationJava) populateMosterJava(fbDeserializationJava)
} }
@OptIn(ExperimentalUnsignedTypes::class) @OptIn(ExperimentalUnsignedTypes::class)
private fun populateMosterKotlin(fb: FlatBufferBuilder) { private fun populateMosterKotlin(fb: FlatBufferBuilder) {
fb.clear() fb.clear()
val monsterName = fb.createString("MonsterName"); val monsterName = fb.createString("MonsterName")
val items = ubyteArrayOf(0u, 1u, 2u, 3u, 4u) val items = ubyteArrayOf(0u, 1u, 2u, 3u, 4u)
val inv = createInventoryVector(fb, items) val inv = createInventoryVector(fb, items)
val monsterOffsets: MonsterOffsetArray = MonsterOffsetArray(repetition) { val monsterOffsets: MonsterOffsetArray =
MonsterOffsetArray(repetition) {
Monster.startMonster(fb) Monster.startMonster(fb)
Monster.addName(fb, monsterName) Monster.addName(fb, monsterName)
Monster.addPos(fb, Vec3.createVec3(fb, 1.0f, 2.0f, 3.0f)) Monster.addPos(fb, Vec3.createVec3(fb, 1.0f, 2.0f, 3.0f))
@@ -57,11 +58,14 @@ open class FlatbufferBenchmark {
} }
@OptIn(ExperimentalUnsignedTypes::class) @OptIn(ExperimentalUnsignedTypes::class)
private fun populateMosterJava(fb: com.google.flatbuffers.FlatBufferBuilder){ private fun populateMosterJava(fb: com.google.flatbuffers.FlatBufferBuilder) {
fb.clear() fb.clear()
val monsterName = fb.createString("MonsterName"); val monsterName = fb.createString("MonsterName")
val inv = JMonster.createInventoryVector(fb, ubyteArrayOf(0u, 1u, 2u, 3u, 4u)) val inv = JMonster.createInventoryVector(fb, ubyteArrayOf(0u, 1u, 2u, 3u, 4u))
val monsters = JAllMonsters.createMonstersVector(fb, IntArray(repetition) { val monsters =
JAllMonsters.createMonstersVector(
fb,
IntArray(repetition) {
JMonster.startJMonster(fb) JMonster.startJMonster(fb)
JMonster.addName(fb, monsterName) JMonster.addName(fb, monsterName)
JMonster.addPos(fb, JVec3.createJVec3(fb, 1.0f, 2.0f, 3.0f)) JMonster.addPos(fb, JVec3.createJVec3(fb, 1.0f, 2.0f, 3.0f))
@@ -70,10 +74,12 @@ open class FlatbufferBenchmark {
JMonster.addInventory(fb, inv) JMonster.addInventory(fb, inv)
JMonster.addColor(fb, JColor.Red) JMonster.addColor(fb, JColor.Red)
JMonster.endJMonster(fb) JMonster.endJMonster(fb)
}) },
)
val allMonsters = JAllMonsters.createJAllMonsters(fb, monsters) val allMonsters = JAllMonsters.createJAllMonsters(fb, monsters)
fb.finish(allMonsters) fb.finish(allMonsters)
} }
@Benchmark @Benchmark
fun monstersSerializationKotlin() { fun monstersSerializationKotlin() {
populateMosterKotlin(fbKotlin) populateMosterKotlin(fbKotlin)
@@ -100,6 +106,7 @@ open class FlatbufferBenchmark {
hole.consume(monster.inventory(3)) hole.consume(monster.inventory(3))
} }
} }
@Benchmark @Benchmark
fun monstersSerializationJava() { fun monstersSerializationJava() {
populateMosterJava(fbJava) populateMosterJava(fbJava)
@@ -125,5 +132,4 @@ open class FlatbufferBenchmark {
hole.consume(monster.inventory(3)) hole.consume(monster.inventory(3))
} }
} }
} }

View File

@@ -16,11 +16,13 @@
@file:OptIn(ExperimentalUnsignedTypes::class) @file:OptIn(ExperimentalUnsignedTypes::class)
package com.google.flatbuffers.kotlin.benchmark package com.google.flatbuffers.kotlin.benchmark
import com.google.flatbuffers.ArrayReadWriteBuf import com.google.flatbuffers.ArrayReadWriteBuf
import com.google.flatbuffers.FlexBuffers import com.google.flatbuffers.FlexBuffers
import com.google.flatbuffers.FlexBuffersBuilder.BUILDER_FLAG_SHARE_ALL import com.google.flatbuffers.FlexBuffersBuilder.BUILDER_FLAG_SHARE_ALL
import com.google.flatbuffers.kotlin.FlexBuffersBuilder import com.google.flatbuffers.kotlin.FlexBuffersBuilder
import com.google.flatbuffers.kotlin.getRoot import com.google.flatbuffers.kotlin.getRoot
import java.util.concurrent.TimeUnit
import kotlinx.benchmark.Blackhole import kotlinx.benchmark.Blackhole
import org.openjdk.jmh.annotations.Benchmark import org.openjdk.jmh.annotations.Benchmark
import org.openjdk.jmh.annotations.BenchmarkMode import org.openjdk.jmh.annotations.BenchmarkMode
@@ -30,7 +32,6 @@ import org.openjdk.jmh.annotations.OutputTimeUnit
import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.Setup import org.openjdk.jmh.annotations.Setup
import org.openjdk.jmh.annotations.State import org.openjdk.jmh.annotations.State
import java.util.concurrent.TimeUnit
@State(Scope.Benchmark) @State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime) @BenchmarkMode(Mode.AverageTime)
@@ -57,9 +58,7 @@ open class FlexBuffersBenchmark {
this["int"] = 10 this["int"] = 10
this["float"] = 12.3 this["float"] = 12.3
this["intarray"] = bigIntArray this["intarray"] = bigIntArray
this.putMap("myMap") { this.putMap("myMap") { this["cool"] = "beans" }
this["cool"] = "beans"
}
} }
val ref = getRoot(kBuilder.finish()) val ref = getRoot(kBuilder.finish())
val map = ref.toMap() val map = ref.toMap()
@@ -74,7 +73,11 @@ open class FlexBuffersBenchmark {
@Benchmark @Benchmark
open fun mapJava(blackhole: Blackhole) { open fun mapJava(blackhole: Blackhole) {
val jBuilder = com.google.flatbuffers.FlexBuffersBuilder(ArrayReadWriteBuf(initialCapacity), BUILDER_FLAG_SHARE_ALL) val jBuilder =
com.google.flatbuffers.FlexBuffersBuilder(
ArrayReadWriteBuf(initialCapacity),
BUILDER_FLAG_SHARE_ALL,
)
val startMap = jBuilder.startMap() val startMap = jBuilder.startMap()
jBuilder.putString("hello", "world") jBuilder.putString("hello", "world")
jBuilder.putInt("int", 10) jBuilder.putInt("int", 10)
@@ -112,18 +115,18 @@ open class FlexBuffersBenchmark {
@Benchmark @Benchmark
open fun intArrayJava(blackhole: Blackhole) { open fun intArrayJava(blackhole: Blackhole) {
val jBuilder = com.google.flatbuffers.FlexBuffersBuilder(ArrayReadWriteBuf(initialCapacity), BUILDER_FLAG_SHARE_ALL) val jBuilder =
com.google.flatbuffers.FlexBuffersBuilder(
ArrayReadWriteBuf(initialCapacity),
BUILDER_FLAG_SHARE_ALL,
)
val v = jBuilder.startVector() val v = jBuilder.startVector()
bigIntArray.forEach { jBuilder.putInt(it) } bigIntArray.forEach { jBuilder.putInt(it) }
jBuilder.endVector(null, v, true, false) jBuilder.endVector(null, v, true, false)
jBuilder.finish() jBuilder.finish()
val root = FlexBuffers.getRoot(jBuilder.buffer) val root = FlexBuffers.getRoot(jBuilder.buffer)
val vec = root.asVector() val vec = root.asVector()
blackhole.consume( blackhole.consume(IntArray(vec.size()) { vec[it].asInt() })
IntArray(vec.size()) {
vec[it].asInt()
}
)
} }
@Benchmark @Benchmark
@@ -138,7 +141,11 @@ open class FlexBuffersBenchmark {
@Benchmark @Benchmark
open fun stringArrayJava(blackhole: Blackhole) { open fun stringArrayJava(blackhole: Blackhole) {
val jBuilder = com.google.flatbuffers.FlexBuffersBuilder(ArrayReadWriteBuf(initialCapacity), BUILDER_FLAG_SHARE_ALL) val jBuilder =
com.google.flatbuffers.FlexBuffersBuilder(
ArrayReadWriteBuf(initialCapacity),
BUILDER_FLAG_SHARE_ALL,
)
val v = jBuilder.startVector() val v = jBuilder.startVector()
stringValue.forEach { jBuilder.putString(it) } stringValue.forEach { jBuilder.putString(it) }
jBuilder.endVector(null, v, false, false) jBuilder.endVector(null, v, false, false)
@@ -182,7 +189,11 @@ open class FlexBuffersBenchmark {
@Benchmark @Benchmark
open fun stringMapJava(blackhole: Blackhole) { open fun stringMapJava(blackhole: Blackhole) {
val jBuilder = com.google.flatbuffers.FlexBuffersBuilder(ArrayReadWriteBuf(initialCapacity), BUILDER_FLAG_SHARE_ALL) val jBuilder =
com.google.flatbuffers.FlexBuffersBuilder(
ArrayReadWriteBuf(initialCapacity),
BUILDER_FLAG_SHARE_ALL,
)
val v = jBuilder.startMap() val v = jBuilder.startMap()
for (i in stringKey.indices) { for (i in stringKey.indices) {
jBuilder.putString(stringKey[i], stringValue[i]) jBuilder.putString(stringKey[i], stringValue[i])

View File

@@ -24,6 +24,9 @@ import com.google.gson.JsonObject
import com.google.gson.JsonParser import com.google.gson.JsonParser
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import java.io.ByteArrayInputStream
import java.io.InputStreamReader
import java.util.concurrent.TimeUnit
import kotlinx.benchmark.Blackhole import kotlinx.benchmark.Blackhole
import okio.Buffer import okio.Buffer
import org.openjdk.jmh.annotations.Benchmark import org.openjdk.jmh.annotations.Benchmark
@@ -33,9 +36,6 @@ import org.openjdk.jmh.annotations.Mode
import org.openjdk.jmh.annotations.OutputTimeUnit import org.openjdk.jmh.annotations.OutputTimeUnit
import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State import org.openjdk.jmh.annotations.State
import java.io.ByteArrayInputStream
import java.io.InputStreamReader
import java.util.concurrent.TimeUnit
@State(Scope.Benchmark) @State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime) @BenchmarkMode(Mode.AverageTime)
@@ -43,9 +43,7 @@ import java.util.concurrent.TimeUnit
@Measurement(iterations = 100, time = 1, timeUnit = TimeUnit.MICROSECONDS) @Measurement(iterations = 100, time = 1, timeUnit = TimeUnit.MICROSECONDS)
open class JsonBenchmark { open class JsonBenchmark {
final val moshi = Moshi.Builder() final val moshi = Moshi.Builder().addLast(KotlinJsonAdapterFactory()).build()
.addLast(KotlinJsonAdapterFactory())
.build()
final val moshiAdapter = moshi.adapter(Map::class.java) final val moshiAdapter = moshi.adapter(Map::class.java)
final val gson = Gson() final val gson = Gson()
@@ -77,46 +75,60 @@ open class JsonBenchmark {
// TWITTER // TWITTER
@Benchmark @Benchmark
open fun readTwitterFlexBuffers(hole: Blackhole? = null) = hole?.consume(readFlexBuffers(twitterData)) open fun readTwitterFlexBuffers(hole: Blackhole? = null) =
@Benchmark hole?.consume(readFlexBuffers(twitterData))
open fun readTwitterMoshi(hole: Blackhole?) = hole?.consume(readMoshi(twitterData))
@Benchmark @Benchmark open fun readTwitterMoshi(hole: Blackhole?) = hole?.consume(readMoshi(twitterData))
open fun readTwitterGson(hole: Blackhole?) = hole?.consume(readGson(twitterData))
@Benchmark open fun readTwitterGson(hole: Blackhole?) = hole?.consume(readGson(twitterData))
@Benchmark @Benchmark
open fun roundTripTwitterFlexBuffers(hole: Blackhole? = null) = hole?.consume(readFlexBuffers(twitterData).toJson()) open fun roundTripTwitterFlexBuffers(hole: Blackhole? = null) =
hole?.consume(readFlexBuffers(twitterData).toJson())
@Benchmark @Benchmark
open fun roundTripTwitterMoshi(hole: Blackhole?) = hole?.consume(moshiAdapter.toJson(readMoshi(twitterData))) open fun roundTripTwitterMoshi(hole: Blackhole?) =
hole?.consume(moshiAdapter.toJson(readMoshi(twitterData)))
@Benchmark @Benchmark
open fun roundTripTwitterGson(hole: Blackhole?) = hole?.consume(gson.toJson(readGson(twitterData))) open fun roundTripTwitterGson(hole: Blackhole?) =
hole?.consume(gson.toJson(readGson(twitterData)))
// CITM // CITM
@Benchmark @Benchmark
open fun readCITMFlexBuffers(hole: Blackhole? = null) = hole?.consume(readFlexBuffers(citmData)) open fun readCITMFlexBuffers(hole: Blackhole? = null) = hole?.consume(readFlexBuffers(citmData))
@Benchmark @Benchmark
open fun readCITMMoshi(hole: Blackhole?) = hole?.consume(moshiAdapter.toJson(readMoshi(citmData))) open fun readCITMMoshi(hole: Blackhole?) = hole?.consume(moshiAdapter.toJson(readMoshi(citmData)))
@Benchmark @Benchmark
open fun readCITMGson(hole: Blackhole?) = hole?.consume(gson.toJson(readGson(citmData))) open fun readCITMGson(hole: Blackhole?) = hole?.consume(gson.toJson(readGson(citmData)))
@Benchmark @Benchmark
open fun roundTripCITMFlexBuffers(hole: Blackhole? = null) = hole?.consume(readFlexBuffers(citmData).toJson()) open fun roundTripCITMFlexBuffers(hole: Blackhole? = null) =
hole?.consume(readFlexBuffers(citmData).toJson())
@Benchmark @Benchmark
open fun roundTripCITMMoshi(hole: Blackhole?) = hole?.consume(moshiAdapter.toJson(readMoshi(citmData))) open fun roundTripCITMMoshi(hole: Blackhole?) =
hole?.consume(moshiAdapter.toJson(readMoshi(citmData)))
@Benchmark @Benchmark
open fun roundTripCITMGson(hole: Blackhole?) = hole?.consume(gson.toJson(readGson(citmData))) open fun roundTripCITMGson(hole: Blackhole?) = hole?.consume(gson.toJson(readGson(citmData)))
@Benchmark @Benchmark
open fun writeCITMFlexBuffers(hole: Blackhole? = null) = hole?.consume(fbCitmRef.toJson()) open fun writeCITMFlexBuffers(hole: Blackhole? = null) = hole?.consume(fbCitmRef.toJson())
@Benchmark @Benchmark
open fun writeCITMMoshi(hole: Blackhole?) = hole?.consume(moshiAdapter.toJson(moshiCitmRef)) open fun writeCITMMoshi(hole: Blackhole?) = hole?.consume(moshiAdapter.toJson(moshiCitmRef))
@Benchmark
open fun writeCITMGson(hole: Blackhole?) = hole?.consume(gson.toJson(gsonCitmRef)) @Benchmark open fun writeCITMGson(hole: Blackhole?) = hole?.consume(gson.toJson(gsonCitmRef))
// CANADA // CANADA
@Benchmark @Benchmark
open fun readCanadaFlexBuffers(hole: Blackhole? = null) = hole?.consume(readFlexBuffers(canadaData)) open fun readCanadaFlexBuffers(hole: Blackhole? = null) =
@Benchmark hole?.consume(readFlexBuffers(canadaData))
open fun readCanadaMoshi(hole: Blackhole?) = hole?.consume(readMoshi(canadaData))
@Benchmark @Benchmark open fun readCanadaMoshi(hole: Blackhole?) = hole?.consume(readMoshi(canadaData))
open fun readCanadaGson(hole: Blackhole?) = hole?.consume(readGson(canadaData))
@Benchmark open fun readCanadaGson(hole: Blackhole?) = hole?.consume(readGson(canadaData))
} }

View File

@@ -18,6 +18,9 @@ package com.google.flatbuffers.kotlin.benchmark
import com.google.flatbuffers.kotlin.ArrayReadWriteBuffer import com.google.flatbuffers.kotlin.ArrayReadWriteBuffer
import com.google.flatbuffers.kotlin.Key import com.google.flatbuffers.kotlin.Key
import com.google.flatbuffers.kotlin.Utf8 import com.google.flatbuffers.kotlin.Utf8
import java.nio.ByteBuffer
import java.util.concurrent.TimeUnit
import kotlin.random.Random
import kotlinx.benchmark.Blackhole import kotlinx.benchmark.Blackhole
import org.openjdk.jmh.annotations.Benchmark import org.openjdk.jmh.annotations.Benchmark
import org.openjdk.jmh.annotations.BenchmarkMode import org.openjdk.jmh.annotations.BenchmarkMode
@@ -27,9 +30,6 @@ import org.openjdk.jmh.annotations.OutputTimeUnit
import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.Setup import org.openjdk.jmh.annotations.Setup
import org.openjdk.jmh.annotations.State import org.openjdk.jmh.annotations.State
import java.nio.ByteBuffer
import java.util.concurrent.TimeUnit
import kotlin.random.Random
@State(Scope.Benchmark) @State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime) @BenchmarkMode(Mode.AverageTime)
@@ -44,9 +44,7 @@ open class UTF8Benchmark {
private var sampleSmallAscii = (0..sampleSize).map { populateAscii(stringSize) }.toList() private var sampleSmallAscii = (0..sampleSize).map { populateAscii(stringSize) }.toList()
private var sampleSmallAsciiDecoded = sampleSmallAscii.map { it.encodeToByteArray() }.toList() private var sampleSmallAsciiDecoded = sampleSmallAscii.map { it.encodeToByteArray() }.toList()
@Setup @Setup fun setUp() {}
fun setUp() {
}
@Benchmark @Benchmark
fun encodeUtf8KotlinStandard(blackhole: Blackhole) { fun encodeUtf8KotlinStandard(blackhole: Blackhole) {
@@ -54,6 +52,7 @@ open class UTF8Benchmark {
blackhole.consume(i.encodeToByteArray()) blackhole.consume(i.encodeToByteArray())
} }
} }
@Benchmark @Benchmark
fun encodeUtf8KotlinFlatbuffers(blackhole: Blackhole) { fun encodeUtf8KotlinFlatbuffers(blackhole: Blackhole) {
for (i in sampleSmallUtf8) { for (i in sampleSmallUtf8) {
@@ -61,6 +60,7 @@ open class UTF8Benchmark {
blackhole.consume(Utf8.encodeUtf8Array(i, byteArray, 0, byteArray.size)) blackhole.consume(Utf8.encodeUtf8Array(i, byteArray, 0, byteArray.size))
} }
} }
@Benchmark @Benchmark
fun encodeUtf8JavaFlatbuffers(blackhole: Blackhole) { fun encodeUtf8JavaFlatbuffers(blackhole: Blackhole) {
val javaUtf8 = com.google.flatbuffers.Utf8.getDefault() val javaUtf8 = com.google.flatbuffers.Utf8.getDefault()
@@ -101,6 +101,7 @@ open class UTF8Benchmark {
blackhole.consume(i.encodeToByteArray()) blackhole.consume(i.encodeToByteArray())
} }
} }
@Benchmark @Benchmark
fun encodeAsciiKotlinFlatbuffers(blackhole: Blackhole) { fun encodeAsciiKotlinFlatbuffers(blackhole: Blackhole) {
for (i in sampleSmallAscii) { for (i in sampleSmallAscii) {
@@ -108,6 +109,7 @@ open class UTF8Benchmark {
blackhole.consume(Utf8.encodeUtf8Array(i, byteArray, 0, byteArray.size)) blackhole.consume(Utf8.encodeUtf8Array(i, byteArray, 0, byteArray.size))
} }
} }
@Benchmark @Benchmark
fun encodeAsciiJavaFlatbuffers(blackhole: Blackhole) { fun encodeAsciiJavaFlatbuffers(blackhole: Blackhole) {
val javaUtf8 = com.google.flatbuffers.Utf8.getDefault() val javaUtf8 = com.google.flatbuffers.Utf8.getDefault()
@@ -179,7 +181,8 @@ open class UTF8Benchmark {
while (i < size) { while (i < size) {
val w = Random.nextInt() and 0xFF val w = Random.nextInt() and 0xFF
when { when {
w < 0x80 -> data[i++] = 0x20; // w; w < 0x80 -> data[i++] = 0x20
// w;
w < 0xE0 -> { w < 0xE0 -> {
data[i++] = (0xC2 + Random.nextInt() % (0xDF - 0xC2 + 1)).toByte() data[i++] = (0xC2 + Random.nextInt() % (0xDF - 0xC2 + 1)).toByte()
data[i++] = (0x80 + Random.nextInt() % (0xBF - 0x80 + 1)).toByte() data[i++] = (0x80 + Random.nextInt() % (0xBF - 0x80 + 1)).toByte()

View File

@@ -1,7 +1,6 @@
import org.gradle.internal.impldep.org.testng.ITestResult.STARTED import java.nio.charset.StandardCharsets
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.nio.charset.StandardCharsets
buildscript { buildscript {
repositories { repositories {
@@ -26,7 +25,8 @@ allprojects {
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<KotlinCommonOptions>>().configureEach { tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<KotlinCommonOptions>>().configureEach {
kotlinOptions { kotlinOptions {
freeCompilerArgs += "-progressive" // https://kotlinlang.org/docs/whatsnew13.html#progressive-mode freeCompilerArgs +=
"-progressive" // https://kotlinlang.org/docs/whatsnew13.html#progressive-mode
} }
} }

View File

@@ -1,7 +1,3 @@
plugins { plugins { `kotlin-dsl` }
`kotlin-dsl`
}
repositories { repositories { gradlePluginPortal() }
gradlePluginPortal()
}

View File

@@ -1,8 +1,8 @@
import java.util.*
import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.bundling.Jar import org.gradle.api.tasks.bundling.Jar
import org.gradle.kotlin.dsl.`maven-publish` import org.gradle.kotlin.dsl.`maven-publish`
import org.gradle.kotlin.dsl.signing import org.gradle.kotlin.dsl.signing
import java.util.*
plugins { plugins {
`maven-publish` `maven-publish`
@@ -11,21 +11,24 @@ plugins {
// Stub secrets to let the project sync and build without the publication values set up // Stub secrets to let the project sync and build without the publication values set up
ext["signing.keyId"] = null ext["signing.keyId"] = null
ext["signing.password"] = null ext["signing.password"] = null
ext["signing.secretKeyRingFile"] = null ext["signing.secretKeyRingFile"] = null
ext["ossrhUsername"] = null ext["ossrhUsername"] = null
ext["ossrhPassword"] = null ext["ossrhPassword"] = null
// Grabbing secrets from local.properties file or from environment variables, which could be used on CI // Grabbing secrets from local.properties file or from environment variables, which could be used on
// CI
val secretPropsFile = project.rootProject.file("local.properties") val secretPropsFile = project.rootProject.file("local.properties")
if (secretPropsFile.exists()) { if (secretPropsFile.exists()) {
secretPropsFile.reader().use { secretPropsFile
Properties().apply { .reader()
load(it) .use { Properties().apply { load(it) } }
} .onEach { (name, value) -> ext[name.toString()] = value }
}.onEach { (name, value) ->
ext[name.toString()] = value
}
} else { } else {
ext["signing.keyId"] = System.getenv("OSSRH_USERNAME") ext["signing.keyId"] = System.getenv("OSSRH_USERNAME")
ext["signing.password"] = System.getenv("OSSRH_PASSWORD") ext["signing.password"] = System.getenv("OSSRH_PASSWORD")
@@ -34,9 +37,7 @@ if (secretPropsFile.exists()) {
ext["ossrhPassword"] = System.getenv("OSSRH_PASSWORD") ext["ossrhPassword"] = System.getenv("OSSRH_PASSWORD")
} }
val javadocJar by tasks.registering(Jar::class) { val javadocJar by tasks.registering(Jar::class) { archiveClassifier.set("javadoc") }
archiveClassifier.set("javadoc")
}
fun getExtraString(name: String) = ext[name]?.toString() fun getExtraString(name: String) = ext[name]?.toString()
@@ -82,14 +83,10 @@ publishing {
email.set("dbaileychess@gmail.com") email.set("dbaileychess@gmail.com")
} }
} }
scm { scm { url.set("https://github.com/google/flatbuffers") }
url.set("https://github.com/google/flatbuffers")
}
} }
} }
} }
// Signing artifacts. Signing.* extra properties values will be used // Signing artifacts. Signing.* extra properties values will be used
signing { signing { sign(publishing.publications) }
sign(publishing.publications)
}

View File

@@ -1,29 +1,19 @@
import org.gradle.internal.impldep.org.fusesource.jansi.AnsiRenderer.test
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework
import org.jetbrains.kotlin.cli.common.toBooleanLenient
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFrameworkConfig
plugins { plugins {
kotlin("multiplatform") kotlin("multiplatform")
id("convention.publication") id("convention.publication")
} }
val libName = "Flatbuffers" val libName = "Flatbuffers"
group = "com.google.flatbuffers.kotlin" group = "com.google.flatbuffers.kotlin"
version = "2.0.0-SNAPSHOT" version = "2.0.0-SNAPSHOT"
kotlin { kotlin {
explicitApi() explicitApi()
jvm() jvm()
js(IR) { js(IR) {
browser { browser { testTask { enabled = false } }
testTask {
enabled = false
}
}
binaries.executable() binaries.executable()
} }
macosX64() macosX64()
@@ -32,17 +22,10 @@ kotlin {
iosSimulatorArm64() iosSimulatorArm64()
sourceSets { sourceSets {
val commonMain by getting { dependencies { implementation(kotlin("stdlib-common")) } }
val commonMain by getting {
dependencies {
implementation(kotlin("stdlib-common"))
}
}
val commonTest by getting { val commonTest by getting {
dependencies { dependencies { implementation(kotlin("test")) }
implementation(kotlin("test"))
}
kotlin.srcDir("src/commonTest/generated/kotlin/") kotlin.srcDir("src/commonTest/generated/kotlin/")
} }
@@ -52,8 +35,7 @@ kotlin {
implementation("com.google.flatbuffers:flatbuffers-java:2.0.3") implementation("com.google.flatbuffers:flatbuffers-java:2.0.3")
} }
} }
val jvmMain by getting { val jvmMain by getting {}
}
val macosX64Main by getting val macosX64Main by getting
val macosArm64Main by getting val macosArm64Main by getting
@@ -69,53 +51,47 @@ kotlin {
iosSimulatorArm64Main.dependsOn(this) iosSimulatorArm64Main.dependsOn(this)
} }
all { all { languageSettings.optIn("kotlin.ExperimentalUnsignedTypes") }
languageSettings.optIn("kotlin.ExperimentalUnsignedTypes")
}
} }
} }
// Fixes JS issue: https://youtrack.jetbrains.com/issue/KT-49109 // Fixes JS issue: https://youtrack.jetbrains.com/issue/KT-49109
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin> { rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin> {
rootProject.the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension>().nodeVersion = "16.0.0" rootProject.the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension>().nodeVersion =
"16.0.0"
} }
// Use the default greeting // Use the default greeting
tasks.register<GenerateFBTestClasses>("generateFBTestClassesKt") { tasks.register<GenerateFBTestClasses>("generateFBTestClassesKt") {
inputFiles.setFrom("$rootDir/../tests/monster_test.fbs", inputFiles.setFrom(
"$rootDir/../tests/monster_test.fbs",
"$rootDir/../tests/dictionary_lookup.fbs", "$rootDir/../tests/dictionary_lookup.fbs",
// @todo Seems like nesting code generation is broken for all generators. // @todo Seems like nesting code generation is broken for all generators.
// disabling test for now. // disabling test for now.
// "$rootDir/../tests/namespace_test/namespace_test1.fbs", // "$rootDir/../tests/namespace_test/namespace_test1.fbs",
// "$rootDir/../tests/namespace_test/namespace_test2.fbs", // "$rootDir/../tests/namespace_test/namespace_test2.fbs",
"$rootDir/../tests/union_vector/union_vector.fbs", "$rootDir/../tests/union_vector/union_vector.fbs",
"$rootDir/../tests/optional_scalars.fbs") "$rootDir/../tests/optional_scalars.fbs",
)
includeFolder.set("$rootDir/../tests/include_test") includeFolder.set("$rootDir/../tests/include_test")
outputFolder.set("${projectDir}/src/commonTest/generated/kotlin/") outputFolder.set("${projectDir}/src/commonTest/generated/kotlin/")
variant.set("kotlin-kmp") variant.set("kotlin-kmp")
} }
project.tasks.forEach { project.tasks.forEach {
if (it.name.contains("compileKotlin")) if (it.name.contains("compileKotlin")) it.dependsOn("generateFBTestClassesKt")
it.dependsOn("generateFBTestClassesKt")
} }
fun String.intProperty() = findProperty(this).toString().toInt() fun String.intProperty() = findProperty(this).toString().toInt()
abstract class GenerateFBTestClasses : DefaultTask() { abstract class GenerateFBTestClasses : DefaultTask() {
@get:InputFiles @get:InputFiles abstract val inputFiles: ConfigurableFileCollection
abstract val inputFiles: ConfigurableFileCollection
@get:Input @get:Input abstract val includeFolder: Property<String>
abstract val includeFolder: Property<String>
@get:Input @get:Input abstract val outputFolder: Property<String>
abstract val outputFolder: Property<String>
@get:Input @get:Input abstract val variant: Property<String>
abstract val variant: Property<String>
@Inject @Inject
protected open fun getExecActionFactory(): org.gradle.process.internal.ExecActionFactory? { protected open fun getExecActionFactory(): org.gradle.process.internal.ExecActionFactory? {
@@ -130,7 +106,7 @@ abstract class GenerateFBTestClasses : DefaultTask() {
fun compile() { fun compile() {
val execAction = getExecActionFactory()!!.newExecAction() val execAction = getExecActionFactory()!!.newExecAction()
val sources = inputFiles.asPath.split(":") val sources = inputFiles.asPath.split(":")
val args = mutableListOf("flatc","-o", outputFolder.get(), "--${variant.get()}") val args = mutableListOf("flatc", "-o", outputFolder.get(), "--${variant.get()}")
if (includeFolder.get().isNotEmpty()) { if (includeFolder.get().isNotEmpty()) {
args.add("-I") args.add("-I")
args.add(includeFolder.get()) args.add(includeFolder.get())

View File

@@ -18,13 +18,12 @@ package com.google.flatbuffers.kotlin
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
/** /** Represent a chunk of data, where FlexBuffers will be read from. */
* Represent a chunk of data, where FlexBuffers will be read from.
*/
public interface ReadBuffer { public interface ReadBuffer {
/** /**
* Scan through the buffer for first byte matching value. * Scan through the buffer for first byte matching value.
*
* @param value to be match * @param value to be match
* @param start inclusive initial position to start searching * @param start inclusive initial position to start searching
* @param end exclusive final position of the search * @param end exclusive final position of the search
@@ -34,6 +33,7 @@ public interface ReadBuffer {
/** /**
* Read boolean from the buffer. Booleans as stored as a single byte * Read boolean from the buffer. Booleans as stored as a single byte
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
* @return [Boolean] element * @return [Boolean] element
*/ */
@@ -41,6 +41,7 @@ public interface ReadBuffer {
/** /**
* Read a [Byte] from the buffer. * Read a [Byte] from the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
* @return a byte * @return a byte
*/ */
@@ -48,6 +49,7 @@ public interface ReadBuffer {
/** /**
* Read a [UByte] from the buffer. * Read a [UByte] from the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
* @return a [UByte] * @return a [UByte]
*/ */
@@ -55,6 +57,7 @@ public interface ReadBuffer {
/** /**
* Read a [Short] from the buffer. * Read a [Short] from the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
* @return a [Short] * @return a [Short]
*/ */
@@ -62,6 +65,7 @@ public interface ReadBuffer {
/** /**
* Read a [UShort] from the buffer. * Read a [UShort] from the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
* @return a [UShort] * @return a [UShort]
*/ */
@@ -69,6 +73,7 @@ public interface ReadBuffer {
/** /**
* Read a [Int] from the buffer. * Read a [Int] from the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
* @return an [Int] * @return an [Int]
*/ */
@@ -76,6 +81,7 @@ public interface ReadBuffer {
/** /**
* Read a [UInt] from the buffer. * Read a [UInt] from the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
* @return an [UInt] * @return an [UInt]
*/ */
@@ -83,6 +89,7 @@ public interface ReadBuffer {
/** /**
* Read a [Long] from the buffer. * Read a [Long] from the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
* @return a [Long] * @return a [Long]
*/ */
@@ -90,6 +97,7 @@ public interface ReadBuffer {
/** /**
* Read a [ULong] from the buffer. * Read a [ULong] from the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
* @return a [ULong] * @return a [ULong]
*/ */
@@ -97,6 +105,7 @@ public interface ReadBuffer {
/** /**
* Read a 32-bit float from the buffer. * Read a 32-bit float from the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
* @return a float * @return a float
*/ */
@@ -104,6 +113,7 @@ public interface ReadBuffer {
/** /**
* Read a 64-bit float from the buffer. * Read a 64-bit float from the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
* @return a double * @return a double
*/ */
@@ -111,6 +121,7 @@ public interface ReadBuffer {
/** /**
* Read a UTF-8 string from the buffer. * Read a UTF-8 string from the buffer.
*
* @param start initial element of the string * @param start initial element of the string
* @param size size of the string in bytes. * @param size size of the string in bytes.
* @return a `String` * @return a `String`
@@ -119,22 +130,25 @@ public interface ReadBuffer {
/** /**
* Read a ByteArray from the buffer. * Read a ByteArray from the buffer.
*
* @param start position from the [ReadBuffer] to be read * @param start position from the [ReadBuffer] to be read
* @param length maximum number of bytes to be written in the buffer * @param length maximum number of bytes to be written in the buffer
*/ */
public fun getBytes(array: ByteArray, start: Int, length: Int = array.size) public fun getBytes(array: ByteArray, start: Int, length: Int = array.size)
/** /**
* Expose [ReadBuffer] as an array of bytes. * Expose [ReadBuffer] as an array of bytes. This method is meant to be as efficient as possible,
* This method is meant to be as efficient as possible, so for an array-backed [ReadBuffer], it should * so for an array-backed [ReadBuffer], it should return its own internal data. In case access to
* return its own internal data. In case access to internal data is not possible, * internal data is not possible, a copy of the data into an array of bytes might occur.
* a copy of the data into an array of bytes might occur. *
* @return [ReadBuffer] as an array of bytes * @return [ReadBuffer] as an array of bytes
*/ */
public fun data(): ByteArray public fun data(): ByteArray
/** /**
* Creates a new [ReadBuffer] point to a region of the current buffer, starting at [start] with size [size]. * Creates a new [ReadBuffer] point to a region of the current buffer, starting at [start] with
* size [size].
*
* @param start starting position of the [ReadBuffer] * @param start starting position of the [ReadBuffer]
* @param size in bytes of the [ReadBuffer] * @param size in bytes of the [ReadBuffer]
* @return [ReadBuffer] slice. * @return [ReadBuffer] slice.
@@ -142,15 +156,17 @@ public interface ReadBuffer {
public fun slice(start: Int, size: Int): ReadBuffer public fun slice(start: Int, size: Int): ReadBuffer
/** /**
* Defines the size of the message in the buffer. It also determines last position that buffer * Defines the size of the message in the buffer. It also determines last position that buffer can
* can be read. Last byte to be accessed is in position `limit() -1`. * be read. Last byte to be accessed is in position `limit() -1`.
*
* @return indicate last position * @return indicate last position
*/ */
public val limit: Int public val limit: Int
} }
/** /**
* Interface to represent a read-write buffers. This interface will be used to access and write FlexBuffer messages. * Interface to represent a read-write buffers. This interface will be used to access and write
* FlexBuffer messages.
*/ */
public interface ReadWriteBuffer : ReadBuffer { public interface ReadWriteBuffer : ReadBuffer {
/** /**
@@ -160,9 +176,9 @@ public interface ReadWriteBuffer : ReadBuffer {
/** /**
* Request capacity of the buffer relative to [writePosition]. In case buffer is already larger * Request capacity of the buffer relative to [writePosition]. In case buffer is already larger
* than the requested, this method will just return true. Otherwise, * than the requested, this method will just return true. Otherwise, It might try to resize the
* It might try to resize the buffer. In case of being unable to allocate * buffer. In case of being unable to allocate enough memory, an exception will be thrown.
* enough memory, an exception will be thrown. *
* @param additional capacity in bytes to be added on top of [writePosition] * @param additional capacity in bytes to be added on top of [writePosition]
* @param copyAtEnd copy current data at the end of new underlying buffer * @param copyAtEnd copy current data at the end of new underlying buffer
* @return new capacity in bytes * @return new capacity in bytes
@@ -171,10 +187,10 @@ public interface ReadWriteBuffer : ReadBuffer {
requestCapacity(writePosition + additional, copyAtEnd) requestCapacity(writePosition + additional, copyAtEnd)
/** /**
* Request capacity of the buffer in absolute values. In case buffer is already larger * Request capacity of the buffer in absolute values. In case buffer is already larger than the
* than the requested the method is a no-op. Otherwise, * requested the method is a no-op. Otherwise, It might try to resize the buffer. In case of being
* It might try to resize the buffer. In case of being unable to allocate * unable to allocate enough memory, an exception will be thrown.
* enough memory, an exception will be thrown. *
* @param capacity new capacity * @param capacity new capacity
* @param copyAtEnd copy current data at the end of new underlying buffer * @param copyAtEnd copy current data at the end of new underlying buffer
* @return new capacity in bytes * @return new capacity in bytes
@@ -182,14 +198,16 @@ public interface ReadWriteBuffer : ReadBuffer {
public fun requestCapacity(capacity: Int, copyAtEnd: Boolean = false): Int public fun requestCapacity(capacity: Int, copyAtEnd: Boolean = false): Int
/** /**
* Put a [Boolean] into the buffer at [writePosition] . Booleans as stored as single byte. * Put a [Boolean] into the buffer at [writePosition] . Booleans as stored as single byte. Write
* Write position will be incremented. * position will be incremented.
*
* @return [Boolean] element * @return [Boolean] element
*/ */
public fun put(value: Boolean) public fun put(value: Boolean)
/** /**
* Put an array of bytes into the buffer at [writePosition]. Write position will be incremented. * Put an array of bytes into the buffer at [writePosition]. Write position will be incremented.
*
* @param value the data to be copied * @param value the data to be copied
* @param start initial position on value to be copied * @param start initial position on value to be copied
* @param length amount of bytes to be copied * @param length amount of bytes to be copied
@@ -198,74 +216,58 @@ public interface ReadWriteBuffer : ReadBuffer {
/** /**
* Put an array of bytes into the buffer at [writePosition]. Write position will be incremented. * Put an array of bytes into the buffer at [writePosition]. Write position will be incremented.
*
* @param value [ReadBuffer] the data to be copied * @param value [ReadBuffer] the data to be copied
* @param start initial position on value to be copied * @param start initial position on value to be copied
* @param length amount of bytes to be copied * @param length amount of bytes to be copied
*/ */
public fun put(value: ReadBuffer, start: Int = 0, length: Int = value.limit - start) public fun put(value: ReadBuffer, start: Int = 0, length: Int = value.limit - start)
/** /** Write a [Byte] into the buffer at [writePosition]. Write position will be incremented. */
* Write a [Byte] into the buffer at [writePosition]. Write position will be incremented.
*/
public fun put(value: Byte) public fun put(value: Byte)
/** /** Write a [UByte] into the buffer at [writePosition]. Write position will be incremented. */
* Write a [UByte] into the buffer at [writePosition]. Write position will be incremented.
*/
public fun put(value: UByte) public fun put(value: UByte)
/** /** Write a [Short] into in the buffer at [writePosition]. Write position will be incremented. */
* Write a [Short] into in the buffer at [writePosition]. Write position will be incremented.
*/
public fun put(value: Short) public fun put(value: Short)
/** /** Write a [UShort] into in the buffer at [writePosition]. Write position will be incremented. */
* Write a [UShort] into in the buffer at [writePosition]. Write position will be incremented.
*/
public fun put(value: UShort) public fun put(value: UShort)
/** /** Write a [Int] in the buffer at [writePosition]. Write position will be incremented. */
* Write a [Int] in the buffer at [writePosition]. Write position will be incremented.
*/
public fun put(value: Int) public fun put(value: Int)
/** /** Write a [UInt] into in the buffer at [writePosition]. Write position will be incremented. */
* Write a [UInt] into in the buffer at [writePosition]. Write position will be incremented.
*/
public fun put(value: UInt) public fun put(value: UInt)
/** /** Write a [Long] into in the buffer at [writePosition]. Write position will be incremented. */
* Write a [Long] into in the buffer at [writePosition]. Write position will be
* incremented.
*/
public fun put(value: Long) public fun put(value: Long)
/** /** Write a [ULong] into in the buffer at [writePosition]. Write position will be incremented. */
* Write a [ULong] into in the buffer at [writePosition]. Write position will be
* incremented.
*/
public fun put(value: ULong) public fun put(value: ULong)
/** /**
* Write a 32-bit [Float] into the buffer at [writePosition]. Write position will be * Write a 32-bit [Float] into the buffer at [writePosition]. Write position will be incremented.
* incremented.
*/ */
public fun put(value: Float) public fun put(value: Float)
/** /**
* Write a 64-bit [Double] into the buffer at [writePosition]. Write position will be * Write a 64-bit [Double] into the buffer at [writePosition]. Write position will be incremented.
* incremented.
*/ */
public fun put(value: Double) public fun put(value: Double)
/** /**
* Write a [String] encoded as UTF-8 into the buffer at [writePosition]. Write position will be incremented. * Write a [String] encoded as UTF-8 into the buffer at [writePosition]. Write position will be
* incremented.
*
* @return size in bytes of the encoded string * @return size in bytes of the encoded string
*/ */
public fun put(value: CharSequence, encodedLength: Int = -1): Int public fun put(value: CharSequence, encodedLength: Int = -1): Int
/** /**
* Write an array of bytes into the buffer. * Write an array of bytes into the buffer.
*
* @param dstIndex initial position where [src] will be copied into. * @param dstIndex initial position where [src] will be copied into.
* @param src the data to be copied. * @param src the data to be copied.
* @param srcStart initial position on [src] that will be copied. * @param srcStart initial position on [src] that will be copied.
@@ -275,6 +277,7 @@ public interface ReadWriteBuffer : ReadBuffer {
/** /**
* Write an array of bytes into the buffer. * Write an array of bytes into the buffer.
*
* @param dstIndex initial position where [src] will be copied into. * @param dstIndex initial position where [src] will be copied into.
* @param src the data to be copied. * @param src the data to be copied.
* @param srcStart initial position on [src] that will be copied. * @param srcStart initial position on [src] that will be copied.
@@ -284,66 +287,77 @@ public interface ReadWriteBuffer : ReadBuffer {
/** /**
* Write [Boolean] into a given position [index] on the buffer. Booleans as stored as single byte. * Write [Boolean] into a given position [index] on the buffer. Booleans as stored as single byte.
*
* @param index position of the element in buffer * @param index position of the element in buffer
*/ */
public operator fun set(index: Int, value: Boolean) public operator fun set(index: Int, value: Boolean)
/** /**
* Write [Byte] into a given position [index] on the buffer. * Write [Byte] into a given position [index] on the buffer.
*
* @param index position of the element in the buffer * @param index position of the element in the buffer
*/ */
public operator fun set(index: Int, value: Byte) public operator fun set(index: Int, value: Byte)
/** /**
* Write [UByte] into a given position [index] on the buffer. * Write [UByte] into a given position [index] on the buffer.
*
* @param index position of the element in the buffer * @param index position of the element in the buffer
*/ */
public operator fun set(index: Int, value: UByte) public operator fun set(index: Int, value: UByte)
/** /**
Short * Short
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
*/ */
public fun set(index: Int, value: Short) public fun set(index: Int, value: Short)
/** /**
* Write [UShort] into a given position [index] on the buffer. * Write [UShort] into a given position [index] on the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
*/ */
public fun set(index: Int, value: UShort) public fun set(index: Int, value: UShort)
/** /**
* Write [Int] into a given position [index] on the buffer. * Write [Int] into a given position [index] on the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
*/ */
public fun set(index: Int, value: Int) public fun set(index: Int, value: Int)
/** /**
* Write [UInt] into a given position [index] on the buffer. * Write [UInt] into a given position [index] on the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
*/ */
public fun set(index: Int, value: UInt) public fun set(index: Int, value: UInt)
/** /**
* Write [Long] into a given position [index] on the buffer. * Write [Long] into a given position [index] on the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
*/ */
public fun set(index: Int, value: Long) public fun set(index: Int, value: Long)
/** /**
* Write [ULong] into a given position [index] on the buffer. * Write [ULong] into a given position [index] on the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
*/ */
public fun set(index: Int, value: ULong) public fun set(index: Int, value: ULong)
/** /**
* Write [Float] into a given position [index] on the buffer. * Write [Float] into a given position [index] on the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
*/ */
public fun set(index: Int, value: Float) public fun set(index: Int, value: Float)
/** /**
* Write [Double] into a given position [index] on the buffer. * Write [Double] into a given position [index] on the buffer.
*
* @param index position of the element in [ReadBuffer] * @param index position of the element in [ReadBuffer]
*/ */
public fun set(index: Int, value: Double) public fun set(index: Int, value: Double)
@@ -351,12 +365,15 @@ public interface ReadWriteBuffer : ReadBuffer {
public fun fill(value: Byte, start: Int, end: Int) public fun fill(value: Byte, start: Int, end: Int)
/** /**
* Current position of the buffer to be written. It will be automatically updated on [put] operations. * Current position of the buffer to be written. It will be automatically updated on [put]
* operations.
*/ */
public var writePosition: Int public var writePosition: Int
/** /**
* Creates a new [ReadWriteBuffer] point to a region of the current buffer, starting at [offset] with size [size]. * Creates a new [ReadWriteBuffer] point to a region of the current buffer, starting at [offset]
* with size [size].
*
* @param offset starting position of the [ReadWriteBuffer] * @param offset starting position of the [ReadWriteBuffer]
* @param size in bytes of the [ReadWriteBuffer] * @param size in bytes of the [ReadWriteBuffer]
* @return [ReadWriteBuffer] slice. * @return [ReadWriteBuffer] slice.
@@ -364,35 +381,35 @@ public interface ReadWriteBuffer : ReadBuffer {
public fun writeSlice(offset: Int, size: Int): ReadWriteBuffer public fun writeSlice(offset: Int, size: Int): ReadWriteBuffer
/** /**
* Special operation where we increase the backed buffer size to [capacity] * Special operation where we increase the backed buffer size to [capacity] and shift all already
* and shift all already written data to the end of the buffer. * written data to the end of the buffer.
*
* This function is mostly used when creating a Flatbuffer message, as data is written from the
* end of the buffer towards index 0.
* *
* This function is mostly used when creating a Flatbuffer message, as
* data is written from the end of the buffer towards index 0.
* @param capacity required in bytes * @param capacity required in bytes
* @return new capacity in bytes * @return new capacity in bytes
*/ */
public fun moveWrittenDataToEnd(capacity: Int): Int public fun moveWrittenDataToEnd(capacity: Int): Int
/** /** Maximum size in bytes that the backed buffer supports. */
* Maximum size in bytes that the backed buffer supports.
*/
public val capacity: Int public val capacity: Int
/** /**
* Defines last relative position of the backed buffer that can be written. * Defines last relative position of the backed buffer that can be written. Any addition to the
* Any addition to the buffer that goes beyond will throw an exception * buffer that goes beyond will throw an exception instead of regrow the buffer (default
* instead of regrow the buffer (default behavior). * behavior).
*/ */
public val writeLimit: Int public val writeLimit: Int
} }
public open class ArrayReadBuffer(protected var buffer: ByteArray, public open class ArrayReadBuffer(
protected var buffer: ByteArray,
// offsets writePosition against backed buffer e.g. offset = 1, writePosition = 1 // offsets writePosition against backed buffer e.g. offset = 1, writePosition = 1
// will write first byte at position 2 of the backed buffer // will write first byte at position 2 of the backed buffer
internal val offset: Int = 0, internal val offset: Int = 0,
override val limit: Int = buffer.size - offset) : ReadBuffer { override val limit: Int = buffer.size - offset,
) : ReadBuffer {
override fun findFirst(value: Byte, start: Int, end: Int): Int { override fun findFirst(value: Byte, start: Int, end: Int): Int {
val e = min(end, limit) val e = min(end, limit)
@@ -423,8 +440,8 @@ public open class ArrayReadBuffer(protected var buffer: ByteArray,
override fun getDouble(index: Int): Double = buffer.getDouble(offset + index) override fun getDouble(index: Int): Double = buffer.getDouble(offset + index)
override fun getString(start: Int, size: Int): String = buffer.decodeToString(this.offset + start, override fun getString(start: Int, size: Int): String =
this.offset + start + size) buffer.decodeToString(this.offset + start, this.offset + start + size)
override fun getBytes(array: ByteArray, start: Int, length: Int) { override fun getBytes(array: ByteArray, start: Int, length: Int) {
val end = min(this.offset + start + length, buffer.size) val end = min(this.offset + start + length, buffer.size)
@@ -436,19 +453,19 @@ public open class ArrayReadBuffer(protected var buffer: ByteArray,
override fun data(): ByteArray = buffer override fun data(): ByteArray = buffer
override fun slice(start: Int, size: Int): ReadBuffer = ArrayReadBuffer(buffer, this.offset + start, size) override fun slice(start: Int, size: Int): ReadBuffer =
ArrayReadBuffer(buffer, this.offset + start, size)
} }
/** /**
* Implements `[ReadWriteBuffer]` using [ByteArray] as backing buffer. Using array of bytes are * Implements `[ReadWriteBuffer]` using [ByteArray] as backing buffer. Using array of bytes are
* usually faster than `ByteBuffer`. * usually faster than `ByteBuffer`.
* *
* This class is not thread-safe, meaning that * This class is not thread-safe, meaning that it must operate on a single thread. Operating from
* it must operate on a single thread. Operating from
* multiple thread leads into an undefined behavior * multiple thread leads into an undefined behavior
* *
* All operations assume Little Endian byte order. * All operations assume Little Endian byte order.
*/ */
public class ArrayReadWriteBuffer( public class ArrayReadWriteBuffer(
buffer: ByteArray, buffer: ByteArray,
offset: Int = 0, offset: Int = 0,
@@ -456,12 +473,13 @@ public class ArrayReadWriteBuffer(
// Any addition to the buffer that goes beyond will throw an exception // Any addition to the buffer that goes beyond will throw an exception
// instead of regrow the buffer (default behavior). // instead of regrow the buffer (default behavior).
public override val writeLimit: Int = -1, public override val writeLimit: Int = -1,
override var writePosition: Int = offset override var writePosition: Int = offset,
) : ArrayReadBuffer(buffer, offset, writePosition), ReadWriteBuffer { ) : ArrayReadBuffer(buffer, offset, writePosition), ReadWriteBuffer {
public constructor(initialCapacity: Int = 10) : this(ByteArray(initialCapacity)) public constructor(initialCapacity: Int = 10) : this(ByteArray(initialCapacity))
override val limit: Int get() = writePosition override val limit: Int
get() = writePosition
override fun clear(): Unit = run { writePosition = 0 } override fun clear(): Unit = run { writePosition = 0 }
@@ -545,9 +563,11 @@ public class ArrayReadWriteBuffer(
} }
override operator fun set(dstIndex: Int, src: ReadBuffer, srcStart: Int, srcLength: Int) { override operator fun set(dstIndex: Int, src: ReadBuffer, srcStart: Int, srcLength: Int) {
when(src) { when (src) {
is ArrayReadBuffer -> { is ArrayReadBuffer -> {
src.data().copyInto(buffer, dstIndex, src.offset + srcStart, src.offset + srcStart + srcLength) src
.data()
.copyInto(buffer, dstIndex, src.offset + srcStart, src.offset + srcStart + srcLength)
} }
else -> { else -> {
for (i in 0 until srcLength) { for (i in 0 until srcLength) {
@@ -557,23 +577,55 @@ public class ArrayReadWriteBuffer(
} }
} }
override operator fun set(index: Int, value: Byte) { buffer[index] = value } override operator fun set(index: Int, value: Byte) {
override operator fun set(index: Int, value: UByte) { buffer.setUByte(index, value) } buffer[index] = value
override operator fun set(index: Int, value: Short) { buffer.setShort(index, value) } }
override operator fun set(index: Int, value: UShort) { buffer.setUShort(index, value) }
override operator fun set(index: Int, value: Int) { buffer.setInt(index, value) } override operator fun set(index: Int, value: UByte) {
override operator fun set(index: Int, value: UInt) { buffer.setUInt(index, value) } buffer.setUByte(index, value)
override operator fun set(index: Int, value: Long) { buffer.setLong(index, value) } }
override operator fun set(index: Int, value: ULong) { buffer.setULong(index, value) }
override operator fun set(index: Int, value: Float) { buffer.setFloat(index, value) } override operator fun set(index: Int, value: Short) {
override operator fun set(index: Int, value: Double) { buffer.setDouble(index, value) } buffer.setShort(index, value)
override fun fill(value: Byte, start: Int, end: Int) { buffer.fill(value, start, end) } }
override operator fun set(index: Int, value: UShort) {
buffer.setUShort(index, value)
}
override operator fun set(index: Int, value: Int) {
buffer.setInt(index, value)
}
override operator fun set(index: Int, value: UInt) {
buffer.setUInt(index, value)
}
override operator fun set(index: Int, value: Long) {
buffer.setLong(index, value)
}
override operator fun set(index: Int, value: ULong) {
buffer.setULong(index, value)
}
override operator fun set(index: Int, value: Float) {
buffer.setFloat(index, value)
}
override operator fun set(index: Int, value: Double) {
buffer.setDouble(index, value)
}
override fun fill(value: Byte, start: Int, end: Int) {
buffer.fill(value, start, end)
}
/** /**
* Request capacity of the buffer. In case buffer is already larger * Request capacity of the buffer. In case buffer is already larger than the requested, it is a
* than the requested, it is a no-op. Otherwise, * no-op. Otherwise, It might try to resize the buffer. In case of being unable to allocate enough
* It might try to resize the buffer. In case of being unable to allocate * memory, an exception will be thrown.
* enough memory, an exception will be thrown. *
* @param capacity new capacity * @param capacity new capacity
* @param copyAtEnd copy current data at the end of new underlying buffer * @param copyAtEnd copy current data at the end of new underlying buffer
*/ */
@@ -582,15 +634,18 @@ public class ArrayReadWriteBuffer(
if (buffer.size >= capacity) return buffer.size if (buffer.size >= capacity) return buffer.size
if (writeLimit > 0 && writeLimit + offset >= buffer.size) error("Buffer in writeLimit mode. In writeLimit mode" + if (writeLimit > 0 && writeLimit + offset >= buffer.size)
error(
"Buffer in writeLimit mode. In writeLimit mode" +
" the buffer does not grow automatically and any write beyond writeLimit will throw exception. " + " the buffer does not grow automatically and any write beyond writeLimit will throw exception. " +
"(writeLimit: $writeLimit, newCapacity: $capacity") "(writeLimit: $writeLimit, newCapacity: $capacity"
)
// implemented in the same growing fashion as ArrayList // implemented in the same growing fashion as ArrayList
val oldCapacity = buffer.size val oldCapacity = buffer.size
if (oldCapacity == Int.MAX_VALUE - 8) { // Ensure we don't grow beyond what fits in an int. if (oldCapacity == Int.MAX_VALUE - 8) { // Ensure we don't grow beyond what fits in an int.
error("FlatBuffers: cannot grow buffer beyond 2 gigabytes.") error("FlatBuffers: cannot grow buffer beyond 2 gigabytes.")
} }
//(old_buf_size & 0xC0000000) != 0 ? MAX_BUFFER_SIZE : old_buf_size << 1; // (old_buf_size & 0xC0000000) != 0 ? MAX_BUFFER_SIZE : old_buf_size << 1;
var newCapacity = 8 var newCapacity = 8
while (newCapacity < capacity) { // Note: this also catches newCapacity int overflow while (newCapacity < capacity) { // Note: this also catches newCapacity int overflow
newCapacity = if (newCapacity and -0x40000000 != 0) Int.MAX_VALUE - 8 else newCapacity shl 1 newCapacity = if (newCapacity and -0x40000000 != 0) Int.MAX_VALUE - 8 else newCapacity shl 1
@@ -603,14 +658,13 @@ public class ArrayReadWriteBuffer(
} }
override fun writeSlice(offset: Int, size: Int): ReadWriteBuffer { override fun writeSlice(offset: Int, size: Int): ReadWriteBuffer {
return ArrayReadWriteBuffer(this.buffer, offset=offset, writeLimit=size) return ArrayReadWriteBuffer(this.buffer, offset = offset, writeLimit = size)
} }
override fun moveWrittenDataToEnd(capacity: Int): Int = requestCapacity(capacity, true) override fun moveWrittenDataToEnd(capacity: Int): Int = requestCapacity(capacity, true)
override val capacity: Int override val capacity: Int
get() = buffer.size get() = buffer.size
} }
public val emptyBuffer: ReadWriteBuffer = ArrayReadWriteBuffer(ByteArray(1)) public val emptyBuffer: ReadWriteBuffer = ArrayReadWriteBuffer(ByteArray(1))

View File

@@ -19,37 +19,53 @@ package com.google.flatbuffers.kotlin
import kotlin.experimental.and import kotlin.experimental.and
internal fun ByteArray.getString(index: Int, size: Int): String = Utf8.decodeUtf8Array(this, index, size) internal fun ByteArray.getString(index: Int, size: Int): String =
Utf8.decodeUtf8Array(this, index, size)
internal fun ByteArray.setCharSequence(index: Int, value: CharSequence): Int = internal fun ByteArray.setCharSequence(index: Int, value: CharSequence): Int =
Utf8.encodeUtf8Array(value, this, index, this.size - index) Utf8.encodeUtf8Array(value, this, index, this.size - index)
// List of functions that needs to be implemented on all platforms. // List of functions that needs to be implemented on all platforms.
internal expect inline fun ByteArray.getUByte(index: Int): UByte internal expect inline fun ByteArray.getUByte(index: Int): UByte
internal expect inline fun ByteArray.getShort(index: Int): Short internal expect inline fun ByteArray.getShort(index: Int): Short
internal expect inline fun ByteArray.getUShort(index: Int): UShort internal expect inline fun ByteArray.getUShort(index: Int): UShort
internal expect inline fun ByteArray.getInt(index: Int): Int internal expect inline fun ByteArray.getInt(index: Int): Int
internal expect inline fun ByteArray.getUInt(index: Int): UInt internal expect inline fun ByteArray.getUInt(index: Int): UInt
internal expect inline fun ByteArray.getLong(index: Int): Long internal expect inline fun ByteArray.getLong(index: Int): Long
internal expect inline fun ByteArray.getULong(index: Int): ULong internal expect inline fun ByteArray.getULong(index: Int): ULong
internal expect inline fun ByteArray.getFloat(index: Int): Float internal expect inline fun ByteArray.getFloat(index: Int): Float
internal expect inline fun ByteArray.getDouble(index: Int): Double internal expect inline fun ByteArray.getDouble(index: Int): Double
internal expect inline fun ByteArray.setUByte(index: Int, value: UByte) internal expect inline fun ByteArray.setUByte(index: Int, value: UByte)
public expect inline fun ByteArray.setShort(index: Int, value: Short) public expect inline fun ByteArray.setShort(index: Int, value: Short)
internal expect inline fun ByteArray.setUShort(index: Int, value: UShort) internal expect inline fun ByteArray.setUShort(index: Int, value: UShort)
internal expect inline fun ByteArray.setInt(index: Int, value: Int) internal expect inline fun ByteArray.setInt(index: Int, value: Int)
internal expect inline fun ByteArray.setUInt(index: Int, value: UInt) internal expect inline fun ByteArray.setUInt(index: Int, value: UInt)
internal expect inline fun ByteArray.setLong(index: Int, value: Long) internal expect inline fun ByteArray.setLong(index: Int, value: Long)
internal expect inline fun ByteArray.setULong(index: Int, value: ULong) internal expect inline fun ByteArray.setULong(index: Int, value: ULong)
internal expect inline fun ByteArray.setFloat(index: Int, value: Float) internal expect inline fun ByteArray.setFloat(index: Int, value: Float)
internal expect inline fun ByteArray.setDouble(index: Int, value: Double) internal expect inline fun ByteArray.setDouble(index: Int, value: Double)
/** /** This implementation uses Little Endian order. */
* This implementation uses Little Endian order.
*/
public object ByteArrayOps { public object ByteArrayOps {
public inline fun getUByte(ary: ByteArray, index: Int): UByte = ary[index].toUByte() public inline fun getUByte(ary: ByteArray, index: Int): UByte = ary[index].toUByte()
public inline fun getShort(ary: ByteArray, index: Int): Short { public inline fun getShort(ary: ByteArray, index: Int): Short {
return (ary[index + 1].toInt() shl 8 or (ary[index].toInt() and 0xff)).toShort() return (ary[index + 1].toInt() shl 8 or (ary[index].toInt() and 0xff)).toShort()
} }
@@ -57,19 +73,18 @@ public object ByteArrayOps {
public inline fun getUShort(ary: ByteArray, index: Int): UShort = getShort(ary, index).toUShort() public inline fun getUShort(ary: ByteArray, index: Int): UShort = getShort(ary, index).toUShort()
public inline fun getInt(ary: ByteArray, index: Int): Int { public inline fun getInt(ary: ByteArray, index: Int): Int {
return ( return ((ary[index + 3].toInt() shl 24) or
(ary[index + 3].toInt() shl 24) or
((ary[index + 2].toInt() and 0xff) shl 16) or ((ary[index + 2].toInt() and 0xff) shl 16) or
((ary[index + 1].toInt() and 0xff) shl 8) or ((ary[index + 1].toInt() and 0xff) shl 8) or
((ary[index].toInt() and 0xff)) ((ary[index].toInt() and 0xff)))
)
} }
public inline fun getUInt(ary: ByteArray, index: Int): UInt = getInt(ary, index).toUInt() public inline fun getUInt(ary: ByteArray, index: Int): UInt = getInt(ary, index).toUInt()
public inline fun getLong(ary: ByteArray, index: Int): Long { public inline fun getLong(ary: ByteArray, index: Int): Long {
var idx = index var idx = index
return ary[idx++].toLong() and 0xff or return ary[idx++].toLong() and
0xff or
(ary[idx++].toLong() and 0xff shl 8) or (ary[idx++].toLong() and 0xff shl 8) or
(ary[idx++].toLong() and 0xff shl 16) or (ary[idx++].toLong() and 0xff shl 16) or
(ary[idx++].toLong() and 0xff shl 24) or (ary[idx++].toLong() and 0xff shl 24) or
@@ -84,13 +99,15 @@ public object ByteArrayOps {
public inline fun setUByte(ary: ByteArray, index: Int, value: UByte) { public inline fun setUByte(ary: ByteArray, index: Int, value: UByte) {
ary[index] = value.toByte() ary[index] = value.toByte()
} }
public inline fun setShort(ary: ByteArray, index: Int, value: Short) { public inline fun setShort(ary: ByteArray, index: Int, value: Short) {
var idx = index var idx = index
ary[idx++] = (value and 0xff).toByte() ary[idx++] = (value and 0xff).toByte()
ary[idx] = (value.toInt() shr 8 and 0xff).toByte() ary[idx] = (value.toInt() shr 8 and 0xff).toByte()
} }
public inline fun setUShort(ary: ByteArray, index: Int, value: UShort): Unit = setShort(ary, index, value.toShort()) public inline fun setUShort(ary: ByteArray, index: Int, value: UShort): Unit =
setShort(ary, index, value.toShort())
public inline fun setInt(ary: ByteArray, index: Int, value: Int) { public inline fun setInt(ary: ByteArray, index: Int, value: Int) {
var idx = index var idx = index
@@ -100,7 +117,8 @@ public object ByteArrayOps {
ary[idx] = (value shr 24 and 0xff).toByte() ary[idx] = (value shr 24 and 0xff).toByte()
} }
public inline fun setUInt(ary: ByteArray, index: Int, value: UInt): Unit = setInt(ary, index, value.toInt()) public inline fun setUInt(ary: ByteArray, index: Int, value: UInt): Unit =
setInt(ary, index, value.toInt())
public inline fun setLong(ary: ByteArray, index: Int, value: Long) { public inline fun setLong(ary: ByteArray, index: Int, value: Long) {
var i = value.toInt() var i = value.toInt()
@@ -109,7 +127,8 @@ public object ByteArrayOps {
setInt(ary, index + 4, i) setInt(ary, index + 4, i)
} }
public inline fun setULong(ary: ByteArray, index: Int, value: ULong): Unit = setLong(ary, index, value.toLong()) public inline fun setULong(ary: ByteArray, index: Int, value: ULong): Unit =
setLong(ary, index, value.toLong())
public inline fun setFloat(ary: ByteArray, index: Int, value: Float) { public inline fun setFloat(ary: ByteArray, index: Int, value: Float) {
setInt(ary, index, value.toRawBits()) setInt(ary, index, value.toRawBits())
@@ -120,5 +139,7 @@ public object ByteArrayOps {
} }
public inline fun getFloat(ary: ByteArray, index: Int): Float = Float.fromBits(getInt(ary, index)) public inline fun getFloat(ary: ByteArray, index: Int): Float = Float.fromBits(getInt(ary, index))
public inline fun getDouble(ary: ByteArray, index: Int): Double = Double.fromBits(getLong(ary, index))
public inline fun getDouble(ary: ByteArray, index: Int): Double =
Double.fromBits(getLong(ary, index))
} }

View File

@@ -17,14 +17,15 @@ package com.google.flatbuffers.kotlin
import kotlin.jvm.JvmOverloads import kotlin.jvm.JvmOverloads
/** /**
* Class that helps you build a FlatBuffer. See the section * Class that helps you build a FlatBuffer. See the section "Use in Kotlin" in the main FlatBuffers
* "Use in Kotlin" in the main FlatBuffers documentation. * documentation.
*/ */
public class FlatBufferBuilder @JvmOverloads constructor( public class FlatBufferBuilder
@JvmOverloads
constructor(
private val initialSize: Int = 1024, private val initialSize: Int = 1024,
private var buffer: ReadWriteBuffer = ArrayReadWriteBuffer(initialSize) private var buffer: ReadWriteBuffer = ArrayReadWriteBuffer(initialSize),
) { ) {
// Remaining space in the ByteBuffer. // Remaining space in the ByteBuffer.
private var space: Int = buffer.capacity private var space: Int = buffer.capacity
@@ -62,9 +63,7 @@ public class FlatBufferBuilder @JvmOverloads constructor(
// map used to cache shared strings. // map used to cache shared strings.
private var stringPool: MutableMap<CharSequence, Offset<String>>? = null private var stringPool: MutableMap<CharSequence, Offset<String>>? = null
/** /** Reset the FlatBufferBuilder by purging all data that it holds. */
* Reset the FlatBufferBuilder by purging all data that it holds.
*/
public fun clear() { public fun clear() {
space = buffer.capacity space = buffer.capacity
buffer.clear() buffer.clear()
@@ -96,11 +95,10 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Prepare to write an element of `size` after `additional_bytes` * Prepare to write an element of `size` after `additional_bytes` have been written, e.g. if you
* have been written, e.g. if you write a string, you need to align such * write a string, you need to align such the int length field is aligned to
* the int length field is aligned to [com.google.flatbuffers.Int.SIZE_BYTES], and * [com.google.flatbuffers.Int.SIZE_BYTES], and the string data follows it directly. If all you
* the string data follows it directly. If all you need to do is alignment, `additional_bytes` * need to do is alignment, `additional_bytes` will be 0.
* will be 0.
* *
* @param size This is the of the new element to write. * @param size This is the of the new element to write.
* @param additionalBytes The padding size. * @param additionalBytes The padding size.
@@ -124,8 +122,8 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Add a `boolean` to the buffer, backwards from the current location. Doesn't align nor * Add a `boolean` to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A `boolean` to put into the buffer. * @param x A `boolean` to put into the buffer.
*/ */
@@ -135,16 +133,16 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Add a [UByte] to the buffer, backwards from the current location. Doesn't align nor * Add a [UByte] to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A [UByte] to put into the buffer. * @param x A [UByte] to put into the buffer.
*/ */
public fun put(x: UByte): Unit = put(x.toByte()) public fun put(x: UByte): Unit = put(x.toByte())
/** /**
* Add a [Byte] to the buffer, backwards from the current location. Doesn't align nor * Add a [Byte] to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A [Byte] to put into the buffer. * @param x A [Byte] to put into the buffer.
*/ */
@@ -154,16 +152,16 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Add a [UShort] to the buffer, backwards from the current location. Doesn't align nor * Add a [UShort] to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A [UShort] to put into the buffer. * @param x A [UShort] to put into the buffer.
*/ */
public fun put(x: UShort): Unit = put(x.toShort()) public fun put(x: UShort): Unit = put(x.toShort())
/** /**
* Add a [Short] to the buffer, backwards from the current location. Doesn't align nor * Add a [Short] to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A [Short] to put into the buffer. * @param x A [Short] to put into the buffer.
*/ */
@@ -173,35 +171,35 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Add an [UInt] to the buffer, backwards from the current location. Doesn't align nor * Add an [UInt] to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x An [UInt] to put into the buffer. * @param x An [UInt] to put into the buffer.
*/ */
public fun put(x: UInt): Unit = put(x.toInt()) public fun put(x: UInt): Unit = put(x.toInt())
/** /**
* Add an [Int] to the buffer, backwards from the current location. Doesn't align nor * Add an [Int] to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x An [Int] to put into the buffer. * @param x An [Int] to put into the buffer.
*/ */
public fun put(x: Int){ public fun put(x: Int) {
space -= Int.SIZE_BYTES space -= Int.SIZE_BYTES
buffer.set(space, x) buffer.set(space, x)
} }
/** /**
* Add a [ULong] to the buffer, backwards from the current location. Doesn't align nor * Add a [ULong] to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A [ULong] to put into the buffer. * @param x A [ULong] to put into the buffer.
*/ */
public fun put(x: ULong): Unit = put(x.toLong()) public fun put(x: ULong): Unit = put(x.toLong())
/** /**
* Add a [Long] to the buffer, backwards from the current location. Doesn't align nor * Add a [Long] to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A [Long] to put into the buffer. * @param x A [Long] to put into the buffer.
*/ */
@@ -211,8 +209,8 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Add a [Float] to the buffer, backwards from the current location. Doesn't align nor * Add a [Float] to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A [Float] to put into the buffer. * @param x A [Float] to put into the buffer.
*/ */
@@ -222,8 +220,8 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Add a [Double] to the buffer, backwards from the current location. Doesn't align nor * Add a [Double] to the buffer, backwards from the current location. Doesn't align nor check for
* check for space. * space.
* *
* @param x A [Double] to put into the buffer. * @param x A [Double] to put into the buffer.
*/ */
@@ -336,27 +334,24 @@ public class FlatBufferBuilder @JvmOverloads constructor(
* @param off The offset to add. * @param off The offset to add.
*/ */
public fun add(off: Offset<*>): Unit = addOffset(off.value) public fun add(off: Offset<*>): Unit = addOffset(off.value)
public fun add(off: VectorOffset<*>): Unit = addOffset(off.value) public fun add(off: VectorOffset<*>): Unit = addOffset(off.value)
private fun addOffset(off: Int) { private fun addOffset(off: Int) {
prep(Int.SIZE_BYTES, 0) // Ensure alignment is already done. prep(Int.SIZE_BYTES, 0) // Ensure alignment is already done.
put(buffer.capacity - space - off + Int.SIZE_BYTES) put(buffer.capacity - space - off + Int.SIZE_BYTES)
} }
/** /**
* Start a new array/vector of objects. Users usually will not call * Start a new array/vector of objects. Users usually will not call this directly. The
* this directly. The `FlatBuffers` compiler will create a start/end * `FlatBuffers` compiler will create a start/end method for vector types in generated code.
* method for vector types in generated code.
*
* *
* The expected sequence of calls is: * The expected sequence of calls is:
*
* 1. Start the array using this method. * 1. Start the array using this method.
* 1. Call [.addOffset] `num_elems` number of times to set * 1. Call [.addOffset] `num_elems` number of times to set the offset of each element in the
* the offset of each element in the array. * array.
* 1. Call [.endVector] to retrieve the offset of the array. * 1. Call [.endVector] to retrieve the offset of the array.
* *
*
*
* For example, to create an array of strings, do: * For example, to create an array of strings, do:
* <pre>`// Need 10 strings * <pre>`// Need 10 strings
* FlatBufferBuilder builder = new FlatBufferBuilder(existingBuffer); * FlatBufferBuilder builder = new FlatBufferBuilder(existingBuffer);
@@ -379,7 +374,7 @@ public class FlatBufferBuilder @JvmOverloads constructor(
* *
* // Finish off the vector * // Finish off the vector
* int offsetOfTheVector = fbb.endVector(); * int offsetOfTheVector = fbb.endVector();
`</pre> * * `</pre> *
* *
* @param elemSize The size of each element in the array. * @param elemSize The size of each element in the array.
* @param numElems The number of elements in the array. * @param numElems The number of elements in the array.
@@ -392,11 +387,12 @@ public class FlatBufferBuilder @JvmOverloads constructor(
prep(alignment, elemSize * numElems) // Just in case alignment > int. prep(alignment, elemSize * numElems) // Just in case alignment > int.
nested = true nested = true
} }
public fun startString(numElems: Int): Unit = startVector(1, numElems, 1) public fun startString(numElems: Int): Unit = startVector(1, numElems, 1)
/** /**
* Finish off the creation of an array and all its elements. The array * Finish off the creation of an array and all its elements. The array must be created with
* must be created with [.startVector]. * [.startVector].
* *
* @return The offset at which the newly created array starts. * @return The offset at which the newly created array starts.
* @see .startVector * @see .startVector
@@ -423,16 +419,19 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Create a new array/vector and return a ByteBuffer to be filled later. * Create a new array/vector and return a ByteBuffer to be filled later. Call [endVector] after
* Call [endVector] after this method to get an offset to the beginning * this method to get an offset to the beginning of vector.
* of vector.
* *
* @param elemSize the size of each element in bytes. * @param elemSize the size of each element in bytes.
* @param numElems number of elements in the vector. * @param numElems number of elements in the vector.
* @param alignment byte alignment. * @param alignment byte alignment.
* @return ByteBuffer with position and limit set to the space allocated for the array. * @return ByteBuffer with position and limit set to the space allocated for the array.
*/ */
public fun createUnintializedVector(elemSize: Int, numElems: Int, alignment: Int): ReadWriteBuffer { public fun createUnintializedVector(
elemSize: Int,
numElems: Int,
alignment: Int,
): ReadWriteBuffer {
val length = elemSize * numElems val length = elemSize * numElems
startVector(elemSize, numElems, alignment) startVector(elemSize, numElems, alignment)
space -= length space -= length
@@ -460,19 +459,21 @@ public class FlatBufferBuilder @JvmOverloads constructor(
* @param offsets Offsets of the tables. * @param offsets Offsets of the tables.
* @return Returns offset of the sorted vector. * @return Returns offset of the sorted vector.
*/ */
public fun <T : Table> createSortedVectorOfTables(obj: T, offsets: Array<Offset<T>>): VectorOffset<T> { public fun <T : Table> createSortedVectorOfTables(
obj: T,
offsets: Array<Offset<T>>,
): VectorOffset<T> {
obj.sortTables(offsets, buffer) obj.sortTables(offsets, buffer)
return createVectorOfTables(offsets) return createVectorOfTables(offsets)
} }
/** /**
* Encode the String `s` in the buffer using UTF-8. If a String with * Encode the String `s` in the buffer using UTF-8. If a String with this exact contents has
* this exact contents has already been serialized using this method, * already been serialized using this method, instead simply returns the offset of the existing
* instead simply returns the offset of the existing String. * String.
* *
* Usage of the method will incur into additional allocations, * Usage of the method will incur into additional allocations, so it is advisable to use it only
* so it is advisable to use it only when it is known upfront that * when it is known upfront that your message will have several repeated strings.
* your message will have several repeated strings.
* *
* @param s The String to encode. * @param s The String to encode.
* @return The offset in the buffer where the encoded String starts. * @return The offset in the buffer where the encoded String starts.
@@ -494,6 +495,7 @@ public class FlatBufferBuilder @JvmOverloads constructor(
/** /**
* Encode the [CharSequence] `s` in the buffer using UTF-8. * Encode the [CharSequence] `s` in the buffer using UTF-8.
*
* @param s The [CharSequence] to encode. * @param s The [CharSequence] to encode.
* @return The offset in the buffer where the encoded string starts. * @return The offset in the buffer where the encoded string starts.
*/ */
@@ -557,13 +559,16 @@ public class FlatBufferBuilder @JvmOverloads constructor(
/** /**
* Create a byte array in the buffer. * Create a byte array in the buffer.
* *
* The source [ReadBuffer] position is advanced until [ReadBuffer.limit] * The source [ReadBuffer] position is advanced until [ReadBuffer.limit] after this call.
* after this call.
* *
* @param data A source [ReadBuffer] with data. * @param data A source [ReadBuffer] with data.
* @return The offset in the buffer where the encoded array starts. * @return The offset in the buffer where the encoded array starts.
*/ */
public fun createByteVector(data: ReadBuffer, from: Int = 0, until: Int = data.limit): VectorOffset<Byte> { public fun createByteVector(
data: ReadBuffer,
from: Int = 0,
until: Int = data.limit,
): VectorOffset<Byte> {
val length: Int = until - from val length: Int = until - from
startVector(1, length, 1) startVector(1, length, 1)
space -= length space -= length
@@ -572,28 +577,25 @@ public class FlatBufferBuilder @JvmOverloads constructor(
return VectorOffset(endVector()) return VectorOffset(endVector())
} }
/** /** Should not be accessing the final buffer before it is finished. */
* Should not be accessing the final buffer before it is finished.
*/
public fun finished() { public fun finished() {
if (!finished) throw AssertionError( if (!finished)
throw AssertionError(
"FlatBuffers: you can only access the serialized buffer after it has been" + "FlatBuffers: you can only access the serialized buffer after it has been" +
" finished by FlatBufferBuilder.finish()." " finished by FlatBufferBuilder.finish()."
) )
} }
/** /**
* Should not be creating any other object, string or vector * Should not be creating any other object, string or vector while an object is being constructed.
* while an object is being constructed.
*/ */
public fun notNested() { public fun notNested() {
if (nested) throw AssertionError("FlatBuffers: object serialization must not be nested.") if (nested) throw AssertionError("FlatBuffers: object serialization must not be nested.")
} }
/** /**
* Structures are always stored inline, they need to be created right * Structures are always stored inline, they need to be created right where they're used. You'll
* where they're used. You'll get this assertion failure if you * get this assertion failure if you created it elsewhere.
* created it elsewhere.
* *
* @param obj The offset of the created object. * @param obj The offset of the created object.
*/ */
@@ -602,14 +604,11 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Start encoding a new object in the buffer. Users will not usually need to * Start encoding a new object in the buffer. Users will not usually need to call this directly.
* call this directly. The `FlatBuffers` compiler will generate helper methods * The `FlatBuffers` compiler will generate helper methods that call this method internally.
* that call this method internally.
*
*
* For example, using the "Monster" code found on the "landing page". An
* object of type `Monster` can be created using the following code:
* *
* For example, using the "Monster" code found on the "landing page". An object of type `Monster`
* can be created using the following code:
* <pre>`int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] { * <pre>`int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] {
* fbb.createString("test1"), * fbb.createString("test1"),
* fbb.createString("test2") * fbb.createString("test2")
@@ -626,19 +625,15 @@ public class FlatBufferBuilder @JvmOverloads constructor(
* Monster.addTest4(fbb, test4); * Monster.addTest4(fbb, test4);
* Monster.addTestarrayofstring(fbb, testArrayOfString); * Monster.addTestarrayofstring(fbb, testArrayOfString);
* int mon = Monster.endMonster(fbb); * int mon = Monster.endMonster(fbb);
`</pre> * * `</pre> *
*
* *
* Here: * Here:
* * * The call to `Monster#startMonster(FlatBufferBuilder)` will call this method with the right
* * The call to `Monster#startMonster(FlatBufferBuilder)` will call this * number of fields set.
* method with the right number of fields set.
* * `Monster#endMonster(FlatBufferBuilder)` will ensure [.endObject] is called. * * `Monster#endMonster(FlatBufferBuilder)` will ensure [.endObject] is called.
* *
* * It's not recommended to call this method directly. If it's called manually, you must ensure to
* * audit all calls to it whenever fields are added or removed from your schema. This is
* It's not recommended to call this method directly. If it's called manually, you must ensure
* to audit all calls to it whenever fields are added or removed from your schema. This is
* automatically done by the code generated by the `FlatBuffers` compiler. * automatically done by the code generated by the `FlatBuffers` compiler.
* *
* @param numFields The number of fields found in this object. * @param numFields The number of fields found in this object.
@@ -649,15 +644,14 @@ public class FlatBufferBuilder @JvmOverloads constructor(
vtable = IntArray(numFields) vtable = IntArray(numFields)
} }
vtableInUse = numFields vtableInUse = numFields
for (i in 0 until vtableInUse) for (i in 0 until vtableInUse) vtable[i] = 0
vtable[i] = 0
nested = true nested = true
objectStart = offset() objectStart = offset()
} }
/** /**
* Add a [Boolean] to a table at `o` into its vtable, with value `x` and default `d`. * Add a [Boolean] to a table at `o` into its vtable, with value `x` and default `d`. If
* If `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
* default value, it can be skipped. * default value, it can be skipped.
*/ */
public fun add(o: Int, x: Boolean, d: Boolean?) { public fun add(o: Int, x: Boolean, d: Boolean?) {
@@ -666,6 +660,7 @@ public class FlatBufferBuilder @JvmOverloads constructor(
slot(o) slot(o)
} }
} }
// unboxed specialization // unboxed specialization
public fun add(o: Int, x: Boolean, d: Boolean) { public fun add(o: Int, x: Boolean, d: Boolean) {
if (forceDefaults || x != d) { if (forceDefaults || x != d) {
@@ -675,17 +670,18 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Add a [UByte] to a table at `o` into its vtable, with value `x` and default `d`. * Add a [UByte] to a table at `o` into its vtable, with value `x` and default `d`. If
* If `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
* default value, it can be skipped. * default value, it can be skipped.
*/ */
public fun add(o: Int, x: UByte, d: UByte?): Unit = add(o, x.toByte(), d?.toByte()) public fun add(o: Int, x: UByte, d: UByte?): Unit = add(o, x.toByte(), d?.toByte())
// unboxed specialization // unboxed specialization
public fun add(o: Int, x: UByte, d: UByte): Unit = add(o, x.toByte(), d.toByte()) public fun add(o: Int, x: UByte, d: UByte): Unit = add(o, x.toByte(), d.toByte())
/** /**
* Add a [Byte] to a table at `o` into its vtable, with value `x` and default `d`. * Add a [Byte] to a table at `o` into its vtable, with value `x` and default `d`. If
* If `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
* default value, it can be skipped. * default value, it can be skipped.
*/ */
public fun add(o: Int, x: Byte, d: Byte?) { public fun add(o: Int, x: Byte, d: Byte?) {
@@ -694,6 +690,7 @@ public class FlatBufferBuilder @JvmOverloads constructor(
slot(o) slot(o)
} }
} }
// unboxed specialization // unboxed specialization
public fun add(o: Int, x: Byte, d: Byte) { public fun add(o: Int, x: Byte, d: Byte) {
if (forceDefaults || x != d) { if (forceDefaults || x != d) {
@@ -701,19 +698,20 @@ public class FlatBufferBuilder @JvmOverloads constructor(
slot(o) slot(o)
} }
} }
/** /**
* Add a [UShort] to a table at `o` into its vtable, with value `x` and default `d`. * Add a [UShort] to a table at `o` into its vtable, with value `x` and default `d`. If
* If `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
* default value, it can be skipped. * default value, it can be skipped.
*/ */
public fun add(o: Int, x: UShort, d: UShort?): Unit = add(o, x.toShort(), d?.toShort()) public fun add(o: Int, x: UShort, d: UShort?): Unit = add(o, x.toShort(), d?.toShort())
// unboxed specialization // unboxed specialization
public fun add(o: Int, x: UShort, d: UShort): Unit = add(o, x.toShort(), d.toShort()) public fun add(o: Int, x: UShort, d: UShort): Unit = add(o, x.toShort(), d.toShort())
/** /**
* Add a [Short] to a table at `o` into its vtable, with value `x` and default `d`. * Add a [Short] to a table at `o` into its vtable, with value `x` and default `d`. If
* If `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
* default value, it can be skipped. * default value, it can be skipped.
*/ */
public fun add(o: Int, x: Short, d: Short?) { public fun add(o: Int, x: Short, d: Short?) {
@@ -722,6 +720,7 @@ public class FlatBufferBuilder @JvmOverloads constructor(
slot(o) slot(o)
} }
} }
// unboxed specialization // unboxed specialization
public fun add(o: Int, x: Short, d: Short) { public fun add(o: Int, x: Short, d: Short) {
if (forceDefaults || x != d) { if (forceDefaults || x != d) {
@@ -731,17 +730,18 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Add a [UInt] to a table at `o` into its vtable, with value `x` and default `d`. * Add a [UInt] to a table at `o` into its vtable, with value `x` and default `d`. If
* If `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
* default value, it can be skipped. * default value, it can be skipped.
*/ */
public fun add(o: Int, x: UInt, d: UInt?): Unit = add(o, x.toInt(), d?.toInt()) public fun add(o: Int, x: UInt, d: UInt?): Unit = add(o, x.toInt(), d?.toInt())
// unboxed specialization // unboxed specialization
public fun add(o: Int, x: UInt, d: UInt): Unit = add(o, x.toInt(), d.toInt()) public fun add(o: Int, x: UInt, d: UInt): Unit = add(o, x.toInt(), d.toInt())
/** /**
* Add a [Int] to a table at `o` into its vtable, with value `x` and default `d`. * Add a [Int] to a table at `o` into its vtable, with value `x` and default `d`. If
* If `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
* default value, it can be skipped. * default value, it can be skipped.
*/ */
public fun add(o: Int, x: Int, d: Int?) { public fun add(o: Int, x: Int, d: Int?) {
@@ -750,6 +750,7 @@ public class FlatBufferBuilder @JvmOverloads constructor(
slot(o) slot(o)
} }
} }
// unboxed specialization // unboxed specialization
public fun add(o: Int, x: Int, d: Int) { public fun add(o: Int, x: Int, d: Int) {
if (forceDefaults || x != d) { if (forceDefaults || x != d) {
@@ -757,17 +758,20 @@ public class FlatBufferBuilder @JvmOverloads constructor(
slot(o) slot(o)
} }
} }
/** /**
* Add a [ULong] to a table at `o` into its vtable, with value `x` and default `d`. * Add a [ULong] to a table at `o` into its vtable, with value `x` and default `d`. If
* If `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
* default value, it can be skipped. * default value, it can be skipped.
*/ */
public fun add(o: Int, x: ULong, d: ULong?): Unit = add(o, x.toLong(), d?.toLong()) public fun add(o: Int, x: ULong, d: ULong?): Unit = add(o, x.toLong(), d?.toLong())
// unboxed specialization // unboxed specialization
public fun add(o: Int, x: ULong, d: ULong): Unit = add(o, x.toLong(), d.toLong()) public fun add(o: Int, x: ULong, d: ULong): Unit = add(o, x.toLong(), d.toLong())
/** /**
* Add a [Long] to a table at `o` into its vtable, with value `x` and default `d`. * Add a [Long] to a table at `o` into its vtable, with value `x` and default `d`. If
* If `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
* default value, it can be skipped. * default value, it can be skipped.
*/ */
public fun add(o: Int, x: Long, d: Long?) { public fun add(o: Int, x: Long, d: Long?) {
@@ -776,6 +780,7 @@ public class FlatBufferBuilder @JvmOverloads constructor(
slot(o) slot(o)
} }
} }
// unboxed specialization // unboxed specialization
public fun add(o: Int, x: Long, d: Long) { public fun add(o: Int, x: Long, d: Long) {
if (forceDefaults || x != d) { if (forceDefaults || x != d) {
@@ -785,8 +790,8 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Add a [Float] to a table at `o` into its vtable, with value `x` and default `d`. * Add a [Float] to a table at `o` into its vtable, with value `x` and default `d`. If
* If `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
* default value, it can be skipped. * default value, it can be skipped.
*/ */
public fun add(o: Int, x: Float, d: Float?) { public fun add(o: Int, x: Float, d: Float?) {
@@ -795,6 +800,7 @@ public class FlatBufferBuilder @JvmOverloads constructor(
slot(o) slot(o)
} }
} }
// unboxed specialization // unboxed specialization
public fun add(o: Int, x: Float, d: Float) { public fun add(o: Int, x: Float, d: Float) {
if (forceDefaults || x != d) { if (forceDefaults || x != d) {
@@ -804,8 +810,8 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Add a [Double] to a table at `o` into its vtable, with value `x` and default `d`. * Add a [Double] to a table at `o` into its vtable, with value `x` and default `d`. If
* If `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
* default value, it can be skipped. * default value, it can be skipped.
*/ */
public fun add(o: Int, x: Double, d: Double?) { public fun add(o: Int, x: Double, d: Double?) {
@@ -814,6 +820,7 @@ public class FlatBufferBuilder @JvmOverloads constructor(
slot(o) slot(o)
} }
} }
// unboxed specialization // unboxed specialization
public fun add(o: Int, x: Double, d: Double) { public fun add(o: Int, x: Double, d: Double) {
if (forceDefaults || x != d) { if (forceDefaults || x != d) {
@@ -837,6 +844,7 @@ public class FlatBufferBuilder @JvmOverloads constructor(
slot(o) slot(o)
} }
} }
public fun add(o: Int, x: VectorOffset<*>, d: Int) { public fun add(o: Int, x: VectorOffset<*>, d: Int) {
if (forceDefaults || x.value != d) { if (forceDefaults || x.value != d) {
add(x) add(x)
@@ -851,15 +859,20 @@ public class FlatBufferBuilder @JvmOverloads constructor(
* @param x The offset of the created struct. * @param x The offset of the created struct.
* @param d The default value is always `0`. * @param d The default value is always `0`.
*/ */
public fun addStruct(vOffset: Int, x: Offset<*>, d: Offset<*>?): Unit = addStruct(vOffset, x.value, d?.value) public fun addStruct(vOffset: Int, x: Offset<*>, d: Offset<*>?): Unit =
addStruct(vOffset, x.value, d?.value)
// unboxed specialization // unboxed specialization
public fun addStruct(vOffset: Int, x: Offset<*>, d: Offset<*>): Unit = addStruct(vOffset, x.value, d.value) public fun addStruct(vOffset: Int, x: Offset<*>, d: Offset<*>): Unit =
addStruct(vOffset, x.value, d.value)
public fun addStruct(vOffset: Int, x: Int, d: Int?) { public fun addStruct(vOffset: Int, x: Int, d: Int?) {
if (x != d) { if (x != d) {
nested(x) nested(x)
slot(vOffset) slot(vOffset)
} }
} }
// unboxed specialization // unboxed specialization
public fun addStruct(vOffset: Int, x: Int, d: Int) { public fun addStruct(vOffset: Int, x: Int, d: Int) {
if (x != d) { if (x != d) {
@@ -871,8 +884,7 @@ public class FlatBufferBuilder @JvmOverloads constructor(
/** /**
* Set the current vtable at `voffset` to the current location in the buffer. * Set the current vtable at `voffset` to the current location in the buffer.
* *
* @param vOffset The index into the vtable to store the offset relative to the end of the * @param vOffset The index into the vtable to store the offset relative to the end of the buffer.
* buffer.
*/ */
public fun slot(vOffset: Int) { public fun slot(vOffset: Int) {
vtable[vOffset] = offset() vtable[vOffset] = offset()
@@ -947,8 +959,7 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Checks that a required field has been set in a given table that has * Checks that a required field has been set in a given table that has just been constructed.
* just been constructed.
* *
* @param table The offset to the start of the table from the `ByteBuffer` capacity. * @param table The offset to the start of the table from the `ByteBuffer` capacity.
* @param field The offset to the field in the vtable. * @param field The offset to the field in the vtable.
@@ -1006,10 +1017,8 @@ public class FlatBufferBuilder @JvmOverloads constructor(
protected fun finish(rootTable: Offset<*>, fileIdentifier: String, sizePrefix: Boolean) { protected fun finish(rootTable: Offset<*>, fileIdentifier: String, sizePrefix: Boolean) {
val identifierSize = 4 val identifierSize = 4
prep(minalign, Int.SIZE_BYTES + identifierSize + if (sizePrefix) Int.SIZE_BYTES else 0) prep(minalign, Int.SIZE_BYTES + identifierSize + if (sizePrefix) Int.SIZE_BYTES else 0)
if (fileIdentifier.length != identifierSize) throw AssertionError( if (fileIdentifier.length != identifierSize)
"FlatBuffers: file identifier must be length " + throw AssertionError("FlatBuffers: file identifier must be length " + identifierSize)
identifierSize
)
for (i in identifierSize - 1 downTo 0) { for (i in identifierSize - 1 downTo 0) {
add(fileIdentifier[i].code.toByte()) add(fileIdentifier[i].code.toByte())
} }
@@ -1039,9 +1048,8 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* In order to save space, fields that are set to their default value * In order to save space, fields that are set to their default value don't get serialized into
* don't get serialized into the buffer. Forcing defaults provides a * the buffer. Forcing defaults provides a way to manually disable this optimization.
* way to manually disable this optimization.
* *
* @param forceDefaults When set to `true`, always serializes default values. * @param forceDefaults When set to `true`, always serializes default values.
* @return Returns `this`. * @return Returns `this`.
@@ -1052,9 +1060,8 @@ public class FlatBufferBuilder @JvmOverloads constructor(
} }
/** /**
* Get the ByteBuffer representing the FlatBuffer. Only call this after you've * Get the ByteBuffer representing the FlatBuffer. Only call this after you've called `finish()`.
* called `finish()`. The actual data starts at the ByteBuffer's current position, * The actual data starts at the ByteBuffer's current position, not necessarily at `0`.
* not necessarily at `0`.
* *
* @return The [ReadBuffer] representing the FlatBuffer * @return The [ReadBuffer] representing the FlatBuffer
*/ */
@@ -1084,22 +1091,25 @@ public class FlatBufferBuilder @JvmOverloads constructor(
public fun Table.isFieldPresent(offset: Int): Boolean = this.offset(offset) != 0 public fun Table.isFieldPresent(offset: Int): Boolean = this.offset(offset) != 0
} }
public fun Double.sign(): Double = when { public fun Double.sign(): Double =
when {
this.isNaN() -> Double.NaN this.isNaN() -> Double.NaN
this > 0 -> 1.0 this > 0 -> 1.0
this < 0 -> -1.0 this < 0 -> -1.0
else -> this else -> this
} }
public fun Float.sign(): Float = when { public fun Float.sign(): Float =
when {
this.isNaN() -> Float.NaN this.isNaN() -> Float.NaN
this > 0 -> 1.0f this > 0 -> 1.0f
this < 0 -> -1.0f this < 0 -> -1.0f
else -> this else -> this
} }
public fun Int.sign(): Int = when { public fun Int.sign(): Int =
when {
this > 0 -> 1 this > 0 -> 1
this < 0 -> -1 this < 0 -> -1
else -> this else -> this
} }

View File

@@ -20,29 +20,33 @@ import kotlin.math.min
// For now a typealias to guarantee type safety. // For now a typealias to guarantee type safety.
public typealias UnionOffset = Offset<Any> public typealias UnionOffset = Offset<Any>
public typealias UnionOffsetArray = OffsetArray<Any> public typealias UnionOffsetArray = OffsetArray<Any>
public typealias StringOffsetArray = OffsetArray<String> public typealias StringOffsetArray = OffsetArray<String>
public inline fun UnionOffsetArray(size: Int, crossinline call: (Int) -> Offset<Any>): UnionOffsetArray = public inline fun UnionOffsetArray(
UnionOffsetArray(IntArray(size) { call(it).value }) size: Int,
public inline fun StringOffsetArray(size: Int, crossinline call: (Int) -> Offset<String>): StringOffsetArray = crossinline call: (Int) -> Offset<Any>,
StringOffsetArray(IntArray(size) { call(it).value }) ): UnionOffsetArray = UnionOffsetArray(IntArray(size) { call(it).value })
/**
* Represents a "pointer" to a pointer types (table, string, struct) within the buffer public inline fun StringOffsetArray(
*/ size: Int,
crossinline call: (Int) -> Offset<String>,
): StringOffsetArray = StringOffsetArray(IntArray(size) { call(it).value })
/** Represents a "pointer" to a pointer types (table, string, struct) within the buffer */
@JvmInline @JvmInline
public value class Offset<T>(public val value: Int) { public value class Offset<T>(public val value: Int) {
public fun toUnion(): UnionOffset = UnionOffset(value) public fun toUnion(): UnionOffset = UnionOffset(value)
} }
/** /** Represents an array of offsets. Used to avoid boxing offset types. */
* Represents an array of offsets. Used to avoid boxing
* offset types.
*/
@JvmInline @JvmInline
public value class OffsetArray<T>(public val value: IntArray) { public value class OffsetArray<T>(public val value: IntArray) {
public inline val size: Int public inline val size: Int
get() = value.size get() = value.size
public inline operator fun get(index: Int): Offset<T> = Offset(value[index]) public inline operator fun get(index: Int): Offset<T> = Offset(value[index])
} }
@@ -50,12 +54,8 @@ public inline fun <T> OffsetArray(size: Int, crossinline call: (Int) -> Offset<T
return OffsetArray(IntArray(size) { call(it).value }) return OffsetArray(IntArray(size) { call(it).value })
} }
/** Represents a "pointer" to a vector type with elements T */
/** @JvmInline public value class VectorOffset<T>(public val value: Int)
* Represents a "pointer" to a vector type with elements T
*/
@JvmInline
public value class VectorOffset<T>(public val value: Int)
public fun <T> Int.toOffset(): Offset<T> = Offset(this) public fun <T> Int.toOffset(): Offset<T> = Offset(this)
@@ -64,9 +64,8 @@ public operator fun <T> Offset<T>.minus(other: Int): Offset<T> = Offset(this.val
public operator fun <T> Int.minus(other: Offset<T>): Int { public operator fun <T> Int.minus(other: Offset<T>): Int {
return this - other.value return this - other.value
} }
/**
* All tables in the generated code derive from this class, and add their own accessors. /** All tables in the generated code derive from this class, and add their own accessors. */
*/
public open class Table { public open class Table {
/** Used to hold the position of the `bb` buffer. */ /** Used to hold the position of the `bb` buffer. */
@@ -81,11 +80,14 @@ public open class Table {
/** Used to hold the vtable size. */ /** Used to hold the vtable size. */
public var vtableSize: Int = 0 public var vtableSize: Int = 0
protected inline fun <reified T> Int.invalid(default: T, crossinline valid: (Int) -> T) : T = protected inline fun <reified T> Int.invalid(default: T, crossinline valid: (Int) -> T): T =
if (this != 0) valid(this) else default if (this != 0) valid(this) else default
protected inline fun <reified T> lookupField(i: Int, default: T, crossinline found: (Int) -> T) : T = protected inline fun <reified T> lookupField(
offset(i).invalid(default) { found(it) } i: Int,
default: T,
crossinline found: (Int) -> T,
): T = offset(i).invalid(default) { found(it) }
/** /**
* Look up a field in the vtable. * Look up a field in the vtable.
@@ -107,10 +109,10 @@ public open class Table {
/** /**
* Create a Java `String` from UTF-8 data stored inside the FlatBuffer. * Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
* *
* This allocates a new string and converts to wide chars upon each access, * This allocates a new string and converts to wide chars upon each access, which is not very
* which is not very efficient. Instead, each FlatBuffer string also comes with an * efficient. Instead, each FlatBuffer string also comes with an accessor based on
* accessor based on __vector_as_ReadWriteBuffer below, which is much more efficient, * __vector_as_ReadWriteBuffer below, which is much more efficient, assuming your Java program can
* assuming your Java program can handle UTF-8 data directly. * handle UTF-8 data directly.
* *
* @param offset An `int` index into the Table's ReadWriteBuffer. * @param offset An `int` index into the Table's ReadWriteBuffer.
* @return Returns a `String` from the data stored inside the FlatBuffer at `offset`. * @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
@@ -141,11 +143,12 @@ public open class Table {
newOffset += bufferPos newOffset += bufferPos
return newOffset + bb.getInt(newOffset) + Int.SIZE_BYTES // data starts after the length return newOffset + bb.getInt(newOffset) + Int.SIZE_BYTES // data starts after the length
} }
/** /**
* Initialize vector as a ReadWriteBuffer. * Initialize vector as a ReadWriteBuffer.
* *
* This is more efficient than using duplicate, since it doesn't copy the data * This is more efficient than using duplicate, since it doesn't copy the data nor allocates a new
* nor allocates a new [ReadBuffer], creating no garbage to be collected. * [ReadBuffer], creating no garbage to be collected.
* *
* @param buffer The [ReadBuffer] for the array * @param buffer The [ReadBuffer] for the array
* @param vectorOffset The position of the vector in the byte buffer * @param vectorOffset The position of the vector in the byte buffer
@@ -194,7 +197,7 @@ public open class Table {
* This method exists primarily to allow recycling Table instances without risking memory leaks * This method exists primarily to allow recycling Table instances without risking memory leaks
* due to `ReadWriteBuffer` references. * due to `ReadWriteBuffer` references.
*/ */
public inline fun <reified T: Table> reset(i: Int, reuseBuffer: ReadWriteBuffer): T { public inline fun <reified T : Table> reset(i: Int, reuseBuffer: ReadWriteBuffer): T {
bb = reuseBuffer bb = reuseBuffer
if (bb != emptyBuffer) { if (bb != emptyBuffer) {
bufferPos = i bufferPos = i
@@ -212,10 +215,10 @@ public open class Table {
* Resets the internal state with a null `ReadWriteBuffer` and a zero position. * Resets the internal state with a null `ReadWriteBuffer` and a zero position.
* *
* This method exists primarily to allow recycling Table instances without risking memory leaks * This method exists primarily to allow recycling Table instances without risking memory leaks
* due to `ReadWriteBuffer` references. The instance will be unusable until it is assigned * due to `ReadWriteBuffer` references. The instance will be unusable until it is assigned again
* again to a `ReadWriteBuffer`. * to a `ReadWriteBuffer`.
*/ */
public inline fun <reified T: Table> reset(): T = reset(0, emptyBuffer) public inline fun <reified T : Table> reset(): T = reset(0, emptyBuffer)
public companion object { public companion object {
@@ -238,10 +241,10 @@ public open class Table {
/** /**
* Create a Java `String` from UTF-8 data stored inside the FlatBuffer. * Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
* *
* This allocates a new string and converts to wide chars upon each access, * This allocates a new string and converts to wide chars upon each access, which is not very
* which is not very efficient. Instead, each FlatBuffer string also comes with an * efficient. Instead, each FlatBuffer string also comes with an accessor based on
* accessor based on __vector_as_ReadWriteBuffer below, which is much more efficient, * __vector_as_ReadWriteBuffer below, which is much more efficient, assuming your Java program
* assuming your Java program can handle UTF-8 data directly. * can handle UTF-8 data directly.
* *
* @param offset An `int` index into the Table's ReadWriteBuffer. * @param offset An `int` index into the Table's ReadWriteBuffer.
* @param bb Table ReadWriteBuffer used to read a string at given offset. * @param bb Table ReadWriteBuffer used to read a string at given offset.
@@ -268,8 +271,7 @@ public open class Table {
/** /**
* Check if a [ReadWriteBuffer] contains a file identifier. * Check if a [ReadWriteBuffer] contains a file identifier.
* *
* @param bb A `ReadWriteBuffer` to check if it contains the identifier * @param bb A `ReadWriteBuffer` to check if it contains the identifier `ident`.
* `ident`.
* @param ident A `String` identifier of the FlatBuffer file. * @param ident A `String` identifier of the FlatBuffer file.
* @return True if the buffer contains the file identifier * @return True if the buffer contains the file identifier
*/ */
@@ -330,9 +332,7 @@ public open class Table {
} }
} }
/** /** All structs in the generated code derive from this class, and add their own accessors. */
* All structs in the generated code derive from this class, and add their own accessors.
*/
public open class Struct { public open class Struct {
/** Used to hold the position of the `bb` buffer. */ /** Used to hold the position of the `bb` buffer. */
protected var bufferPos: Int = 0 protected var bufferPos: Int = 0
@@ -346,7 +346,7 @@ public open class Struct {
* This method exists primarily to allow recycling Table instances without risking memory leaks * This method exists primarily to allow recycling Table instances without risking memory leaks
* due to `ByteBuffer` references. * due to `ByteBuffer` references.
*/ */
protected inline fun <reified T: Struct> reset(i: Int, reuseBuffer: ReadWriteBuffer): T { protected inline fun <reified T : Struct> reset(i: Int, reuseBuffer: ReadWriteBuffer): T {
bb = reuseBuffer bb = reuseBuffer
bufferPos = if (bb != emptyBuffer) i else 0 bufferPos = if (bb != emptyBuffer) i else 0
return this as T return this as T
@@ -356,12 +356,13 @@ public open class Struct {
* Resets internal state with a null `ByteBuffer` and a zero position. * Resets internal state with a null `ByteBuffer` and a zero position.
* *
* This method exists primarily to allow recycling Struct instances without risking memory leaks * This method exists primarily to allow recycling Struct instances without risking memory leaks
* due to `ByteBuffer` references. The instance will be unusable until it is assigned * due to `ByteBuffer` references. The instance will be unusable until it is assigned again to a
* again to a `ByteBuffer`. * `ByteBuffer`.
*/ */
private inline fun <reified T: Struct> reset(): T = reset(0, emptyBuffer) private inline fun <reified T : Struct> reset(): T = reset(0, emptyBuffer)
} }
public inline val <T> T.value: T get() = this public inline val <T> T.value: T
get() = this
public const val VERSION_2_0_8: Int = 1 public const val VERSION_2_0_8: Int = 1

View File

@@ -15,13 +15,14 @@
*/ */
@file:Suppress("NOTHING_TO_INLINE") @file:Suppress("NOTHING_TO_INLINE")
@file:JvmName("FlexBuffers") @file:JvmName("FlexBuffers")
package com.google.flatbuffers.kotlin package com.google.flatbuffers.kotlin
import kotlin.jvm.JvmName import kotlin.jvm.JvmName
/** /**
* Reads a FlexBuffer message in ReadBuf and returns [Reference] to * Reads a FlexBuffer message in ReadBuf and returns [Reference] to the root element.
* the root element. *
* @param buffer ReadBuf containing FlexBuffer message * @param buffer ReadBuf containing FlexBuffer message
* @return [Reference] to the root object * @return [Reference] to the root object
*/ */
@@ -34,199 +35,231 @@ public fun getRoot(buffer: ReadBuffer): Reference {
} }
/** /**
* Represents an generic element in the buffer. It can be specialized into scalar types, using for example, * Represents an generic element in the buffer. It can be specialized into scalar types, using for
* [Reference.toInt], or casted into Flexbuffer object types, like [Reference.toMap] or [Reference.toBlob]. * example, [Reference.toInt], or casted into Flexbuffer object types, like [Reference.toMap] or
* [Reference.toBlob].
*/ */
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")
public class Reference internal constructor( public class Reference
internal constructor(
internal val buffer: ReadBuffer, internal val buffer: ReadBuffer,
internal val end: Int, internal val end: Int,
internal val parentWidth: ByteWidth, internal val parentWidth: ByteWidth,
internal val byteWidth: ByteWidth, internal val byteWidth: ByteWidth,
public val type: FlexBufferType public val type: FlexBufferType,
) { ) {
internal constructor(bb: ReadBuffer, end: Int, parentWidth: ByteWidth, packedType: Int) : internal constructor(
this(bb, end, parentWidth, ByteWidth(1 shl (packedType and 3)), FlexBufferType((packedType shr 2))) bb: ReadBuffer,
end: Int,
parentWidth: ByteWidth,
packedType: Int,
) : this(
bb,
end,
parentWidth,
ByteWidth(1 shl (packedType and 3)),
FlexBufferType((packedType shr 2)),
)
/** /**
* Checks whether the element is null type * Checks whether the element is null type
*
* @return true if null type * @return true if null type
*/ */
public val isNull: Boolean get() = type == T_NULL public val isNull: Boolean
get() = type == T_NULL
/** /**
* Checks whether the element is boolean type * Checks whether the element is boolean type
*
* @return true if boolean type * @return true if boolean type
*/ */
public val isBoolean: Boolean get() = type == T_BOOL public val isBoolean: Boolean
get() = type == T_BOOL
/** /**
* Checks whether the element type is numeric (signed/unsigned integers and floats) * Checks whether the element type is numeric (signed/unsigned integers and floats)
*
* @return true if numeric type * @return true if numeric type
*/ */
public val isNumeric: Boolean get() = isIntOrUInt || isFloat public val isNumeric: Boolean
get() = isIntOrUInt || isFloat
/** /**
* Checks whether the element type is signed or unsigned integers * Checks whether the element type is signed or unsigned integers
*
* @return true if an integer type * @return true if an integer type
*/ */
public val isIntOrUInt: Boolean get() = isInt || isUInt public val isIntOrUInt: Boolean
get() = isInt || isUInt
/** /**
* Checks whether the element type is float * Checks whether the element type is float
*
* @return true if a float type * @return true if a float type
*/ */
public val isFloat: Boolean get() = type == T_FLOAT || type == T_INDIRECT_FLOAT public val isFloat: Boolean
get() = type == T_FLOAT || type == T_INDIRECT_FLOAT
/** /**
* Checks whether the element type is signed integer * Checks whether the element type is signed integer
*
* @return true if a signed integer type * @return true if a signed integer type
*/ */
public val isInt: Boolean get() = type == T_INT || type == T_INDIRECT_INT public val isInt: Boolean
get() = type == T_INT || type == T_INDIRECT_INT
/** /**
* Checks whether the element type is signed integer * Checks whether the element type is signed integer
*
* @return true if a signed integer type * @return true if a signed integer type
*/ */
public val isUInt: Boolean get() = type == T_UINT || type == T_INDIRECT_UINT public val isUInt: Boolean
get() = type == T_UINT || type == T_INDIRECT_UINT
/** /**
* Checks whether the element type is string * Checks whether the element type is string
*
* @return true if a string type * @return true if a string type
*/ */
public val isString: Boolean get() = type == T_STRING public val isString: Boolean
get() = type == T_STRING
/** /**
* Checks whether the element type is key * Checks whether the element type is key
*
* @return true if a key type * @return true if a key type
*/ */
public val isKey: Boolean get() = type == T_KEY public val isKey: Boolean
get() = type == T_KEY
/** /**
* Checks whether the element type is vector or a map. [TypedVector] are considered different types and will return * Checks whether the element type is vector or a map. [TypedVector] are considered different
* false. * types and will return false.
*
* @return true if a vector type * @return true if a vector type
*/ */
public val isVector: Boolean get() = type == T_VECTOR || type == T_MAP public val isVector: Boolean
get() = type == T_VECTOR || type == T_MAP
/** /**
* Checks whether the element type is typed vector * Checks whether the element type is typed vector
*
* @return true if a typed vector type * @return true if a typed vector type
*/ */
public val isTypedVector: Boolean get() = type.isTypedVector() public val isTypedVector: Boolean
get() = type.isTypedVector()
/** /**
* Checks whether the element type is a map * Checks whether the element type is a map
*
* @return true if a map type * @return true if a map type
*/ */
public val isMap: Boolean get() = type == T_MAP public val isMap: Boolean
get() = type == T_MAP
/** /**
* Checks whether the element type is a blob * Checks whether the element type is a blob
*
* @return true if a blob type * @return true if a blob type
*/ */
public val isBlob: Boolean get() = type == T_BLOB public val isBlob: Boolean
get() = type == T_BLOB
/** /** Assumes [Reference] as a [Vector] and returns a [Reference] at index [index]. */
* Assumes [Reference] as a [Vector] and returns a [Reference] at index [index].
*/
public operator fun get(index: Int): Reference = toVector()[index] public operator fun get(index: Int): Reference = toVector()[index]
/** /** Assumes [Reference] as a [Map] and returns a [Reference] for the value at key [key]. */
* Assumes [Reference] as a [Map] and returns a [Reference] for the value at key [key].
*/
public operator fun get(key: String): Reference = toMap()[key] public operator fun get(key: String): Reference = toMap()[key]
/** /**
* Returns element as a [Boolean]. * Returns element as a [Boolean]. If element type is not boolean, it will be casted to integer
* If element type is not boolean, it will be casted to integer and compared against 0 * and compared against 0
*
* @return element as [Boolean] * @return element as [Boolean]
*/ */
public fun toBoolean(): Boolean = if (isBoolean) buffer.getBoolean(end) else toUInt() != 0u public fun toBoolean(): Boolean = if (isBoolean) buffer.getBoolean(end) else toUInt() != 0u
/** /**
* Returns element as [Byte]. * Returns element as [Byte]. For vector types, it will return size of the vector. For String
* For vector types, it will return size of the vector. * type, it will be parsed as integer. Unsigned elements will become signed (with possible
* For String type, it will be parsed as integer. * overflow). Float elements will be casted to [Byte].
* Unsigned elements will become signed (with possible overflow). *
* Float elements will be casted to [Byte].
* @return [Byte] or 0 if fail to convert element to integer. * @return [Byte] or 0 if fail to convert element to integer.
*/ */
public fun toByte(): Byte = toULong().toByte() public fun toByte(): Byte = toULong().toByte()
/** /**
* Returns element as [Short]. * Returns element as [Short]. For vector types, it will return size of the vector. For String
* For vector types, it will return size of the vector. * type, it will type to be parsed as integer. Unsigned elements will become signed (with possible
* For String type, it will type to be parsed as integer. * overflow). Float elements will be casted to [Short]
* Unsigned elements will become signed (with possible overflow). *
* Float elements will be casted to [Short]
* @return [Short] or 0 if fail to convert element to integer. * @return [Short] or 0 if fail to convert element to integer.
*/ */
public fun toShort(): Short = toULong().toShort() public fun toShort(): Short = toULong().toShort()
/** /**
* Returns element as [Int]. * Returns element as [Int]. For vector types, it will return size of the vector. For String type,
* For vector types, it will return size of the vector. * it will type to be parsed as integer. Unsigned elements will become signed (with possible
* For String type, it will type to be parsed as integer. * overflow). Float elements will be casted to [Int]
* Unsigned elements will become signed (with possible overflow). *
* Float elements will be casted to [Int]
* @return [Int] or 0 if fail to convert element to integer. * @return [Int] or 0 if fail to convert element to integer.
*/ */
public fun toInt(): Int = toULong().toInt() public fun toInt(): Int = toULong().toInt()
/** /**
* Returns element as [Long]. * Returns element as [Long]. For vector types, it will return size of the vector For String type,
* For vector types, it will return size of the vector * it will type to be parsed as integer Unsigned elements will become negative Float elements will
* For String type, it will type to be parsed as integer * be casted to integer
* Unsigned elements will become negative *
* Float elements will be casted to integer
* @return [Long] integer or 0 if fail to convert element to long. * @return [Long] integer or 0 if fail to convert element to long.
*/ */
public fun toLong(): Long = toULong().toLong() public fun toLong(): Long = toULong().toLong()
/** /**
* Returns element as [UByte]. * Returns element as [UByte]. For vector types, it will return size of the vector. For String
* For vector types, it will return size of the vector. * type, it will type to be parsed as integer. Negative elements will become unsigned counterpart.
* For String type, it will type to be parsed as integer.
* Negative elements will become unsigned counterpart.
* Float elements will be casted to [UByte] * Float elements will be casted to [UByte]
*
* @return [UByte] or 0 if fail to convert element to integer. * @return [UByte] or 0 if fail to convert element to integer.
*/ */
public fun toUByte(): UByte = toULong().toUByte() public fun toUByte(): UByte = toULong().toUByte()
/** /**
* Returns element as [UShort]. * Returns element as [UShort]. For vector types, it will return size of the vector. For String
* For vector types, it will return size of the vector. * type, it will type to be parsed as integer. Negative elements will become unsigned counterpart.
* For String type, it will type to be parsed as integer.
* Negative elements will become unsigned counterpart.
* Float elements will be casted to [UShort] * Float elements will be casted to [UShort]
*
* @return [UShort] or 0 if fail to convert element to integer. * @return [UShort] or 0 if fail to convert element to integer.
*/ */
public fun toUShort(): UShort = toULong().toUShort() public fun toUShort(): UShort = toULong().toUShort()
/** /**
* Returns element as [UInt]. * Returns element as [UInt]. For vector types, it will return size of the vector. For String
* For vector types, it will return size of the vector. * type, it will type to be parsed as integer. Negative elements will become unsigned counterpart.
* For String type, it will type to be parsed as integer.
* Negative elements will become unsigned counterpart.
* Float elements will be casted to [UInt] * Float elements will be casted to [UInt]
*
* @return [UInt] or 0 if fail to convert element to integer. * @return [UInt] or 0 if fail to convert element to integer.
*/ */
public fun toUInt(): UInt = toULong().toUInt() public fun toUInt(): UInt = toULong().toUInt()
/** /**
* Returns element as [ULong] integer. * Returns element as [ULong] integer. For vector types, it will return size of the vector For
* For vector types, it will return size of the vector * String type, it will type to be parsed as integer Negative elements will become unsigned
* For String type, it will type to be parsed as integer * counterpart. Float elements will be casted to integer
* Negative elements will become unsigned counterpart. *
* Float elements will be casted to integer
* @return [ULong] integer or 0 if fail to convert element to long. * @return [ULong] integer or 0 if fail to convert element to long.
*/ */
public fun toULong(): ULong = resolve { pos: Int, width: ByteWidth -> public fun toULong(): ULong = resolve { pos: Int, width: ByteWidth ->
when (type) { when (type) {
T_INDIRECT_INT, T_INDIRECT_UINT, T_INT, T_BOOL, T_UINT -> buffer.readULong(pos, width) T_INDIRECT_INT,
T_FLOAT, T_INDIRECT_FLOAT -> buffer.readFloat(pos, width).toULong() T_INDIRECT_UINT,
T_INT,
T_BOOL,
T_UINT -> buffer.readULong(pos, width)
T_FLOAT,
T_INDIRECT_FLOAT -> buffer.readFloat(pos, width).toULong()
T_STRING -> toString().toULong() T_STRING -> toString().toULong()
T_VECTOR -> toVector().size.toULong() T_VECTOR -> toVector().size.toULong()
else -> 0UL else -> 0UL
@@ -234,17 +267,18 @@ public class Reference internal constructor(
} }
/** /**
* Returns element as [Float]. * Returns element as [Float]. For vector types, it will return size of the vector For String
* For vector types, it will return size of the vector * type, it will type to be parsed as [Float] Float elements will be casted to integer
* For String type, it will type to be parsed as [Float] *
* Float elements will be casted to integer
* @return [Float] integer or 0 if fail to convert element to long. * @return [Float] integer or 0 if fail to convert element to long.
*/ */
public fun toFloat(): Float = resolve { pos: Int, width: ByteWidth -> public fun toFloat(): Float = resolve { pos: Int, width: ByteWidth ->
when (type) { when (type) {
T_INDIRECT_FLOAT, T_FLOAT -> buffer.readFloat(pos, width).toFloat() T_INDIRECT_FLOAT,
T_FLOAT -> buffer.readFloat(pos, width).toFloat()
T_INT -> buffer.readInt(end, parentWidth).toFloat() T_INT -> buffer.readInt(end, parentWidth).toFloat()
T_UINT, T_BOOL -> buffer.readUInt(end, parentWidth).toFloat() T_UINT,
T_BOOL -> buffer.readUInt(end, parentWidth).toFloat()
T_INDIRECT_INT -> buffer.readInt(pos, width).toFloat() T_INDIRECT_INT -> buffer.readInt(pos, width).toFloat()
T_INDIRECT_UINT -> buffer.readUInt(pos, width).toFloat() T_INDIRECT_UINT -> buffer.readUInt(pos, width).toFloat()
T_NULL -> 0.0f T_NULL -> 0.0f
@@ -255,16 +289,18 @@ public class Reference internal constructor(
} }
/** /**
* Returns element as [Double]. * Returns element as [Double]. For vector types, it will return size of the vector For String
* For vector types, it will return size of the vector * type, it will type to be parsed as [Double]
* For String type, it will type to be parsed as [Double] *
* @return [Float] integer or 0 if fail to convert element to long. * @return [Float] integer or 0 if fail to convert element to long.
*/ */
public fun toDouble(): Double = resolve { pos: Int, width: ByteWidth -> public fun toDouble(): Double = resolve { pos: Int, width: ByteWidth ->
when (type) { when (type) {
T_INDIRECT_FLOAT, T_FLOAT -> buffer.readFloat(pos, width) T_INDIRECT_FLOAT,
T_FLOAT -> buffer.readFloat(pos, width)
T_INT -> buffer.readInt(pos, width).toDouble() T_INT -> buffer.readInt(pos, width).toDouble()
T_UINT, T_BOOL -> buffer.readUInt(pos, width).toDouble() T_UINT,
T_BOOL -> buffer.readUInt(pos, width).toDouble()
T_INDIRECT_INT -> buffer.readInt(pos, width).toDouble() T_INDIRECT_INT -> buffer.readInt(pos, width).toDouble()
T_INDIRECT_UINT -> buffer.readUInt(pos, width).toDouble() T_INDIRECT_UINT -> buffer.readUInt(pos, width).toDouble()
T_NULL -> 0.0 T_NULL -> 0.0
@@ -274,18 +310,20 @@ public class Reference internal constructor(
} }
} }
/** /** Returns element as [Key] or invalid key. */
* Returns element as [Key] or invalid key. public fun toKey(): Key =
*/ when (type) {
public fun toKey(): Key = when (type) {
T_KEY -> Key(buffer, buffer.indirect(end, parentWidth)) T_KEY -> Key(buffer, buffer.indirect(end, parentWidth))
else -> nullKey() else -> nullKey()
} }
/** /**
* Returns element as a [String] * Returns element as a [String]
*
* @return element as [String] or empty [String] if fail * @return element as [String] or empty [String] if fail
*/ */
override fun toString(): String = when (type) { override fun toString(): String =
when (type) {
T_STRING -> { T_STRING -> {
val start = buffer.indirect(end, parentWidth) val start = buffer.indirect(end, parentWidth)
val size = buffer.readULong(start - byteWidth, byteWidth).toInt() val size = buffer.readULong(start - byteWidth, byteWidth).toInt()
@@ -293,9 +331,13 @@ public class Reference internal constructor(
} }
T_KEY -> buffer.getKeyString(buffer.indirect(end, parentWidth)) T_KEY -> buffer.getKeyString(buffer.indirect(end, parentWidth))
T_MAP -> "{ ${toMap().entries.joinToString(", ") { "${it.key}: ${it.value}"}} }" T_MAP -> "{ ${toMap().entries.joinToString(", ") { "${it.key}: ${it.value}"}} }"
T_VECTOR, T_VECTOR_BOOL, T_VECTOR_FLOAT, T_VECTOR_INT, T_VECTOR,
T_VECTOR_UINT, T_VECTOR_KEY, T_VECTOR_STRING_DEPRECATED -> T_VECTOR_BOOL,
"[ ${toVector().joinToString(", ") { it.toString() }} ]" T_VECTOR_FLOAT,
T_VECTOR_INT,
T_VECTOR_UINT,
T_VECTOR_KEY,
T_VECTOR_STRING_DEPRECATED -> "[ ${toVector().joinToString(", ") { it.toString() }} ]"
T_INT -> toLong().toString() T_INT -> toLong().toString()
T_UINT -> toULong().toString() T_UINT -> toULong().toString()
T_FLOAT -> toDouble().toString() T_FLOAT -> toDouble().toString()
@@ -304,10 +346,12 @@ public class Reference internal constructor(
/** /**
* Returns element as a [ByteArray], converting scalar types when possible. * Returns element as a [ByteArray], converting scalar types when possible.
*
* @return element as [ByteArray] or empty [ByteArray] if fail. * @return element as [ByteArray] or empty [ByteArray] if fail.
*/ */
public fun toByteArray(): ByteArray { public fun toByteArray(): ByteArray {
val vec = TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth) val vec =
TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth)
return when (type) { return when (type) {
T_VECTOR_INT -> ByteArray(vec.size) { vec.getInt(it).toByte() } T_VECTOR_INT -> ByteArray(vec.size) { vec.getInt(it).toByte() }
T_VECTOR_UINT -> ByteArray(vec.size) { vec.getUInt(it).toByte() } T_VECTOR_UINT -> ByteArray(vec.size) { vec.getUInt(it).toByte() }
@@ -319,10 +363,12 @@ public class Reference internal constructor(
/** /**
* Returns element as a [ByteArray], converting scalar types when possible. * Returns element as a [ByteArray], converting scalar types when possible.
*
* @return element as [ByteArray] or empty [ByteArray] if fail. * @return element as [ByteArray] or empty [ByteArray] if fail.
*/ */
public fun toShortArray(): ShortArray { public fun toShortArray(): ShortArray {
val vec = TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth) val vec =
TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth)
return when (type) { return when (type) {
T_VECTOR_INT -> ShortArray(vec.size) { vec.getInt(it).toShort() } T_VECTOR_INT -> ShortArray(vec.size) { vec.getInt(it).toShort() }
T_VECTOR_UINT -> ShortArray(vec.size) { vec.getUInt(it).toShort() } T_VECTOR_UINT -> ShortArray(vec.size) { vec.getUInt(it).toShort() }
@@ -334,10 +380,12 @@ public class Reference internal constructor(
/** /**
* Returns element as a [IntArray], converting scalar types when possible. * Returns element as a [IntArray], converting scalar types when possible.
*
* @return element as [IntArray] or empty [IntArray] if fail. * @return element as [IntArray] or empty [IntArray] if fail.
*/ */
public fun toIntArray(): IntArray { public fun toIntArray(): IntArray {
val vec = TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth) val vec =
TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth)
return when (type) { return when (type) {
T_VECTOR_INT -> IntArray(vec.size) { vec.getInt(it).toInt() } T_VECTOR_INT -> IntArray(vec.size) { vec.getInt(it).toInt() }
T_VECTOR_UINT -> IntArray(vec.size) { vec.getUInt(it).toInt() } T_VECTOR_UINT -> IntArray(vec.size) { vec.getUInt(it).toInt() }
@@ -349,10 +397,12 @@ public class Reference internal constructor(
/** /**
* Returns element as a [LongArray], converting scalar types when possible. * Returns element as a [LongArray], converting scalar types when possible.
*
* @return element as [LongArray] or empty [LongArray] if fail. * @return element as [LongArray] or empty [LongArray] if fail.
*/ */
public fun toLongArray(): LongArray { public fun toLongArray(): LongArray {
val vec = TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth) val vec =
TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth)
return when (type) { return when (type) {
T_VECTOR_INT -> LongArray(vec.size) { vec.getInt(it) } T_VECTOR_INT -> LongArray(vec.size) { vec.getInt(it) }
T_VECTOR_UINT -> LongArray(vec.size) { vec.getInt(it) } T_VECTOR_UINT -> LongArray(vec.size) { vec.getInt(it) }
@@ -364,10 +414,12 @@ public class Reference internal constructor(
/** /**
* Returns element as a [UByteArray], converting scalar types when possible. * Returns element as a [UByteArray], converting scalar types when possible.
*
* @return element as [UByteArray] or empty [UByteArray] if fail. * @return element as [UByteArray] or empty [UByteArray] if fail.
*/ */
public fun toUByteArray(): UByteArray { public fun toUByteArray(): UByteArray {
val vec = TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth) val vec =
TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth)
return when (type) { return when (type) {
T_VECTOR_INT -> UByteArray(vec.size) { vec.getInt(it).toUByte() } T_VECTOR_INT -> UByteArray(vec.size) { vec.getInt(it).toUByte() }
T_VECTOR_UINT -> UByteArray(vec.size) { vec.getUInt(it).toUByte() } T_VECTOR_UINT -> UByteArray(vec.size) { vec.getUInt(it).toUByte() }
@@ -379,10 +431,12 @@ public class Reference internal constructor(
/** /**
* Returns element as a [UIntArray], converting scalar types when possible. * Returns element as a [UIntArray], converting scalar types when possible.
*
* @return element as [UIntArray] or empty [UIntArray] if fail. * @return element as [UIntArray] or empty [UIntArray] if fail.
*/ */
public fun toUShortArray(): UShortArray { public fun toUShortArray(): UShortArray {
val vec = TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth) val vec =
TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth)
return when (type) { return when (type) {
T_VECTOR_INT -> UShortArray(vec.size) { vec.getInt(it).toUShort() } T_VECTOR_INT -> UShortArray(vec.size) { vec.getInt(it).toUShort() }
T_VECTOR_UINT -> UShortArray(vec.size) { vec.getUInt(it).toUShort() } T_VECTOR_UINT -> UShortArray(vec.size) { vec.getUInt(it).toUShort() }
@@ -394,10 +448,12 @@ public class Reference internal constructor(
/** /**
* Returns element as a [UIntArray], converting scalar types when possible. * Returns element as a [UIntArray], converting scalar types when possible.
*
* @return element as [UIntArray] or empty [UIntArray] if fail. * @return element as [UIntArray] or empty [UIntArray] if fail.
*/ */
public fun toUIntArray(): UIntArray { public fun toUIntArray(): UIntArray {
val vec = TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth) val vec =
TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth)
return when (type) { return when (type) {
T_VECTOR_INT -> UIntArray(vec.size) { vec.getInt(it).toUInt() } T_VECTOR_INT -> UIntArray(vec.size) { vec.getInt(it).toUInt() }
T_VECTOR_UINT -> UIntArray(vec.size) { vec.getUInt(it).toUInt() } T_VECTOR_UINT -> UIntArray(vec.size) { vec.getUInt(it).toUInt() }
@@ -409,10 +465,12 @@ public class Reference internal constructor(
/** /**
* Returns element as a [ULongArray], converting scalar types when possible. * Returns element as a [ULongArray], converting scalar types when possible.
*
* @return element as [ULongArray] or empty [ULongArray] if fail. * @return element as [ULongArray] or empty [ULongArray] if fail.
*/ */
public fun toULongArray(): ULongArray { public fun toULongArray(): ULongArray {
val vec = TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth) val vec =
TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth)
return when (type) { return when (type) {
T_VECTOR_INT -> ULongArray(vec.size) { vec.getUInt(it) } T_VECTOR_INT -> ULongArray(vec.size) { vec.getUInt(it) }
T_VECTOR_UINT -> ULongArray(vec.size) { vec.getUInt(it) } T_VECTOR_UINT -> ULongArray(vec.size) { vec.getUInt(it) }
@@ -424,10 +482,12 @@ public class Reference internal constructor(
/** /**
* Returns element as a [FloatArray], converting scalar types when possible. * Returns element as a [FloatArray], converting scalar types when possible.
*
* @return element as [FloatArray] or empty [FloatArray] if fail. * @return element as [FloatArray] or empty [FloatArray] if fail.
*/ */
public fun toFloatArray(): FloatArray { public fun toFloatArray(): FloatArray {
val vec = TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth) val vec =
TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth)
return when (type) { return when (type) {
T_VECTOR_FLOAT -> FloatArray(vec.size) { vec.getFloat(it).toFloat() } T_VECTOR_FLOAT -> FloatArray(vec.size) { vec.getFloat(it).toFloat() }
T_VECTOR_INT -> FloatArray(vec.size) { vec.getInt(it).toFloat() } T_VECTOR_INT -> FloatArray(vec.size) { vec.getInt(it).toFloat() }
@@ -439,10 +499,12 @@ public class Reference internal constructor(
/** /**
* Returns element as a [DoubleArray], converting scalar types when possible. * Returns element as a [DoubleArray], converting scalar types when possible.
*
* @return element as [DoubleArray] or empty [DoubleArray] if fail. * @return element as [DoubleArray] or empty [DoubleArray] if fail.
*/ */
public fun toDoubleArray(): DoubleArray { public fun toDoubleArray(): DoubleArray {
val vec = TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth) val vec =
TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth)
return when (type) { return when (type) {
T_VECTOR_FLOAT -> DoubleArray(vec.size) { vec[it].toDouble() } T_VECTOR_FLOAT -> DoubleArray(vec.size) { vec[it].toDouble() }
T_VECTOR_INT -> DoubleArray(vec.size) { vec[it].toDouble() } T_VECTOR_INT -> DoubleArray(vec.size) { vec[it].toDouble() }
@@ -454,32 +516,43 @@ public class Reference internal constructor(
/** /**
* Returns element as a [Vector] * Returns element as a [Vector]
*
* @return element as [Vector] or empty [Vector] if fail * @return element as [Vector] or empty [Vector] if fail
*/ */
public fun toVector(): Vector { public fun toVector(): Vector {
return when { return when {
isVector -> Vector(buffer, buffer.indirect(end, parentWidth), byteWidth) isVector -> Vector(buffer, buffer.indirect(end, parentWidth), byteWidth)
isTypedVector -> TypedVector(type.toElementTypedVector(), buffer, buffer.indirect(end, parentWidth), byteWidth) isTypedVector ->
TypedVector(
type.toElementTypedVector(),
buffer,
buffer.indirect(end, parentWidth),
byteWidth,
)
else -> emptyVector() else -> emptyVector()
} }
} }
/** /**
* Returns element as a [Blob] * Returns element as a [Blob]
*
* @return element as [Blob] or empty [Blob] if fail * @return element as [Blob] or empty [Blob] if fail
*/ */
public fun toBlob(): Blob { public fun toBlob(): Blob {
return when (type) { return when (type) {
T_BLOB, T_STRING -> Blob(buffer, buffer.indirect(end, parentWidth), byteWidth) T_BLOB,
T_STRING -> Blob(buffer, buffer.indirect(end, parentWidth), byteWidth)
else -> emptyBlob() else -> emptyBlob()
} }
} }
/** /**
* Returns element as a [Map]. * Returns element as a [Map].
*
* @return element as [Map] or empty [Map] if fail * @return element as [Map] or empty [Map] if fail
*/ */
public fun toMap(): Map = when (type) { public fun toMap(): Map =
when (type) {
T_MAP -> Map(buffer, buffer.indirect(end, parentWidth), byteWidth) T_MAP -> Map(buffer, buffer.indirect(end, parentWidth), byteWidth)
else -> emptyMap() else -> emptyMap()
} }
@@ -496,12 +569,14 @@ public class Reference internal constructor(
if (this === other) return true if (this === other) return true
if (other == null || this::class != other::class) return false if (other == null || this::class != other::class) return false
other as Reference other as Reference
if (buffer != other.buffer || if (
buffer != other.buffer ||
end != other.end || end != other.end ||
parentWidth != other.parentWidth || parentWidth != other.parentWidth ||
byteWidth != other.byteWidth || byteWidth != other.byteWidth ||
type != other.type type != other.type
) return false )
return false
return true return true
} }
@@ -518,30 +593,28 @@ public class Reference internal constructor(
/** /**
* Represents any element that has a size property to it, like: [Map], [Vector] and [TypedVector]. * Represents any element that has a size property to it, like: [Map], [Vector] and [TypedVector].
*/ */
public open class Sized internal constructor( public open class Sized
internal constructor(
public val buffer: ReadBuffer, public val buffer: ReadBuffer,
public val end: Int, public val end: Int,
public val byteWidth: ByteWidth public val byteWidth: ByteWidth,
) { ) {
public open val size: Int = buffer.readSize(end, byteWidth) public open val size: Int = buffer.readSize(end, byteWidth)
} }
/** /** Represent an array of bytes in the buffer. */
* Represent an array of bytes in the buffer. public open class Blob internal constructor(buffer: ReadBuffer, end: Int, byteWidth: ByteWidth) :
*/ Sized(buffer, end, byteWidth) {
public open class Blob internal constructor(
buffer: ReadBuffer,
end: Int,
byteWidth: ByteWidth
) : Sized(buffer, end, byteWidth) {
/** /**
* Return [Blob] as [ReadBuffer] * Return [Blob] as [ReadBuffer]
*
* @return blob as [ReadBuffer] * @return blob as [ReadBuffer]
*/ */
public fun data(): ReadBuffer = buffer.slice(end, size) public fun data(): ReadBuffer = buffer.slice(end, size)
/** /**
* Copy [Blob] into a [ByteArray] * Copy [Blob] into a [ByteArray]
*
* @return A [ByteArray] containing the blob data. * @return A [ByteArray] containing the blob data.
*/ */
public fun toByteArray(): ByteArray { public fun toByteArray(): ByteArray {
@@ -554,6 +627,7 @@ public open class Blob internal constructor(
/** /**
* Return individual byte at a given position * Return individual byte at a given position
*
* @param pos position of the byte to be read * @param pos position of the byte to be read
*/ */
public operator fun get(pos: Int): Byte { public operator fun get(pos: Int): Byte {
@@ -564,18 +638,13 @@ public open class Blob internal constructor(
override fun toString(): String = buffer.getString(end, size) override fun toString(): String = buffer.getString(end, size)
} }
/** /** [Vector] represents an array of elements in the buffer. The element can be of any type. */
* [Vector] represents an array of elements in the buffer. The element can be of any type. public open class Vector internal constructor(buffer: ReadBuffer, end: Int, byteWidth: ByteWidth) :
*/ Collection<Reference>, Sized(buffer, end, byteWidth) {
public open class Vector internal constructor(
buffer: ReadBuffer,
end: Int,
byteWidth: ByteWidth
) : Collection<Reference>,
Sized(buffer, end, byteWidth) {
/** /**
* Returns a [Reference] from the [Vector] at position [index]. Returns a null reference * Returns a [Reference] from the [Vector] at position [index]. Returns a null reference
*
* @param index position in the vector. * @param index position in the vector.
* @return [Reference] for a key or a null [Reference] if not found. * @return [Reference] for a key or a null [Reference] if not found.
*/ */
@@ -597,25 +666,27 @@ public open class Vector internal constructor(
override fun isEmpty(): Boolean = size == 0 override fun isEmpty(): Boolean = size == 0
override fun iterator(): Iterator<Reference> = object : Iterator<Reference> { override fun iterator(): Iterator<Reference> =
object : Iterator<Reference> {
var position = 0 var position = 0
override fun hasNext(): Boolean = position != size override fun hasNext(): Boolean = position != size
override fun next(): Reference = get(position++) override fun next(): Reference = get(position++)
} }
} }
/** /** [TypedVector] represents an array of scalar elements of the same type in the buffer. */
* [TypedVector] represents an array of scalar elements of the same type in the buffer.
*/
public open class TypedVector( public open class TypedVector(
private val elementType: FlexBufferType, private val elementType: FlexBufferType,
buffer: ReadBuffer, buffer: ReadBuffer,
end: Int, end: Int,
byteWidth: ByteWidth byteWidth: ByteWidth,
) : Vector(buffer, end, byteWidth) { ) : Vector(buffer, end, byteWidth) {
/** /**
* Returns a [Reference] from the [TypedVector] at position [index]. Returns a null reference * Returns a [Reference] from the [TypedVector] at position [index]. Returns a null reference
*
* @param index position in the vector. * @param index position in the vector.
* @return [Reference] for a key or a null [Reference] if not found. * @return [Reference] for a key or a null [Reference] if not found.
*/ */
@@ -630,28 +701,24 @@ public open class TypedVector(
return block(childPos, byteWidth) return block(childPos, byteWidth)
} }
internal fun getBoolean(index: Int): Boolean = resolveAt(index) { internal fun getBoolean(index: Int): Boolean =
pos: Int, _: ByteWidth -> buffer.getBoolean(pos) resolveAt(index) { pos: Int, _: ByteWidth -> buffer.getBoolean(pos) }
}
internal fun getInt(index: Int): Long = resolveAt(index) { internal fun getInt(index: Int): Long =
pos: Int, width: ByteWidth -> buffer.readLong(pos, width) resolveAt(index) { pos: Int, width: ByteWidth -> buffer.readLong(pos, width) }
}
internal fun getUInt(index: Int): ULong = resolveAt(index) { internal fun getUInt(index: Int): ULong =
pos: Int, width: ByteWidth -> buffer.readULong(pos, width) resolveAt(index) { pos: Int, width: ByteWidth -> buffer.readULong(pos, width) }
}
internal fun getFloat(index: Int): Double = resolveAt(index) { internal fun getFloat(index: Int): Double =
pos: Int, width: ByteWidth -> buffer.readFloat(pos, width) resolveAt(index) { pos: Int, width: ByteWidth -> buffer.readFloat(pos, width) }
}
} }
/** /** Represents a key element in the buffer. Keys are used to reference objects in a [Map] */
* Represents a key element in the buffer. Keys are
* used to reference objects in a [Map]
*/
public data class Key( public data class Key(
public val buffer: ReadBuffer, public val buffer: ReadBuffer,
public val start: Int, public val start: Int,
public val end: Int = buffer.findFirst(ZeroByte, start) public val end: Int = buffer.findFirst(ZeroByte, start),
) { ) {
val sizeInBytes: Int = end - start val sizeInBytes: Int = end - start
@@ -704,25 +771,21 @@ public data class Key(
} }
} }
override fun toString(): String = if (sizeInBytes > 0) buffer.getString(start, sizeInBytes) else "" override fun toString(): String =
if (sizeInBytes > 0) buffer.getString(start, sizeInBytes) else ""
/** /** Checks whether Key is invalid or not. */
* Checks whether Key is invalid or not.
*/
public fun isInvalid(): Boolean = sizeInBytes <= 0 public fun isInvalid(): Boolean = sizeInBytes <= 0
} }
/** /** A Map class that provide support to access Key-Value data from Flexbuffers. */
* A Map class that provide support to access Key-Value data from Flexbuffers. public class Map internal constructor(buffer: ReadBuffer, end: Int, byteWidth: ByteWidth) :
*/ Sized(buffer, end, byteWidth), kotlin.collections.Map<Key, Reference> {
public class Map
internal constructor(buffer: ReadBuffer, end: Int, byteWidth: ByteWidth):
Sized(buffer, end, byteWidth),
kotlin.collections.Map<Key, Reference> {
// used for accessing the key vector elements // used for accessing the key vector elements
private var keyVectorEnd: Int private var keyVectorEnd: Int
private var keyVectorByteWidth: ByteWidth private var keyVectorByteWidth: ByteWidth
init { init {
val keysOffset = end - (3 * byteWidth) // 3 is number of prefixed fields val keysOffset = end - (3 * byteWidth) // 3 is number of prefixed fields
keyVectorEnd = buffer.indirect(keysOffset, byteWidth) keyVectorEnd = buffer.indirect(keysOffset, byteWidth)
@@ -731,6 +794,7 @@ public class Map
/** /**
* Returns a [Reference] from the [Map] at position [index]. Returns a null reference * Returns a [Reference] from the [Map] at position [index]. Returns a null reference
*
* @param index position in the map * @param index position in the map
* @return [Reference] for a key or a null [Reference] if not found. * @return [Reference] for a key or a null [Reference] if not found.
*/ */
@@ -744,6 +808,7 @@ public class Map
/** /**
* Returns a [Reference] from the [Map] for a given [String] [key]. * Returns a [Reference] from the [Map] for a given [String] [key].
*
* @param key access key to element on map * @param key access key to element on map
* @return [Reference] for a key or a null [Reference] if not found. * @return [Reference] for a key or a null [Reference] if not found.
*/ */
@@ -756,6 +821,7 @@ public class Map
/** /**
* Returns a [Reference] from the [Map] for a given [Key] [key]. * Returns a [Reference] from the [Map] for a given [Key] [key].
*
* @param key access key to element on map * @param key access key to element on map
* @return [Reference] for a key or a null [Reference] if not found. * @return [Reference] for a key or a null [Reference] if not found.
*/ */
@@ -768,6 +834,7 @@ public class Map
/** /**
* Checks whether the map contains a [key]. * Checks whether the map contains a [key].
*
* @param key [String] * @param key [String]
* @return true if key is found in the map, otherwise false. * @return true if key is found in the map, otherwise false.
*/ */
@@ -775,6 +842,7 @@ public class Map
/** /**
* Returns a [Key] for a given position [index] in the [Map]. * Returns a [Key] for a given position [index] in the [Map].
*
* @param index of the key in the map * @param index of the key in the map
* @return a Key for the given index. Out of bounds indexes returns invalid keys. * @return a Key for the given index. Out of bounds indexes returns invalid keys.
*/ */
@@ -785,6 +853,7 @@ public class Map
/** /**
* Returns a [Key] as [String] for a given position [index] in the [Map]. * Returns a [Key] as [String] for a given position [index] in the [Map].
*
* @param index of the key in the map * @param index of the key in the map
* @return a Key for the given index. Out of bounds indexes returns empty string. * @return a Key for the given index. Out of bounds indexes returns empty string.
*/ */
@@ -815,6 +884,7 @@ public class Map
/** /**
* Returns a [Vector] for accessing all values in the [Map]. * Returns a [Vector] for accessing all values in the [Map].
*
* @return [Vector] of values. * @return [Vector] of values.
*/ */
override val values: Collection<Reference> override val values: Collection<Reference>
@@ -822,8 +892,7 @@ public class Map
override fun containsKey(key: Key): Boolean { override fun containsKey(key: Key): Boolean {
for (i in 0 until size) { for (i in 0 until size) {
if (key == keyAt(i)) if (key == keyAt(i)) return true
return true
} }
return false return false
} }
@@ -833,7 +902,10 @@ public class Map
override fun isEmpty(): Boolean = size == 0 override fun isEmpty(): Boolean = size == 0
// Performs a binary search on a key vector and return index of the key in key vector // Performs a binary search on a key vector and return index of the key in key vector
private fun binarySearch(searchedKey: String) = binarySearch { compareCharSequence(it, searchedKey) } private fun binarySearch(searchedKey: String) = binarySearch {
compareCharSequence(it, searchedKey)
}
// Performs a binary search on a key vector and return index of the key in key vector // Performs a binary search on a key vector and return index of the key in key vector
private fun binarySearch(key: Key): Int = binarySearch { compareKeys(it, key.start) } private fun binarySearch(key: Key): Int = binarySearch { compareKeys(it, key.start) }
@@ -891,8 +963,7 @@ public class Map
++bufferPos ++bufferPos
++otherPos ++otherPos
} }
if (bufferPos < limit) if (bufferPos < limit) return 0
return 0
val comparisonBuffer = ByteArray(4) val comparisonBuffer = ByteArray(4)
while (bufferPos < limit) { while (bufferPos < limit) {

Some files were not shown because too many files have changed in this diff Show More