| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856 |
- package flatbuffers
- import "sort"
- // 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
- sharedStrings map[string]UOffsetT
- }
- const fileIdentifierLength = 4
- const sizePrefixLength = 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]
- }
- if b.sharedStrings != nil {
- for key := range b.sharedStrings {
- delete(b.sharedStrings, key)
- }
- }
- 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()
- }
- // CreateVectorOfTables serializes slice of table offsets into a vector.
- func (b *Builder) CreateVectorOfTables(offsets []UOffsetT) UOffsetT {
- b.assertNotNested()
- b.StartVector(4, len(offsets), 4)
- for i := len(offsets) - 1; i >= 0; i-- {
- b.PrependUOffsetT(offsets[i])
- }
- return b.EndVector(len(offsets))
- }
- type KeyCompare func(o1, o2 UOffsetT, buf []byte) bool
- func (b *Builder) CreateVectorOfSortedTables(offsets []UOffsetT, keyCompare KeyCompare) UOffsetT {
- sort.Slice(offsets, func(i, j int) bool {
- return keyCompare(offsets[i], offsets[j], b.Bytes)
- })
- return b.CreateVectorOfTables(offsets)
- }
- // CreateSharedString Checks if the string is already written
- // to the buffer before calling CreateString
- func (b *Builder) CreateSharedString(s string) UOffsetT {
- if b.sharedStrings == nil {
- b.sharedStrings = make(map[string]UOffsetT)
- }
- if v, ok := b.sharedStrings[s]; ok {
- return v
- }
- off := b.CreateString(s)
- b.sharedStrings[s] = off
- return off
- }
- // 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)
- }
- // FinishSizePrefixed finalizes a buffer, pointing to the given `rootTable`.
- // The buffer is prefixed with the size of the buffer, excluding the size
- // of the prefix itself.
- func (b *Builder) FinishSizePrefixed(rootTable UOffsetT) {
- b.finish(rootTable, true)
- }
- // FinishSizePrefixedWithFileIdentifier finalizes a buffer, pointing to the given `rootTable`
- // and applies a file identifier. The buffer is prefixed with the size of the buffer,
- // excluding the size of the prefix itself.
- func (b *Builder) FinishSizePrefixedWithFileIdentifier(rootTable UOffsetT, fid []byte) {
- if fid == nil || len(fid) != fileIdentifierLength {
- panic("incorrect file identifier length")
- }
- // In order to add a file identifier and size prefix to the flatbuffer message,
- // we need to prepare an alignment, a size prefix length, and file identifier length
- b.Prep(b.minalign, SizeInt32+fileIdentifierLength+sizePrefixLength)
- for i := fileIdentifierLength - 1; i >= 0; i-- {
- // place the file identifier
- b.PlaceByte(fid[i])
- }
- // finish
- b.finish(rootTable, true)
- }
- // Finish finalizes a buffer, pointing to the given `rootTable`.
- func (b *Builder) Finish(rootTable UOffsetT) {
- b.finish(rootTable, false)
- }
- // finish finalizes a buffer, pointing to the given `rootTable`
- // with an optional size prefix.
- func (b *Builder) finish(rootTable UOffsetT, sizePrefix bool) {
- b.assertNotNested()
- if sizePrefix {
- b.Prep(b.minalign, SizeUOffsetT+sizePrefixLength)
- } else {
- b.Prep(b.minalign, SizeUOffsetT)
- }
- b.PrependUOffsetT(rootTable)
- if sizePrefix {
- b.PlaceUint32(uint32(b.Offset()))
- }
- 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)
- }
|