WIP: Spawn backend plugins v2 (#19835)
* WIP: Spawn backend plugins v2 * Add test for plugin version * Fix support for SDK plugins Co-authored-by: Kyle Brandt <kyle@kbrandt.com> Co-authored-by: Marcus Olsson <olsson.e.marcus@gmail.com> Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com> * WIP: Draft PR for fork of V2 sdk / bi-directional support (#19890) * temporary use export-datasource-plugin branch of grafana-plugin-sdk * fix failing test * remove debug (spew) lines * misc cleanup * add expressions feature toggle * use latest grafana-plugin-sdk-go
This commit is contained in:
committed by
Marcus Efraimsson
co-authored by
Kyle Brandt
Marcus Olsson
Marcus Efraimsson
parent
b0198e7c9c
commit
fc08c26025
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2014 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go",
|
||||
srcs = [
|
||||
"builder.go",
|
||||
"doc.go",
|
||||
"encode.go",
|
||||
"grpc.go",
|
||||
"lib.go",
|
||||
"sizes.go",
|
||||
"struct.go",
|
||||
"table.go",
|
||||
],
|
||||
importpath = "github.com/google/flatbuffers/go",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
+771
@@ -0,0 +1,771 @@
|
||||
package flatbuffers
|
||||
|
||||
// Builder is a state machine for creating FlatBuffer objects.
|
||||
// Use a Builder to construct object(s) starting from leaf nodes.
|
||||
//
|
||||
// A Builder constructs byte buffers in a last-first manner for simplicity and
|
||||
// performance.
|
||||
type Builder struct {
|
||||
// `Bytes` gives raw access to the buffer. Most users will want to use
|
||||
// FinishedBytes() instead.
|
||||
Bytes []byte
|
||||
|
||||
minalign int
|
||||
vtable []UOffsetT
|
||||
objectEnd UOffsetT
|
||||
vtables []UOffsetT
|
||||
head UOffsetT
|
||||
nested bool
|
||||
finished bool
|
||||
}
|
||||
|
||||
const fileIdentifierLength = 4
|
||||
|
||||
// NewBuilder initializes a Builder of size `initial_size`.
|
||||
// The internal buffer is grown as needed.
|
||||
func NewBuilder(initialSize int) *Builder {
|
||||
if initialSize <= 0 {
|
||||
initialSize = 0
|
||||
}
|
||||
|
||||
b := &Builder{}
|
||||
b.Bytes = make([]byte, initialSize)
|
||||
b.head = UOffsetT(initialSize)
|
||||
b.minalign = 1
|
||||
b.vtables = make([]UOffsetT, 0, 16) // sensible default capacity
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// Reset truncates the underlying Builder buffer, facilitating alloc-free
|
||||
// reuse of a Builder. It also resets bookkeeping data.
|
||||
func (b *Builder) Reset() {
|
||||
if b.Bytes != nil {
|
||||
b.Bytes = b.Bytes[:cap(b.Bytes)]
|
||||
}
|
||||
|
||||
if b.vtables != nil {
|
||||
b.vtables = b.vtables[:0]
|
||||
}
|
||||
|
||||
if b.vtable != nil {
|
||||
b.vtable = b.vtable[:0]
|
||||
}
|
||||
|
||||
b.head = UOffsetT(len(b.Bytes))
|
||||
b.minalign = 1
|
||||
b.nested = false
|
||||
b.finished = false
|
||||
}
|
||||
|
||||
// FinishedBytes returns a pointer to the written data in the byte buffer.
|
||||
// Panics if the builder is not in a finished state (which is caused by calling
|
||||
// `Finish()`).
|
||||
func (b *Builder) FinishedBytes() []byte {
|
||||
b.assertFinished()
|
||||
return b.Bytes[b.Head():]
|
||||
}
|
||||
|
||||
// StartObject initializes bookkeeping for writing a new object.
|
||||
func (b *Builder) StartObject(numfields int) {
|
||||
b.assertNotNested()
|
||||
b.nested = true
|
||||
|
||||
// use 32-bit offsets so that arithmetic doesn't overflow.
|
||||
if cap(b.vtable) < numfields || b.vtable == nil {
|
||||
b.vtable = make([]UOffsetT, numfields)
|
||||
} else {
|
||||
b.vtable = b.vtable[:numfields]
|
||||
for i := 0; i < len(b.vtable); i++ {
|
||||
b.vtable[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
b.objectEnd = b.Offset()
|
||||
}
|
||||
|
||||
// WriteVtable serializes the vtable for the current object, if applicable.
|
||||
//
|
||||
// Before writing out the vtable, this checks pre-existing vtables for equality
|
||||
// to this one. If an equal vtable is found, point the object to the existing
|
||||
// vtable and return.
|
||||
//
|
||||
// Because vtable values are sensitive to alignment of object data, not all
|
||||
// logically-equal vtables will be deduplicated.
|
||||
//
|
||||
// A vtable has the following format:
|
||||
// <VOffsetT: size of the vtable in bytes, including this value>
|
||||
// <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
|
||||
// the schema for this type. Includes deprecated fields.
|
||||
// Thus, a vtable is made of 2 + N elements, each SizeVOffsetT bytes wide.
|
||||
//
|
||||
// An object has the following format:
|
||||
// <SOffsetT: offset to this object's vtable (may be negative)>
|
||||
// <byte: data>+
|
||||
func (b *Builder) WriteVtable() (n UOffsetT) {
|
||||
// Prepend a zero scalar to the object. Later in this function we'll
|
||||
// write an offset here that points to the object's vtable:
|
||||
b.PrependSOffsetT(0)
|
||||
|
||||
objectOffset := b.Offset()
|
||||
existingVtable := UOffsetT(0)
|
||||
|
||||
// Trim vtable of trailing zeroes.
|
||||
i := len(b.vtable) - 1
|
||||
for ; i >= 0 && b.vtable[i] == 0; i-- {
|
||||
}
|
||||
b.vtable = b.vtable[:i+1]
|
||||
|
||||
// Search backwards through existing vtables, because similar vtables
|
||||
// are likely to have been recently appended. See
|
||||
// BenchmarkVtableDeduplication for a case in which this heuristic
|
||||
// saves about 30% of the time used in writing objects with duplicate
|
||||
// tables.
|
||||
for i := len(b.vtables) - 1; i >= 0; i-- {
|
||||
// Find the other vtable, which is associated with `i`:
|
||||
vt2Offset := b.vtables[i]
|
||||
vt2Start := len(b.Bytes) - int(vt2Offset)
|
||||
vt2Len := GetVOffsetT(b.Bytes[vt2Start:])
|
||||
|
||||
metadata := VtableMetadataFields * SizeVOffsetT
|
||||
vt2End := vt2Start + int(vt2Len)
|
||||
vt2 := b.Bytes[vt2Start+metadata : vt2End]
|
||||
|
||||
// Compare the other vtable to the one under consideration.
|
||||
// If they are equal, store the offset and break:
|
||||
if vtableEqual(b.vtable, objectOffset, vt2) {
|
||||
existingVtable = vt2Offset
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if existingVtable == 0 {
|
||||
// Did not find a vtable, so write this one to the buffer.
|
||||
|
||||
// Write out the current vtable in reverse , because
|
||||
// serialization occurs in last-first order:
|
||||
for i := len(b.vtable) - 1; i >= 0; i-- {
|
||||
var off UOffsetT
|
||||
if b.vtable[i] != 0 {
|
||||
// Forward reference to field;
|
||||
// use 32bit number to assert no overflow:
|
||||
off = objectOffset - b.vtable[i]
|
||||
}
|
||||
|
||||
b.PrependVOffsetT(VOffsetT(off))
|
||||
}
|
||||
|
||||
// The two metadata fields are written last.
|
||||
|
||||
// First, store the object bytesize:
|
||||
objectSize := objectOffset - b.objectEnd
|
||||
b.PrependVOffsetT(VOffsetT(objectSize))
|
||||
|
||||
// Second, store the vtable bytesize:
|
||||
vBytes := (len(b.vtable) + VtableMetadataFields) * SizeVOffsetT
|
||||
b.PrependVOffsetT(VOffsetT(vBytes))
|
||||
|
||||
// Next, write the offset to the new vtable in the
|
||||
// already-allocated SOffsetT at the beginning of this object:
|
||||
objectStart := SOffsetT(len(b.Bytes)) - SOffsetT(objectOffset)
|
||||
WriteSOffsetT(b.Bytes[objectStart:],
|
||||
SOffsetT(b.Offset())-SOffsetT(objectOffset))
|
||||
|
||||
// Finally, store this vtable in memory for future
|
||||
// deduplication:
|
||||
b.vtables = append(b.vtables, b.Offset())
|
||||
} else {
|
||||
// Found a duplicate vtable.
|
||||
|
||||
objectStart := SOffsetT(len(b.Bytes)) - SOffsetT(objectOffset)
|
||||
b.head = UOffsetT(objectStart)
|
||||
|
||||
// Write the offset to the found vtable in the
|
||||
// already-allocated SOffsetT at the beginning of this object:
|
||||
WriteSOffsetT(b.Bytes[b.head:],
|
||||
SOffsetT(existingVtable)-SOffsetT(objectOffset))
|
||||
}
|
||||
|
||||
b.vtable = b.vtable[:0]
|
||||
return objectOffset
|
||||
}
|
||||
|
||||
// EndObject writes data necessary to finish object construction.
|
||||
func (b *Builder) EndObject() UOffsetT {
|
||||
b.assertNested()
|
||||
n := b.WriteVtable()
|
||||
b.nested = false
|
||||
return n
|
||||
}
|
||||
|
||||
// Doubles the size of the byteslice, and copies the old data towards the
|
||||
// end of the new byteslice (since we build the buffer backwards).
|
||||
func (b *Builder) growByteBuffer() {
|
||||
if (int64(len(b.Bytes)) & int64(0xC0000000)) != 0 {
|
||||
panic("cannot grow buffer beyond 2 gigabytes")
|
||||
}
|
||||
newLen := len(b.Bytes) * 2
|
||||
if newLen == 0 {
|
||||
newLen = 1
|
||||
}
|
||||
|
||||
if cap(b.Bytes) >= newLen {
|
||||
b.Bytes = b.Bytes[:newLen]
|
||||
} else {
|
||||
extension := make([]byte, newLen-len(b.Bytes))
|
||||
b.Bytes = append(b.Bytes, extension...)
|
||||
}
|
||||
|
||||
middle := newLen / 2
|
||||
copy(b.Bytes[middle:], b.Bytes[:middle])
|
||||
}
|
||||
|
||||
// Head gives the start of useful data in the underlying byte buffer.
|
||||
// Note: unlike other functions, this value is interpreted as from the left.
|
||||
func (b *Builder) Head() UOffsetT {
|
||||
return b.head
|
||||
}
|
||||
|
||||
// Offset relative to the end of the buffer.
|
||||
func (b *Builder) Offset() UOffsetT {
|
||||
return UOffsetT(len(b.Bytes)) - b.head
|
||||
}
|
||||
|
||||
// Pad places zeros at the current offset.
|
||||
func (b *Builder) Pad(n int) {
|
||||
for i := 0; i < n; i++ {
|
||||
b.PlaceByte(0)
|
||||
}
|
||||
}
|
||||
|
||||
// Prep prepares to write an element of `size` after `additional_bytes`
|
||||
// have been written, e.g. if you write a string, you need to align such
|
||||
// the int length field is aligned to SizeInt32, and the string data follows it
|
||||
// directly.
|
||||
// If all you need to do is align, `additionalBytes` will be 0.
|
||||
func (b *Builder) Prep(size, additionalBytes int) {
|
||||
// Track the biggest thing we've ever aligned to.
|
||||
if size > b.minalign {
|
||||
b.minalign = size
|
||||
}
|
||||
// Find the amount of alignment needed such that `size` is properly
|
||||
// aligned after `additionalBytes`:
|
||||
alignSize := (^(len(b.Bytes) - int(b.Head()) + additionalBytes)) + 1
|
||||
alignSize &= (size - 1)
|
||||
|
||||
// Reallocate the buffer if needed:
|
||||
for int(b.head) <= alignSize+size+additionalBytes {
|
||||
oldBufSize := len(b.Bytes)
|
||||
b.growByteBuffer()
|
||||
b.head += UOffsetT(len(b.Bytes) - oldBufSize)
|
||||
}
|
||||
b.Pad(alignSize)
|
||||
}
|
||||
|
||||
// PrependSOffsetT prepends an SOffsetT, relative to where it will be written.
|
||||
func (b *Builder) PrependSOffsetT(off SOffsetT) {
|
||||
b.Prep(SizeSOffsetT, 0) // Ensure alignment is already done.
|
||||
if !(UOffsetT(off) <= b.Offset()) {
|
||||
panic("unreachable: off <= b.Offset()")
|
||||
}
|
||||
off2 := SOffsetT(b.Offset()) - off + SOffsetT(SizeSOffsetT)
|
||||
b.PlaceSOffsetT(off2)
|
||||
}
|
||||
|
||||
// PrependUOffsetT prepends an UOffsetT, relative to where it will be written.
|
||||
func (b *Builder) PrependUOffsetT(off UOffsetT) {
|
||||
b.Prep(SizeUOffsetT, 0) // Ensure alignment is already done.
|
||||
if !(off <= b.Offset()) {
|
||||
panic("unreachable: off <= b.Offset()")
|
||||
}
|
||||
off2 := b.Offset() - off + UOffsetT(SizeUOffsetT)
|
||||
b.PlaceUOffsetT(off2)
|
||||
}
|
||||
|
||||
// StartVector initializes bookkeeping for writing a new vector.
|
||||
//
|
||||
// A vector has the following format:
|
||||
// <UOffsetT: number of elements in this vector>
|
||||
// <T: data>+, where T is the type of elements of this vector.
|
||||
func (b *Builder) StartVector(elemSize, numElems, alignment int) UOffsetT {
|
||||
b.assertNotNested()
|
||||
b.nested = true
|
||||
b.Prep(SizeUint32, elemSize*numElems)
|
||||
b.Prep(alignment, elemSize*numElems) // Just in case alignment > int.
|
||||
return b.Offset()
|
||||
}
|
||||
|
||||
// EndVector writes data necessary to finish vector construction.
|
||||
func (b *Builder) EndVector(vectorNumElems int) UOffsetT {
|
||||
b.assertNested()
|
||||
|
||||
// we already made space for this, so write without PrependUint32
|
||||
b.PlaceUOffsetT(UOffsetT(vectorNumElems))
|
||||
|
||||
b.nested = false
|
||||
return b.Offset()
|
||||
}
|
||||
|
||||
// CreateString writes a null-terminated string as a vector.
|
||||
func (b *Builder) CreateString(s string) UOffsetT {
|
||||
b.assertNotNested()
|
||||
b.nested = true
|
||||
|
||||
b.Prep(int(SizeUOffsetT), (len(s)+1)*SizeByte)
|
||||
b.PlaceByte(0)
|
||||
|
||||
l := UOffsetT(len(s))
|
||||
|
||||
b.head -= l
|
||||
copy(b.Bytes[b.head:b.head+l], s)
|
||||
|
||||
return b.EndVector(len(s))
|
||||
}
|
||||
|
||||
// CreateByteString writes a byte slice as a string (null-terminated).
|
||||
func (b *Builder) CreateByteString(s []byte) UOffsetT {
|
||||
b.assertNotNested()
|
||||
b.nested = true
|
||||
|
||||
b.Prep(int(SizeUOffsetT), (len(s)+1)*SizeByte)
|
||||
b.PlaceByte(0)
|
||||
|
||||
l := UOffsetT(len(s))
|
||||
|
||||
b.head -= l
|
||||
copy(b.Bytes[b.head:b.head+l], s)
|
||||
|
||||
return b.EndVector(len(s))
|
||||
}
|
||||
|
||||
// CreateByteVector writes a ubyte vector
|
||||
func (b *Builder) CreateByteVector(v []byte) UOffsetT {
|
||||
b.assertNotNested()
|
||||
b.nested = true
|
||||
|
||||
b.Prep(int(SizeUOffsetT), len(v)*SizeByte)
|
||||
|
||||
l := UOffsetT(len(v))
|
||||
|
||||
b.head -= l
|
||||
copy(b.Bytes[b.head:b.head+l], v)
|
||||
|
||||
return b.EndVector(len(v))
|
||||
}
|
||||
|
||||
func (b *Builder) assertNested() {
|
||||
// If you get this assert, you're in an object while trying to write
|
||||
// data that belongs outside of an object.
|
||||
// To fix this, write non-inline data (like vectors) before creating
|
||||
// objects.
|
||||
if !b.nested {
|
||||
panic("Incorrect creation order: must be inside object.")
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Builder) assertNotNested() {
|
||||
// If you hit this, you're trying to construct a Table/Vector/String
|
||||
// during the construction of its parent table (between the MyTableBuilder
|
||||
// and builder.Finish()).
|
||||
// Move the creation of these sub-objects to above the MyTableBuilder to
|
||||
// not get this assert.
|
||||
// Ignoring this assert may appear to work in simple cases, but the reason
|
||||
// it is here is that storing objects in-line may cause vtable offsets
|
||||
// to not fit anymore. It also leads to vtable duplication.
|
||||
if b.nested {
|
||||
panic("Incorrect creation order: object must not be nested.")
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Builder) assertFinished() {
|
||||
// If you get this assert, you're attempting to get access a buffer
|
||||
// which hasn't been finished yet. Be sure to call builder.Finish()
|
||||
// with your root table.
|
||||
// If you really need to access an unfinished buffer, use the Bytes
|
||||
// buffer directly.
|
||||
if !b.finished {
|
||||
panic("Incorrect use of FinishedBytes(): must call 'Finish' first.")
|
||||
}
|
||||
}
|
||||
|
||||
// PrependBoolSlot prepends a bool onto the object at vtable slot `o`.
|
||||
// If value `x` equals default `d`, then the slot will be set to zero and no
|
||||
// other data will be written.
|
||||
func (b *Builder) PrependBoolSlot(o int, x, d bool) {
|
||||
val := byte(0)
|
||||
if x {
|
||||
val = 1
|
||||
}
|
||||
def := byte(0)
|
||||
if d {
|
||||
def = 1
|
||||
}
|
||||
b.PrependByteSlot(o, val, def)
|
||||
}
|
||||
|
||||
// PrependByteSlot prepends a byte onto the object at vtable slot `o`.
|
||||
// If value `x` equals default `d`, then the slot will be set to zero and no
|
||||
// other data will be written.
|
||||
func (b *Builder) PrependByteSlot(o int, x, d byte) {
|
||||
if x != d {
|
||||
b.PrependByte(x)
|
||||
b.Slot(o)
|
||||
}
|
||||
}
|
||||
|
||||
// PrependUint8Slot prepends a uint8 onto the object at vtable slot `o`.
|
||||
// If value `x` equals default `d`, then the slot will be set to zero and no
|
||||
// other data will be written.
|
||||
func (b *Builder) PrependUint8Slot(o int, x, d uint8) {
|
||||
if x != d {
|
||||
b.PrependUint8(x)
|
||||
b.Slot(o)
|
||||
}
|
||||
}
|
||||
|
||||
// PrependUint16Slot prepends a uint16 onto the object at vtable slot `o`.
|
||||
// If value `x` equals default `d`, then the slot will be set to zero and no
|
||||
// other data will be written.
|
||||
func (b *Builder) PrependUint16Slot(o int, x, d uint16) {
|
||||
if x != d {
|
||||
b.PrependUint16(x)
|
||||
b.Slot(o)
|
||||
}
|
||||
}
|
||||
|
||||
// PrependUint32Slot prepends a uint32 onto the object at vtable slot `o`.
|
||||
// If value `x` equals default `d`, then the slot will be set to zero and no
|
||||
// other data will be written.
|
||||
func (b *Builder) PrependUint32Slot(o int, x, d uint32) {
|
||||
if x != d {
|
||||
b.PrependUint32(x)
|
||||
b.Slot(o)
|
||||
}
|
||||
}
|
||||
|
||||
// PrependUint64Slot prepends a uint64 onto the object at vtable slot `o`.
|
||||
// If value `x` equals default `d`, then the slot will be set to zero and no
|
||||
// other data will be written.
|
||||
func (b *Builder) PrependUint64Slot(o int, x, d uint64) {
|
||||
if x != d {
|
||||
b.PrependUint64(x)
|
||||
b.Slot(o)
|
||||
}
|
||||
}
|
||||
|
||||
// PrependInt8Slot prepends a int8 onto the object at vtable slot `o`.
|
||||
// If value `x` equals default `d`, then the slot will be set to zero and no
|
||||
// other data will be written.
|
||||
func (b *Builder) PrependInt8Slot(o int, x, d int8) {
|
||||
if x != d {
|
||||
b.PrependInt8(x)
|
||||
b.Slot(o)
|
||||
}
|
||||
}
|
||||
|
||||
// PrependInt16Slot prepends a int16 onto the object at vtable slot `o`.
|
||||
// If value `x` equals default `d`, then the slot will be set to zero and no
|
||||
// other data will be written.
|
||||
func (b *Builder) PrependInt16Slot(o int, x, d int16) {
|
||||
if x != d {
|
||||
b.PrependInt16(x)
|
||||
b.Slot(o)
|
||||
}
|
||||
}
|
||||
|
||||
// PrependInt32Slot prepends a int32 onto the object at vtable slot `o`.
|
||||
// If value `x` equals default `d`, then the slot will be set to zero and no
|
||||
// other data will be written.
|
||||
func (b *Builder) PrependInt32Slot(o int, x, d int32) {
|
||||
if x != d {
|
||||
b.PrependInt32(x)
|
||||
b.Slot(o)
|
||||
}
|
||||
}
|
||||
|
||||
// PrependInt64Slot prepends a int64 onto the object at vtable slot `o`.
|
||||
// If value `x` equals default `d`, then the slot will be set to zero and no
|
||||
// other data will be written.
|
||||
func (b *Builder) PrependInt64Slot(o int, x, d int64) {
|
||||
if x != d {
|
||||
b.PrependInt64(x)
|
||||
b.Slot(o)
|
||||
}
|
||||
}
|
||||
|
||||
// PrependFloat32Slot prepends a float32 onto the object at vtable slot `o`.
|
||||
// If value `x` equals default `d`, then the slot will be set to zero and no
|
||||
// other data will be written.
|
||||
func (b *Builder) PrependFloat32Slot(o int, x, d float32) {
|
||||
if x != d {
|
||||
b.PrependFloat32(x)
|
||||
b.Slot(o)
|
||||
}
|
||||
}
|
||||
|
||||
// PrependFloat64Slot prepends a float64 onto the object at vtable slot `o`.
|
||||
// If value `x` equals default `d`, then the slot will be set to zero and no
|
||||
// other data will be written.
|
||||
func (b *Builder) PrependFloat64Slot(o int, x, d float64) {
|
||||
if x != d {
|
||||
b.PrependFloat64(x)
|
||||
b.Slot(o)
|
||||
}
|
||||
}
|
||||
|
||||
// PrependUOffsetTSlot prepends an UOffsetT onto the object at vtable slot `o`.
|
||||
// If value `x` equals default `d`, then the slot will be set to zero and no
|
||||
// other data will be written.
|
||||
func (b *Builder) PrependUOffsetTSlot(o int, x, d UOffsetT) {
|
||||
if x != d {
|
||||
b.PrependUOffsetT(x)
|
||||
b.Slot(o)
|
||||
}
|
||||
}
|
||||
|
||||
// PrependStructSlot prepends a struct onto the object at vtable slot `o`.
|
||||
// Structs are stored inline, so nothing additional is being added.
|
||||
// In generated code, `d` is always 0.
|
||||
func (b *Builder) PrependStructSlot(voffset int, x, d UOffsetT) {
|
||||
if x != d {
|
||||
b.assertNested()
|
||||
if x != b.Offset() {
|
||||
panic("inline data write outside of object")
|
||||
}
|
||||
b.Slot(voffset)
|
||||
}
|
||||
}
|
||||
|
||||
// Slot sets the vtable key `voffset` to the current location in the buffer.
|
||||
func (b *Builder) Slot(slotnum int) {
|
||||
b.vtable[slotnum] = UOffsetT(b.Offset())
|
||||
}
|
||||
|
||||
// FinishWithFileIdentifier finalizes a buffer, pointing to the given `rootTable`.
|
||||
// as well as applys a file identifier
|
||||
func (b *Builder) FinishWithFileIdentifier(rootTable UOffsetT, fid []byte) {
|
||||
if fid == nil || len(fid) != fileIdentifierLength {
|
||||
panic("incorrect file identifier length")
|
||||
}
|
||||
// In order to add a file identifier to the flatbuffer message, we need
|
||||
// to prepare an alignment and file identifier length
|
||||
b.Prep(b.minalign, SizeInt32+fileIdentifierLength)
|
||||
for i := fileIdentifierLength - 1; i >= 0; i-- {
|
||||
// place the file identifier
|
||||
b.PlaceByte(fid[i])
|
||||
}
|
||||
// finish
|
||||
b.Finish(rootTable)
|
||||
}
|
||||
|
||||
// Finish finalizes a buffer, pointing to the given `rootTable`.
|
||||
func (b *Builder) Finish(rootTable UOffsetT) {
|
||||
b.assertNotNested()
|
||||
b.Prep(b.minalign, SizeUOffsetT)
|
||||
b.PrependUOffsetT(rootTable)
|
||||
b.finished = true
|
||||
}
|
||||
|
||||
// vtableEqual compares an unwritten vtable to a written vtable.
|
||||
func vtableEqual(a []UOffsetT, objectStart UOffsetT, b []byte) bool {
|
||||
if len(a)*SizeVOffsetT != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < len(a); i++ {
|
||||
x := GetVOffsetT(b[i*SizeVOffsetT : (i+1)*SizeVOffsetT])
|
||||
|
||||
// Skip vtable entries that indicate a default value.
|
||||
if x == 0 && a[i] == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
y := SOffsetT(objectStart) - SOffsetT(a[i])
|
||||
if SOffsetT(x) != y {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// PrependBool prepends a bool to the Builder buffer.
|
||||
// Aligns and checks for space.
|
||||
func (b *Builder) PrependBool(x bool) {
|
||||
b.Prep(SizeBool, 0)
|
||||
b.PlaceBool(x)
|
||||
}
|
||||
|
||||
// PrependUint8 prepends a uint8 to the Builder buffer.
|
||||
// Aligns and checks for space.
|
||||
func (b *Builder) PrependUint8(x uint8) {
|
||||
b.Prep(SizeUint8, 0)
|
||||
b.PlaceUint8(x)
|
||||
}
|
||||
|
||||
// PrependUint16 prepends a uint16 to the Builder buffer.
|
||||
// Aligns and checks for space.
|
||||
func (b *Builder) PrependUint16(x uint16) {
|
||||
b.Prep(SizeUint16, 0)
|
||||
b.PlaceUint16(x)
|
||||
}
|
||||
|
||||
// PrependUint32 prepends a uint32 to the Builder buffer.
|
||||
// Aligns and checks for space.
|
||||
func (b *Builder) PrependUint32(x uint32) {
|
||||
b.Prep(SizeUint32, 0)
|
||||
b.PlaceUint32(x)
|
||||
}
|
||||
|
||||
// PrependUint64 prepends a uint64 to the Builder buffer.
|
||||
// Aligns and checks for space.
|
||||
func (b *Builder) PrependUint64(x uint64) {
|
||||
b.Prep(SizeUint64, 0)
|
||||
b.PlaceUint64(x)
|
||||
}
|
||||
|
||||
// PrependInt8 prepends a int8 to the Builder buffer.
|
||||
// Aligns and checks for space.
|
||||
func (b *Builder) PrependInt8(x int8) {
|
||||
b.Prep(SizeInt8, 0)
|
||||
b.PlaceInt8(x)
|
||||
}
|
||||
|
||||
// PrependInt16 prepends a int16 to the Builder buffer.
|
||||
// Aligns and checks for space.
|
||||
func (b *Builder) PrependInt16(x int16) {
|
||||
b.Prep(SizeInt16, 0)
|
||||
b.PlaceInt16(x)
|
||||
}
|
||||
|
||||
// PrependInt32 prepends a int32 to the Builder buffer.
|
||||
// Aligns and checks for space.
|
||||
func (b *Builder) PrependInt32(x int32) {
|
||||
b.Prep(SizeInt32, 0)
|
||||
b.PlaceInt32(x)
|
||||
}
|
||||
|
||||
// PrependInt64 prepends a int64 to the Builder buffer.
|
||||
// Aligns and checks for space.
|
||||
func (b *Builder) PrependInt64(x int64) {
|
||||
b.Prep(SizeInt64, 0)
|
||||
b.PlaceInt64(x)
|
||||
}
|
||||
|
||||
// PrependFloat32 prepends a float32 to the Builder buffer.
|
||||
// Aligns and checks for space.
|
||||
func (b *Builder) PrependFloat32(x float32) {
|
||||
b.Prep(SizeFloat32, 0)
|
||||
b.PlaceFloat32(x)
|
||||
}
|
||||
|
||||
// PrependFloat64 prepends a float64 to the Builder buffer.
|
||||
// Aligns and checks for space.
|
||||
func (b *Builder) PrependFloat64(x float64) {
|
||||
b.Prep(SizeFloat64, 0)
|
||||
b.PlaceFloat64(x)
|
||||
}
|
||||
|
||||
// PrependByte prepends a byte to the Builder buffer.
|
||||
// Aligns and checks for space.
|
||||
func (b *Builder) PrependByte(x byte) {
|
||||
b.Prep(SizeByte, 0)
|
||||
b.PlaceByte(x)
|
||||
}
|
||||
|
||||
// PrependVOffsetT prepends a VOffsetT to the Builder buffer.
|
||||
// Aligns and checks for space.
|
||||
func (b *Builder) PrependVOffsetT(x VOffsetT) {
|
||||
b.Prep(SizeVOffsetT, 0)
|
||||
b.PlaceVOffsetT(x)
|
||||
}
|
||||
|
||||
// PlaceBool prepends a bool to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceBool(x bool) {
|
||||
b.head -= UOffsetT(SizeBool)
|
||||
WriteBool(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceUint8 prepends a uint8 to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceUint8(x uint8) {
|
||||
b.head -= UOffsetT(SizeUint8)
|
||||
WriteUint8(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceUint16 prepends a uint16 to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceUint16(x uint16) {
|
||||
b.head -= UOffsetT(SizeUint16)
|
||||
WriteUint16(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceUint32 prepends a uint32 to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceUint32(x uint32) {
|
||||
b.head -= UOffsetT(SizeUint32)
|
||||
WriteUint32(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceUint64 prepends a uint64 to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceUint64(x uint64) {
|
||||
b.head -= UOffsetT(SizeUint64)
|
||||
WriteUint64(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceInt8 prepends a int8 to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceInt8(x int8) {
|
||||
b.head -= UOffsetT(SizeInt8)
|
||||
WriteInt8(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceInt16 prepends a int16 to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceInt16(x int16) {
|
||||
b.head -= UOffsetT(SizeInt16)
|
||||
WriteInt16(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceInt32 prepends a int32 to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceInt32(x int32) {
|
||||
b.head -= UOffsetT(SizeInt32)
|
||||
WriteInt32(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceInt64 prepends a int64 to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceInt64(x int64) {
|
||||
b.head -= UOffsetT(SizeInt64)
|
||||
WriteInt64(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceFloat32 prepends a float32 to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceFloat32(x float32) {
|
||||
b.head -= UOffsetT(SizeFloat32)
|
||||
WriteFloat32(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceFloat64 prepends a float64 to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceFloat64(x float64) {
|
||||
b.head -= UOffsetT(SizeFloat64)
|
||||
WriteFloat64(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceByte prepends a byte to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceByte(x byte) {
|
||||
b.head -= UOffsetT(SizeByte)
|
||||
WriteByte(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceVOffsetT prepends a VOffsetT to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceVOffsetT(x VOffsetT) {
|
||||
b.head -= UOffsetT(SizeVOffsetT)
|
||||
WriteVOffsetT(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceSOffsetT prepends a SOffsetT to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceSOffsetT(x SOffsetT) {
|
||||
b.head -= UOffsetT(SizeSOffsetT)
|
||||
WriteSOffsetT(b.Bytes[b.head:], x)
|
||||
}
|
||||
|
||||
// PlaceUOffsetT prepends a UOffsetT to the Builder, without checking for space.
|
||||
func (b *Builder) PlaceUOffsetT(x UOffsetT) {
|
||||
b.head -= UOffsetT(SizeUOffsetT)
|
||||
WriteUOffsetT(b.Bytes[b.head:], x)
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
// Package flatbuffers provides facilities to read and write flatbuffers
|
||||
// objects.
|
||||
package flatbuffers
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
package flatbuffers
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
type (
|
||||
// A SOffsetT stores a signed offset into arbitrary data.
|
||||
SOffsetT int32
|
||||
// A UOffsetT stores an unsigned offset into vector data.
|
||||
UOffsetT uint32
|
||||
// A VOffsetT stores an unsigned offset in a vtable.
|
||||
VOffsetT uint16
|
||||
)
|
||||
|
||||
const (
|
||||
// VtableMetadataFields is the count of metadata fields in each vtable.
|
||||
VtableMetadataFields = 2
|
||||
)
|
||||
|
||||
// GetByte decodes a little-endian byte from a byte slice.
|
||||
func GetByte(buf []byte) byte {
|
||||
return byte(GetUint8(buf))
|
||||
}
|
||||
|
||||
// GetBool decodes a little-endian bool from a byte slice.
|
||||
func GetBool(buf []byte) bool {
|
||||
return buf[0] == 1
|
||||
}
|
||||
|
||||
// GetUint8 decodes a little-endian uint8 from a byte slice.
|
||||
func GetUint8(buf []byte) (n uint8) {
|
||||
n = uint8(buf[0])
|
||||
return
|
||||
}
|
||||
|
||||
// GetUint16 decodes a little-endian uint16 from a byte slice.
|
||||
func GetUint16(buf []byte) (n uint16) {
|
||||
_ = buf[1] // Force one bounds check. See: golang.org/issue/14808
|
||||
n |= uint16(buf[0])
|
||||
n |= uint16(buf[1]) << 8
|
||||
return
|
||||
}
|
||||
|
||||
// GetUint32 decodes a little-endian uint32 from a byte slice.
|
||||
func GetUint32(buf []byte) (n uint32) {
|
||||
_ = buf[3] // Force one bounds check. See: golang.org/issue/14808
|
||||
n |= uint32(buf[0])
|
||||
n |= uint32(buf[1]) << 8
|
||||
n |= uint32(buf[2]) << 16
|
||||
n |= uint32(buf[3]) << 24
|
||||
return
|
||||
}
|
||||
|
||||
// GetUint64 decodes a little-endian uint64 from a byte slice.
|
||||
func GetUint64(buf []byte) (n uint64) {
|
||||
_ = buf[7] // Force one bounds check. See: golang.org/issue/14808
|
||||
n |= uint64(buf[0])
|
||||
n |= uint64(buf[1]) << 8
|
||||
n |= uint64(buf[2]) << 16
|
||||
n |= uint64(buf[3]) << 24
|
||||
n |= uint64(buf[4]) << 32
|
||||
n |= uint64(buf[5]) << 40
|
||||
n |= uint64(buf[6]) << 48
|
||||
n |= uint64(buf[7]) << 56
|
||||
return
|
||||
}
|
||||
|
||||
// GetInt8 decodes a little-endian int8 from a byte slice.
|
||||
func GetInt8(buf []byte) (n int8) {
|
||||
n = int8(buf[0])
|
||||
return
|
||||
}
|
||||
|
||||
// GetInt16 decodes a little-endian int16 from a byte slice.
|
||||
func GetInt16(buf []byte) (n int16) {
|
||||
_ = buf[1] // Force one bounds check. See: golang.org/issue/14808
|
||||
n |= int16(buf[0])
|
||||
n |= int16(buf[1]) << 8
|
||||
return
|
||||
}
|
||||
|
||||
// GetInt32 decodes a little-endian int32 from a byte slice.
|
||||
func GetInt32(buf []byte) (n int32) {
|
||||
_ = buf[3] // Force one bounds check. See: golang.org/issue/14808
|
||||
n |= int32(buf[0])
|
||||
n |= int32(buf[1]) << 8
|
||||
n |= int32(buf[2]) << 16
|
||||
n |= int32(buf[3]) << 24
|
||||
return
|
||||
}
|
||||
|
||||
// GetInt64 decodes a little-endian int64 from a byte slice.
|
||||
func GetInt64(buf []byte) (n int64) {
|
||||
_ = buf[7] // Force one bounds check. See: golang.org/issue/14808
|
||||
n |= int64(buf[0])
|
||||
n |= int64(buf[1]) << 8
|
||||
n |= int64(buf[2]) << 16
|
||||
n |= int64(buf[3]) << 24
|
||||
n |= int64(buf[4]) << 32
|
||||
n |= int64(buf[5]) << 40
|
||||
n |= int64(buf[6]) << 48
|
||||
n |= int64(buf[7]) << 56
|
||||
return
|
||||
}
|
||||
|
||||
// GetFloat32 decodes a little-endian float32 from a byte slice.
|
||||
func GetFloat32(buf []byte) float32 {
|
||||
x := GetUint32(buf)
|
||||
return math.Float32frombits(x)
|
||||
}
|
||||
|
||||
// GetFloat64 decodes a little-endian float64 from a byte slice.
|
||||
func GetFloat64(buf []byte) float64 {
|
||||
x := GetUint64(buf)
|
||||
return math.Float64frombits(x)
|
||||
}
|
||||
|
||||
// GetUOffsetT decodes a little-endian UOffsetT from a byte slice.
|
||||
func GetUOffsetT(buf []byte) UOffsetT {
|
||||
return UOffsetT(GetInt32(buf))
|
||||
}
|
||||
|
||||
// GetSOffsetT decodes a little-endian SOffsetT from a byte slice.
|
||||
func GetSOffsetT(buf []byte) SOffsetT {
|
||||
return SOffsetT(GetInt32(buf))
|
||||
}
|
||||
|
||||
// GetVOffsetT decodes a little-endian VOffsetT from a byte slice.
|
||||
func GetVOffsetT(buf []byte) VOffsetT {
|
||||
return VOffsetT(GetUint16(buf))
|
||||
}
|
||||
|
||||
// WriteByte encodes a little-endian uint8 into a byte slice.
|
||||
func WriteByte(buf []byte, n byte) {
|
||||
WriteUint8(buf, uint8(n))
|
||||
}
|
||||
|
||||
// WriteBool encodes a little-endian bool into a byte slice.
|
||||
func WriteBool(buf []byte, b bool) {
|
||||
buf[0] = 0
|
||||
if b {
|
||||
buf[0] = 1
|
||||
}
|
||||
}
|
||||
|
||||
// WriteUint8 encodes a little-endian uint8 into a byte slice.
|
||||
func WriteUint8(buf []byte, n uint8) {
|
||||
buf[0] = byte(n)
|
||||
}
|
||||
|
||||
// WriteUint16 encodes a little-endian uint16 into a byte slice.
|
||||
func WriteUint16(buf []byte, n uint16) {
|
||||
_ = buf[1] // Force one bounds check. See: golang.org/issue/14808
|
||||
buf[0] = byte(n)
|
||||
buf[1] = byte(n >> 8)
|
||||
}
|
||||
|
||||
// WriteUint32 encodes a little-endian uint32 into a byte slice.
|
||||
func WriteUint32(buf []byte, n uint32) {
|
||||
_ = buf[3] // Force one bounds check. See: golang.org/issue/14808
|
||||
buf[0] = byte(n)
|
||||
buf[1] = byte(n >> 8)
|
||||
buf[2] = byte(n >> 16)
|
||||
buf[3] = byte(n >> 24)
|
||||
}
|
||||
|
||||
// WriteUint64 encodes a little-endian uint64 into a byte slice.
|
||||
func WriteUint64(buf []byte, n uint64) {
|
||||
_ = buf[7] // Force one bounds check. See: golang.org/issue/14808
|
||||
buf[0] = byte(n)
|
||||
buf[1] = byte(n >> 8)
|
||||
buf[2] = byte(n >> 16)
|
||||
buf[3] = byte(n >> 24)
|
||||
buf[4] = byte(n >> 32)
|
||||
buf[5] = byte(n >> 40)
|
||||
buf[6] = byte(n >> 48)
|
||||
buf[7] = byte(n >> 56)
|
||||
}
|
||||
|
||||
// WriteInt8 encodes a little-endian int8 into a byte slice.
|
||||
func WriteInt8(buf []byte, n int8) {
|
||||
buf[0] = byte(n)
|
||||
}
|
||||
|
||||
// WriteInt16 encodes a little-endian int16 into a byte slice.
|
||||
func WriteInt16(buf []byte, n int16) {
|
||||
_ = buf[1] // Force one bounds check. See: golang.org/issue/14808
|
||||
buf[0] = byte(n)
|
||||
buf[1] = byte(n >> 8)
|
||||
}
|
||||
|
||||
// WriteInt32 encodes a little-endian int32 into a byte slice.
|
||||
func WriteInt32(buf []byte, n int32) {
|
||||
_ = buf[3] // Force one bounds check. See: golang.org/issue/14808
|
||||
buf[0] = byte(n)
|
||||
buf[1] = byte(n >> 8)
|
||||
buf[2] = byte(n >> 16)
|
||||
buf[3] = byte(n >> 24)
|
||||
}
|
||||
|
||||
// WriteInt64 encodes a little-endian int64 into a byte slice.
|
||||
func WriteInt64(buf []byte, n int64) {
|
||||
_ = buf[7] // Force one bounds check. See: golang.org/issue/14808
|
||||
buf[0] = byte(n)
|
||||
buf[1] = byte(n >> 8)
|
||||
buf[2] = byte(n >> 16)
|
||||
buf[3] = byte(n >> 24)
|
||||
buf[4] = byte(n >> 32)
|
||||
buf[5] = byte(n >> 40)
|
||||
buf[6] = byte(n >> 48)
|
||||
buf[7] = byte(n >> 56)
|
||||
}
|
||||
|
||||
// WriteFloat32 encodes a little-endian float32 into a byte slice.
|
||||
func WriteFloat32(buf []byte, n float32) {
|
||||
WriteUint32(buf, math.Float32bits(n))
|
||||
}
|
||||
|
||||
// WriteFloat64 encodes a little-endian float64 into a byte slice.
|
||||
func WriteFloat64(buf []byte, n float64) {
|
||||
WriteUint64(buf, math.Float64bits(n))
|
||||
}
|
||||
|
||||
// WriteVOffsetT encodes a little-endian VOffsetT into a byte slice.
|
||||
func WriteVOffsetT(buf []byte, n VOffsetT) {
|
||||
WriteUint16(buf, uint16(n))
|
||||
}
|
||||
|
||||
// WriteSOffsetT encodes a little-endian SOffsetT into a byte slice.
|
||||
func WriteSOffsetT(buf []byte, n SOffsetT) {
|
||||
WriteInt32(buf, int32(n))
|
||||
}
|
||||
|
||||
// WriteUOffsetT encodes a little-endian UOffsetT into a byte slice.
|
||||
func WriteUOffsetT(buf []byte, n UOffsetT) {
|
||||
WriteUint32(buf, uint32(n))
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package flatbuffers
|
||||
|
||||
// Codec implements gRPC-go Codec which is used to encode and decode messages.
|
||||
var Codec = "flatbuffers"
|
||||
|
||||
type FlatbuffersCodec struct{}
|
||||
|
||||
func (FlatbuffersCodec) Marshal(v interface{}) ([]byte, error) {
|
||||
return v.(*Builder).FinishedBytes(), nil
|
||||
}
|
||||
|
||||
func (FlatbuffersCodec) Unmarshal(data []byte, v interface{}) error {
|
||||
v.(flatbuffersInit).Init(data, GetUOffsetT(data))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (FlatbuffersCodec) String() string {
|
||||
return Codec
|
||||
}
|
||||
|
||||
type flatbuffersInit interface {
|
||||
Init(data []byte, i UOffsetT)
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package flatbuffers
|
||||
|
||||
// FlatBuffer is the interface that represents a flatbuffer.
|
||||
type FlatBuffer interface {
|
||||
Table() Table
|
||||
Init(buf []byte, i UOffsetT)
|
||||
}
|
||||
|
||||
// GetRootAs is a generic helper to initialize a FlatBuffer with the provided buffer bytes and its data offset.
|
||||
func GetRootAs(buf []byte, offset UOffsetT, fb FlatBuffer) {
|
||||
n := GetUOffsetT(buf[offset:])
|
||||
fb.Init(buf, n+offset)
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package flatbuffers
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// See http://golang.org/ref/spec#Numeric_types
|
||||
|
||||
// SizeUint8 is the byte size of a uint8.
|
||||
SizeUint8 = 1
|
||||
// SizeUint16 is the byte size of a uint16.
|
||||
SizeUint16 = 2
|
||||
// SizeUint32 is the byte size of a uint32.
|
||||
SizeUint32 = 4
|
||||
// SizeUint64 is the byte size of a uint64.
|
||||
SizeUint64 = 8
|
||||
|
||||
// SizeInt8 is the byte size of a int8.
|
||||
SizeInt8 = 1
|
||||
// SizeInt16 is the byte size of a int16.
|
||||
SizeInt16 = 2
|
||||
// SizeInt32 is the byte size of a int32.
|
||||
SizeInt32 = 4
|
||||
// SizeInt64 is the byte size of a int64.
|
||||
SizeInt64 = 8
|
||||
|
||||
// SizeFloat32 is the byte size of a float32.
|
||||
SizeFloat32 = 4
|
||||
// SizeFloat64 is the byte size of a float64.
|
||||
SizeFloat64 = 8
|
||||
|
||||
// SizeByte is the byte size of a byte.
|
||||
// The `byte` type is aliased (by Go definition) to uint8.
|
||||
SizeByte = 1
|
||||
|
||||
// SizeBool is the byte size of a bool.
|
||||
// The `bool` type is aliased (by flatbuffers convention) to uint8.
|
||||
SizeBool = 1
|
||||
|
||||
// SizeSOffsetT is the byte size of an SOffsetT.
|
||||
// The `SOffsetT` type is aliased (by flatbuffers convention) to int32.
|
||||
SizeSOffsetT = 4
|
||||
// SizeUOffsetT is the byte size of an UOffsetT.
|
||||
// The `UOffsetT` type is aliased (by flatbuffers convention) to uint32.
|
||||
SizeUOffsetT = 4
|
||||
// SizeVOffsetT is the byte size of an VOffsetT.
|
||||
// The `VOffsetT` type is aliased (by flatbuffers convention) to uint16.
|
||||
SizeVOffsetT = 2
|
||||
)
|
||||
|
||||
// byteSliceToString converts a []byte to string without a heap allocation.
|
||||
func byteSliceToString(b []byte) string {
|
||||
return *(*string)(unsafe.Pointer(&b))
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package flatbuffers
|
||||
|
||||
// Struct wraps a byte slice and provides read access to its data.
|
||||
//
|
||||
// Structs do not have a vtable.
|
||||
type Struct struct {
|
||||
Table
|
||||
}
|
||||
+505
@@ -0,0 +1,505 @@
|
||||
package flatbuffers
|
||||
|
||||
// Table wraps a byte slice and provides read access to its data.
|
||||
//
|
||||
// The variable `Pos` indicates the root of the FlatBuffers object therein.
|
||||
type Table struct {
|
||||
Bytes []byte
|
||||
Pos UOffsetT // Always < 1<<31.
|
||||
}
|
||||
|
||||
// Offset provides access into the Table's vtable.
|
||||
//
|
||||
// Fields which are deprecated are ignored by checking against the vtable's length.
|
||||
func (t *Table) Offset(vtableOffset VOffsetT) VOffsetT {
|
||||
vtable := UOffsetT(SOffsetT(t.Pos) - t.GetSOffsetT(t.Pos))
|
||||
if vtableOffset < t.GetVOffsetT(vtable) {
|
||||
return t.GetVOffsetT(vtable + UOffsetT(vtableOffset))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Indirect retrieves the relative offset stored at `offset`.
|
||||
func (t *Table) Indirect(off UOffsetT) UOffsetT {
|
||||
return off + GetUOffsetT(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// String gets a string from data stored inside the flatbuffer.
|
||||
func (t *Table) String(off UOffsetT) string {
|
||||
b := t.ByteVector(off)
|
||||
return byteSliceToString(b)
|
||||
}
|
||||
|
||||
// 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 t.Bytes[start : start+length]
|
||||
}
|
||||
|
||||
// VectorLen retrieves the length of the vector whose offset is stored at
|
||||
// "off" in this object.
|
||||
func (t *Table) VectorLen(off UOffsetT) int {
|
||||
off += t.Pos
|
||||
off += GetUOffsetT(t.Bytes[off:])
|
||||
return int(GetUOffsetT(t.Bytes[off:]))
|
||||
}
|
||||
|
||||
// Vector retrieves the start of data of the vector whose offset is stored
|
||||
// at "off" in this object.
|
||||
func (t *Table) Vector(off UOffsetT) UOffsetT {
|
||||
off += t.Pos
|
||||
x := off + GetUOffsetT(t.Bytes[off:])
|
||||
// data starts after metadata containing the vector length
|
||||
x += UOffsetT(SizeUOffsetT)
|
||||
return x
|
||||
}
|
||||
|
||||
// Union initializes any Table-derived type to point to the union at the given
|
||||
// offset.
|
||||
func (t *Table) Union(t2 *Table, off UOffsetT) {
|
||||
off += t.Pos
|
||||
t2.Pos = off + t.GetUOffsetT(off)
|
||||
t2.Bytes = t.Bytes
|
||||
}
|
||||
|
||||
// GetBool retrieves a bool at the given offset.
|
||||
func (t *Table) GetBool(off UOffsetT) bool {
|
||||
return GetBool(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetByte retrieves a byte at the given offset.
|
||||
func (t *Table) GetByte(off UOffsetT) byte {
|
||||
return GetByte(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetUint8 retrieves a uint8 at the given offset.
|
||||
func (t *Table) GetUint8(off UOffsetT) uint8 {
|
||||
return GetUint8(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetUint16 retrieves a uint16 at the given offset.
|
||||
func (t *Table) GetUint16(off UOffsetT) uint16 {
|
||||
return GetUint16(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetUint32 retrieves a uint32 at the given offset.
|
||||
func (t *Table) GetUint32(off UOffsetT) uint32 {
|
||||
return GetUint32(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetUint64 retrieves a uint64 at the given offset.
|
||||
func (t *Table) GetUint64(off UOffsetT) uint64 {
|
||||
return GetUint64(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetInt8 retrieves a int8 at the given offset.
|
||||
func (t *Table) GetInt8(off UOffsetT) int8 {
|
||||
return GetInt8(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetInt16 retrieves a int16 at the given offset.
|
||||
func (t *Table) GetInt16(off UOffsetT) int16 {
|
||||
return GetInt16(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetInt32 retrieves a int32 at the given offset.
|
||||
func (t *Table) GetInt32(off UOffsetT) int32 {
|
||||
return GetInt32(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetInt64 retrieves a int64 at the given offset.
|
||||
func (t *Table) GetInt64(off UOffsetT) int64 {
|
||||
return GetInt64(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetFloat32 retrieves a float32 at the given offset.
|
||||
func (t *Table) GetFloat32(off UOffsetT) float32 {
|
||||
return GetFloat32(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetFloat64 retrieves a float64 at the given offset.
|
||||
func (t *Table) GetFloat64(off UOffsetT) float64 {
|
||||
return GetFloat64(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetUOffsetT retrieves a UOffsetT at the given offset.
|
||||
func (t *Table) GetUOffsetT(off UOffsetT) UOffsetT {
|
||||
return GetUOffsetT(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetVOffsetT retrieves a VOffsetT at the given offset.
|
||||
func (t *Table) GetVOffsetT(off UOffsetT) VOffsetT {
|
||||
return GetVOffsetT(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetSOffsetT retrieves a SOffsetT at the given offset.
|
||||
func (t *Table) GetSOffsetT(off UOffsetT) SOffsetT {
|
||||
return GetSOffsetT(t.Bytes[off:])
|
||||
}
|
||||
|
||||
// GetBoolSlot retrieves the bool that the given vtable location
|
||||
// points to. If the vtable value is zero, the default value `d`
|
||||
// will be returned.
|
||||
func (t *Table) GetBoolSlot(slot VOffsetT, d bool) bool {
|
||||
off := t.Offset(slot)
|
||||
if off == 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
return t.GetBool(t.Pos + UOffsetT(off))
|
||||
}
|
||||
|
||||
// GetByteSlot retrieves the byte that the given vtable location
|
||||
// points to. If the vtable value is zero, the default value `d`
|
||||
// will be returned.
|
||||
func (t *Table) GetByteSlot(slot VOffsetT, d byte) byte {
|
||||
off := t.Offset(slot)
|
||||
if off == 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
return t.GetByte(t.Pos + UOffsetT(off))
|
||||
}
|
||||
|
||||
// GetInt8Slot retrieves the int8 that the given vtable location
|
||||
// points to. If the vtable value is zero, the default value `d`
|
||||
// will be returned.
|
||||
func (t *Table) GetInt8Slot(slot VOffsetT, d int8) int8 {
|
||||
off := t.Offset(slot)
|
||||
if off == 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
return t.GetInt8(t.Pos + UOffsetT(off))
|
||||
}
|
||||
|
||||
// GetUint8Slot retrieves the uint8 that the given vtable location
|
||||
// points to. If the vtable value is zero, the default value `d`
|
||||
// will be returned.
|
||||
func (t *Table) GetUint8Slot(slot VOffsetT, d uint8) uint8 {
|
||||
off := t.Offset(slot)
|
||||
if off == 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
return t.GetUint8(t.Pos + UOffsetT(off))
|
||||
}
|
||||
|
||||
// GetInt16Slot retrieves the int16 that the given vtable location
|
||||
// points to. If the vtable value is zero, the default value `d`
|
||||
// will be returned.
|
||||
func (t *Table) GetInt16Slot(slot VOffsetT, d int16) int16 {
|
||||
off := t.Offset(slot)
|
||||
if off == 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
return t.GetInt16(t.Pos + UOffsetT(off))
|
||||
}
|
||||
|
||||
// GetUint16Slot retrieves the uint16 that the given vtable location
|
||||
// points to. If the vtable value is zero, the default value `d`
|
||||
// will be returned.
|
||||
func (t *Table) GetUint16Slot(slot VOffsetT, d uint16) uint16 {
|
||||
off := t.Offset(slot)
|
||||
if off == 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
return t.GetUint16(t.Pos + UOffsetT(off))
|
||||
}
|
||||
|
||||
// GetInt32Slot retrieves the int32 that the given vtable location
|
||||
// points to. If the vtable value is zero, the default value `d`
|
||||
// will be returned.
|
||||
func (t *Table) GetInt32Slot(slot VOffsetT, d int32) int32 {
|
||||
off := t.Offset(slot)
|
||||
if off == 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
return t.GetInt32(t.Pos + UOffsetT(off))
|
||||
}
|
||||
|
||||
// GetUint32Slot retrieves the uint32 that the given vtable location
|
||||
// points to. If the vtable value is zero, the default value `d`
|
||||
// will be returned.
|
||||
func (t *Table) GetUint32Slot(slot VOffsetT, d uint32) uint32 {
|
||||
off := t.Offset(slot)
|
||||
if off == 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
return t.GetUint32(t.Pos + UOffsetT(off))
|
||||
}
|
||||
|
||||
// GetInt64Slot retrieves the int64 that the given vtable location
|
||||
// points to. If the vtable value is zero, the default value `d`
|
||||
// will be returned.
|
||||
func (t *Table) GetInt64Slot(slot VOffsetT, d int64) int64 {
|
||||
off := t.Offset(slot)
|
||||
if off == 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
return t.GetInt64(t.Pos + UOffsetT(off))
|
||||
}
|
||||
|
||||
// GetUint64Slot retrieves the uint64 that the given vtable location
|
||||
// points to. If the vtable value is zero, the default value `d`
|
||||
// will be returned.
|
||||
func (t *Table) GetUint64Slot(slot VOffsetT, d uint64) uint64 {
|
||||
off := t.Offset(slot)
|
||||
if off == 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
return t.GetUint64(t.Pos + UOffsetT(off))
|
||||
}
|
||||
|
||||
// GetFloat32Slot retrieves the float32 that the given vtable location
|
||||
// points to. If the vtable value is zero, the default value `d`
|
||||
// will be returned.
|
||||
func (t *Table) GetFloat32Slot(slot VOffsetT, d float32) float32 {
|
||||
off := t.Offset(slot)
|
||||
if off == 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
return t.GetFloat32(t.Pos + UOffsetT(off))
|
||||
}
|
||||
|
||||
// GetFloat64Slot retrieves the float64 that the given vtable location
|
||||
// points to. If the vtable value is zero, the default value `d`
|
||||
// will be returned.
|
||||
func (t *Table) GetFloat64Slot(slot VOffsetT, d float64) float64 {
|
||||
off := t.Offset(slot)
|
||||
if off == 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
return t.GetFloat64(t.Pos + UOffsetT(off))
|
||||
}
|
||||
|
||||
// GetVOffsetTSlot retrieves the VOffsetT that the given vtable location
|
||||
// points to. If the vtable value is zero, the default value `d`
|
||||
// will be returned.
|
||||
func (t *Table) GetVOffsetTSlot(slot VOffsetT, d VOffsetT) VOffsetT {
|
||||
off := t.Offset(slot)
|
||||
if off == 0 {
|
||||
return d
|
||||
}
|
||||
return VOffsetT(off)
|
||||
}
|
||||
|
||||
// MutateBool updates a bool at the given offset.
|
||||
func (t *Table) MutateBool(off UOffsetT, n bool) bool {
|
||||
WriteBool(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateByte updates a Byte at the given offset.
|
||||
func (t *Table) MutateByte(off UOffsetT, n byte) bool {
|
||||
WriteByte(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateUint8 updates a Uint8 at the given offset.
|
||||
func (t *Table) MutateUint8(off UOffsetT, n uint8) bool {
|
||||
WriteUint8(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateUint16 updates a Uint16 at the given offset.
|
||||
func (t *Table) MutateUint16(off UOffsetT, n uint16) bool {
|
||||
WriteUint16(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateUint32 updates a Uint32 at the given offset.
|
||||
func (t *Table) MutateUint32(off UOffsetT, n uint32) bool {
|
||||
WriteUint32(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateUint64 updates a Uint64 at the given offset.
|
||||
func (t *Table) MutateUint64(off UOffsetT, n uint64) bool {
|
||||
WriteUint64(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateInt8 updates a Int8 at the given offset.
|
||||
func (t *Table) MutateInt8(off UOffsetT, n int8) bool {
|
||||
WriteInt8(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateInt16 updates a Int16 at the given offset.
|
||||
func (t *Table) MutateInt16(off UOffsetT, n int16) bool {
|
||||
WriteInt16(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateInt32 updates a Int32 at the given offset.
|
||||
func (t *Table) MutateInt32(off UOffsetT, n int32) bool {
|
||||
WriteInt32(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateInt64 updates a Int64 at the given offset.
|
||||
func (t *Table) MutateInt64(off UOffsetT, n int64) bool {
|
||||
WriteInt64(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateFloat32 updates a Float32 at the given offset.
|
||||
func (t *Table) MutateFloat32(off UOffsetT, n float32) bool {
|
||||
WriteFloat32(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateFloat64 updates a Float64 at the given offset.
|
||||
func (t *Table) MutateFloat64(off UOffsetT, n float64) bool {
|
||||
WriteFloat64(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateUOffsetT updates a UOffsetT at the given offset.
|
||||
func (t *Table) MutateUOffsetT(off UOffsetT, n UOffsetT) bool {
|
||||
WriteUOffsetT(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateVOffsetT updates a VOffsetT at the given offset.
|
||||
func (t *Table) MutateVOffsetT(off UOffsetT, n VOffsetT) bool {
|
||||
WriteVOffsetT(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateSOffsetT updates a SOffsetT at the given offset.
|
||||
func (t *Table) MutateSOffsetT(off UOffsetT, n SOffsetT) bool {
|
||||
WriteSOffsetT(t.Bytes[off:], n)
|
||||
return true
|
||||
}
|
||||
|
||||
// MutateBoolSlot updates the bool at given vtable location
|
||||
func (t *Table) MutateBoolSlot(slot VOffsetT, n bool) bool {
|
||||
if off := t.Offset(slot); off != 0 {
|
||||
t.MutateBool(t.Pos+UOffsetT(off), n)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MutateByteSlot updates the byte at given vtable location
|
||||
func (t *Table) MutateByteSlot(slot VOffsetT, n byte) bool {
|
||||
if off := t.Offset(slot); off != 0 {
|
||||
t.MutateByte(t.Pos+UOffsetT(off), n)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MutateInt8Slot updates the int8 at given vtable location
|
||||
func (t *Table) MutateInt8Slot(slot VOffsetT, n int8) bool {
|
||||
if off := t.Offset(slot); off != 0 {
|
||||
t.MutateInt8(t.Pos+UOffsetT(off), n)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MutateUint8Slot updates the uint8 at given vtable location
|
||||
func (t *Table) MutateUint8Slot(slot VOffsetT, n uint8) bool {
|
||||
if off := t.Offset(slot); off != 0 {
|
||||
t.MutateUint8(t.Pos+UOffsetT(off), n)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MutateInt16Slot updates the int16 at given vtable location
|
||||
func (t *Table) MutateInt16Slot(slot VOffsetT, n int16) bool {
|
||||
if off := t.Offset(slot); off != 0 {
|
||||
t.MutateInt16(t.Pos+UOffsetT(off), n)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MutateUint16Slot updates the uint16 at given vtable location
|
||||
func (t *Table) MutateUint16Slot(slot VOffsetT, n uint16) bool {
|
||||
if off := t.Offset(slot); off != 0 {
|
||||
t.MutateUint16(t.Pos+UOffsetT(off), n)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MutateInt32Slot updates the int32 at given vtable location
|
||||
func (t *Table) MutateInt32Slot(slot VOffsetT, n int32) bool {
|
||||
if off := t.Offset(slot); off != 0 {
|
||||
t.MutateInt32(t.Pos+UOffsetT(off), n)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MutateUint32Slot updates the uint32 at given vtable location
|
||||
func (t *Table) MutateUint32Slot(slot VOffsetT, n uint32) bool {
|
||||
if off := t.Offset(slot); off != 0 {
|
||||
t.MutateUint32(t.Pos+UOffsetT(off), n)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MutateInt64Slot updates the int64 at given vtable location
|
||||
func (t *Table) MutateInt64Slot(slot VOffsetT, n int64) bool {
|
||||
if off := t.Offset(slot); off != 0 {
|
||||
t.MutateInt64(t.Pos+UOffsetT(off), n)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MutateUint64Slot updates the uint64 at given vtable location
|
||||
func (t *Table) MutateUint64Slot(slot VOffsetT, n uint64) bool {
|
||||
if off := t.Offset(slot); off != 0 {
|
||||
t.MutateUint64(t.Pos+UOffsetT(off), n)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MutateFloat32Slot updates the float32 at given vtable location
|
||||
func (t *Table) MutateFloat32Slot(slot VOffsetT, n float32) bool {
|
||||
if off := t.Offset(slot); off != 0 {
|
||||
t.MutateFloat32(t.Pos+UOffsetT(off), n)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MutateFloat64Slot updates the float64 at given vtable location
|
||||
func (t *Table) MutateFloat64Slot(slot VOffsetT, n float64) bool {
|
||||
if off := t.Offset(slot); off != 0 {
|
||||
t.MutateFloat64(t.Pos+UOffsetT(off), n)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user