Add byte slice accessor to Go code
authorBen Harper <rogojin@gmail.com>
Wed, 1 Apr 2015 14:39:53 +0000 (16:39 +0200)
committerWouter van Oortmerssen <wvo@google.com>
Mon, 6 Apr 2015 18:44:22 +0000 (11:44 -0700)
Change-Id: I15cc8924d6607bd93068c762fd67e6088cfd9789

go/table.go
src/idl_gen_go.cpp
tests/MyGame/Example/Monster.go
tests/go_test.go

index dc5c399..695b92d 100644 (file)
@@ -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
index b509439..9cbaf99 100644 (file)
@@ -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);
+    }
   }
 }
 
index 1abb902..0ca0c80 100644 (file)
@@ -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 {
index 492b896..08e823c 100644 (file)
@@ -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 {