From 8b99bf614c3b91e3fa79e8b225bff7e6f03ca7f2 Mon Sep 17 00:00:00 2001 From: Ben Harper Date: Wed, 1 Apr 2015 16:39:53 +0200 Subject: [PATCH] Add byte slice accessor to Go code Change-Id: I15cc8924d6607bd93068c762fd67e6088cfd9789 --- go/table.go | 7 ++++++- src/idl_gen_go.cpp | 16 ++++++++++++++++ tests/MyGame/Example/Monster.go | 18 ++++++++++++++++++ tests/go_test.go | 8 ++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/go/table.go b/go/table.go index dc5c399..695b92d 100644 --- a/go/table.go +++ b/go/table.go @@ -26,10 +26,15 @@ func (t *Table) Indirect(off UOffsetT) UOffsetT { // String gets a string from data stored inside the flatbuffer. func (t *Table) String(off UOffsetT) string { + return string(t.ByteVector(off)) +} + +// ByteVector gets a byte slice from data stored inside the flatbuffer. +func (t *Table) ByteVector(off UOffsetT) []byte { off += GetUOffsetT(t.Bytes[off:]) start := off + UOffsetT(SizeUOffsetT) length := GetUOffsetT(t.Bytes[off:]) - return string(t.Bytes[start : start+length]) + return t.Bytes[start : start+length] } // VectorLen retrieves the length of the vector whose offset is stored at diff --git a/src/idl_gen_go.cpp b/src/idl_gen_go.cpp index b509439..9cbaf99 100644 --- a/src/idl_gen_go.cpp +++ b/src/idl_gen_go.cpp @@ -144,6 +144,19 @@ static void GetVectorLen(const StructDef &struct_def, code += "\treturn 0\n}\n\n"; } +// Get a [ubyte] vector as a byte slice. +static void GetUByteSlice(const StructDef &struct_def, + const FieldDef &field, + std::string *code_ptr) { + std::string &code = *code_ptr; + + GenReceiver(struct_def, code_ptr); + code += " " + MakeCamel(field.name) + "Bytes("; + code += ") []byte " + OffsetPrefix(field); + code += "\t\treturn rcv._tab.ByteVector(o + rcv._tab.Pos)\n\t}\n"; + code += "\treturn nil\n}\n\n"; +} + // Get the value of a struct's scalar. static void GetScalarFieldOfStruct(const StructDef &struct_def, const FieldDef &field, @@ -480,6 +493,9 @@ static void GenStructAccessor(const StructDef &struct_def, } if (field.value.type.base_type == BASE_TYPE_VECTOR) { GetVectorLen(struct_def, field, code_ptr); + if (field.value.type.element == BASE_TYPE_UCHAR) { + GetUByteSlice(struct_def, field, code_ptr); + } } } diff --git a/tests/MyGame/Example/Monster.go b/tests/MyGame/Example/Monster.go index 1abb902..0ca0c80 100644 --- a/tests/MyGame/Example/Monster.go +++ b/tests/MyGame/Example/Monster.go @@ -75,6 +75,14 @@ func (rcv *Monster) InventoryLength() int { return 0 } +func (rcv *Monster) InventoryBytes() []byte { + o := flatbuffers.UOffsetT(rcv._tab.Offset(14)) + if o != 0 { + return rcv._tab.ByteVector(o + rcv._tab.Pos) + } + return nil +} + func (rcv *Monster) Color() int8 { o := flatbuffers.UOffsetT(rcv._tab.Offset(16)) if o != 0 { @@ -140,7 +148,9 @@ func (rcv *Monster) TestarrayofstringLength() int { } /// an example documentation comment: this will end up in the generated code + /// multiline too + func (rcv *Monster) Testarrayoftables(obj *Monster, j int) bool { o := flatbuffers.UOffsetT(rcv._tab.Offset(26)) if o != 0 { @@ -194,6 +204,14 @@ func (rcv *Monster) TestnestedflatbufferLength() int { return 0 } +func (rcv *Monster) TestnestedflatbufferBytes() []byte { + o := flatbuffers.UOffsetT(rcv._tab.Offset(30)) + if o != 0 { + return rcv._tab.ByteVector(o + rcv._tab.Pos) + } + return nil +} + func (rcv *Monster) Testempty(obj *Stat) *Stat { o := flatbuffers.UOffsetT(rcv._tab.Offset(32)) if o != 0 { diff --git a/tests/go_test.go b/tests/go_test.go index 492b896..08e823c 100644 --- a/tests/go_test.go +++ b/tests/go_test.go @@ -214,6 +214,11 @@ func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string, fail(FailString("monster2.Name()", "Fred", got)) } + inventorySlice := monster.InventoryBytes() + if len(inventorySlice) != monster.InventoryLength() { + fail(FailString("len(monster.InventoryBytes) != monster.InventoryLength", len(inventorySlice), monster.InventoryLength())) + } + if got := monster.InventoryLength(); 5 != got { fail(FailString("monster.InventoryLength", 5, got)) } @@ -222,6 +227,9 @@ func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string, l := monster.InventoryLength() for i := 0; i < l; i++ { v := monster.Inventory(i) + if v != inventorySlice[i] { + fail(FailString("monster inventory slice[i] != Inventory(i)", v, inventorySlice[i])) + } invsum += int(v) } if invsum != 10 { -- 2.7.4