Remove some unused fbs files
This commit is contained in:
parent
be9d562d57
commit
8866f72340
@ -1,7 +0,0 @@
|
|||||||
version = "2.0.8"
|
|
||||||
author = "flatbuffers"
|
|
||||||
description = "Flatbuffers"
|
|
||||||
license = "Apache 2.0"
|
|
||||||
srcDir = "flatbuffers"
|
|
||||||
|
|
||||||
requires "nim >= 1.4.0"
|
|
@ -1,7 +0,0 @@
|
|||||||
import
|
|
||||||
src/[
|
|
||||||
builder,
|
|
||||||
struct,
|
|
||||||
table
|
|
||||||
]
|
|
||||||
export flatbuffers.builder, flatbuffers.table, flatbuffers.struct
|
|
@ -1,262 +0,0 @@
|
|||||||
import math
|
|
||||||
import table
|
|
||||||
|
|
||||||
|
|
||||||
const MAX_BUFFER_SIZE* = 2^31
|
|
||||||
|
|
||||||
|
|
||||||
type Builder* = ref object of RootObj
|
|
||||||
bytes*: seq[byte]
|
|
||||||
minalign*: int
|
|
||||||
current_vtable*: seq[uoffset]
|
|
||||||
objectEnd*: uoffset
|
|
||||||
vtables*: seq[uoffset] #?
|
|
||||||
head*: uoffset
|
|
||||||
nested*: bool
|
|
||||||
finished*: bool
|
|
||||||
vectorNumElems*: uoffset
|
|
||||||
|
|
||||||
using this: var Builder
|
|
||||||
|
|
||||||
func newBuilder*(size: int): Builder =
|
|
||||||
result = new Builder
|
|
||||||
result.bytes.setLen(size)
|
|
||||||
result.minalign = 1
|
|
||||||
result.head = size.uoffset
|
|
||||||
result.nested = false
|
|
||||||
result.finished = false
|
|
||||||
result.vectorNumElems = 0
|
|
||||||
|
|
||||||
proc FinishedBytes*(this): seq[byte] =
|
|
||||||
if not this.finished:
|
|
||||||
quit("Builder not finished, Incorrect use of FinishedBytes(): must call 'Finish' first.")
|
|
||||||
result = this.bytes[this.head..^1]
|
|
||||||
|
|
||||||
proc Output*(this): seq[byte] =
|
|
||||||
if not this.finished:
|
|
||||||
quit("Builder not finished, Incorrect use of Output(): must call 'Finish' first.")
|
|
||||||
|
|
||||||
result = this.bytes[this.head..^1]
|
|
||||||
|
|
||||||
func Offset*(this): uoffset =
|
|
||||||
result = this.bytes.len.uoffset - this.head
|
|
||||||
|
|
||||||
proc StartObject*(this; numfields: int) =
|
|
||||||
if this.nested:
|
|
||||||
quit("builder is nested")
|
|
||||||
|
|
||||||
this.current_vtable.setLen(numfields)
|
|
||||||
for i in this.current_vtable.mitems():
|
|
||||||
i = 0
|
|
||||||
this.objectEnd = this.Offset()
|
|
||||||
this.nested = true
|
|
||||||
|
|
||||||
proc GrowByteBuffer*(this) =
|
|
||||||
if this.bytes.len == MAX_BUFFER_SIZE:
|
|
||||||
quit("flatbuffers: cannot grow buffer beyond 2 gigabytes")
|
|
||||||
let oldLen = this.bytes.len
|
|
||||||
var newLen = min(this.bytes.len * 2, MAX_BUFFER_SIZE)
|
|
||||||
if newLen == 0:
|
|
||||||
newLen = 1
|
|
||||||
this.bytes.setLen(newLen)
|
|
||||||
var j = this.bytes.len - 1
|
|
||||||
while j >= 0:
|
|
||||||
if j >= newLen - oldLen:
|
|
||||||
this.bytes[j] = this.bytes[j - (newLen - oldLen)]
|
|
||||||
else:
|
|
||||||
this.bytes[j] = 0
|
|
||||||
dec(j)
|
|
||||||
|
|
||||||
proc Place*[T](this; x: T) =
|
|
||||||
this.head -= uoffset x.sizeof
|
|
||||||
WriteVal(this.bytes, this.head, x)
|
|
||||||
|
|
||||||
func Pad*(this; n: int) =
|
|
||||||
for i in 0..<n:
|
|
||||||
this.Place(0.byte)
|
|
||||||
|
|
||||||
proc Prep*(this; size: int; additionalBytes: int) =
|
|
||||||
if size > this.minalign:
|
|
||||||
this.minalign = size
|
|
||||||
var alignsize = (not (this.bytes.len - this.head.int + additionalBytes)) + 1
|
|
||||||
alignsize = alignsize and (size - 1)
|
|
||||||
|
|
||||||
while this.head.int < alignsize + size + additionalBytes:
|
|
||||||
let oldbufSize = this.bytes.len
|
|
||||||
this.GrowByteBuffer()
|
|
||||||
this.head = (this.head.int + this.bytes.len - oldbufSize).uoffset
|
|
||||||
this.Pad(alignsize)
|
|
||||||
|
|
||||||
proc PrependOffsetRelative*[T: Offsets](this; off: T) =
|
|
||||||
when T is voffset:
|
|
||||||
this.Prep(T.sizeof, 0)
|
|
||||||
if not off.uoffset <= this.Offset:
|
|
||||||
quit("flatbuffers: Offset arithmetic error.")
|
|
||||||
this.Place(off)
|
|
||||||
else:
|
|
||||||
this.Prep(T.sizeof, 0)
|
|
||||||
if not off.uoffset <= this.Offset:
|
|
||||||
quit("flatbuffers: Offset arithmetic error.")
|
|
||||||
let off2: T = this.Offset.T - off + sizeof(T).T
|
|
||||||
this.Place(off2)
|
|
||||||
|
|
||||||
|
|
||||||
proc Prepend*[T](this; x: T) =
|
|
||||||
this.Prep(x.sizeof, 0)
|
|
||||||
this.Place(x)
|
|
||||||
|
|
||||||
proc Slot*(this; slotnum: int) =
|
|
||||||
this.current_vtable[slotnum] = this.Offset
|
|
||||||
|
|
||||||
proc PrependSlot*[T](this; o: int; x, d: T) =
|
|
||||||
if x != d:
|
|
||||||
when T is uoffset or T is soffset or T is voffset:
|
|
||||||
this.PrependOffsetRelative(x)
|
|
||||||
else:
|
|
||||||
this.Prepend(x)
|
|
||||||
this.Slot(o)
|
|
||||||
|
|
||||||
proc AssertStuctInline(this; obj: uoffset) =
|
|
||||||
if obj != this.Offset:
|
|
||||||
quit("flatbuffers: Tried to write a Struct at an Offset that is different from the current Offset of the Builder.")
|
|
||||||
|
|
||||||
proc PrependStructSlot*(this; o: int; x: uoffset; d: uoffset) =
|
|
||||||
if x != d:
|
|
||||||
this.AssertStuctInline(x)
|
|
||||||
this.Slot(o)
|
|
||||||
|
|
||||||
proc Add*[T](this; n: T) =
|
|
||||||
this.Prep(T.sizeof, 0)
|
|
||||||
WriteVal(this.bytes, this.head, n)
|
|
||||||
|
|
||||||
proc VtableEqual*(a: seq[uoffset]; objectStart: uoffset; b: seq[byte]): bool =
|
|
||||||
if a.len * voffset.sizeof != b.len:
|
|
||||||
return false
|
|
||||||
|
|
||||||
var i = 0
|
|
||||||
while i < a.len:
|
|
||||||
var seq = b[i * voffset.sizeof..<(i + 1) * voffset.sizeof]
|
|
||||||
let x = GetVal[voffset](addr seq)
|
|
||||||
|
|
||||||
if x == 0 and a[i] == 0:
|
|
||||||
inc i
|
|
||||||
continue
|
|
||||||
|
|
||||||
let y = objectStart.soffset - a[i].soffset
|
|
||||||
if x.soffset != y:
|
|
||||||
return false
|
|
||||||
inc i
|
|
||||||
return true
|
|
||||||
|
|
||||||
proc WriteVtable*(this): uoffset =
|
|
||||||
this.PrependOffsetRelative(0.soffset)
|
|
||||||
|
|
||||||
let objectOffset = this.Offset
|
|
||||||
var existingVtable = uoffset 0
|
|
||||||
|
|
||||||
var i = this.current_vtable.len - 1
|
|
||||||
while i >= 0 and this.current_vtable[i] == 0: dec i
|
|
||||||
|
|
||||||
this.current_vtable = this.current_vtable[0..i]
|
|
||||||
for i in countdown(this.vtables.len - 1, 0):
|
|
||||||
let
|
|
||||||
vt2Offset: uoffset = this.vtables[i]
|
|
||||||
vt2Start: int = this.bytes.len - int vt2Offset
|
|
||||||
|
|
||||||
var seq = this.bytes[vt2Start..<this.bytes.len]
|
|
||||||
let
|
|
||||||
vt2Len = GetVal[voffset](addr seq)
|
|
||||||
metadata = 2 * voffset.sizeof # VtableMetadataFields * SizeVOffsetT
|
|
||||||
vt2End = vt2Start + vt2Len.int
|
|
||||||
vt2 = this.bytes[this.bytes.len - vt2Offset.int + metadata..<vt2End]
|
|
||||||
|
|
||||||
if VtableEqual(this.current_vtable, objectOffset, vt2):
|
|
||||||
existingVtable = vt2Offset
|
|
||||||
break
|
|
||||||
|
|
||||||
if existingVtable == 0:
|
|
||||||
for i in countdown(this.current_vtable.len - 1, 0):
|
|
||||||
var off: uoffset
|
|
||||||
if this.current_vtable[i] != 0:
|
|
||||||
off = objectOffset - this.current_vtable[i]
|
|
||||||
|
|
||||||
this.PrependOffsetRelative(off.voffset)
|
|
||||||
|
|
||||||
let objectSize = objectOffset - this.objectEnd
|
|
||||||
this.PrependOffsetRelative(objectSize.voffset)
|
|
||||||
|
|
||||||
let vBytes = (this.current_vtable.len + 2) * voffset.sizeof
|
|
||||||
this.PrependOffsetRelative(vBytes.voffset)
|
|
||||||
|
|
||||||
let objectStart: uoffset = (this.bytes.len.uoffset - objectOffset)
|
|
||||||
WriteVal(this.bytes, objectStart, (this.Offset - objectOffset).soffset)
|
|
||||||
this.vtables.add this.Offset
|
|
||||||
else:
|
|
||||||
let objectStart: uoffset = this.bytes.len.uoffset - objectOffset
|
|
||||||
this.head = objectStart
|
|
||||||
WriteVal(this.bytes, this.head,
|
|
||||||
(existingVtable.soffset - objectOffset.soffset))
|
|
||||||
|
|
||||||
this.current_vtable = @[]
|
|
||||||
result = objectOffset
|
|
||||||
|
|
||||||
proc EndObject*(this): uoffset =
|
|
||||||
if not this.nested:
|
|
||||||
quit("builder is not nested")
|
|
||||||
result = this.WriteVtable()
|
|
||||||
this.nested = false
|
|
||||||
|
|
||||||
proc End*(this: var Builder): uoffset =
|
|
||||||
result = this.EndObject()
|
|
||||||
|
|
||||||
proc StartVector*(this; elemSize: int; numElems: uoffset;
|
|
||||||
alignment: int) =
|
|
||||||
if this.nested:
|
|
||||||
quit("builder is nested")
|
|
||||||
this.nested = true
|
|
||||||
this.vectorNumElems = numElems
|
|
||||||
this.Prep(sizeof(uint32), elemSize * numElems.int)
|
|
||||||
this.Prep(alignment, elemSize * numElems.int)
|
|
||||||
|
|
||||||
proc EndVector*(this): uoffset =
|
|
||||||
if not this.nested:
|
|
||||||
quit("builder is not nested")
|
|
||||||
this.nested = false
|
|
||||||
this.Place(this.vectorNumElems)
|
|
||||||
this.vectorNumElems = 0
|
|
||||||
result = this.Offset
|
|
||||||
|
|
||||||
proc getChars*(str: seq[byte]): string =
|
|
||||||
var bytes = str
|
|
||||||
result = GetVal[string](addr bytes)
|
|
||||||
|
|
||||||
proc getBytes*(str: string | cstring): seq[byte] =
|
|
||||||
for chr in str:
|
|
||||||
result.add byte chr
|
|
||||||
result.add byte 0
|
|
||||||
|
|
||||||
proc Create*[T](this; s: T): uoffset = # Both CreateString and CreateByteVector functionality
|
|
||||||
if this.nested:
|
|
||||||
quit("builder is nested")
|
|
||||||
this.nested = true
|
|
||||||
when T is cstring or T is string:
|
|
||||||
let x = s.getBytes()
|
|
||||||
let l = x.len.uoffset
|
|
||||||
this.vectorNumElems = l-1
|
|
||||||
else:
|
|
||||||
let x = s
|
|
||||||
let l = x.len.uoffset
|
|
||||||
this.vectorNumElems = l
|
|
||||||
this.Prep(uoffset.sizeof, l.int * byte.sizeof)
|
|
||||||
this.head -= l
|
|
||||||
this.bytes[this.head..<this.head+l] = x
|
|
||||||
result = this.EndVector()
|
|
||||||
|
|
||||||
proc Finish*(this; rootTable: uoffset) =
|
|
||||||
if this.nested:
|
|
||||||
quit("builder is nested")
|
|
||||||
this.nested = true
|
|
||||||
|
|
||||||
this.Prep(this.minalign, uoffset.sizeof)
|
|
||||||
this.PrependOffsetRelative(rootTable)
|
|
||||||
this.finished = true
|
|
@ -1,12 +0,0 @@
|
|||||||
template swapEndian*(outp, inp: pointer, size: int) =
|
|
||||||
var i = cast[cstring](inp)
|
|
||||||
var o = cast[cstring](outp)
|
|
||||||
for x in 0..<size:
|
|
||||||
o[x] = i[(0..<size).len - x - 1]
|
|
||||||
|
|
||||||
when system.cpuEndian == bigEndian:
|
|
||||||
func littleEndianX*(outp, inp: pointer, size: int) {.inline.} = swapEndian(outp, inp, size)
|
|
||||||
func bigEndianX*(outp, inp: pointer, size: int) {.inline.} = copyMem(outp, inp, size)
|
|
||||||
else:
|
|
||||||
func littleEndianX*(outp, inp: pointer, size: int) {.inline.} = copyMem(outp, inp, size)
|
|
||||||
func bigEndianX*(outp, inp: pointer, size: int) {.inline.} = swapEndian(outp, inp, size)
|
|
@ -1,24 +0,0 @@
|
|||||||
import table
|
|
||||||
|
|
||||||
|
|
||||||
type FlatObj* {.inheritable.} = object
|
|
||||||
tab*: Vtable
|
|
||||||
|
|
||||||
func Table*(this: var FlatObj): Vtable = this.tab
|
|
||||||
|
|
||||||
func Init*(this: var FlatObj; buf: seq[byte]; i: uoffset) =
|
|
||||||
this.tab.Bytes = buf
|
|
||||||
this.tab.Pos = i
|
|
||||||
|
|
||||||
# Cant define it in table.nim since it needs FlatObj and Init
|
|
||||||
func GetUnion*[T: FlatObj](this: var Vtable; off: uoffset): T =
|
|
||||||
result.Init(this.Bytes, this.Indirect(off))
|
|
||||||
|
|
||||||
func GetRootAs*(result: var FlatObj; buf: seq[byte]; offset: uoffset) =
|
|
||||||
var
|
|
||||||
vtable = Vtable(Bytes: buf[offset..^1], Pos: offset)
|
|
||||||
n = Get[uoffset](vtable, offset)
|
|
||||||
result.Init(buf, n+offset)
|
|
||||||
|
|
||||||
func GetRootAs*(result: var FlatObj; buf: string; offset: uoffset) =
|
|
||||||
result.GetRootAs(cast[seq[byte]](buf), offset)
|
|
@ -1,149 +0,0 @@
|
|||||||
import endian
|
|
||||||
|
|
||||||
|
|
||||||
type
|
|
||||||
uoffset* = uint32 ## offset in to the buffer
|
|
||||||
soffset* = int32 ## offset from start of table, to a vtable
|
|
||||||
voffset* = uint16 ## offset from start of table to value
|
|
||||||
|
|
||||||
type Offsets* = uoffset | soffset | voffset
|
|
||||||
|
|
||||||
type Vtable* = object
|
|
||||||
Bytes*: seq[byte]
|
|
||||||
Pos*: uoffset
|
|
||||||
|
|
||||||
|
|
||||||
using this: Vtable
|
|
||||||
|
|
||||||
|
|
||||||
func GetVal*[T](b: ptr seq[byte]): T {.inline.} =
|
|
||||||
when T is float64:
|
|
||||||
result = cast[T](GetVal[uint64](b))
|
|
||||||
elif T is float32:
|
|
||||||
result = cast[T](GetVal[uint32](b))
|
|
||||||
elif T is string:
|
|
||||||
result = cast[T](b[])
|
|
||||||
else:
|
|
||||||
if b[].len < T.sizeof:
|
|
||||||
b[].setLen T.sizeof
|
|
||||||
result = cast[ptr T](unsafeAddr b[][0])[]
|
|
||||||
|
|
||||||
|
|
||||||
template Get*[T](this; off: uoffset): T =
|
|
||||||
var seq = this.Bytes[off..^1]
|
|
||||||
GetVal[T](addr seq)
|
|
||||||
|
|
||||||
template Get*[T](this; off: soffset): T =
|
|
||||||
var seq = this.Bytes[off..^1]
|
|
||||||
GetVal[T](addr seq)
|
|
||||||
|
|
||||||
template Get*[T](this; off: voffset): T =
|
|
||||||
var seq = this.Bytes[off..^1]
|
|
||||||
GetVal[T](addr seq)
|
|
||||||
|
|
||||||
func WriteVal*[T: not SomeFloat](b: var openArray[byte]; off: uoffset;
|
|
||||||
n: T) {.inline.} =
|
|
||||||
when sizeof(T) == 8:
|
|
||||||
littleEndianX(addr b[off], unsafeAddr n, T.sizeof)
|
|
||||||
elif sizeof(T) == 4:
|
|
||||||
littleEndianX(addr b[off], unsafeAddr n, T.sizeof)
|
|
||||||
elif sizeof(T) == 2:
|
|
||||||
littleEndianX(addr b[off], unsafeAddr n, T.sizeof)
|
|
||||||
elif sizeof(T) == 1:
|
|
||||||
b[off] = n.uint8
|
|
||||||
else:
|
|
||||||
discard
|
|
||||||
#littleEndianX(addr b[off], unsafeAddr n, T.sizeof)
|
|
||||||
#{.error:"shouldnt appear".}
|
|
||||||
|
|
||||||
func WriteVal*[T: not SomeFloat](b: var seq[byte]; off: uoffset;
|
|
||||||
n: T) {.inline.} =
|
|
||||||
when sizeof(T) == 8:
|
|
||||||
littleEndianX(addr b[off], unsafeAddr n, T.sizeof)
|
|
||||||
elif sizeof(T) == 4:
|
|
||||||
littleEndianX(addr b[off], unsafeAddr n, T.sizeof)
|
|
||||||
elif sizeof(T) == 2:
|
|
||||||
littleEndianX(addr b[off], unsafeAddr n, T.sizeof)
|
|
||||||
elif sizeof(T) == 1:
|
|
||||||
b[off] = n.uint8
|
|
||||||
else:
|
|
||||||
discard
|
|
||||||
#littleEndianX(addr b[off], unsafeAddr n, T.sizeof)
|
|
||||||
#{.error:"shouldnt appear".}
|
|
||||||
|
|
||||||
func WriteVal*[T: SomeFloat](b: var openArray[byte]; off: uoffset;
|
|
||||||
n: T) {.inline.} =
|
|
||||||
when T is float64:
|
|
||||||
WriteVal(b, off, cast[uint64](n))
|
|
||||||
elif T is float32:
|
|
||||||
WriteVal(b, off, cast[uint32](n))
|
|
||||||
|
|
||||||
func WriteVal*[T: SomeFloat](b: var seq[byte]; off: uoffset; n: T) {.inline.} =
|
|
||||||
when T is float64:
|
|
||||||
WriteVal(b, off, cast[uint64](n))
|
|
||||||
elif T is float32:
|
|
||||||
WriteVal(b, off, cast[uint32](n))
|
|
||||||
|
|
||||||
func Offset*(this; off: voffset): voffset =
|
|
||||||
let vtable = (this.Pos - this.Get[:uoffset](this.Pos)).voffset
|
|
||||||
let vtableEnd = this.Get[:voffset](vtable)
|
|
||||||
if off < vtableEnd:
|
|
||||||
return this.Get[:voffset](vtable + off)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
func Indirect*(this; off: uoffset): uoffset =
|
|
||||||
result = off + this.Get[:uoffset](off)
|
|
||||||
|
|
||||||
func VectorLen*(this; off: uoffset): int =
|
|
||||||
var newoff: uoffset = off + this.Pos
|
|
||||||
newoff += this.Get[:uoffset](newoff)
|
|
||||||
return this.Get[:uoffset](newoff).int
|
|
||||||
|
|
||||||
func Vector*(this; off: uoffset): uoffset =
|
|
||||||
let newoff: uoffset = off + this.Pos
|
|
||||||
var x: uoffset = newoff + this.Get[:uoffset](newoff)
|
|
||||||
x += (uoffset.sizeof).uoffset
|
|
||||||
result = x
|
|
||||||
|
|
||||||
func Union*(this; off: uoffset): Vtable =
|
|
||||||
let newoff: uoffset = off + this.Pos
|
|
||||||
result.Pos = newoff + this.Get[:uoffset](newoff)
|
|
||||||
result.Bytes = this.Bytes
|
|
||||||
|
|
||||||
func GetSlot*[T](this; slot: voffset; d: T): T =
|
|
||||||
let off = this.Offset(slot)
|
|
||||||
if off == 0:
|
|
||||||
return d
|
|
||||||
return this.Get[T](this.Pos + off)
|
|
||||||
|
|
||||||
func GetOffsetSlot*[T: Offsets](this; slot: voffset; d: T): T =
|
|
||||||
let off = this.Offset(slot)
|
|
||||||
if off == 0:
|
|
||||||
return d
|
|
||||||
return off
|
|
||||||
|
|
||||||
func ByteVector*(this; off: uoffset): seq[byte] =
|
|
||||||
let
|
|
||||||
newoff: uoffset = off + this.Get[:uoffset](off)
|
|
||||||
start = newoff + (uoffset.sizeof).uoffset
|
|
||||||
var newseq = this.Bytes[newoff..^1]
|
|
||||||
let
|
|
||||||
length = GetVal[uoffset](addr newseq)
|
|
||||||
result = this.Bytes[start..<start+length]
|
|
||||||
|
|
||||||
func String*(this; off: uoffset): string =
|
|
||||||
var byte_seq = this.ByteVector(off)
|
|
||||||
result = GetVal[string](addr byte_seq)
|
|
||||||
|
|
||||||
using this: var Vtable
|
|
||||||
|
|
||||||
proc Mutate*[T](this; off: uoffset; n: T): bool =
|
|
||||||
WriteVal(this.Bytes, off, n)
|
|
||||||
return true
|
|
||||||
|
|
||||||
func MutateSlot*[T](this; slot: voffset; n: T): bool =
|
|
||||||
let off: voffset = this.Offset(slot)
|
|
||||||
if off != 0:
|
|
||||||
return this.Mutate(this.Pos + off.uoffset, n)
|
|
||||||
return false
|
|
2
third_party/flatbuffers/python/.gitignore
vendored
2
third_party/flatbuffers/python/.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
/dist/
|
|
||||||
/*.egg-info/
|
|
@ -1,19 +0,0 @@
|
|||||||
# Copyright 2014 Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from .builder import Builder
|
|
||||||
from .table import Table
|
|
||||||
from .compat import range_func as compat_range
|
|
||||||
from ._version import __version__
|
|
||||||
from . import util
|
|
@ -1,17 +0,0 @@
|
|||||||
# Copyright 2019 Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
# Placeholder, to be updated during the release process
|
|
||||||
# by the setup.py
|
|
||||||
__version__ = u"24.3.25"
|
|
@ -1,824 +0,0 @@
|
|||||||
# Copyright 2014 Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from . import number_types as N
|
|
||||||
from .number_types import (UOffsetTFlags, SOffsetTFlags, VOffsetTFlags)
|
|
||||||
|
|
||||||
from . import encode
|
|
||||||
from . import packer
|
|
||||||
|
|
||||||
from . import compat
|
|
||||||
from .compat import range_func
|
|
||||||
from .compat import memoryview_type
|
|
||||||
from .compat import import_numpy, NumpyRequiredForThisFeature
|
|
||||||
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
np = import_numpy()
|
|
||||||
## @file
|
|
||||||
## @addtogroup flatbuffers_python_api
|
|
||||||
## @{
|
|
||||||
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
class OffsetArithmeticError(RuntimeError):
|
|
||||||
"""
|
|
||||||
Error caused by an Offset arithmetic error. Probably caused by bad
|
|
||||||
writing of fields. This is considered an unreachable situation in
|
|
||||||
normal circumstances.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class IsNotNestedError(RuntimeError):
|
|
||||||
"""
|
|
||||||
Error caused by using a Builder to write Object data when not inside
|
|
||||||
an Object.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class IsNestedError(RuntimeError):
|
|
||||||
"""
|
|
||||||
Error caused by using a Builder to begin an Object when an Object is
|
|
||||||
already being built.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class StructIsNotInlineError(RuntimeError):
|
|
||||||
"""
|
|
||||||
Error caused by using a Builder to write a Struct at a location that
|
|
||||||
is not the current Offset.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class BuilderSizeError(RuntimeError):
|
|
||||||
"""
|
|
||||||
Error caused by causing a Builder to exceed the hardcoded limit of 2
|
|
||||||
gigabytes.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
class BuilderNotFinishedError(RuntimeError):
|
|
||||||
"""
|
|
||||||
Error caused by not calling `Finish` before calling `Output`.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
class EndVectorLengthMismatched(RuntimeError):
|
|
||||||
"""
|
|
||||||
The number of elements passed to EndVector does not match the number
|
|
||||||
specified in StartVector.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# VtableMetadataFields is the count of metadata fields in each vtable.
|
|
||||||
VtableMetadataFields = 2
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
class Builder(object):
|
|
||||||
""" A Builder is used to construct one or more FlatBuffers.
|
|
||||||
|
|
||||||
Typically, Builder objects will be used from code generated by the `flatc`
|
|
||||||
compiler.
|
|
||||||
|
|
||||||
A Builder constructs byte buffers in a last-first manner for simplicity and
|
|
||||||
performance during reading.
|
|
||||||
|
|
||||||
Internally, a Builder is a state machine for creating FlatBuffer objects.
|
|
||||||
|
|
||||||
It holds the following internal state:
|
|
||||||
- Bytes: an array of bytes.
|
|
||||||
- current_vtable: a list of integers.
|
|
||||||
- vtables: a hash of vtable entries.
|
|
||||||
|
|
||||||
Attributes:
|
|
||||||
Bytes: The internal `bytearray` for the Builder.
|
|
||||||
finished: A boolean determining if the Builder has been finalized.
|
|
||||||
"""
|
|
||||||
|
|
||||||
## @cond FLATBUFFERS_INTENRAL
|
|
||||||
__slots__ = ("Bytes", "current_vtable", "head", "minalign", "objectEnd",
|
|
||||||
"vtables", "nested", "forceDefaults", "finished", "vectorNumElems",
|
|
||||||
"sharedStrings")
|
|
||||||
|
|
||||||
"""Maximum buffer size constant, in bytes.
|
|
||||||
|
|
||||||
Builder will never allow it's buffer grow over this size.
|
|
||||||
Currently equals 2Gb.
|
|
||||||
"""
|
|
||||||
MAX_BUFFER_SIZE = 2**31
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
def __init__(self, initialSize=1024):
|
|
||||||
"""Initializes a Builder of size `initial_size`.
|
|
||||||
|
|
||||||
The internal buffer is grown as needed.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if not (0 <= initialSize <= Builder.MAX_BUFFER_SIZE):
|
|
||||||
msg = "flatbuffers: Cannot create Builder larger than 2 gigabytes."
|
|
||||||
raise BuilderSizeError(msg)
|
|
||||||
|
|
||||||
self.Bytes = bytearray(initialSize)
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
self.current_vtable = None
|
|
||||||
self.head = UOffsetTFlags.py_type(initialSize)
|
|
||||||
self.minalign = 1
|
|
||||||
self.objectEnd = None
|
|
||||||
self.vtables = {}
|
|
||||||
self.nested = False
|
|
||||||
self.forceDefaults = False
|
|
||||||
self.sharedStrings = {}
|
|
||||||
## @endcond
|
|
||||||
self.finished = False
|
|
||||||
|
|
||||||
def Clear(self) -> None:
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
self.current_vtable = None
|
|
||||||
self.head = UOffsetTFlags.py_type(len(self.Bytes))
|
|
||||||
self.minalign = 1
|
|
||||||
self.objectEnd = None
|
|
||||||
self.vtables = {}
|
|
||||||
self.nested = False
|
|
||||||
self.forceDefaults = False
|
|
||||||
self.sharedStrings = {}
|
|
||||||
self.vectorNumElems = None
|
|
||||||
## @endcond
|
|
||||||
self.finished = False
|
|
||||||
|
|
||||||
def Output(self):
|
|
||||||
"""Return the portion of the buffer that has been used for writing data.
|
|
||||||
|
|
||||||
This is the typical way to access the FlatBuffer data inside the
|
|
||||||
builder. If you try to access `Builder.Bytes` directly, you would need
|
|
||||||
to manually index it with `Head()`, since the buffer is constructed
|
|
||||||
backwards.
|
|
||||||
|
|
||||||
It raises BuilderNotFinishedError if the buffer has not been finished
|
|
||||||
with `Finish`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if not self.finished:
|
|
||||||
raise BuilderNotFinishedError()
|
|
||||||
|
|
||||||
return self.Bytes[self.Head():]
|
|
||||||
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
def StartObject(self, numfields):
|
|
||||||
"""StartObject initializes bookkeeping for writing a new object."""
|
|
||||||
|
|
||||||
self.assertNotNested()
|
|
||||||
|
|
||||||
# use 32-bit offsets so that arithmetic doesn't overflow.
|
|
||||||
self.current_vtable = [0 for _ in range_func(numfields)]
|
|
||||||
self.objectEnd = self.Offset()
|
|
||||||
self.nested = True
|
|
||||||
|
|
||||||
def WriteVtable(self):
|
|
||||||
"""
|
|
||||||
WriteVtable serializes the vtable for the current object, if needed.
|
|
||||||
|
|
||||||
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 VOffsetT bytes wide.
|
|
||||||
|
|
||||||
An object has the following format:
|
|
||||||
<SOffsetT: offset to this object's vtable (may be negative)>
|
|
||||||
<byte: data>+
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Prepend a zero scalar to the object. Later in this function we'll
|
|
||||||
# write an offset here that points to the object's vtable:
|
|
||||||
self.PrependSOffsetTRelative(0)
|
|
||||||
|
|
||||||
objectOffset = self.Offset()
|
|
||||||
|
|
||||||
vtKey = []
|
|
||||||
trim = True
|
|
||||||
for elem in reversed(self.current_vtable):
|
|
||||||
if elem == 0:
|
|
||||||
if trim:
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
elem = objectOffset - elem
|
|
||||||
trim = False
|
|
||||||
|
|
||||||
vtKey.append(elem)
|
|
||||||
|
|
||||||
vtKey = tuple(vtKey)
|
|
||||||
vt2Offset = self.vtables.get(vtKey)
|
|
||||||
if vt2Offset is None:
|
|
||||||
# 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:
|
|
||||||
i = len(self.current_vtable) - 1
|
|
||||||
trailing = 0
|
|
||||||
trim = True
|
|
||||||
while i >= 0:
|
|
||||||
off = 0
|
|
||||||
elem = self.current_vtable[i]
|
|
||||||
i -= 1
|
|
||||||
|
|
||||||
if elem == 0:
|
|
||||||
if trim:
|
|
||||||
trailing += 1
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
# Forward reference to field;
|
|
||||||
# use 32bit number to ensure no overflow:
|
|
||||||
off = objectOffset - elem
|
|
||||||
trim = False
|
|
||||||
|
|
||||||
self.PrependVOffsetT(off)
|
|
||||||
|
|
||||||
# The two metadata fields are written last.
|
|
||||||
|
|
||||||
# First, store the object bytesize:
|
|
||||||
objectSize = UOffsetTFlags.py_type(objectOffset - self.objectEnd)
|
|
||||||
self.PrependVOffsetT(VOffsetTFlags.py_type(objectSize))
|
|
||||||
|
|
||||||
# Second, store the vtable bytesize:
|
|
||||||
vBytes = len(self.current_vtable) - trailing + VtableMetadataFields
|
|
||||||
vBytes *= N.VOffsetTFlags.bytewidth
|
|
||||||
self.PrependVOffsetT(VOffsetTFlags.py_type(vBytes))
|
|
||||||
|
|
||||||
# Next, write the offset to the new vtable in the
|
|
||||||
# already-allocated SOffsetT at the beginning of this object:
|
|
||||||
objectStart = SOffsetTFlags.py_type(len(self.Bytes) - objectOffset)
|
|
||||||
encode.Write(packer.soffset, self.Bytes, objectStart,
|
|
||||||
SOffsetTFlags.py_type(self.Offset() - objectOffset))
|
|
||||||
|
|
||||||
# Finally, store this vtable in memory for future
|
|
||||||
# deduplication:
|
|
||||||
self.vtables[vtKey] = self.Offset()
|
|
||||||
else:
|
|
||||||
# Found a duplicate vtable.
|
|
||||||
objectStart = SOffsetTFlags.py_type(len(self.Bytes) - objectOffset)
|
|
||||||
self.head = UOffsetTFlags.py_type(objectStart)
|
|
||||||
|
|
||||||
# Write the offset to the found vtable in the
|
|
||||||
# already-allocated SOffsetT at the beginning of this object:
|
|
||||||
encode.Write(packer.soffset, self.Bytes, self.Head(),
|
|
||||||
SOffsetTFlags.py_type(vt2Offset - objectOffset))
|
|
||||||
|
|
||||||
self.current_vtable = None
|
|
||||||
return objectOffset
|
|
||||||
|
|
||||||
def EndObject(self):
|
|
||||||
"""EndObject writes data necessary to finish object construction."""
|
|
||||||
self.assertNested()
|
|
||||||
self.nested = False
|
|
||||||
return self.WriteVtable()
|
|
||||||
|
|
||||||
def growByteBuffer(self):
|
|
||||||
"""Doubles the size of the byteslice, and copies the old data towards
|
|
||||||
the end of the new buffer (since we build the buffer backwards)."""
|
|
||||||
if len(self.Bytes) == Builder.MAX_BUFFER_SIZE:
|
|
||||||
msg = "flatbuffers: cannot grow buffer beyond 2 gigabytes"
|
|
||||||
raise BuilderSizeError(msg)
|
|
||||||
|
|
||||||
newSize = min(len(self.Bytes) * 2, Builder.MAX_BUFFER_SIZE)
|
|
||||||
if newSize == 0:
|
|
||||||
newSize = 1
|
|
||||||
bytes2 = bytearray(newSize)
|
|
||||||
bytes2[newSize-len(self.Bytes):] = self.Bytes
|
|
||||||
self.Bytes = bytes2
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
def Head(self):
|
|
||||||
"""Get the start of useful data in the underlying byte buffer.
|
|
||||||
|
|
||||||
Note: unlike other functions, this value is interpreted as from the
|
|
||||||
left.
|
|
||||||
"""
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
return self.head
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
def Offset(self):
|
|
||||||
"""Offset relative to the end of the buffer."""
|
|
||||||
return UOffsetTFlags.py_type(len(self.Bytes) - self.Head())
|
|
||||||
|
|
||||||
def Pad(self, n):
|
|
||||||
"""Pad places zeros at the current offset."""
|
|
||||||
for i in range_func(n):
|
|
||||||
self.Place(0, N.Uint8Flags)
|
|
||||||
|
|
||||||
def Prep(self, size, additionalBytes):
|
|
||||||
"""
|
|
||||||
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.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Track the biggest thing we've ever aligned to.
|
|
||||||
if size > self.minalign:
|
|
||||||
self.minalign = size
|
|
||||||
|
|
||||||
# Find the amount of alignment needed such that `size` is properly
|
|
||||||
# aligned after `additionalBytes`:
|
|
||||||
alignSize = (~(len(self.Bytes) - self.Head() + additionalBytes)) + 1
|
|
||||||
alignSize &= (size - 1)
|
|
||||||
|
|
||||||
# Reallocate the buffer if needed:
|
|
||||||
while self.Head() < alignSize+size+additionalBytes:
|
|
||||||
oldBufSize = len(self.Bytes)
|
|
||||||
self.growByteBuffer()
|
|
||||||
updated_head = self.head + len(self.Bytes) - oldBufSize
|
|
||||||
self.head = UOffsetTFlags.py_type(updated_head)
|
|
||||||
self.Pad(alignSize)
|
|
||||||
|
|
||||||
def PrependSOffsetTRelative(self, off):
|
|
||||||
"""
|
|
||||||
PrependSOffsetTRelative prepends an SOffsetT, relative to where it
|
|
||||||
will be written.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Ensure alignment is already done:
|
|
||||||
self.Prep(N.SOffsetTFlags.bytewidth, 0)
|
|
||||||
if not (off <= self.Offset()):
|
|
||||||
msg = "flatbuffers: Offset arithmetic error."
|
|
||||||
raise OffsetArithmeticError(msg)
|
|
||||||
off2 = self.Offset() - off + N.SOffsetTFlags.bytewidth
|
|
||||||
self.PlaceSOffsetT(off2)
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
def PrependUOffsetTRelative(self, off):
|
|
||||||
"""Prepends an unsigned offset into vector data, relative to where it
|
|
||||||
will be written.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Ensure alignment is already done:
|
|
||||||
self.Prep(N.UOffsetTFlags.bytewidth, 0)
|
|
||||||
if not (off <= self.Offset()):
|
|
||||||
msg = "flatbuffers: Offset arithmetic error."
|
|
||||||
raise OffsetArithmeticError(msg)
|
|
||||||
off2 = self.Offset() - off + N.UOffsetTFlags.bytewidth
|
|
||||||
self.PlaceUOffsetT(off2)
|
|
||||||
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
def StartVector(self, elemSize, numElems, alignment):
|
|
||||||
"""
|
|
||||||
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.
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.assertNotNested()
|
|
||||||
self.nested = True
|
|
||||||
self.vectorNumElems = numElems
|
|
||||||
self.Prep(N.Uint32Flags.bytewidth, elemSize*numElems)
|
|
||||||
self.Prep(alignment, elemSize*numElems) # In case alignment > int.
|
|
||||||
return self.Offset()
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
def EndVector(self, numElems = None):
|
|
||||||
"""EndVector writes data necessary to finish vector construction."""
|
|
||||||
|
|
||||||
self.assertNested()
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
self.nested = False
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
if numElems:
|
|
||||||
warnings.warn("numElems is deprecated.",
|
|
||||||
DeprecationWarning, stacklevel=2)
|
|
||||||
if numElems != self.vectorNumElems:
|
|
||||||
raise EndVectorLengthMismatched();
|
|
||||||
|
|
||||||
# we already made space for this, so write without PrependUint32
|
|
||||||
self.PlaceUOffsetT(self.vectorNumElems)
|
|
||||||
self.vectorNumElems = None
|
|
||||||
return self.Offset()
|
|
||||||
|
|
||||||
def CreateSharedString(self, s, encoding='utf-8', errors='strict'):
|
|
||||||
"""
|
|
||||||
CreateSharedString checks if the string is already written to the buffer
|
|
||||||
before calling CreateString.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if s in self.sharedStrings:
|
|
||||||
return self.sharedStrings[s]
|
|
||||||
|
|
||||||
off = self.CreateString(s, encoding, errors)
|
|
||||||
self.sharedStrings[s] = off
|
|
||||||
|
|
||||||
return off
|
|
||||||
|
|
||||||
def CreateString(self, s, encoding='utf-8', errors='strict'):
|
|
||||||
"""CreateString writes a null-terminated byte string as a vector."""
|
|
||||||
|
|
||||||
self.assertNotNested()
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
self.nested = True
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
if isinstance(s, compat.string_types):
|
|
||||||
x = s.encode(encoding, errors)
|
|
||||||
elif isinstance(s, compat.binary_types):
|
|
||||||
x = s
|
|
||||||
else:
|
|
||||||
raise TypeError("non-string passed to CreateString")
|
|
||||||
|
|
||||||
self.Prep(N.UOffsetTFlags.bytewidth, (len(x)+1)*N.Uint8Flags.bytewidth)
|
|
||||||
self.Place(0, N.Uint8Flags)
|
|
||||||
|
|
||||||
l = UOffsetTFlags.py_type(len(s))
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
self.head = UOffsetTFlags.py_type(self.Head() - l)
|
|
||||||
## @endcond
|
|
||||||
self.Bytes[self.Head():self.Head()+l] = x
|
|
||||||
|
|
||||||
self.vectorNumElems = len(x)
|
|
||||||
return self.EndVector()
|
|
||||||
|
|
||||||
def CreateByteVector(self, x):
|
|
||||||
"""CreateString writes a byte vector."""
|
|
||||||
|
|
||||||
self.assertNotNested()
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
self.nested = True
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
if not isinstance(x, compat.binary_types):
|
|
||||||
raise TypeError("non-byte vector passed to CreateByteVector")
|
|
||||||
|
|
||||||
self.Prep(N.UOffsetTFlags.bytewidth, len(x)*N.Uint8Flags.bytewidth)
|
|
||||||
|
|
||||||
l = UOffsetTFlags.py_type(len(x))
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
self.head = UOffsetTFlags.py_type(self.Head() - l)
|
|
||||||
## @endcond
|
|
||||||
self.Bytes[self.Head():self.Head()+l] = x
|
|
||||||
|
|
||||||
self.vectorNumElems = len(x)
|
|
||||||
return self.EndVector()
|
|
||||||
|
|
||||||
def CreateNumpyVector(self, x):
|
|
||||||
"""CreateNumpyVector writes a numpy array into the buffer."""
|
|
||||||
|
|
||||||
if np is None:
|
|
||||||
# Numpy is required for this feature
|
|
||||||
raise NumpyRequiredForThisFeature("Numpy was not found.")
|
|
||||||
|
|
||||||
if not isinstance(x, np.ndarray):
|
|
||||||
raise TypeError("non-numpy-ndarray passed to CreateNumpyVector")
|
|
||||||
|
|
||||||
if x.dtype.kind not in ['b', 'i', 'u', 'f']:
|
|
||||||
raise TypeError("numpy-ndarray holds elements of unsupported datatype")
|
|
||||||
|
|
||||||
if x.ndim > 1:
|
|
||||||
raise TypeError("multidimensional-ndarray passed to CreateNumpyVector")
|
|
||||||
|
|
||||||
self.StartVector(x.itemsize, x.size, x.dtype.alignment)
|
|
||||||
|
|
||||||
# Ensure little endian byte ordering
|
|
||||||
if x.dtype.str[0] == "<":
|
|
||||||
x_lend = x
|
|
||||||
else:
|
|
||||||
x_lend = x.byteswap(inplace=False)
|
|
||||||
|
|
||||||
# Calculate total length
|
|
||||||
l = UOffsetTFlags.py_type(x_lend.itemsize * x_lend.size)
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
self.head = UOffsetTFlags.py_type(self.Head() - l)
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
# tobytes ensures c_contiguous ordering
|
|
||||||
self.Bytes[self.Head():self.Head()+l] = x_lend.tobytes(order='C')
|
|
||||||
|
|
||||||
self.vectorNumElems = x.size
|
|
||||||
return self.EndVector()
|
|
||||||
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
def assertNested(self):
|
|
||||||
"""
|
|
||||||
Check that we are in the process of building an object.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if not self.nested:
|
|
||||||
raise IsNotNestedError()
|
|
||||||
|
|
||||||
def assertNotNested(self):
|
|
||||||
"""
|
|
||||||
Check that no other objects are being built while making this
|
|
||||||
object. If not, raise an exception.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if self.nested:
|
|
||||||
raise IsNestedError()
|
|
||||||
|
|
||||||
def assertStructIsInline(self, obj):
|
|
||||||
"""
|
|
||||||
Structs are always stored inline, so need to be created right
|
|
||||||
where they are used. You'll get this error if you created it
|
|
||||||
elsewhere.
|
|
||||||
"""
|
|
||||||
|
|
||||||
N.enforce_number(obj, N.UOffsetTFlags)
|
|
||||||
if obj != self.Offset():
|
|
||||||
msg = ("flatbuffers: Tried to write a Struct at an Offset that "
|
|
||||||
"is different from the current Offset of the Builder.")
|
|
||||||
raise StructIsNotInlineError(msg)
|
|
||||||
|
|
||||||
def Slot(self, slotnum):
|
|
||||||
"""
|
|
||||||
Slot sets the vtable key `voffset` to the current location in the
|
|
||||||
buffer.
|
|
||||||
|
|
||||||
"""
|
|
||||||
self.assertNested()
|
|
||||||
self.current_vtable[slotnum] = self.Offset()
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
def __Finish(self, rootTable, sizePrefix, file_identifier=None):
|
|
||||||
"""Finish finalizes a buffer, pointing to the given `rootTable`."""
|
|
||||||
N.enforce_number(rootTable, N.UOffsetTFlags)
|
|
||||||
|
|
||||||
prepSize = N.UOffsetTFlags.bytewidth
|
|
||||||
if file_identifier is not None:
|
|
||||||
prepSize += N.Int32Flags.bytewidth
|
|
||||||
if sizePrefix:
|
|
||||||
prepSize += N.Int32Flags.bytewidth
|
|
||||||
self.Prep(self.minalign, prepSize)
|
|
||||||
|
|
||||||
if file_identifier is not None:
|
|
||||||
self.Prep(N.UOffsetTFlags.bytewidth, encode.FILE_IDENTIFIER_LENGTH)
|
|
||||||
|
|
||||||
# Convert bytes object file_identifier to an array of 4 8-bit integers,
|
|
||||||
# and use big-endian to enforce size compliance.
|
|
||||||
# https://docs.python.org/2/library/struct.html#format-characters
|
|
||||||
file_identifier = N.struct.unpack(">BBBB", file_identifier)
|
|
||||||
for i in range(encode.FILE_IDENTIFIER_LENGTH-1, -1, -1):
|
|
||||||
# Place the bytes of the file_identifer in reverse order:
|
|
||||||
self.Place(file_identifier[i], N.Uint8Flags)
|
|
||||||
|
|
||||||
self.PrependUOffsetTRelative(rootTable)
|
|
||||||
if sizePrefix:
|
|
||||||
size = len(self.Bytes) - self.Head()
|
|
||||||
N.enforce_number(size, N.Int32Flags)
|
|
||||||
self.PrependInt32(size)
|
|
||||||
self.finished = True
|
|
||||||
return self.Head()
|
|
||||||
|
|
||||||
def Finish(self, rootTable, file_identifier=None):
|
|
||||||
"""Finish finalizes a buffer, pointing to the given `rootTable`."""
|
|
||||||
return self.__Finish(rootTable, False, file_identifier=file_identifier)
|
|
||||||
|
|
||||||
def FinishSizePrefixed(self, rootTable, file_identifier=None):
|
|
||||||
"""
|
|
||||||
Finish finalizes a buffer, pointing to the given `rootTable`,
|
|
||||||
with the size prefixed.
|
|
||||||
"""
|
|
||||||
return self.__Finish(rootTable, True, file_identifier=file_identifier)
|
|
||||||
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
def Prepend(self, flags, off):
|
|
||||||
self.Prep(flags.bytewidth, 0)
|
|
||||||
self.Place(off, flags)
|
|
||||||
|
|
||||||
def PrependSlot(self, flags, o, x, d):
|
|
||||||
if x is not None:
|
|
||||||
N.enforce_number(x, flags)
|
|
||||||
if d is not None:
|
|
||||||
N.enforce_number(d, flags)
|
|
||||||
if x != d or (self.forceDefaults and d is not None):
|
|
||||||
self.Prepend(flags, x)
|
|
||||||
self.Slot(o)
|
|
||||||
|
|
||||||
def PrependBoolSlot(self, *args): self.PrependSlot(N.BoolFlags, *args)
|
|
||||||
|
|
||||||
def PrependByteSlot(self, *args): self.PrependSlot(N.Uint8Flags, *args)
|
|
||||||
|
|
||||||
def PrependUint8Slot(self, *args): self.PrependSlot(N.Uint8Flags, *args)
|
|
||||||
|
|
||||||
def PrependUint16Slot(self, *args): self.PrependSlot(N.Uint16Flags, *args)
|
|
||||||
|
|
||||||
def PrependUint32Slot(self, *args): self.PrependSlot(N.Uint32Flags, *args)
|
|
||||||
|
|
||||||
def PrependUint64Slot(self, *args): self.PrependSlot(N.Uint64Flags, *args)
|
|
||||||
|
|
||||||
def PrependInt8Slot(self, *args): self.PrependSlot(N.Int8Flags, *args)
|
|
||||||
|
|
||||||
def PrependInt16Slot(self, *args): self.PrependSlot(N.Int16Flags, *args)
|
|
||||||
|
|
||||||
def PrependInt32Slot(self, *args): self.PrependSlot(N.Int32Flags, *args)
|
|
||||||
|
|
||||||
def PrependInt64Slot(self, *args): self.PrependSlot(N.Int64Flags, *args)
|
|
||||||
|
|
||||||
def PrependFloat32Slot(self, *args): self.PrependSlot(N.Float32Flags,
|
|
||||||
*args)
|
|
||||||
|
|
||||||
def PrependFloat64Slot(self, *args): self.PrependSlot(N.Float64Flags,
|
|
||||||
*args)
|
|
||||||
|
|
||||||
def PrependUOffsetTRelativeSlot(self, o, x, d):
|
|
||||||
"""
|
|
||||||
PrependUOffsetTRelativeSlot 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.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if x != d or self.forceDefaults:
|
|
||||||
self.PrependUOffsetTRelative(x)
|
|
||||||
self.Slot(o)
|
|
||||||
|
|
||||||
def PrependStructSlot(self, v, x, d):
|
|
||||||
"""
|
|
||||||
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.
|
|
||||||
"""
|
|
||||||
|
|
||||||
N.enforce_number(d, N.UOffsetTFlags)
|
|
||||||
if x != d:
|
|
||||||
self.assertStructIsInline(x)
|
|
||||||
self.Slot(v)
|
|
||||||
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
def PrependBool(self, x):
|
|
||||||
"""Prepend a `bool` to the Builder buffer.
|
|
||||||
|
|
||||||
Note: aligns and checks for space.
|
|
||||||
"""
|
|
||||||
self.Prepend(N.BoolFlags, x)
|
|
||||||
|
|
||||||
def PrependByte(self, x):
|
|
||||||
"""Prepend a `byte` to the Builder buffer.
|
|
||||||
|
|
||||||
Note: aligns and checks for space.
|
|
||||||
"""
|
|
||||||
self.Prepend(N.Uint8Flags, x)
|
|
||||||
|
|
||||||
def PrependUint8(self, x):
|
|
||||||
"""Prepend an `uint8` to the Builder buffer.
|
|
||||||
|
|
||||||
Note: aligns and checks for space.
|
|
||||||
"""
|
|
||||||
self.Prepend(N.Uint8Flags, x)
|
|
||||||
|
|
||||||
def PrependUint16(self, x):
|
|
||||||
"""Prepend an `uint16` to the Builder buffer.
|
|
||||||
|
|
||||||
Note: aligns and checks for space.
|
|
||||||
"""
|
|
||||||
self.Prepend(N.Uint16Flags, x)
|
|
||||||
|
|
||||||
def PrependUint32(self, x):
|
|
||||||
"""Prepend an `uint32` to the Builder buffer.
|
|
||||||
|
|
||||||
Note: aligns and checks for space.
|
|
||||||
"""
|
|
||||||
self.Prepend(N.Uint32Flags, x)
|
|
||||||
|
|
||||||
def PrependUint64(self, x):
|
|
||||||
"""Prepend an `uint64` to the Builder buffer.
|
|
||||||
|
|
||||||
Note: aligns and checks for space.
|
|
||||||
"""
|
|
||||||
self.Prepend(N.Uint64Flags, x)
|
|
||||||
|
|
||||||
def PrependInt8(self, x):
|
|
||||||
"""Prepend an `int8` to the Builder buffer.
|
|
||||||
|
|
||||||
Note: aligns and checks for space.
|
|
||||||
"""
|
|
||||||
self.Prepend(N.Int8Flags, x)
|
|
||||||
|
|
||||||
def PrependInt16(self, x):
|
|
||||||
"""Prepend an `int16` to the Builder buffer.
|
|
||||||
|
|
||||||
Note: aligns and checks for space.
|
|
||||||
"""
|
|
||||||
self.Prepend(N.Int16Flags, x)
|
|
||||||
|
|
||||||
def PrependInt32(self, x):
|
|
||||||
"""Prepend an `int32` to the Builder buffer.
|
|
||||||
|
|
||||||
Note: aligns and checks for space.
|
|
||||||
"""
|
|
||||||
self.Prepend(N.Int32Flags, x)
|
|
||||||
|
|
||||||
def PrependInt64(self, x):
|
|
||||||
"""Prepend an `int64` to the Builder buffer.
|
|
||||||
|
|
||||||
Note: aligns and checks for space.
|
|
||||||
"""
|
|
||||||
self.Prepend(N.Int64Flags, x)
|
|
||||||
|
|
||||||
def PrependFloat32(self, x):
|
|
||||||
"""Prepend a `float32` to the Builder buffer.
|
|
||||||
|
|
||||||
Note: aligns and checks for space.
|
|
||||||
"""
|
|
||||||
self.Prepend(N.Float32Flags, x)
|
|
||||||
|
|
||||||
def PrependFloat64(self, x):
|
|
||||||
"""Prepend a `float64` to the Builder buffer.
|
|
||||||
|
|
||||||
Note: aligns and checks for space.
|
|
||||||
"""
|
|
||||||
self.Prepend(N.Float64Flags, x)
|
|
||||||
|
|
||||||
def ForceDefaults(self, forceDefaults):
|
|
||||||
"""
|
|
||||||
In order to save space, fields that are set to their default value
|
|
||||||
don't get serialized into the buffer. Forcing defaults provides a
|
|
||||||
way to manually disable this optimization. When set to `True`, will
|
|
||||||
always serialize default values.
|
|
||||||
"""
|
|
||||||
self.forceDefaults = forceDefaults
|
|
||||||
|
|
||||||
##############################################################
|
|
||||||
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
def PrependVOffsetT(self, x): self.Prepend(N.VOffsetTFlags, x)
|
|
||||||
|
|
||||||
def Place(self, x, flags):
|
|
||||||
"""
|
|
||||||
Place prepends a value specified by `flags` to the Builder,
|
|
||||||
without checking for available space.
|
|
||||||
"""
|
|
||||||
|
|
||||||
N.enforce_number(x, flags)
|
|
||||||
self.head = self.head - flags.bytewidth
|
|
||||||
encode.Write(flags.packer_type, self.Bytes, self.Head(), x)
|
|
||||||
|
|
||||||
def PlaceVOffsetT(self, x):
|
|
||||||
"""PlaceVOffsetT prepends a VOffsetT to the Builder, without checking
|
|
||||||
for space.
|
|
||||||
"""
|
|
||||||
N.enforce_number(x, N.VOffsetTFlags)
|
|
||||||
self.head = self.head - N.VOffsetTFlags.bytewidth
|
|
||||||
encode.Write(packer.voffset, self.Bytes, self.Head(), x)
|
|
||||||
|
|
||||||
def PlaceSOffsetT(self, x):
|
|
||||||
"""PlaceSOffsetT prepends a SOffsetT to the Builder, without checking
|
|
||||||
for space.
|
|
||||||
"""
|
|
||||||
N.enforce_number(x, N.SOffsetTFlags)
|
|
||||||
self.head = self.head - N.SOffsetTFlags.bytewidth
|
|
||||||
encode.Write(packer.soffset, self.Bytes, self.Head(), x)
|
|
||||||
|
|
||||||
def PlaceUOffsetT(self, x):
|
|
||||||
"""PlaceUOffsetT prepends a UOffsetT to the Builder, without checking
|
|
||||||
for space.
|
|
||||||
"""
|
|
||||||
N.enforce_number(x, N.UOffsetTFlags)
|
|
||||||
self.head = self.head - N.UOffsetTFlags.bytewidth
|
|
||||||
encode.Write(packer.uoffset, self.Bytes, self.Head(), x)
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
def vtableEqual(a, objectStart, b):
|
|
||||||
"""vtableEqual compares an unwritten vtable to a written vtable."""
|
|
||||||
|
|
||||||
N.enforce_number(objectStart, N.UOffsetTFlags)
|
|
||||||
|
|
||||||
if len(a) * N.VOffsetTFlags.bytewidth != len(b):
|
|
||||||
return False
|
|
||||||
|
|
||||||
for i, elem in enumerate(a):
|
|
||||||
x = encode.Get(packer.voffset, b, i * N.VOffsetTFlags.bytewidth)
|
|
||||||
|
|
||||||
# Skip vtable entries that indicate a default value.
|
|
||||||
if x == 0 and elem == 0:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
y = objectStart - elem
|
|
||||||
if x != y:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
## @endcond
|
|
||||||
## @}
|
|
@ -1,86 +0,0 @@
|
|||||||
# Copyright 2016 Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
""" A tiny version of `six` to help with backwards compability. Also includes
|
|
||||||
compatibility helpers for numpy. """
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
PY2 = sys.version_info[0] == 2
|
|
||||||
PY26 = sys.version_info[0:2] == (2, 6)
|
|
||||||
PY27 = sys.version_info[0:2] == (2, 7)
|
|
||||||
PY275 = sys.version_info[0:3] >= (2, 7, 5)
|
|
||||||
PY3 = sys.version_info[0] == 3
|
|
||||||
PY34 = sys.version_info[0:2] >= (3, 4)
|
|
||||||
|
|
||||||
if PY3:
|
|
||||||
import importlib.machinery
|
|
||||||
string_types = (str,)
|
|
||||||
binary_types = (bytes,bytearray)
|
|
||||||
range_func = range
|
|
||||||
memoryview_type = memoryview
|
|
||||||
struct_bool_decl = "?"
|
|
||||||
else:
|
|
||||||
import imp
|
|
||||||
string_types = (unicode,)
|
|
||||||
if PY26 or PY27:
|
|
||||||
binary_types = (str,bytearray)
|
|
||||||
else:
|
|
||||||
binary_types = (str,)
|
|
||||||
range_func = xrange
|
|
||||||
if PY26 or (PY27 and not PY275):
|
|
||||||
memoryview_type = buffer
|
|
||||||
struct_bool_decl = "<b"
|
|
||||||
else:
|
|
||||||
memoryview_type = memoryview
|
|
||||||
struct_bool_decl = "?"
|
|
||||||
|
|
||||||
# Helper functions to facilitate making numpy optional instead of required
|
|
||||||
|
|
||||||
def import_numpy():
|
|
||||||
"""
|
|
||||||
Returns the numpy module if it exists on the system,
|
|
||||||
otherwise returns None.
|
|
||||||
"""
|
|
||||||
if PY3:
|
|
||||||
numpy_exists = (
|
|
||||||
importlib.machinery.PathFinder.find_spec('numpy') is not None)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
imp.find_module('numpy')
|
|
||||||
numpy_exists = True
|
|
||||||
except ImportError:
|
|
||||||
numpy_exists = False
|
|
||||||
|
|
||||||
if numpy_exists:
|
|
||||||
# We do this outside of try/except block in case numpy exists
|
|
||||||
# but is not installed correctly. We do not want to catch an
|
|
||||||
# incorrect installation which would manifest as an
|
|
||||||
# ImportError.
|
|
||||||
import numpy as np
|
|
||||||
else:
|
|
||||||
np = None
|
|
||||||
|
|
||||||
return np
|
|
||||||
|
|
||||||
|
|
||||||
class NumpyRequiredForThisFeature(RuntimeError):
|
|
||||||
"""
|
|
||||||
Error raised when user tries to use a feature that
|
|
||||||
requires numpy without having numpy installed.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# NOTE: Future Jython support may require code here (look at `six`).
|
|
@ -1,42 +0,0 @@
|
|||||||
# Copyright 2014 Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from . import number_types as N
|
|
||||||
from . import packer
|
|
||||||
from .compat import memoryview_type
|
|
||||||
from .compat import import_numpy, NumpyRequiredForThisFeature
|
|
||||||
|
|
||||||
np = import_numpy()
|
|
||||||
|
|
||||||
FILE_IDENTIFIER_LENGTH=4
|
|
||||||
|
|
||||||
def Get(packer_type, buf, head):
|
|
||||||
""" Get decodes a value at buf[head] using `packer_type`. """
|
|
||||||
return packer_type.unpack_from(memoryview_type(buf), head)[0]
|
|
||||||
|
|
||||||
|
|
||||||
def GetVectorAsNumpy(numpy_type, buf, count, offset):
|
|
||||||
""" GetVecAsNumpy decodes values starting at buf[head] as
|
|
||||||
`numpy_type`, where `numpy_type` is a numpy dtype. """
|
|
||||||
if np is not None:
|
|
||||||
# TODO: could set .flags.writeable = False to make users jump through
|
|
||||||
# hoops before modifying...
|
|
||||||
return np.frombuffer(buf, dtype=numpy_type, count=count, offset=offset)
|
|
||||||
else:
|
|
||||||
raise NumpyRequiredForThisFeature('Numpy was not found.')
|
|
||||||
|
|
||||||
|
|
||||||
def Write(packer_type, buf, head, n):
|
|
||||||
""" Write encodes `n` at buf[head] using `packer_type`. """
|
|
||||||
packer_type.pack_into(buf, head, n)
|
|
File diff suppressed because it is too large
Load Diff
@ -1,181 +0,0 @@
|
|||||||
# Copyright 2014 Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
import collections
|
|
||||||
import struct
|
|
||||||
|
|
||||||
from . import packer
|
|
||||||
from .compat import import_numpy, NumpyRequiredForThisFeature
|
|
||||||
|
|
||||||
np = import_numpy()
|
|
||||||
|
|
||||||
# For reference, see:
|
|
||||||
# https://docs.python.org/2/library/ctypes.html#ctypes-fundamental-data-types-2
|
|
||||||
|
|
||||||
# These classes could be collections.namedtuple instances, but those are new
|
|
||||||
# in 2.6 and we want to work towards 2.5 compatability.
|
|
||||||
|
|
||||||
class BoolFlags(object):
|
|
||||||
bytewidth = 1
|
|
||||||
min_val = False
|
|
||||||
max_val = True
|
|
||||||
py_type = bool
|
|
||||||
name = "bool"
|
|
||||||
packer_type = packer.boolean
|
|
||||||
|
|
||||||
|
|
||||||
class Uint8Flags(object):
|
|
||||||
bytewidth = 1
|
|
||||||
min_val = 0
|
|
||||||
max_val = (2**8) - 1
|
|
||||||
py_type = int
|
|
||||||
name = "uint8"
|
|
||||||
packer_type = packer.uint8
|
|
||||||
|
|
||||||
|
|
||||||
class Uint16Flags(object):
|
|
||||||
bytewidth = 2
|
|
||||||
min_val = 0
|
|
||||||
max_val = (2**16) - 1
|
|
||||||
py_type = int
|
|
||||||
name = "uint16"
|
|
||||||
packer_type = packer.uint16
|
|
||||||
|
|
||||||
|
|
||||||
class Uint32Flags(object):
|
|
||||||
bytewidth = 4
|
|
||||||
min_val = 0
|
|
||||||
max_val = (2**32) - 1
|
|
||||||
py_type = int
|
|
||||||
name = "uint32"
|
|
||||||
packer_type = packer.uint32
|
|
||||||
|
|
||||||
|
|
||||||
class Uint64Flags(object):
|
|
||||||
bytewidth = 8
|
|
||||||
min_val = 0
|
|
||||||
max_val = (2**64) - 1
|
|
||||||
py_type = int
|
|
||||||
name = "uint64"
|
|
||||||
packer_type = packer.uint64
|
|
||||||
|
|
||||||
|
|
||||||
class Int8Flags(object):
|
|
||||||
bytewidth = 1
|
|
||||||
min_val = -(2**7)
|
|
||||||
max_val = (2**7) - 1
|
|
||||||
py_type = int
|
|
||||||
name = "int8"
|
|
||||||
packer_type = packer.int8
|
|
||||||
|
|
||||||
|
|
||||||
class Int16Flags(object):
|
|
||||||
bytewidth = 2
|
|
||||||
min_val = -(2**15)
|
|
||||||
max_val = (2**15) - 1
|
|
||||||
py_type = int
|
|
||||||
name = "int16"
|
|
||||||
packer_type = packer.int16
|
|
||||||
|
|
||||||
|
|
||||||
class Int32Flags(object):
|
|
||||||
bytewidth = 4
|
|
||||||
min_val = -(2**31)
|
|
||||||
max_val = (2**31) - 1
|
|
||||||
py_type = int
|
|
||||||
name = "int32"
|
|
||||||
packer_type = packer.int32
|
|
||||||
|
|
||||||
|
|
||||||
class Int64Flags(object):
|
|
||||||
bytewidth = 8
|
|
||||||
min_val = -(2**63)
|
|
||||||
max_val = (2**63) - 1
|
|
||||||
py_type = int
|
|
||||||
name = "int64"
|
|
||||||
packer_type = packer.int64
|
|
||||||
|
|
||||||
|
|
||||||
class Float32Flags(object):
|
|
||||||
bytewidth = 4
|
|
||||||
min_val = None
|
|
||||||
max_val = None
|
|
||||||
py_type = float
|
|
||||||
name = "float32"
|
|
||||||
packer_type = packer.float32
|
|
||||||
|
|
||||||
|
|
||||||
class Float64Flags(object):
|
|
||||||
bytewidth = 8
|
|
||||||
min_val = None
|
|
||||||
max_val = None
|
|
||||||
py_type = float
|
|
||||||
name = "float64"
|
|
||||||
packer_type = packer.float64
|
|
||||||
|
|
||||||
|
|
||||||
class SOffsetTFlags(Int32Flags):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class UOffsetTFlags(Uint32Flags):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class VOffsetTFlags(Uint16Flags):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def valid_number(n, flags):
|
|
||||||
if flags.min_val is None and flags.max_val is None:
|
|
||||||
return True
|
|
||||||
return flags.min_val <= n <= flags.max_val
|
|
||||||
|
|
||||||
|
|
||||||
def enforce_number(n, flags):
|
|
||||||
if flags.min_val is None and flags.max_val is None:
|
|
||||||
return
|
|
||||||
if not flags.min_val <= n <= flags.max_val:
|
|
||||||
raise TypeError("bad number %s for type %s" % (str(n), flags.name))
|
|
||||||
|
|
||||||
|
|
||||||
def float32_to_uint32(n):
|
|
||||||
packed = struct.pack("<1f", n)
|
|
||||||
(converted,) = struct.unpack("<1L", packed)
|
|
||||||
return converted
|
|
||||||
|
|
||||||
|
|
||||||
def uint32_to_float32(n):
|
|
||||||
packed = struct.pack("<1L", n)
|
|
||||||
(unpacked,) = struct.unpack("<1f", packed)
|
|
||||||
return unpacked
|
|
||||||
|
|
||||||
|
|
||||||
def float64_to_uint64(n):
|
|
||||||
packed = struct.pack("<1d", n)
|
|
||||||
(converted,) = struct.unpack("<1Q", packed)
|
|
||||||
return converted
|
|
||||||
|
|
||||||
|
|
||||||
def uint64_to_float64(n):
|
|
||||||
packed = struct.pack("<1Q", n)
|
|
||||||
(unpacked,) = struct.unpack("<1d", packed)
|
|
||||||
return unpacked
|
|
||||||
|
|
||||||
|
|
||||||
def to_numpy_type(number_type):
|
|
||||||
if np is not None:
|
|
||||||
return np.dtype(number_type.name).newbyteorder('<')
|
|
||||||
else:
|
|
||||||
raise NumpyRequiredForThisFeature('Numpy was not found.')
|
|
@ -1,42 +0,0 @@
|
|||||||
# Copyright 2016 Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
"""
|
|
||||||
Provide pre-compiled struct packers for encoding and decoding.
|
|
||||||
|
|
||||||
See: https://docs.python.org/2/library/struct.html#format-characters
|
|
||||||
"""
|
|
||||||
|
|
||||||
import struct
|
|
||||||
from . import compat
|
|
||||||
|
|
||||||
|
|
||||||
boolean = struct.Struct(compat.struct_bool_decl)
|
|
||||||
|
|
||||||
uint8 = struct.Struct("<B")
|
|
||||||
uint16 = struct.Struct("<H")
|
|
||||||
uint32 = struct.Struct("<I")
|
|
||||||
uint64 = struct.Struct("<Q")
|
|
||||||
|
|
||||||
int8 = struct.Struct("<b")
|
|
||||||
int16 = struct.Struct("<h")
|
|
||||||
int32 = struct.Struct("<i")
|
|
||||||
int64 = struct.Struct("<q")
|
|
||||||
|
|
||||||
float32 = struct.Struct("<f")
|
|
||||||
float64 = struct.Struct("<d")
|
|
||||||
|
|
||||||
uoffset = uint32
|
|
||||||
soffset = int32
|
|
||||||
voffset = uint16
|
|
@ -1,10 +0,0 @@
|
|||||||
# automatically generated by the FlatBuffers compiler, do not modify
|
|
||||||
|
|
||||||
# namespace: reflection
|
|
||||||
|
|
||||||
# New schema language features that are not supported by old code generators.
|
|
||||||
class AdvancedFeatures(object):
|
|
||||||
AdvancedArrayFeatures = 1
|
|
||||||
AdvancedUnionFeatures = 2
|
|
||||||
OptionalScalars = 4
|
|
||||||
DefaultVectorsAndStrings = 8
|
|
@ -1,25 +0,0 @@
|
|||||||
# automatically generated by the FlatBuffers compiler, do not modify
|
|
||||||
|
|
||||||
# namespace: reflection
|
|
||||||
|
|
||||||
class BaseType(object):
|
|
||||||
None_ = 0
|
|
||||||
UType = 1
|
|
||||||
Bool = 2
|
|
||||||
Byte = 3
|
|
||||||
UByte = 4
|
|
||||||
Short = 5
|
|
||||||
UShort = 6
|
|
||||||
Int = 7
|
|
||||||
UInt = 8
|
|
||||||
Long = 9
|
|
||||||
ULong = 10
|
|
||||||
Float = 11
|
|
||||||
Double = 12
|
|
||||||
String = 13
|
|
||||||
Vector = 14
|
|
||||||
Obj = 15
|
|
||||||
Union = 16
|
|
||||||
Array = 17
|
|
||||||
Vector64 = 18
|
|
||||||
MaxBaseType = 19
|
|
@ -1,204 +0,0 @@
|
|||||||
# automatically generated by the FlatBuffers compiler, do not modify
|
|
||||||
|
|
||||||
# namespace: reflection
|
|
||||||
|
|
||||||
import flatbuffers
|
|
||||||
from flatbuffers.compat import import_numpy
|
|
||||||
np = import_numpy()
|
|
||||||
|
|
||||||
class Enum(object):
|
|
||||||
__slots__ = ['_tab']
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAs(cls, buf, offset=0):
|
|
||||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
|
||||||
x = Enum()
|
|
||||||
x.Init(buf, n + offset)
|
|
||||||
return x
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAsEnum(cls, buf, offset=0):
|
|
||||||
"""This method is deprecated. Please switch to GetRootAs."""
|
|
||||||
return cls.GetRootAs(buf, offset)
|
|
||||||
@classmethod
|
|
||||||
def EnumBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
|
|
||||||
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
|
|
||||||
|
|
||||||
# Enum
|
|
||||||
def Init(self, buf, pos):
|
|
||||||
self._tab = flatbuffers.table.Table(buf, pos)
|
|
||||||
|
|
||||||
# Enum
|
|
||||||
def Name(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Enum
|
|
||||||
def Values(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Vector(o)
|
|
||||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
|
||||||
x = self._tab.Indirect(x)
|
|
||||||
from reflection.EnumVal import EnumVal
|
|
||||||
obj = EnumVal()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Enum
|
|
||||||
def ValuesLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Enum
|
|
||||||
def ValuesIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# Enum
|
|
||||||
def IsUnion(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
|
|
||||||
if o != 0:
|
|
||||||
return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Enum
|
|
||||||
def UnderlyingType(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Indirect(o + self._tab.Pos)
|
|
||||||
from reflection.Type import Type
|
|
||||||
obj = Type()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Enum
|
|
||||||
def Attributes(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Vector(o)
|
|
||||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
|
||||||
x = self._tab.Indirect(x)
|
|
||||||
from reflection.KeyValue import KeyValue
|
|
||||||
obj = KeyValue()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Enum
|
|
||||||
def AttributesLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Enum
|
|
||||||
def AttributesIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# Enum
|
|
||||||
def Documentation(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
if o != 0:
|
|
||||||
a = self._tab.Vector(o)
|
|
||||||
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# Enum
|
|
||||||
def DocumentationLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Enum
|
|
||||||
def DocumentationIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# File that this Enum is declared in.
|
|
||||||
# Enum
|
|
||||||
def DeclarationFile(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def EnumStart(builder):
|
|
||||||
builder.StartObject(7)
|
|
||||||
|
|
||||||
def Start(builder):
|
|
||||||
EnumStart(builder)
|
|
||||||
|
|
||||||
def EnumAddName(builder, name):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
|
|
||||||
|
|
||||||
def AddName(builder, name):
|
|
||||||
EnumAddName(builder, name)
|
|
||||||
|
|
||||||
def EnumAddValues(builder, values):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(values), 0)
|
|
||||||
|
|
||||||
def AddValues(builder, values):
|
|
||||||
EnumAddValues(builder, values)
|
|
||||||
|
|
||||||
def EnumStartValuesVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartValuesVector(builder, numElems):
|
|
||||||
return EnumStartValuesVector(builder, numElems)
|
|
||||||
|
|
||||||
def EnumAddIsUnion(builder, isUnion):
|
|
||||||
builder.PrependBoolSlot(2, isUnion, 0)
|
|
||||||
|
|
||||||
def AddIsUnion(builder, isUnion):
|
|
||||||
EnumAddIsUnion(builder, isUnion)
|
|
||||||
|
|
||||||
def EnumAddUnderlyingType(builder, underlyingType):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(underlyingType), 0)
|
|
||||||
|
|
||||||
def AddUnderlyingType(builder, underlyingType):
|
|
||||||
EnumAddUnderlyingType(builder, underlyingType)
|
|
||||||
|
|
||||||
def EnumAddAttributes(builder, attributes):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
|
|
||||||
|
|
||||||
def AddAttributes(builder, attributes):
|
|
||||||
EnumAddAttributes(builder, attributes)
|
|
||||||
|
|
||||||
def EnumStartAttributesVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartAttributesVector(builder, numElems):
|
|
||||||
return EnumStartAttributesVector(builder, numElems)
|
|
||||||
|
|
||||||
def EnumAddDocumentation(builder, documentation):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
|
||||||
|
|
||||||
def AddDocumentation(builder, documentation):
|
|
||||||
EnumAddDocumentation(builder, documentation)
|
|
||||||
|
|
||||||
def EnumStartDocumentationVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartDocumentationVector(builder, numElems):
|
|
||||||
return EnumStartDocumentationVector(builder, numElems)
|
|
||||||
|
|
||||||
def EnumAddDeclarationFile(builder, declarationFile):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(6, flatbuffers.number_types.UOffsetTFlags.py_type(declarationFile), 0)
|
|
||||||
|
|
||||||
def AddDeclarationFile(builder, declarationFile):
|
|
||||||
EnumAddDeclarationFile(builder, declarationFile)
|
|
||||||
|
|
||||||
def EnumEnd(builder):
|
|
||||||
return builder.EndObject()
|
|
||||||
|
|
||||||
def End(builder):
|
|
||||||
return EnumEnd(builder)
|
|
@ -1,153 +0,0 @@
|
|||||||
# automatically generated by the FlatBuffers compiler, do not modify
|
|
||||||
|
|
||||||
# namespace: reflection
|
|
||||||
|
|
||||||
import flatbuffers
|
|
||||||
from flatbuffers.compat import import_numpy
|
|
||||||
np = import_numpy()
|
|
||||||
|
|
||||||
class EnumVal(object):
|
|
||||||
__slots__ = ['_tab']
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAs(cls, buf, offset=0):
|
|
||||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
|
||||||
x = EnumVal()
|
|
||||||
x.Init(buf, n + offset)
|
|
||||||
return x
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAsEnumVal(cls, buf, offset=0):
|
|
||||||
"""This method is deprecated. Please switch to GetRootAs."""
|
|
||||||
return cls.GetRootAs(buf, offset)
|
|
||||||
@classmethod
|
|
||||||
def EnumValBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
|
|
||||||
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
|
|
||||||
|
|
||||||
# EnumVal
|
|
||||||
def Init(self, buf, pos):
|
|
||||||
self._tab = flatbuffers.table.Table(buf, pos)
|
|
||||||
|
|
||||||
# EnumVal
|
|
||||||
def Name(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
# EnumVal
|
|
||||||
def Value(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# EnumVal
|
|
||||||
def UnionType(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Indirect(o + self._tab.Pos)
|
|
||||||
from reflection.Type import Type
|
|
||||||
obj = Type()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# EnumVal
|
|
||||||
def Documentation(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
if o != 0:
|
|
||||||
a = self._tab.Vector(o)
|
|
||||||
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# EnumVal
|
|
||||||
def DocumentationLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# EnumVal
|
|
||||||
def DocumentationIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# EnumVal
|
|
||||||
def Attributes(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Vector(o)
|
|
||||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
|
||||||
x = self._tab.Indirect(x)
|
|
||||||
from reflection.KeyValue import KeyValue
|
|
||||||
obj = KeyValue()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# EnumVal
|
|
||||||
def AttributesLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# EnumVal
|
|
||||||
def AttributesIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
def EnumValStart(builder):
|
|
||||||
builder.StartObject(6)
|
|
||||||
|
|
||||||
def Start(builder):
|
|
||||||
EnumValStart(builder)
|
|
||||||
|
|
||||||
def EnumValAddName(builder, name):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
|
|
||||||
|
|
||||||
def AddName(builder, name):
|
|
||||||
EnumValAddName(builder, name)
|
|
||||||
|
|
||||||
def EnumValAddValue(builder, value):
|
|
||||||
builder.PrependInt64Slot(1, value, 0)
|
|
||||||
|
|
||||||
def AddValue(builder, value):
|
|
||||||
EnumValAddValue(builder, value)
|
|
||||||
|
|
||||||
def EnumValAddUnionType(builder, unionType):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(unionType), 0)
|
|
||||||
|
|
||||||
def AddUnionType(builder, unionType):
|
|
||||||
EnumValAddUnionType(builder, unionType)
|
|
||||||
|
|
||||||
def EnumValAddDocumentation(builder, documentation):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
|
||||||
|
|
||||||
def AddDocumentation(builder, documentation):
|
|
||||||
EnumValAddDocumentation(builder, documentation)
|
|
||||||
|
|
||||||
def EnumValStartDocumentationVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartDocumentationVector(builder, numElems):
|
|
||||||
return EnumValStartDocumentationVector(builder, numElems)
|
|
||||||
|
|
||||||
def EnumValAddAttributes(builder, attributes):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
|
|
||||||
|
|
||||||
def AddAttributes(builder, attributes):
|
|
||||||
EnumValAddAttributes(builder, attributes)
|
|
||||||
|
|
||||||
def EnumValStartAttributesVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartAttributesVector(builder, numElems):
|
|
||||||
return EnumValStartAttributesVector(builder, numElems)
|
|
||||||
|
|
||||||
def EnumValEnd(builder):
|
|
||||||
return builder.EndObject()
|
|
||||||
|
|
||||||
def End(builder):
|
|
||||||
return EnumValEnd(builder)
|
|
@ -1,272 +0,0 @@
|
|||||||
# automatically generated by the FlatBuffers compiler, do not modify
|
|
||||||
|
|
||||||
# namespace: reflection
|
|
||||||
|
|
||||||
import flatbuffers
|
|
||||||
from flatbuffers.compat import import_numpy
|
|
||||||
np = import_numpy()
|
|
||||||
|
|
||||||
class Field(object):
|
|
||||||
__slots__ = ['_tab']
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAs(cls, buf, offset=0):
|
|
||||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
|
||||||
x = Field()
|
|
||||||
x.Init(buf, n + offset)
|
|
||||||
return x
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAsField(cls, buf, offset=0):
|
|
||||||
"""This method is deprecated. Please switch to GetRootAs."""
|
|
||||||
return cls.GetRootAs(buf, offset)
|
|
||||||
@classmethod
|
|
||||||
def FieldBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
|
|
||||||
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def Init(self, buf, pos):
|
|
||||||
self._tab = flatbuffers.table.Table(buf, pos)
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def Name(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def Type(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Indirect(o + self._tab.Pos)
|
|
||||||
from reflection.Type import Type
|
|
||||||
obj = Type()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def Id(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def Offset(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def DefaultInteger(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def DefaultReal(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
|
|
||||||
return 0.0
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def Deprecated(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
|
|
||||||
if o != 0:
|
|
||||||
return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def Required(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
|
|
||||||
if o != 0:
|
|
||||||
return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def Key(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
|
|
||||||
if o != 0:
|
|
||||||
return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def Attributes(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Vector(o)
|
|
||||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
|
||||||
x = self._tab.Indirect(x)
|
|
||||||
from reflection.KeyValue import KeyValue
|
|
||||||
obj = KeyValue()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def AttributesLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def AttributesIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def Documentation(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
|
|
||||||
if o != 0:
|
|
||||||
a = self._tab.Vector(o)
|
|
||||||
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def DocumentationLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def DocumentationIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# Field
|
|
||||||
def Optional(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
|
|
||||||
if o != 0:
|
|
||||||
return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Number of padding octets to always add after this field. Structs only.
|
|
||||||
# Field
|
|
||||||
def Padding(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(28))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# If the field uses 64-bit offsets.
|
|
||||||
# Field
|
|
||||||
def Offset64(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
|
|
||||||
if o != 0:
|
|
||||||
return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
|
|
||||||
return False
|
|
||||||
|
|
||||||
def FieldStart(builder):
|
|
||||||
builder.StartObject(14)
|
|
||||||
|
|
||||||
def Start(builder):
|
|
||||||
FieldStart(builder)
|
|
||||||
|
|
||||||
def FieldAddName(builder, name):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
|
|
||||||
|
|
||||||
def AddName(builder, name):
|
|
||||||
FieldAddName(builder, name)
|
|
||||||
|
|
||||||
def FieldAddType(builder, type):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(type), 0)
|
|
||||||
|
|
||||||
def AddType(builder, type):
|
|
||||||
FieldAddType(builder, type)
|
|
||||||
|
|
||||||
def FieldAddId(builder, id):
|
|
||||||
builder.PrependUint16Slot(2, id, 0)
|
|
||||||
|
|
||||||
def AddId(builder, id):
|
|
||||||
FieldAddId(builder, id)
|
|
||||||
|
|
||||||
def FieldAddOffset(builder, offset):
|
|
||||||
builder.PrependUint16Slot(3, offset, 0)
|
|
||||||
|
|
||||||
def AddOffset(builder, offset):
|
|
||||||
FieldAddOffset(builder, offset)
|
|
||||||
|
|
||||||
def FieldAddDefaultInteger(builder, defaultInteger):
|
|
||||||
builder.PrependInt64Slot(4, defaultInteger, 0)
|
|
||||||
|
|
||||||
def AddDefaultInteger(builder, defaultInteger):
|
|
||||||
FieldAddDefaultInteger(builder, defaultInteger)
|
|
||||||
|
|
||||||
def FieldAddDefaultReal(builder, defaultReal):
|
|
||||||
builder.PrependFloat64Slot(5, defaultReal, 0.0)
|
|
||||||
|
|
||||||
def AddDefaultReal(builder, defaultReal):
|
|
||||||
FieldAddDefaultReal(builder, defaultReal)
|
|
||||||
|
|
||||||
def FieldAddDeprecated(builder, deprecated):
|
|
||||||
builder.PrependBoolSlot(6, deprecated, 0)
|
|
||||||
|
|
||||||
def AddDeprecated(builder, deprecated):
|
|
||||||
FieldAddDeprecated(builder, deprecated)
|
|
||||||
|
|
||||||
def FieldAddRequired(builder, required):
|
|
||||||
builder.PrependBoolSlot(7, required, 0)
|
|
||||||
|
|
||||||
def AddRequired(builder, required):
|
|
||||||
FieldAddRequired(builder, required)
|
|
||||||
|
|
||||||
def FieldAddKey(builder, key):
|
|
||||||
builder.PrependBoolSlot(8, key, 0)
|
|
||||||
|
|
||||||
def AddKey(builder, key):
|
|
||||||
FieldAddKey(builder, key)
|
|
||||||
|
|
||||||
def FieldAddAttributes(builder, attributes):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
|
|
||||||
|
|
||||||
def AddAttributes(builder, attributes):
|
|
||||||
FieldAddAttributes(builder, attributes)
|
|
||||||
|
|
||||||
def FieldStartAttributesVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartAttributesVector(builder, numElems):
|
|
||||||
return FieldStartAttributesVector(builder, numElems)
|
|
||||||
|
|
||||||
def FieldAddDocumentation(builder, documentation):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(10, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
|
||||||
|
|
||||||
def AddDocumentation(builder, documentation):
|
|
||||||
FieldAddDocumentation(builder, documentation)
|
|
||||||
|
|
||||||
def FieldStartDocumentationVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartDocumentationVector(builder, numElems):
|
|
||||||
return FieldStartDocumentationVector(builder, numElems)
|
|
||||||
|
|
||||||
def FieldAddOptional(builder, optional):
|
|
||||||
builder.PrependBoolSlot(11, optional, 0)
|
|
||||||
|
|
||||||
def AddOptional(builder, optional):
|
|
||||||
FieldAddOptional(builder, optional)
|
|
||||||
|
|
||||||
def FieldAddPadding(builder, padding):
|
|
||||||
builder.PrependUint16Slot(12, padding, 0)
|
|
||||||
|
|
||||||
def AddPadding(builder, padding):
|
|
||||||
FieldAddPadding(builder, padding)
|
|
||||||
|
|
||||||
def FieldAddOffset64(builder, offset64):
|
|
||||||
builder.PrependBoolSlot(13, offset64, 0)
|
|
||||||
|
|
||||||
def AddOffset64(builder, offset64):
|
|
||||||
FieldAddOffset64(builder, offset64)
|
|
||||||
|
|
||||||
def FieldEnd(builder):
|
|
||||||
return builder.EndObject()
|
|
||||||
|
|
||||||
def End(builder):
|
|
||||||
return FieldEnd(builder)
|
|
@ -1,67 +0,0 @@
|
|||||||
# automatically generated by the FlatBuffers compiler, do not modify
|
|
||||||
|
|
||||||
# namespace: reflection
|
|
||||||
|
|
||||||
import flatbuffers
|
|
||||||
from flatbuffers.compat import import_numpy
|
|
||||||
np = import_numpy()
|
|
||||||
|
|
||||||
class KeyValue(object):
|
|
||||||
__slots__ = ['_tab']
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAs(cls, buf, offset=0):
|
|
||||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
|
||||||
x = KeyValue()
|
|
||||||
x.Init(buf, n + offset)
|
|
||||||
return x
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAsKeyValue(cls, buf, offset=0):
|
|
||||||
"""This method is deprecated. Please switch to GetRootAs."""
|
|
||||||
return cls.GetRootAs(buf, offset)
|
|
||||||
@classmethod
|
|
||||||
def KeyValueBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
|
|
||||||
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
|
|
||||||
|
|
||||||
# KeyValue
|
|
||||||
def Init(self, buf, pos):
|
|
||||||
self._tab = flatbuffers.table.Table(buf, pos)
|
|
||||||
|
|
||||||
# KeyValue
|
|
||||||
def Key(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
# KeyValue
|
|
||||||
def Value(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def KeyValueStart(builder):
|
|
||||||
builder.StartObject(2)
|
|
||||||
|
|
||||||
def Start(builder):
|
|
||||||
KeyValueStart(builder)
|
|
||||||
|
|
||||||
def KeyValueAddKey(builder, key):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(key), 0)
|
|
||||||
|
|
||||||
def AddKey(builder, key):
|
|
||||||
KeyValueAddKey(builder, key)
|
|
||||||
|
|
||||||
def KeyValueAddValue(builder, value):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(value), 0)
|
|
||||||
|
|
||||||
def AddValue(builder, value):
|
|
||||||
KeyValueAddValue(builder, value)
|
|
||||||
|
|
||||||
def KeyValueEnd(builder):
|
|
||||||
return builder.EndObject()
|
|
||||||
|
|
||||||
def End(builder):
|
|
||||||
return KeyValueEnd(builder)
|
|
@ -1,213 +0,0 @@
|
|||||||
# automatically generated by the FlatBuffers compiler, do not modify
|
|
||||||
|
|
||||||
# namespace: reflection
|
|
||||||
|
|
||||||
import flatbuffers
|
|
||||||
from flatbuffers.compat import import_numpy
|
|
||||||
np = import_numpy()
|
|
||||||
|
|
||||||
class Object(object):
|
|
||||||
__slots__ = ['_tab']
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAs(cls, buf, offset=0):
|
|
||||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
|
||||||
x = Object()
|
|
||||||
x.Init(buf, n + offset)
|
|
||||||
return x
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAsObject(cls, buf, offset=0):
|
|
||||||
"""This method is deprecated. Please switch to GetRootAs."""
|
|
||||||
return cls.GetRootAs(buf, offset)
|
|
||||||
@classmethod
|
|
||||||
def ObjectBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
|
|
||||||
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def Init(self, buf, pos):
|
|
||||||
self._tab = flatbuffers.table.Table(buf, pos)
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def Name(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def Fields(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Vector(o)
|
|
||||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
|
||||||
x = self._tab.Indirect(x)
|
|
||||||
from reflection.Field import Field
|
|
||||||
obj = Field()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def FieldsLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def FieldsIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def IsStruct(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
|
|
||||||
if o != 0:
|
|
||||||
return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def Minalign(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def Bytesize(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def Attributes(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Vector(o)
|
|
||||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
|
||||||
x = self._tab.Indirect(x)
|
|
||||||
from reflection.KeyValue import KeyValue
|
|
||||||
obj = KeyValue()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def AttributesLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def AttributesIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def Documentation(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
|
|
||||||
if o != 0:
|
|
||||||
a = self._tab.Vector(o)
|
|
||||||
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def DocumentationLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Object
|
|
||||||
def DocumentationIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# File that this Object is declared in.
|
|
||||||
# Object
|
|
||||||
def DeclarationFile(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def ObjectStart(builder):
|
|
||||||
builder.StartObject(8)
|
|
||||||
|
|
||||||
def Start(builder):
|
|
||||||
ObjectStart(builder)
|
|
||||||
|
|
||||||
def ObjectAddName(builder, name):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
|
|
||||||
|
|
||||||
def AddName(builder, name):
|
|
||||||
ObjectAddName(builder, name)
|
|
||||||
|
|
||||||
def ObjectAddFields(builder, fields):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(fields), 0)
|
|
||||||
|
|
||||||
def AddFields(builder, fields):
|
|
||||||
ObjectAddFields(builder, fields)
|
|
||||||
|
|
||||||
def ObjectStartFieldsVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartFieldsVector(builder, numElems):
|
|
||||||
return ObjectStartFieldsVector(builder, numElems)
|
|
||||||
|
|
||||||
def ObjectAddIsStruct(builder, isStruct):
|
|
||||||
builder.PrependBoolSlot(2, isStruct, 0)
|
|
||||||
|
|
||||||
def AddIsStruct(builder, isStruct):
|
|
||||||
ObjectAddIsStruct(builder, isStruct)
|
|
||||||
|
|
||||||
def ObjectAddMinalign(builder, minalign):
|
|
||||||
builder.PrependInt32Slot(3, minalign, 0)
|
|
||||||
|
|
||||||
def AddMinalign(builder, minalign):
|
|
||||||
ObjectAddMinalign(builder, minalign)
|
|
||||||
|
|
||||||
def ObjectAddBytesize(builder, bytesize):
|
|
||||||
builder.PrependInt32Slot(4, bytesize, 0)
|
|
||||||
|
|
||||||
def AddBytesize(builder, bytesize):
|
|
||||||
ObjectAddBytesize(builder, bytesize)
|
|
||||||
|
|
||||||
def ObjectAddAttributes(builder, attributes):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
|
|
||||||
|
|
||||||
def AddAttributes(builder, attributes):
|
|
||||||
ObjectAddAttributes(builder, attributes)
|
|
||||||
|
|
||||||
def ObjectStartAttributesVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartAttributesVector(builder, numElems):
|
|
||||||
return ObjectStartAttributesVector(builder, numElems)
|
|
||||||
|
|
||||||
def ObjectAddDocumentation(builder, documentation):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(6, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
|
||||||
|
|
||||||
def AddDocumentation(builder, documentation):
|
|
||||||
ObjectAddDocumentation(builder, documentation)
|
|
||||||
|
|
||||||
def ObjectStartDocumentationVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartDocumentationVector(builder, numElems):
|
|
||||||
return ObjectStartDocumentationVector(builder, numElems)
|
|
||||||
|
|
||||||
def ObjectAddDeclarationFile(builder, declarationFile):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(7, flatbuffers.number_types.UOffsetTFlags.py_type(declarationFile), 0)
|
|
||||||
|
|
||||||
def AddDeclarationFile(builder, declarationFile):
|
|
||||||
ObjectAddDeclarationFile(builder, declarationFile)
|
|
||||||
|
|
||||||
def ObjectEnd(builder):
|
|
||||||
return builder.EndObject()
|
|
||||||
|
|
||||||
def End(builder):
|
|
||||||
return ObjectEnd(builder)
|
|
@ -1,157 +0,0 @@
|
|||||||
# automatically generated by the FlatBuffers compiler, do not modify
|
|
||||||
|
|
||||||
# namespace: reflection
|
|
||||||
|
|
||||||
import flatbuffers
|
|
||||||
from flatbuffers.compat import import_numpy
|
|
||||||
np = import_numpy()
|
|
||||||
|
|
||||||
class RPCCall(object):
|
|
||||||
__slots__ = ['_tab']
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAs(cls, buf, offset=0):
|
|
||||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
|
||||||
x = RPCCall()
|
|
||||||
x.Init(buf, n + offset)
|
|
||||||
return x
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAsRPCCall(cls, buf, offset=0):
|
|
||||||
"""This method is deprecated. Please switch to GetRootAs."""
|
|
||||||
return cls.GetRootAs(buf, offset)
|
|
||||||
@classmethod
|
|
||||||
def RPCCallBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
|
|
||||||
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
|
|
||||||
|
|
||||||
# RPCCall
|
|
||||||
def Init(self, buf, pos):
|
|
||||||
self._tab = flatbuffers.table.Table(buf, pos)
|
|
||||||
|
|
||||||
# RPCCall
|
|
||||||
def Name(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
# RPCCall
|
|
||||||
def Request(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Indirect(o + self._tab.Pos)
|
|
||||||
from reflection.Object import Object
|
|
||||||
obj = Object()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# RPCCall
|
|
||||||
def Response(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Indirect(o + self._tab.Pos)
|
|
||||||
from reflection.Object import Object
|
|
||||||
obj = Object()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# RPCCall
|
|
||||||
def Attributes(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Vector(o)
|
|
||||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
|
||||||
x = self._tab.Indirect(x)
|
|
||||||
from reflection.KeyValue import KeyValue
|
|
||||||
obj = KeyValue()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# RPCCall
|
|
||||||
def AttributesLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# RPCCall
|
|
||||||
def AttributesIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# RPCCall
|
|
||||||
def Documentation(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
if o != 0:
|
|
||||||
a = self._tab.Vector(o)
|
|
||||||
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# RPCCall
|
|
||||||
def DocumentationLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# RPCCall
|
|
||||||
def DocumentationIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
def RPCCallStart(builder):
|
|
||||||
builder.StartObject(5)
|
|
||||||
|
|
||||||
def Start(builder):
|
|
||||||
RPCCallStart(builder)
|
|
||||||
|
|
||||||
def RPCCallAddName(builder, name):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
|
|
||||||
|
|
||||||
def AddName(builder, name):
|
|
||||||
RPCCallAddName(builder, name)
|
|
||||||
|
|
||||||
def RPCCallAddRequest(builder, request):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(request), 0)
|
|
||||||
|
|
||||||
def AddRequest(builder, request):
|
|
||||||
RPCCallAddRequest(builder, request)
|
|
||||||
|
|
||||||
def RPCCallAddResponse(builder, response):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(response), 0)
|
|
||||||
|
|
||||||
def AddResponse(builder, response):
|
|
||||||
RPCCallAddResponse(builder, response)
|
|
||||||
|
|
||||||
def RPCCallAddAttributes(builder, attributes):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
|
|
||||||
|
|
||||||
def AddAttributes(builder, attributes):
|
|
||||||
RPCCallAddAttributes(builder, attributes)
|
|
||||||
|
|
||||||
def RPCCallStartAttributesVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartAttributesVector(builder, numElems):
|
|
||||||
return RPCCallStartAttributesVector(builder, numElems)
|
|
||||||
|
|
||||||
def RPCCallAddDocumentation(builder, documentation):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
|
||||||
|
|
||||||
def AddDocumentation(builder, documentation):
|
|
||||||
RPCCallAddDocumentation(builder, documentation)
|
|
||||||
|
|
||||||
def RPCCallStartDocumentationVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartDocumentationVector(builder, numElems):
|
|
||||||
return RPCCallStartDocumentationVector(builder, numElems)
|
|
||||||
|
|
||||||
def RPCCallEnd(builder):
|
|
||||||
return builder.EndObject()
|
|
||||||
|
|
||||||
def End(builder):
|
|
||||||
return RPCCallEnd(builder)
|
|
@ -1,247 +0,0 @@
|
|||||||
# automatically generated by the FlatBuffers compiler, do not modify
|
|
||||||
|
|
||||||
# namespace: reflection
|
|
||||||
|
|
||||||
import flatbuffers
|
|
||||||
from flatbuffers.compat import import_numpy
|
|
||||||
np = import_numpy()
|
|
||||||
|
|
||||||
class Schema(object):
|
|
||||||
__slots__ = ['_tab']
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAs(cls, buf, offset=0):
|
|
||||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
|
||||||
x = Schema()
|
|
||||||
x.Init(buf, n + offset)
|
|
||||||
return x
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAsSchema(cls, buf, offset=0):
|
|
||||||
"""This method is deprecated. Please switch to GetRootAs."""
|
|
||||||
return cls.GetRootAs(buf, offset)
|
|
||||||
@classmethod
|
|
||||||
def SchemaBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
|
|
||||||
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def Init(self, buf, pos):
|
|
||||||
self._tab = flatbuffers.table.Table(buf, pos)
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def Objects(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Vector(o)
|
|
||||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
|
||||||
x = self._tab.Indirect(x)
|
|
||||||
from reflection.Object import Object
|
|
||||||
obj = Object()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def ObjectsLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def ObjectsIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def Enums(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Vector(o)
|
|
||||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
|
||||||
x = self._tab.Indirect(x)
|
|
||||||
from reflection.Enum import Enum
|
|
||||||
obj = Enum()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def EnumsLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def EnumsIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def FileIdent(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def FileExt(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def RootTable(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Indirect(o + self._tab.Pos)
|
|
||||||
from reflection.Object import Object
|
|
||||||
obj = Object()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def Services(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Vector(o)
|
|
||||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
|
||||||
x = self._tab.Indirect(x)
|
|
||||||
from reflection.Service import Service
|
|
||||||
obj = Service()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def ServicesLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def ServicesIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def AdvancedFeatures(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# All the files used in this compilation. Files are relative to where
|
|
||||||
# flatc was invoked.
|
|
||||||
# Schema
|
|
||||||
def FbsFiles(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Vector(o)
|
|
||||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
|
||||||
x = self._tab.Indirect(x)
|
|
||||||
from reflection.SchemaFile import SchemaFile
|
|
||||||
obj = SchemaFile()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def FbsFilesLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Schema
|
|
||||||
def FbsFilesIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
def SchemaStart(builder):
|
|
||||||
builder.StartObject(8)
|
|
||||||
|
|
||||||
def Start(builder):
|
|
||||||
SchemaStart(builder)
|
|
||||||
|
|
||||||
def SchemaAddObjects(builder, objects):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(objects), 0)
|
|
||||||
|
|
||||||
def AddObjects(builder, objects):
|
|
||||||
SchemaAddObjects(builder, objects)
|
|
||||||
|
|
||||||
def SchemaStartObjectsVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartObjectsVector(builder, numElems):
|
|
||||||
return SchemaStartObjectsVector(builder, numElems)
|
|
||||||
|
|
||||||
def SchemaAddEnums(builder, enums):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(enums), 0)
|
|
||||||
|
|
||||||
def AddEnums(builder, enums):
|
|
||||||
SchemaAddEnums(builder, enums)
|
|
||||||
|
|
||||||
def SchemaStartEnumsVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartEnumsVector(builder, numElems):
|
|
||||||
return SchemaStartEnumsVector(builder, numElems)
|
|
||||||
|
|
||||||
def SchemaAddFileIdent(builder, fileIdent):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(fileIdent), 0)
|
|
||||||
|
|
||||||
def AddFileIdent(builder, fileIdent):
|
|
||||||
SchemaAddFileIdent(builder, fileIdent)
|
|
||||||
|
|
||||||
def SchemaAddFileExt(builder, fileExt):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(fileExt), 0)
|
|
||||||
|
|
||||||
def AddFileExt(builder, fileExt):
|
|
||||||
SchemaAddFileExt(builder, fileExt)
|
|
||||||
|
|
||||||
def SchemaAddRootTable(builder, rootTable):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(rootTable), 0)
|
|
||||||
|
|
||||||
def AddRootTable(builder, rootTable):
|
|
||||||
SchemaAddRootTable(builder, rootTable)
|
|
||||||
|
|
||||||
def SchemaAddServices(builder, services):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(services), 0)
|
|
||||||
|
|
||||||
def AddServices(builder, services):
|
|
||||||
SchemaAddServices(builder, services)
|
|
||||||
|
|
||||||
def SchemaStartServicesVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartServicesVector(builder, numElems):
|
|
||||||
return SchemaStartServicesVector(builder, numElems)
|
|
||||||
|
|
||||||
def SchemaAddAdvancedFeatures(builder, advancedFeatures):
|
|
||||||
builder.PrependUint64Slot(6, advancedFeatures, 0)
|
|
||||||
|
|
||||||
def AddAdvancedFeatures(builder, advancedFeatures):
|
|
||||||
SchemaAddAdvancedFeatures(builder, advancedFeatures)
|
|
||||||
|
|
||||||
def SchemaAddFbsFiles(builder, fbsFiles):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(7, flatbuffers.number_types.UOffsetTFlags.py_type(fbsFiles), 0)
|
|
||||||
|
|
||||||
def AddFbsFiles(builder, fbsFiles):
|
|
||||||
SchemaAddFbsFiles(builder, fbsFiles)
|
|
||||||
|
|
||||||
def SchemaStartFbsFilesVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartFbsFilesVector(builder, numElems):
|
|
||||||
return SchemaStartFbsFilesVector(builder, numElems)
|
|
||||||
|
|
||||||
def SchemaEnd(builder):
|
|
||||||
return builder.EndObject()
|
|
||||||
|
|
||||||
def End(builder):
|
|
||||||
return SchemaEnd(builder)
|
|
@ -1,91 +0,0 @@
|
|||||||
# automatically generated by the FlatBuffers compiler, do not modify
|
|
||||||
|
|
||||||
# namespace: reflection
|
|
||||||
|
|
||||||
import flatbuffers
|
|
||||||
from flatbuffers.compat import import_numpy
|
|
||||||
np = import_numpy()
|
|
||||||
|
|
||||||
# File specific information.
|
|
||||||
# Symbols declared within a file may be recovered by iterating over all
|
|
||||||
# symbols and examining the `declaration_file` field.
|
|
||||||
class SchemaFile(object):
|
|
||||||
__slots__ = ['_tab']
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAs(cls, buf, offset=0):
|
|
||||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
|
||||||
x = SchemaFile()
|
|
||||||
x.Init(buf, n + offset)
|
|
||||||
return x
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAsSchemaFile(cls, buf, offset=0):
|
|
||||||
"""This method is deprecated. Please switch to GetRootAs."""
|
|
||||||
return cls.GetRootAs(buf, offset)
|
|
||||||
@classmethod
|
|
||||||
def SchemaFileBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
|
|
||||||
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
|
|
||||||
|
|
||||||
# SchemaFile
|
|
||||||
def Init(self, buf, pos):
|
|
||||||
self._tab = flatbuffers.table.Table(buf, pos)
|
|
||||||
|
|
||||||
# Filename, relative to project root.
|
|
||||||
# SchemaFile
|
|
||||||
def Filename(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Names of included files, relative to project root.
|
|
||||||
# SchemaFile
|
|
||||||
def IncludedFilenames(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
a = self._tab.Vector(o)
|
|
||||||
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# SchemaFile
|
|
||||||
def IncludedFilenamesLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# SchemaFile
|
|
||||||
def IncludedFilenamesIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
def SchemaFileStart(builder):
|
|
||||||
builder.StartObject(2)
|
|
||||||
|
|
||||||
def Start(builder):
|
|
||||||
SchemaFileStart(builder)
|
|
||||||
|
|
||||||
def SchemaFileAddFilename(builder, filename):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(filename), 0)
|
|
||||||
|
|
||||||
def AddFilename(builder, filename):
|
|
||||||
SchemaFileAddFilename(builder, filename)
|
|
||||||
|
|
||||||
def SchemaFileAddIncludedFilenames(builder, includedFilenames):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(includedFilenames), 0)
|
|
||||||
|
|
||||||
def AddIncludedFilenames(builder, includedFilenames):
|
|
||||||
SchemaFileAddIncludedFilenames(builder, includedFilenames)
|
|
||||||
|
|
||||||
def SchemaFileStartIncludedFilenamesVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartIncludedFilenamesVector(builder, numElems):
|
|
||||||
return SchemaFileStartIncludedFilenamesVector(builder, numElems)
|
|
||||||
|
|
||||||
def SchemaFileEnd(builder):
|
|
||||||
return builder.EndObject()
|
|
||||||
|
|
||||||
def End(builder):
|
|
||||||
return SchemaFileEnd(builder)
|
|
@ -1,174 +0,0 @@
|
|||||||
# automatically generated by the FlatBuffers compiler, do not modify
|
|
||||||
|
|
||||||
# namespace: reflection
|
|
||||||
|
|
||||||
import flatbuffers
|
|
||||||
from flatbuffers.compat import import_numpy
|
|
||||||
np = import_numpy()
|
|
||||||
|
|
||||||
class Service(object):
|
|
||||||
__slots__ = ['_tab']
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAs(cls, buf, offset=0):
|
|
||||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
|
||||||
x = Service()
|
|
||||||
x.Init(buf, n + offset)
|
|
||||||
return x
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAsService(cls, buf, offset=0):
|
|
||||||
"""This method is deprecated. Please switch to GetRootAs."""
|
|
||||||
return cls.GetRootAs(buf, offset)
|
|
||||||
@classmethod
|
|
||||||
def ServiceBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
|
|
||||||
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
|
|
||||||
|
|
||||||
# Service
|
|
||||||
def Init(self, buf, pos):
|
|
||||||
self._tab = flatbuffers.table.Table(buf, pos)
|
|
||||||
|
|
||||||
# Service
|
|
||||||
def Name(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Service
|
|
||||||
def Calls(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Vector(o)
|
|
||||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
|
||||||
x = self._tab.Indirect(x)
|
|
||||||
from reflection.RPCCall import RPCCall
|
|
||||||
obj = RPCCall()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Service
|
|
||||||
def CallsLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Service
|
|
||||||
def CallsIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# Service
|
|
||||||
def Attributes(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
|
|
||||||
if o != 0:
|
|
||||||
x = self._tab.Vector(o)
|
|
||||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
|
||||||
x = self._tab.Indirect(x)
|
|
||||||
from reflection.KeyValue import KeyValue
|
|
||||||
obj = KeyValue()
|
|
||||||
obj.Init(self._tab.Bytes, x)
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Service
|
|
||||||
def AttributesLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Service
|
|
||||||
def AttributesIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# Service
|
|
||||||
def Documentation(self, j):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
|
|
||||||
if o != 0:
|
|
||||||
a = self._tab.Vector(o)
|
|
||||||
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# Service
|
|
||||||
def DocumentationLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.VectorLen(o)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Service
|
|
||||||
def DocumentationIsNone(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
|
|
||||||
return o == 0
|
|
||||||
|
|
||||||
# File that this Service is declared in.
|
|
||||||
# Service
|
|
||||||
def DeclarationFile(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.String(o + self._tab.Pos)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def ServiceStart(builder):
|
|
||||||
builder.StartObject(5)
|
|
||||||
|
|
||||||
def Start(builder):
|
|
||||||
ServiceStart(builder)
|
|
||||||
|
|
||||||
def ServiceAddName(builder, name):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
|
|
||||||
|
|
||||||
def AddName(builder, name):
|
|
||||||
ServiceAddName(builder, name)
|
|
||||||
|
|
||||||
def ServiceAddCalls(builder, calls):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(calls), 0)
|
|
||||||
|
|
||||||
def AddCalls(builder, calls):
|
|
||||||
ServiceAddCalls(builder, calls)
|
|
||||||
|
|
||||||
def ServiceStartCallsVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartCallsVector(builder, numElems):
|
|
||||||
return ServiceStartCallsVector(builder, numElems)
|
|
||||||
|
|
||||||
def ServiceAddAttributes(builder, attributes):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
|
|
||||||
|
|
||||||
def AddAttributes(builder, attributes):
|
|
||||||
ServiceAddAttributes(builder, attributes)
|
|
||||||
|
|
||||||
def ServiceStartAttributesVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartAttributesVector(builder, numElems):
|
|
||||||
return ServiceStartAttributesVector(builder, numElems)
|
|
||||||
|
|
||||||
def ServiceAddDocumentation(builder, documentation):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
|
||||||
|
|
||||||
def AddDocumentation(builder, documentation):
|
|
||||||
ServiceAddDocumentation(builder, documentation)
|
|
||||||
|
|
||||||
def ServiceStartDocumentationVector(builder, numElems):
|
|
||||||
return builder.StartVector(4, numElems, 4)
|
|
||||||
|
|
||||||
def StartDocumentationVector(builder, numElems):
|
|
||||||
return ServiceStartDocumentationVector(builder, numElems)
|
|
||||||
|
|
||||||
def ServiceAddDeclarationFile(builder, declarationFile):
|
|
||||||
builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(declarationFile), 0)
|
|
||||||
|
|
||||||
def AddDeclarationFile(builder, declarationFile):
|
|
||||||
ServiceAddDeclarationFile(builder, declarationFile)
|
|
||||||
|
|
||||||
def ServiceEnd(builder):
|
|
||||||
return builder.EndObject()
|
|
||||||
|
|
||||||
def End(builder):
|
|
||||||
return ServiceEnd(builder)
|
|
@ -1,121 +0,0 @@
|
|||||||
# automatically generated by the FlatBuffers compiler, do not modify
|
|
||||||
|
|
||||||
# namespace: reflection
|
|
||||||
|
|
||||||
import flatbuffers
|
|
||||||
from flatbuffers.compat import import_numpy
|
|
||||||
np = import_numpy()
|
|
||||||
|
|
||||||
class Type(object):
|
|
||||||
__slots__ = ['_tab']
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAs(cls, buf, offset=0):
|
|
||||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
|
||||||
x = Type()
|
|
||||||
x.Init(buf, n + offset)
|
|
||||||
return x
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GetRootAsType(cls, buf, offset=0):
|
|
||||||
"""This method is deprecated. Please switch to GetRootAs."""
|
|
||||||
return cls.GetRootAs(buf, offset)
|
|
||||||
@classmethod
|
|
||||||
def TypeBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
|
|
||||||
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
|
|
||||||
|
|
||||||
# Type
|
|
||||||
def Init(self, buf, pos):
|
|
||||||
self._tab = flatbuffers.table.Table(buf, pos)
|
|
||||||
|
|
||||||
# Type
|
|
||||||
def BaseType(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Type
|
|
||||||
def Element(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Type
|
|
||||||
def Index(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
|
|
||||||
return -1
|
|
||||||
|
|
||||||
# Type
|
|
||||||
def FixedLength(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# The size (octets) of the `base_type` field.
|
|
||||||
# Type
|
|
||||||
def BaseSize(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
|
|
||||||
return 4
|
|
||||||
|
|
||||||
# The size (octets) of the `element` field, if present.
|
|
||||||
# Type
|
|
||||||
def ElementSize(self):
|
|
||||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
||||||
if o != 0:
|
|
||||||
return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def TypeStart(builder):
|
|
||||||
builder.StartObject(6)
|
|
||||||
|
|
||||||
def Start(builder):
|
|
||||||
TypeStart(builder)
|
|
||||||
|
|
||||||
def TypeAddBaseType(builder, baseType):
|
|
||||||
builder.PrependInt8Slot(0, baseType, 0)
|
|
||||||
|
|
||||||
def AddBaseType(builder, baseType):
|
|
||||||
TypeAddBaseType(builder, baseType)
|
|
||||||
|
|
||||||
def TypeAddElement(builder, element):
|
|
||||||
builder.PrependInt8Slot(1, element, 0)
|
|
||||||
|
|
||||||
def AddElement(builder, element):
|
|
||||||
TypeAddElement(builder, element)
|
|
||||||
|
|
||||||
def TypeAddIndex(builder, index):
|
|
||||||
builder.PrependInt32Slot(2, index, -1)
|
|
||||||
|
|
||||||
def AddIndex(builder, index):
|
|
||||||
TypeAddIndex(builder, index)
|
|
||||||
|
|
||||||
def TypeAddFixedLength(builder, fixedLength):
|
|
||||||
builder.PrependUint16Slot(3, fixedLength, 0)
|
|
||||||
|
|
||||||
def AddFixedLength(builder, fixedLength):
|
|
||||||
TypeAddFixedLength(builder, fixedLength)
|
|
||||||
|
|
||||||
def TypeAddBaseSize(builder, baseSize):
|
|
||||||
builder.PrependUint32Slot(4, baseSize, 4)
|
|
||||||
|
|
||||||
def AddBaseSize(builder, baseSize):
|
|
||||||
TypeAddBaseSize(builder, baseSize)
|
|
||||||
|
|
||||||
def TypeAddElementSize(builder, elementSize):
|
|
||||||
builder.PrependUint32Slot(5, elementSize, 0)
|
|
||||||
|
|
||||||
def AddElementSize(builder, elementSize):
|
|
||||||
TypeAddElementSize(builder, elementSize)
|
|
||||||
|
|
||||||
def TypeEnd(builder):
|
|
||||||
return builder.EndObject()
|
|
||||||
|
|
||||||
def End(builder):
|
|
||||||
return TypeEnd(builder)
|
|
138
third_party/flatbuffers/python/flatbuffers/table.py
vendored
138
third_party/flatbuffers/python/flatbuffers/table.py
vendored
@ -1,138 +0,0 @@
|
|||||||
# Copyright 2014 Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from . import encode
|
|
||||||
from . import number_types as N
|
|
||||||
|
|
||||||
|
|
||||||
class Table(object):
|
|
||||||
"""Table wraps a byte slice and provides read access to its data.
|
|
||||||
|
|
||||||
The variable `Pos` indicates the root of the FlatBuffers object therein."""
|
|
||||||
|
|
||||||
__slots__ = ("Bytes", "Pos")
|
|
||||||
|
|
||||||
def __init__(self, buf, pos):
|
|
||||||
N.enforce_number(pos, N.UOffsetTFlags)
|
|
||||||
|
|
||||||
self.Bytes = buf
|
|
||||||
self.Pos = pos
|
|
||||||
|
|
||||||
def Offset(self, vtableOffset):
|
|
||||||
"""Offset provides access into the Table's vtable.
|
|
||||||
|
|
||||||
Deprecated fields are ignored by checking the vtable's length."""
|
|
||||||
|
|
||||||
vtable = self.Pos - self.Get(N.SOffsetTFlags, self.Pos)
|
|
||||||
vtableEnd = self.Get(N.VOffsetTFlags, vtable)
|
|
||||||
if vtableOffset < vtableEnd:
|
|
||||||
return self.Get(N.VOffsetTFlags, vtable + vtableOffset)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def Indirect(self, off):
|
|
||||||
"""Indirect retrieves the relative offset stored at `offset`."""
|
|
||||||
N.enforce_number(off, N.UOffsetTFlags)
|
|
||||||
return off + encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
|
|
||||||
|
|
||||||
def String(self, off):
|
|
||||||
"""String gets a string from data stored inside the flatbuffer."""
|
|
||||||
N.enforce_number(off, N.UOffsetTFlags)
|
|
||||||
off += encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
|
|
||||||
start = off + N.UOffsetTFlags.bytewidth
|
|
||||||
length = encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
|
|
||||||
return bytes(self.Bytes[start:start+length])
|
|
||||||
|
|
||||||
def VectorLen(self, off):
|
|
||||||
"""VectorLen retrieves the length of the vector whose offset is stored
|
|
||||||
at "off" in this object."""
|
|
||||||
N.enforce_number(off, N.UOffsetTFlags)
|
|
||||||
|
|
||||||
off += self.Pos
|
|
||||||
off += encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
|
|
||||||
ret = encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def Vector(self, off):
|
|
||||||
"""Vector retrieves the start of data of the vector whose offset is
|
|
||||||
stored at "off" in this object."""
|
|
||||||
N.enforce_number(off, N.UOffsetTFlags)
|
|
||||||
|
|
||||||
off += self.Pos
|
|
||||||
x = off + self.Get(N.UOffsetTFlags, off)
|
|
||||||
# data starts after metadata containing the vector length
|
|
||||||
x += N.UOffsetTFlags.bytewidth
|
|
||||||
return x
|
|
||||||
|
|
||||||
def Union(self, t2, off):
|
|
||||||
"""Union initializes any Table-derived type to point to the union at
|
|
||||||
the given offset."""
|
|
||||||
assert type(t2) is Table
|
|
||||||
N.enforce_number(off, N.UOffsetTFlags)
|
|
||||||
|
|
||||||
off += self.Pos
|
|
||||||
t2.Pos = off + self.Get(N.UOffsetTFlags, off)
|
|
||||||
t2.Bytes = self.Bytes
|
|
||||||
|
|
||||||
def Get(self, flags, off):
|
|
||||||
"""
|
|
||||||
Get retrieves a value of the type specified by `flags` at the
|
|
||||||
given offset.
|
|
||||||
"""
|
|
||||||
N.enforce_number(off, N.UOffsetTFlags)
|
|
||||||
return flags.py_type(encode.Get(flags.packer_type, self.Bytes, off))
|
|
||||||
|
|
||||||
def GetSlot(self, slot, d, validator_flags):
|
|
||||||
N.enforce_number(slot, N.VOffsetTFlags)
|
|
||||||
if validator_flags is not None:
|
|
||||||
N.enforce_number(d, validator_flags)
|
|
||||||
off = self.Offset(slot)
|
|
||||||
if off == 0:
|
|
||||||
return d
|
|
||||||
return self.Get(validator_flags, self.Pos + off)
|
|
||||||
|
|
||||||
def GetVectorAsNumpy(self, flags, off):
|
|
||||||
"""
|
|
||||||
GetVectorAsNumpy returns the vector that starts at `Vector(off)`
|
|
||||||
as a numpy array with the type specified by `flags`. The array is
|
|
||||||
a `view` into Bytes, so modifying the returned array will
|
|
||||||
modify Bytes in place.
|
|
||||||
"""
|
|
||||||
offset = self.Vector(off)
|
|
||||||
length = self.VectorLen(off) # TODO: length accounts for bytewidth, right?
|
|
||||||
numpy_dtype = N.to_numpy_type(flags)
|
|
||||||
return encode.GetVectorAsNumpy(numpy_dtype, self.Bytes, length, offset)
|
|
||||||
|
|
||||||
def GetArrayAsNumpy(self, flags, off, length):
|
|
||||||
"""
|
|
||||||
GetArrayAsNumpy returns the array with fixed width that starts at `Vector(offset)`
|
|
||||||
with length `length` as a numpy array with the type specified by `flags`. The
|
|
||||||
array is a `view` into Bytes so modifying the returned will modify Bytes in place.
|
|
||||||
"""
|
|
||||||
numpy_dtype = N.to_numpy_type(flags)
|
|
||||||
return encode.GetVectorAsNumpy(numpy_dtype, self.Bytes, length, off)
|
|
||||||
|
|
||||||
def GetVOffsetTSlot(self, slot, d):
|
|
||||||
"""
|
|
||||||
GetVOffsetTSlot retrieves the VOffsetT that the given vtable location
|
|
||||||
points to. If the vtable value is zero, the default value `d`
|
|
||||||
will be returned.
|
|
||||||
"""
|
|
||||||
|
|
||||||
N.enforce_number(slot, N.VOffsetTFlags)
|
|
||||||
N.enforce_number(d, N.VOffsetTFlags)
|
|
||||||
|
|
||||||
off = self.Offset(slot)
|
|
||||||
if off == 0:
|
|
||||||
return d
|
|
||||||
return off
|
|
@ -1,43 +0,0 @@
|
|||||||
# Copyright 2017 Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from . import encode
|
|
||||||
from . import number_types
|
|
||||||
from . import packer
|
|
||||||
|
|
||||||
def GetSizePrefix(buf, offset):
|
|
||||||
"""Extract the size prefix from a buffer."""
|
|
||||||
return encode.Get(packer.int32, buf, offset)
|
|
||||||
|
|
||||||
def GetBufferIdentifier(buf, offset, size_prefixed=False):
|
|
||||||
"""Extract the file_identifier from a buffer"""
|
|
||||||
if size_prefixed:
|
|
||||||
# increase offset by size of UOffsetTFlags
|
|
||||||
offset += number_types.UOffsetTFlags.bytewidth
|
|
||||||
# increase offset by size of root table pointer
|
|
||||||
offset += number_types.UOffsetTFlags.bytewidth
|
|
||||||
# end of FILE_IDENTIFIER
|
|
||||||
end = offset + encode.FILE_IDENTIFIER_LENGTH
|
|
||||||
return buf[offset:end]
|
|
||||||
|
|
||||||
def BufferHasIdentifier(buf, offset, file_identifier, size_prefixed=False):
|
|
||||||
got = GetBufferIdentifier(buf, offset, size_prefixed=size_prefixed)
|
|
||||||
return got == file_identifier
|
|
||||||
|
|
||||||
def RemoveSizePrefix(buf, offset):
|
|
||||||
"""
|
|
||||||
Create a slice of a size-prefixed buffer that has
|
|
||||||
its position advanced just past the size prefix.
|
|
||||||
"""
|
|
||||||
return buf, offset + number_types.Int32Flags.bytewidth
|
|
0
third_party/flatbuffers/python/py.typed
vendored
0
third_party/flatbuffers/python/py.typed
vendored
6
third_party/flatbuffers/python/setup.cfg
vendored
6
third_party/flatbuffers/python/setup.cfg
vendored
@ -1,6 +0,0 @@
|
|||||||
[bdist_wheel]
|
|
||||||
universal=1
|
|
||||||
|
|
||||||
[metadata]
|
|
||||||
license_files =
|
|
||||||
../license
|
|
45
third_party/flatbuffers/python/setup.py
vendored
45
third_party/flatbuffers/python/setup.py
vendored
@ -1,45 +0,0 @@
|
|||||||
# Copyright 2016 Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from setuptools import setup
|
|
||||||
|
|
||||||
setup(
|
|
||||||
name='flatbuffers',
|
|
||||||
version='24.3.25',
|
|
||||||
license='Apache 2.0',
|
|
||||||
license_files='../LICENSE',
|
|
||||||
author='Derek Bailey',
|
|
||||||
author_email='derekbailey@google.com',
|
|
||||||
url='https://google.github.io/flatbuffers/',
|
|
||||||
long_description=('Python runtime library for use with the '
|
|
||||||
'`Flatbuffers <https://google.github.io/flatbuffers/>`_ '
|
|
||||||
'serialization format.'),
|
|
||||||
packages=['flatbuffers'],
|
|
||||||
include_package_data=True,
|
|
||||||
requires=[],
|
|
||||||
description='The FlatBuffers serialization format for Python',
|
|
||||||
classifiers=[
|
|
||||||
'Intended Audience :: Developers',
|
|
||||||
'License :: OSI Approved :: Apache Software License',
|
|
||||||
'Operating System :: OS Independent',
|
|
||||||
'Programming Language :: Python',
|
|
||||||
'Programming Language :: Python :: 2',
|
|
||||||
'Programming Language :: Python :: 3',
|
|
||||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
|
||||||
],
|
|
||||||
project_urls={
|
|
||||||
'Documentation': 'https://google.github.io/flatbuffers/',
|
|
||||||
'Source': 'https://github.com/google/flatbuffers',
|
|
||||||
},
|
|
||||||
)
|
|
8
third_party/flatbuffers/swift/BUILD.bazel
vendored
8
third_party/flatbuffers/swift/BUILD.bazel
vendored
@ -1,8 +0,0 @@
|
|||||||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
|
||||||
|
|
||||||
swift_library(
|
|
||||||
name = "swift",
|
|
||||||
srcs = glob(["Sources/FlatBuffers/*.swift"]),
|
|
||||||
module_name = "FlatBuffers",
|
|
||||||
visibility = ["//visibility:public"],
|
|
||||||
)
|
|
202
third_party/flatbuffers/swift/LICENSE
vendored
202
third_party/flatbuffers/swift/LICENSE
vendored
@ -1,202 +0,0 @@
|
|||||||
|
|
||||||
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 [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
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.
|
|
11
third_party/flatbuffers/swift/README.md
vendored
11
third_party/flatbuffers/swift/README.md
vendored
@ -1,11 +0,0 @@
|
|||||||
FlatBuffers swift can be found in both SPM
|
|
||||||
|
|
||||||
`.package(url: "https://github.com/google/flatbuffers.git", from: "X.Y.Z"),`
|
|
||||||
|
|
||||||
and Cocoapods
|
|
||||||
|
|
||||||
`pod 'FlatBuffers'`
|
|
||||||
|
|
||||||
### Contribute
|
|
||||||
|
|
||||||
1- Always run `swift test --generate-linuxmain` whenever new test functions are added or removed
|
|
@ -1,544 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// `ByteBuffer` is the interface that stores the data for a `Flatbuffers` object
|
|
||||||
/// it allows users to write and read data directly from memory thus the use of its
|
|
||||||
/// functions should be used
|
|
||||||
@frozen
|
|
||||||
public struct ByteBuffer {
|
|
||||||
|
|
||||||
/// Storage is a container that would hold the memory pointer to solve the issue of
|
|
||||||
/// deallocating the memory that was held by (memory: UnsafeMutableRawPointer)
|
|
||||||
@usableFromInline
|
|
||||||
final class Storage {
|
|
||||||
// This storage doesn't own the memory, therefore, we won't deallocate on deinit.
|
|
||||||
private let unowned: Bool
|
|
||||||
/// pointer to the start of the buffer object in memory
|
|
||||||
var memory: UnsafeMutableRawPointer
|
|
||||||
/// Capacity of UInt8 the buffer can hold
|
|
||||||
var capacity: Int
|
|
||||||
|
|
||||||
@usableFromInline
|
|
||||||
init(count: Int, alignment: Int) {
|
|
||||||
memory = UnsafeMutableRawPointer.allocate(
|
|
||||||
byteCount: count,
|
|
||||||
alignment: alignment)
|
|
||||||
capacity = count
|
|
||||||
unowned = false
|
|
||||||
}
|
|
||||||
|
|
||||||
@usableFromInline
|
|
||||||
init(memory: UnsafeMutableRawPointer, capacity: Int, unowned: Bool) {
|
|
||||||
self.memory = memory
|
|
||||||
self.capacity = capacity
|
|
||||||
self.unowned = unowned
|
|
||||||
}
|
|
||||||
|
|
||||||
deinit {
|
|
||||||
if !unowned {
|
|
||||||
memory.deallocate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@usableFromInline
|
|
||||||
func copy(from ptr: UnsafeRawPointer, count: Int) {
|
|
||||||
assert(
|
|
||||||
!unowned,
|
|
||||||
"copy should NOT be called on a buffer that is built by assumingMemoryBound")
|
|
||||||
memory.copyMemory(from: ptr, byteCount: count)
|
|
||||||
}
|
|
||||||
|
|
||||||
@usableFromInline
|
|
||||||
func initialize(for size: Int) {
|
|
||||||
assert(
|
|
||||||
!unowned,
|
|
||||||
"initalize should NOT be called on a buffer that is built by assumingMemoryBound")
|
|
||||||
memset(memory, 0, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reallocates the buffer incase the object to be written doesnt fit in the current buffer
|
|
||||||
/// - Parameter size: Size of the current object
|
|
||||||
@usableFromInline
|
|
||||||
func reallocate(_ size: Int, writerSize: Int, alignment: Int) {
|
|
||||||
let currentWritingIndex = capacity &- writerSize
|
|
||||||
while capacity <= writerSize &+ size {
|
|
||||||
capacity = capacity << 1
|
|
||||||
}
|
|
||||||
|
|
||||||
/// solution take from Apple-NIO
|
|
||||||
capacity = capacity.convertToPowerofTwo
|
|
||||||
|
|
||||||
let newData = UnsafeMutableRawPointer.allocate(
|
|
||||||
byteCount: capacity,
|
|
||||||
alignment: alignment)
|
|
||||||
memset(newData, 0, capacity &- writerSize)
|
|
||||||
memcpy(
|
|
||||||
newData.advanced(by: capacity &- writerSize),
|
|
||||||
memory.advanced(by: currentWritingIndex),
|
|
||||||
writerSize)
|
|
||||||
memory.deallocate()
|
|
||||||
memory = newData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@usableFromInline var _storage: Storage
|
|
||||||
|
|
||||||
/// The size of the elements written to the buffer + their paddings
|
|
||||||
private var _writerSize: Int = 0
|
|
||||||
/// Aliginment of the current memory being written to the buffer
|
|
||||||
var alignment = 1
|
|
||||||
/// Current Index which is being used to write to the buffer, it is written from the end to the start of the buffer
|
|
||||||
var writerIndex: Int { _storage.capacity &- _writerSize }
|
|
||||||
|
|
||||||
/// Reader is the position of the current Writer Index (capacity - size)
|
|
||||||
public var reader: Int { writerIndex }
|
|
||||||
/// Current size of the buffer
|
|
||||||
public var size: UOffset { UOffset(_writerSize) }
|
|
||||||
/// Public Pointer to the buffer object in memory. This should NOT be modified for any reason
|
|
||||||
public var memory: UnsafeMutableRawPointer { _storage.memory }
|
|
||||||
/// Current capacity for the buffer
|
|
||||||
public var capacity: Int { _storage.capacity }
|
|
||||||
/// Crash if the trying to read an unaligned buffer instead of allowing users to read them.
|
|
||||||
public let allowReadingUnalignedBuffers: Bool
|
|
||||||
|
|
||||||
/// Constructor that creates a Flatbuffer object from a UInt8
|
|
||||||
/// - Parameter
|
|
||||||
/// - bytes: Array of UInt8
|
|
||||||
/// - allowReadingUnalignedBuffers: allow reading from unaligned buffer
|
|
||||||
public init(
|
|
||||||
bytes: [UInt8],
|
|
||||||
allowReadingUnalignedBuffers allowUnalignedBuffers: Bool = false)
|
|
||||||
{
|
|
||||||
var b = bytes
|
|
||||||
_storage = Storage(count: bytes.count, alignment: alignment)
|
|
||||||
_writerSize = _storage.capacity
|
|
||||||
allowReadingUnalignedBuffers = allowUnalignedBuffers
|
|
||||||
b.withUnsafeMutableBytes { bufferPointer in
|
|
||||||
self._storage.copy(from: bufferPointer.baseAddress!, count: bytes.count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
/// Constructor that creates a Flatbuffer from the Swift Data type object
|
|
||||||
/// - Parameter
|
|
||||||
/// - data: Swift data Object
|
|
||||||
/// - allowReadingUnalignedBuffers: allow reading from unaligned buffer
|
|
||||||
public init(
|
|
||||||
data: Data,
|
|
||||||
allowReadingUnalignedBuffers allowUnalignedBuffers: Bool = false)
|
|
||||||
{
|
|
||||||
var b = data
|
|
||||||
_storage = Storage(count: data.count, alignment: alignment)
|
|
||||||
_writerSize = _storage.capacity
|
|
||||||
allowReadingUnalignedBuffers = allowUnalignedBuffers
|
|
||||||
b.withUnsafeMutableBytes { bufferPointer in
|
|
||||||
self._storage.copy(from: bufferPointer.baseAddress!, count: data.count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Constructor that creates a Flatbuffer instance with a size
|
|
||||||
/// - Parameter:
|
|
||||||
/// - size: Length of the buffer
|
|
||||||
/// - allowReadingUnalignedBuffers: allow reading from unaligned buffer
|
|
||||||
init(initialSize size: Int) {
|
|
||||||
let size = size.convertToPowerofTwo
|
|
||||||
_storage = Storage(count: size, alignment: alignment)
|
|
||||||
_storage.initialize(for: size)
|
|
||||||
allowReadingUnalignedBuffers = false
|
|
||||||
}
|
|
||||||
|
|
||||||
#if swift(>=5.0) && !os(WASI)
|
|
||||||
/// Constructor that creates a Flatbuffer object from a ContiguousBytes
|
|
||||||
/// - Parameters:
|
|
||||||
/// - contiguousBytes: Binary stripe to use as the buffer
|
|
||||||
/// - count: amount of readable bytes
|
|
||||||
/// - allowReadingUnalignedBuffers: allow reading from unaligned buffer
|
|
||||||
public init<Bytes: ContiguousBytes>(
|
|
||||||
contiguousBytes: Bytes,
|
|
||||||
count: Int,
|
|
||||||
allowReadingUnalignedBuffers allowUnalignedBuffers: Bool = false)
|
|
||||||
{
|
|
||||||
_storage = Storage(count: count, alignment: alignment)
|
|
||||||
_writerSize = _storage.capacity
|
|
||||||
allowReadingUnalignedBuffers = allowUnalignedBuffers
|
|
||||||
contiguousBytes.withUnsafeBytes { buf in
|
|
||||||
_storage.copy(from: buf.baseAddress!, count: buf.count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Constructor that creates a Flatbuffer from unsafe memory region without copying
|
|
||||||
/// - Parameter:
|
|
||||||
/// - assumingMemoryBound: The unsafe memory region
|
|
||||||
/// - capacity: The size of the given memory region
|
|
||||||
/// - allowReadingUnalignedBuffers: allow reading from unaligned buffer
|
|
||||||
public init(
|
|
||||||
assumingMemoryBound memory: UnsafeMutableRawPointer,
|
|
||||||
capacity: Int,
|
|
||||||
allowReadingUnalignedBuffers allowUnalignedBuffers: Bool = false)
|
|
||||||
{
|
|
||||||
_storage = Storage(memory: memory, capacity: capacity, unowned: true)
|
|
||||||
_writerSize = capacity
|
|
||||||
allowReadingUnalignedBuffers = allowUnalignedBuffers
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a copy of the buffer that's being built by calling sizedBuffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - memory: Current memory of the buffer
|
|
||||||
/// - count: count of bytes
|
|
||||||
/// - allowReadingUnalignedBuffers: allow reading from unaligned buffer
|
|
||||||
init(
|
|
||||||
memory: UnsafeMutableRawPointer,
|
|
||||||
count: Int,
|
|
||||||
allowReadingUnalignedBuffers allowUnalignedBuffers: Bool = false)
|
|
||||||
{
|
|
||||||
_storage = Storage(count: count, alignment: alignment)
|
|
||||||
_storage.copy(from: memory, count: count)
|
|
||||||
_writerSize = _storage.capacity
|
|
||||||
allowReadingUnalignedBuffers = allowUnalignedBuffers
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a copy of the existing flatbuffer, by copying it to a different memory.
|
|
||||||
/// - Parameters:
|
|
||||||
/// - memory: Current memory of the buffer
|
|
||||||
/// - count: count of bytes
|
|
||||||
/// - removeBytes: Removes a number of bytes from the current size
|
|
||||||
/// - allowReadingUnalignedBuffers: allow reading from unaligned buffer
|
|
||||||
init(
|
|
||||||
memory: UnsafeMutableRawPointer,
|
|
||||||
count: Int,
|
|
||||||
removing removeBytes: Int,
|
|
||||||
allowReadingUnalignedBuffers allowUnalignedBuffers: Bool = false)
|
|
||||||
{
|
|
||||||
_storage = Storage(count: count, alignment: alignment)
|
|
||||||
_storage.copy(from: memory, count: count)
|
|
||||||
_writerSize = removeBytes
|
|
||||||
allowReadingUnalignedBuffers = allowUnalignedBuffers
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Fills the buffer with padding by adding to the writersize
|
|
||||||
/// - Parameter padding: Amount of padding between two to be serialized objects
|
|
||||||
@inline(__always)
|
|
||||||
@usableFromInline
|
|
||||||
mutating func fill(padding: Int) {
|
|
||||||
assert(padding >= 0, "Fill should be larger than or equal to zero")
|
|
||||||
ensureSpace(size: padding)
|
|
||||||
_writerSize = _writerSize &+ (MemoryLayout<UInt8>.size &* padding)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds an array of type Scalar to the buffer memory
|
|
||||||
/// - Parameter elements: An array of Scalars
|
|
||||||
@inline(__always)
|
|
||||||
@usableFromInline
|
|
||||||
mutating func push<T: Scalar>(elements: [T]) {
|
|
||||||
elements.withUnsafeBytes { ptr in
|
|
||||||
ensureSpace(size: ptr.count)
|
|
||||||
memcpy(
|
|
||||||
_storage.memory.advanced(by: writerIndex &- ptr.count),
|
|
||||||
UnsafeRawPointer(ptr.baseAddress!),
|
|
||||||
ptr.count)
|
|
||||||
self._writerSize = self._writerSize &+ ptr.count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds an array of type Scalar to the buffer memory
|
|
||||||
/// - Parameter elements: An array of Scalars
|
|
||||||
@inline(__always)
|
|
||||||
@usableFromInline
|
|
||||||
mutating func push<T: NativeStruct>(elements: [T]) {
|
|
||||||
elements.withUnsafeBytes { ptr in
|
|
||||||
ensureSpace(size: ptr.count)
|
|
||||||
_storage.memory
|
|
||||||
.advanced(by: writerIndex &- ptr.count)
|
|
||||||
.copyMemory(from: ptr.baseAddress!, byteCount: ptr.count)
|
|
||||||
self._writerSize = self._writerSize &+ ptr.count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds a `ContiguousBytes` to buffer memory
|
|
||||||
/// - Parameter value: bytes to copy
|
|
||||||
#if swift(>=5.0) && !os(WASI)
|
|
||||||
@inline(__always)
|
|
||||||
@usableFromInline
|
|
||||||
mutating func push(bytes: ContiguousBytes) {
|
|
||||||
bytes.withUnsafeBytes { ptr in
|
|
||||||
ensureSpace(size: ptr.count)
|
|
||||||
memcpy(
|
|
||||||
_storage.memory.advanced(by: writerIndex &- ptr.count),
|
|
||||||
UnsafeRawPointer(ptr.baseAddress!),
|
|
||||||
ptr.count)
|
|
||||||
self._writerSize = self._writerSize &+ ptr.count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Adds an object of type NativeStruct into the buffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - value: Object that will be written to the buffer
|
|
||||||
/// - size: size to subtract from the WriterIndex
|
|
||||||
@usableFromInline
|
|
||||||
@inline(__always)
|
|
||||||
mutating func push<T: NativeStruct>(struct value: T, size: Int) {
|
|
||||||
ensureSpace(size: size)
|
|
||||||
var v = value
|
|
||||||
withUnsafeBytes(of: &v) {
|
|
||||||
memcpy(
|
|
||||||
_storage.memory.advanced(by: writerIndex &- size),
|
|
||||||
$0.baseAddress!,
|
|
||||||
size)
|
|
||||||
self._writerSize = self._writerSize &+ size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds an object of type Scalar into the buffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - value: Object that will be written to the buffer
|
|
||||||
/// - len: Offset to subtract from the WriterIndex
|
|
||||||
@inline(__always)
|
|
||||||
@usableFromInline
|
|
||||||
mutating func push<T: Scalar>(value: T, len: Int) {
|
|
||||||
ensureSpace(size: len)
|
|
||||||
var v = value
|
|
||||||
withUnsafeBytes(of: &v) {
|
|
||||||
memcpy(
|
|
||||||
_storage.memory.advanced(by: writerIndex &- len),
|
|
||||||
$0.baseAddress!,
|
|
||||||
len)
|
|
||||||
self._writerSize = self._writerSize &+ len
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds a string to the buffer using swift.utf8 object
|
|
||||||
/// - Parameter str: String that will be added to the buffer
|
|
||||||
/// - Parameter len: length of the string
|
|
||||||
@inline(__always)
|
|
||||||
@usableFromInline
|
|
||||||
mutating func push(string str: String, len: Int) {
|
|
||||||
ensureSpace(size: len)
|
|
||||||
if str.utf8
|
|
||||||
.withContiguousStorageIfAvailable({ self.push(bytes: $0, len: len) }) !=
|
|
||||||
nil
|
|
||||||
{
|
|
||||||
} else {
|
|
||||||
let utf8View = str.utf8
|
|
||||||
for c in utf8View.reversed() {
|
|
||||||
push(value: c, len: 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a string to Bytebuffer using UTF8View
|
|
||||||
/// - Parameters:
|
|
||||||
/// - bytes: Pointer to the view
|
|
||||||
/// - len: Size of string
|
|
||||||
@usableFromInline
|
|
||||||
@inline(__always)
|
|
||||||
mutating func push(
|
|
||||||
bytes: UnsafeBufferPointer<String.UTF8View.Element>,
|
|
||||||
len: Int) -> Bool
|
|
||||||
{
|
|
||||||
memcpy(
|
|
||||||
_storage.memory.advanced(by: writerIndex &- len),
|
|
||||||
UnsafeRawPointer(bytes.baseAddress!),
|
|
||||||
len)
|
|
||||||
_writerSize = _writerSize &+ len
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write stores an object into the buffer directly or indirectly.
|
|
||||||
///
|
|
||||||
/// Direct: ignores the capacity of buffer which would mean we are referring to the direct point in memory
|
|
||||||
/// indirect: takes into respect the current capacity of the buffer (capacity - index), writing to the buffer from the end
|
|
||||||
/// - Parameters:
|
|
||||||
/// - value: Value that needs to be written to the buffer
|
|
||||||
/// - index: index to write to
|
|
||||||
/// - direct: Should take into consideration the capacity of the buffer
|
|
||||||
@inline(__always)
|
|
||||||
func write<T>(value: T, index: Int, direct: Bool = false) {
|
|
||||||
var index = index
|
|
||||||
if !direct {
|
|
||||||
index = _storage.capacity &- index
|
|
||||||
}
|
|
||||||
assert(index < _storage.capacity, "Write index is out of writing bound")
|
|
||||||
assert(index >= 0, "Writer index should be above zero")
|
|
||||||
_storage.memory.storeBytes(of: value, toByteOffset: index, as: T.self)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Makes sure that buffer has enouch space for each of the objects that will be written into it
|
|
||||||
/// - Parameter size: size of object
|
|
||||||
@discardableResult
|
|
||||||
@usableFromInline
|
|
||||||
@inline(__always)
|
|
||||||
mutating func ensureSpace(size: Int) -> Int {
|
|
||||||
if size &+ _writerSize > _storage.capacity {
|
|
||||||
_storage.reallocate(size, writerSize: _writerSize, alignment: alignment)
|
|
||||||
}
|
|
||||||
assert(size < FlatBufferMaxSize, "Buffer can't grow beyond 2 Gigabytes")
|
|
||||||
return size
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pops the written VTable if it's already written into the buffer
|
|
||||||
/// - Parameter size: size of the `VTable`
|
|
||||||
@usableFromInline
|
|
||||||
@inline(__always)
|
|
||||||
mutating func pop(_ size: Int) {
|
|
||||||
assert(
|
|
||||||
(_writerSize &- size) > 0,
|
|
||||||
"New size should NOT be a negative number")
|
|
||||||
memset(_storage.memory.advanced(by: writerIndex), 0, _writerSize &- size)
|
|
||||||
_writerSize = size
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clears the current size of the buffer
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func clearSize() {
|
|
||||||
_writerSize = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clears the current instance of the buffer, replacing it with new memory
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func clear() {
|
|
||||||
_writerSize = 0
|
|
||||||
alignment = 1
|
|
||||||
_storage.initialize(for: _storage.capacity)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads an object from the buffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - def: Type of the object
|
|
||||||
/// - position: the index of the object in the buffer
|
|
||||||
@inline(__always)
|
|
||||||
public func read<T>(def: T.Type, position: Int) -> T {
|
|
||||||
#if swift(>=5.7)
|
|
||||||
if allowReadingUnalignedBuffers {
|
|
||||||
return _storage.memory.advanced(by: position).loadUnaligned(as: T.self)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return _storage.memory.advanced(by: position).load(as: T.self)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a slice from the memory assuming a type of T
|
|
||||||
/// - Parameters:
|
|
||||||
/// - index: index of the object to be read from the buffer
|
|
||||||
/// - count: count of bytes in memory
|
|
||||||
@inline(__always)
|
|
||||||
public func readSlice<T>(
|
|
||||||
index: Int,
|
|
||||||
count: Int) -> [T]
|
|
||||||
{
|
|
||||||
assert(
|
|
||||||
index + count <= _storage.capacity,
|
|
||||||
"Reading out of bounds is illegal")
|
|
||||||
let start = _storage.memory.advanced(by: index)
|
|
||||||
.assumingMemoryBound(to: T.self)
|
|
||||||
let array = UnsafeBufferPointer(start: start, count: count)
|
|
||||||
return Array(array)
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
/// Reads a string from the buffer and encodes it to a swift string
|
|
||||||
/// - Parameters:
|
|
||||||
/// - index: index of the string in the buffer
|
|
||||||
/// - count: length of the string
|
|
||||||
/// - type: Encoding of the string
|
|
||||||
@inline(__always)
|
|
||||||
public func readString(
|
|
||||||
at index: Int,
|
|
||||||
count: Int,
|
|
||||||
type: String.Encoding = .utf8) -> String?
|
|
||||||
{
|
|
||||||
assert(
|
|
||||||
index + count <= _storage.capacity,
|
|
||||||
"Reading out of bounds is illegal")
|
|
||||||
let start = _storage.memory.advanced(by: index)
|
|
||||||
.assumingMemoryBound(to: UInt8.self)
|
|
||||||
let bufprt = UnsafeBufferPointer(start: start, count: count)
|
|
||||||
return String(bytes: Array(bufprt), encoding: type)
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/// Reads a string from the buffer and encodes it to a swift string
|
|
||||||
/// - Parameters:
|
|
||||||
/// - index: index of the string in the buffer
|
|
||||||
/// - count: length of the string
|
|
||||||
/// - type: Encoding of the string
|
|
||||||
@inline(__always)
|
|
||||||
public func readString(
|
|
||||||
at index: Int,
|
|
||||||
count: Int) -> String?
|
|
||||||
{
|
|
||||||
assert(
|
|
||||||
index + count <= _storage.capacity,
|
|
||||||
"Reading out of bounds is illegal")
|
|
||||||
let start = _storage.memory.advanced(by: index)
|
|
||||||
.assumingMemoryBound(to: UInt8.self)
|
|
||||||
let bufprt = UnsafeBufferPointer(start: start, count: count)
|
|
||||||
return String(cString: bufprt.baseAddress!)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Creates a new Flatbuffer object that's duplicated from the current one
|
|
||||||
/// - Parameter removeBytes: the amount of bytes to remove from the current Size
|
|
||||||
@inline(__always)
|
|
||||||
public func duplicate(removing removeBytes: Int = 0) -> ByteBuffer {
|
|
||||||
assert(removeBytes > 0, "Can NOT remove negative bytes")
|
|
||||||
assert(
|
|
||||||
removeBytes < _storage.capacity,
|
|
||||||
"Can NOT remove more bytes than the ones allocated")
|
|
||||||
return ByteBuffer(
|
|
||||||
memory: _storage.memory,
|
|
||||||
count: _storage.capacity,
|
|
||||||
removing: _writerSize &- removeBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the written bytes into the ``ByteBuffer``
|
|
||||||
public var underlyingBytes: [UInt8] {
|
|
||||||
let cp = capacity &- writerIndex
|
|
||||||
let start = memory.advanced(by: writerIndex)
|
|
||||||
.bindMemory(to: UInt8.self, capacity: cp)
|
|
||||||
|
|
||||||
let ptr = UnsafeBufferPointer<UInt8>(start: start, count: cp)
|
|
||||||
return Array(ptr)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// SkipPrefix Skips the first 4 bytes in case one of the following
|
|
||||||
/// functions are called `getPrefixedSizeCheckedRoot` & `getPrefixedSizeRoot`
|
|
||||||
/// which allows us to skip the first 4 bytes instead of recreating the buffer
|
|
||||||
@discardableResult
|
|
||||||
@usableFromInline
|
|
||||||
@inline(__always)
|
|
||||||
mutating func skipPrefix() -> Int32 {
|
|
||||||
_writerSize = _writerSize &- MemoryLayout<Int32>.size
|
|
||||||
return read(def: Int32.self, position: 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ByteBuffer: CustomDebugStringConvertible {
|
|
||||||
|
|
||||||
public var debugDescription: String {
|
|
||||||
"""
|
|
||||||
buffer located at: \(_storage.memory), with capacity of \(_storage.capacity)
|
|
||||||
{ writerSize: \(_writerSize), readerSize: \(reader), writerIndex: \(writerIndex) }
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,122 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
#if os(Linux)
|
|
||||||
import CoreFoundation
|
|
||||||
#else
|
|
||||||
import Foundation
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// A boolean to see if the system is littleEndian
|
|
||||||
let isLitteEndian: Bool = {
|
|
||||||
let number: UInt32 = 0x12345678
|
|
||||||
return number == number.littleEndian
|
|
||||||
}()
|
|
||||||
/// Constant for the file id length
|
|
||||||
let FileIdLength = 4
|
|
||||||
/// Type aliases
|
|
||||||
public typealias Byte = UInt8
|
|
||||||
public typealias UOffset = UInt32
|
|
||||||
public typealias SOffset = Int32
|
|
||||||
public typealias VOffset = UInt16
|
|
||||||
/// Maximum size for a buffer
|
|
||||||
public let FlatBufferMaxSize = UInt32
|
|
||||||
.max << ((MemoryLayout<SOffset>.size * 8 - 1) - 1)
|
|
||||||
|
|
||||||
/// Protocol that All Scalars should conform to
|
|
||||||
///
|
|
||||||
/// Scalar is used to conform all the numbers that can be represented in a FlatBuffer. It's used to write/read from the buffer.
|
|
||||||
public protocol Scalar: Equatable {
|
|
||||||
associatedtype NumericValue
|
|
||||||
var convertedEndian: NumericValue { get }
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Scalar where Self: Verifiable {}
|
|
||||||
|
|
||||||
extension Scalar where Self: FixedWidthInteger {
|
|
||||||
/// Converts the value from BigEndian to LittleEndian
|
|
||||||
///
|
|
||||||
/// Converts values to little endian on machines that work with BigEndian, however this is NOT TESTED yet.
|
|
||||||
public var convertedEndian: NumericValue {
|
|
||||||
self as! Self.NumericValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Double: Scalar, Verifiable {
|
|
||||||
public typealias NumericValue = UInt64
|
|
||||||
|
|
||||||
public var convertedEndian: UInt64 {
|
|
||||||
bitPattern.littleEndian
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Float32: Scalar, Verifiable {
|
|
||||||
public typealias NumericValue = UInt32
|
|
||||||
|
|
||||||
public var convertedEndian: UInt32 {
|
|
||||||
bitPattern.littleEndian
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Bool: Scalar, Verifiable {
|
|
||||||
public var convertedEndian: UInt8 {
|
|
||||||
self == true ? 1 : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
public typealias NumericValue = UInt8
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Int: Scalar, Verifiable {
|
|
||||||
public typealias NumericValue = Int
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Int8: Scalar, Verifiable {
|
|
||||||
public typealias NumericValue = Int8
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Int16: Scalar, Verifiable {
|
|
||||||
public typealias NumericValue = Int16
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Int32: Scalar, Verifiable {
|
|
||||||
public typealias NumericValue = Int32
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Int64: Scalar, Verifiable {
|
|
||||||
public typealias NumericValue = Int64
|
|
||||||
}
|
|
||||||
|
|
||||||
extension UInt8: Scalar, Verifiable {
|
|
||||||
public typealias NumericValue = UInt8
|
|
||||||
}
|
|
||||||
|
|
||||||
extension UInt16: Scalar, Verifiable {
|
|
||||||
public typealias NumericValue = UInt16
|
|
||||||
}
|
|
||||||
|
|
||||||
extension UInt32: Scalar, Verifiable {
|
|
||||||
public typealias NumericValue = UInt32
|
|
||||||
}
|
|
||||||
|
|
||||||
extension UInt64: Scalar, Verifiable {
|
|
||||||
public typealias NumericValue = UInt64
|
|
||||||
}
|
|
||||||
|
|
||||||
public func FlatBuffersVersion_24_3_25() {}
|
|
@ -1,22 +0,0 @@
|
|||||||
# ``FlatBuffers``
|
|
||||||
|
|
||||||
FlatBuffers: Memory Efficient Serialization Library
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
- Access to serialized data without parsing/unpacking - What sets FlatBuffers apart is that it represents hierarchical data in a flat binary buffer in such a way that it can still be accessed directly without parsing/unpacking, while also still supporting data structure evolution (forwards/backwards compatibility).
|
|
||||||
- Memory efficiency and speed - The only memory needed to access your data is that of the buffer. It requires 0 additional allocations (in C++, other languages may vary). FlatBuffers is also very suitable for use with mmap (or streaming), requiring only part of the buffer to be in memory. Access is close to the speed of raw struct access with only one extra indirection (a kind of vtable) to allow for format evolution and optional fields. It is aimed at projects where spending time and space (many memory allocations) to be able to access or construct serialized data is undesirable, such as in games or any other performance sensitive applications. See the benchmarks for details.
|
|
||||||
- Flexible - Optional fields means not only do you get great forwards and backwards compatibility (increasingly important for long-lived games: don't have to update all data with each new version!). It also means you have a lot of choice in what data you write and what data you don't, and how you design data structures.
|
|
||||||
- Tiny code footprint - Small amounts of generated code, and just a single small header as the minimum dependency, which is very easy to integrate. Again, see the benchmark section for details.
|
|
||||||
- Strongly typed - Errors happen at compile time rather than manually having to write repetitive and error prone run-time checks. Useful code can be generated for you.
|
|
||||||
|
|
||||||
## Topics
|
|
||||||
|
|
||||||
### Read this first
|
|
||||||
|
|
||||||
- <doc:Tutorial_Table_of_Contents>
|
|
||||||
|
|
||||||
### Where to start
|
|
||||||
|
|
||||||
- ``FlatBufferBuilder``
|
|
||||||
- ``ByteBuffer``
|
|
@ -1 +0,0 @@
|
|||||||
|
|
@ -1 +0,0 @@
|
|||||||
enum Color:byte { red, green, blue }
|
|
@ -1,6 +0,0 @@
|
|||||||
enum Color:byte { red, green, blue }
|
|
||||||
|
|
||||||
struct Vec3 {
|
|
||||||
x:float;
|
|
||||||
y:float;
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
enum Color:byte { red, green, blue }
|
|
||||||
|
|
||||||
struct Vec3 {
|
|
||||||
x:float;
|
|
||||||
y:float;
|
|
||||||
}
|
|
||||||
|
|
||||||
table Monster {
|
|
||||||
pos:Vec3;
|
|
||||||
color:Color = Blue;
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
|||||||
enum Color:byte { red, green, blue }
|
|
||||||
|
|
||||||
struct Vec3 {
|
|
||||||
x:float;
|
|
||||||
y:float;
|
|
||||||
}
|
|
||||||
|
|
||||||
table Monster {
|
|
||||||
pos:Vec3;
|
|
||||||
color:Color = Blue;
|
|
||||||
|
|
||||||
mana:short = 150;
|
|
||||||
hp:short = 100;
|
|
||||||
name:string;
|
|
||||||
equipped:Equipment;
|
|
||||||
weapons:[Weapon];
|
|
||||||
path:[Vec3];
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
enum Color:byte { red, green, blue }
|
|
||||||
|
|
||||||
union Equipment { Weapon } // Optionally add more tables.
|
|
||||||
|
|
||||||
struct Vec3 {
|
|
||||||
x:float;
|
|
||||||
y:float;
|
|
||||||
}
|
|
||||||
|
|
||||||
table Monster {
|
|
||||||
pos:Vec3;
|
|
||||||
color:Color = Blue;
|
|
||||||
|
|
||||||
mana:short = 150;
|
|
||||||
hp:short = 100;
|
|
||||||
name:string;
|
|
||||||
equipped:Equipment;
|
|
||||||
weapons:[Weapon];
|
|
||||||
path:[Vec3];
|
|
||||||
}
|
|
||||||
|
|
||||||
table Weapon {
|
|
||||||
name:string;
|
|
||||||
damage:short;
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
enum Color:byte { red, green, blue }
|
|
||||||
|
|
||||||
union Equipment { Weapon } // Optionally add more tables.
|
|
||||||
|
|
||||||
struct Vec3 {
|
|
||||||
x:float;
|
|
||||||
y:float;
|
|
||||||
}
|
|
||||||
|
|
||||||
table Monster {
|
|
||||||
pos:Vec3;
|
|
||||||
color:Color = Blue;
|
|
||||||
|
|
||||||
mana:short = 150;
|
|
||||||
hp:short = 100;
|
|
||||||
name:string;
|
|
||||||
equipped:Equipment;
|
|
||||||
weapons:[Weapon];
|
|
||||||
path:[Vec3];
|
|
||||||
}
|
|
||||||
|
|
||||||
table Weapon {
|
|
||||||
name:string;
|
|
||||||
damage:short;
|
|
||||||
}
|
|
||||||
|
|
||||||
root_type Monster; // flatc --swift monster.fbs
|
|
@ -1 +0,0 @@
|
|||||||
import Foundation
|
|
@ -1,71 +0,0 @@
|
|||||||
import FlatBuffers
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
func run() {
|
|
||||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
|
||||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
|
||||||
|
|
||||||
let weapon1Name = builder.create(string: "Sword")
|
|
||||||
let weapon2Name = builder.create(string: "Axe")
|
|
||||||
|
|
||||||
// start creating the weapon by calling startWeapon
|
|
||||||
let weapon1Start = Weapon.startWeapon(&builder)
|
|
||||||
Weapon.add(name: weapon1Name, &builder)
|
|
||||||
Weapon.add(damage: 3, &builder)
|
|
||||||
// end the object by passing the start point for the weapon 1
|
|
||||||
let sword = Weapon.endWeapon(&builder, start: weapon1Start)
|
|
||||||
|
|
||||||
let weapon2Start = Weapon.startWeapon(&builder)
|
|
||||||
Weapon.add(name: weapon2Name, &builder)
|
|
||||||
Weapon.add(damage: 5, &builder)
|
|
||||||
let axe = Weapon.endWeapon(&builder, start: weapon2Start)
|
|
||||||
|
|
||||||
// Create a FlatBuffer `vector` that contains offsets to the sword and axe
|
|
||||||
// we created above.
|
|
||||||
let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
|
|
||||||
|
|
||||||
// Name of the Monster.
|
|
||||||
let name = builder.create(string: "Orc")
|
|
||||||
|
|
||||||
let pathOffset = fbb.createVector(ofStructs: [
|
|
||||||
Vec3(x: 0, y: 0),
|
|
||||||
Vec3(x: 5, y: 5),
|
|
||||||
])
|
|
||||||
|
|
||||||
// startVector(len, elementSize: MemoryLayout<Offset>.size)
|
|
||||||
// for o in offsets.reversed() {
|
|
||||||
// push(element: o)
|
|
||||||
// }
|
|
||||||
// endVector(len: len)
|
|
||||||
|
|
||||||
let orc = Monster.createMonster(
|
|
||||||
&builder,
|
|
||||||
pos: Vec3(x: 1, y: 2),
|
|
||||||
hp: 300,
|
|
||||||
nameOffset: name,
|
|
||||||
color: .red,
|
|
||||||
weaponsVectorOffset: weaponsOffset,
|
|
||||||
equippedType: .weapon,
|
|
||||||
equippedOffset: axe,
|
|
||||||
pathOffset: pathOffset)
|
|
||||||
|
|
||||||
// let start = Monster.startMonster(&builder)
|
|
||||||
// Monster.add(pos: Vec3(x: 1, y: 2), &builder)
|
|
||||||
// Monster.add(hp: 300, &builder)
|
|
||||||
// Monster.add(name: name, &builder)
|
|
||||||
// Monster.add(color: .red, &builder)
|
|
||||||
// Monster.addVectorOf(weapons: weaponsOffset, &builder)
|
|
||||||
// Monster.add(equippedType: .weapon, &builder)
|
|
||||||
// Monster.addVectorOf(paths: weaponsOffset, &builder)
|
|
||||||
// Monster.add(equipped: axe, &builder)
|
|
||||||
// var orc = Monster.endMonster(&builder, start: start)
|
|
||||||
|
|
||||||
// Call `finish(offset:)` to instruct the builder that this monster is complete.
|
|
||||||
builder.finish(offset: orc)
|
|
||||||
// This must be called after `finish()`.
|
|
||||||
// `sizedByteArray` returns the finished buf of type [UInt8].
|
|
||||||
let buf = builder.sizedByteArray
|
|
||||||
|
|
||||||
// or you can use to get an object of type Data
|
|
||||||
let bufData = ByteBuffer(data: builder.sizedBuffer)
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
import FlatBuffers
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
func run() {
|
|
||||||
// create a ByteBuffer(:) from an [UInt8] or Data()
|
|
||||||
let buf = [] // Get your data
|
|
||||||
var byteBuffer = ByteBuffer(bytes: buf)
|
|
||||||
// Get an accessor to the root object inside the buffer.
|
|
||||||
let monster: Monster = try! getCheckedRoot(byteBuffer: &byteBuffer)
|
|
||||||
// let monster: Monster = getRoot(byteBuffer: &byteBuffer)
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
import FlatBuffers
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
func run() {
|
|
||||||
// create a ByteBuffer(:) from an [UInt8] or Data()
|
|
||||||
let buf = [] // Get your data
|
|
||||||
var byteBuffer = ByteBuffer(bytes: buf)
|
|
||||||
// Get an accessor to the root object inside the buffer.
|
|
||||||
let monster: Monster = try! getCheckedRoot(byteBuffer: &byteBuffer)
|
|
||||||
// let monster: Monster = getRoot(byteBuffer: &byteBuffer)
|
|
||||||
|
|
||||||
let hp = monster.hp
|
|
||||||
let mana = monster.mana
|
|
||||||
let name = monster.name // returns an optional string
|
|
||||||
|
|
||||||
let pos = monster.pos
|
|
||||||
let x = pos.x
|
|
||||||
let y = pos.y
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
import FlatBuffers
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
func run() {
|
|
||||||
// create a ByteBuffer(:) from an [UInt8] or Data()
|
|
||||||
let buf = [] // Get your data
|
|
||||||
var byteBuffer = ByteBuffer(bytes: buf)
|
|
||||||
// Get an accessor to the root object inside the buffer.
|
|
||||||
let monster: Monster = try! getCheckedRoot(byteBuffer: &byteBuffer)
|
|
||||||
// let monster: Monster = getRoot(byteBuffer: &byteBuffer)
|
|
||||||
|
|
||||||
let hp = monster.hp
|
|
||||||
let mana = monster.mana
|
|
||||||
let name = monster.name // returns an optional string
|
|
||||||
|
|
||||||
let pos = monster.pos
|
|
||||||
let x = pos.x
|
|
||||||
let y = pos.y
|
|
||||||
|
|
||||||
// Get and check if the monster has an equipped item
|
|
||||||
if monster.equippedType == .weapon {
|
|
||||||
let _weapon = monster.equipped(type: Weapon.self)
|
|
||||||
let name = _weapon.name // should return "Axe"
|
|
||||||
let dmg = _weapon.damage // should return 5
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
import FlatBuffers
|
|
||||||
import Foundation
|
|
@ -1,7 +0,0 @@
|
|||||||
import FlatBuffers
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
func run() {
|
|
||||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
|
||||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
import FlatBuffers
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
func run() {
|
|
||||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
|
||||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
|
||||||
|
|
||||||
let weapon1Name = builder.create(string: "Sword")
|
|
||||||
let weapon2Name = builder.create(string: "Axe")
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
import FlatBuffers
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
func run() {
|
|
||||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
|
||||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
|
||||||
|
|
||||||
let weapon1Name = builder.create(string: "Sword")
|
|
||||||
let weapon2Name = builder.create(string: "Axe")
|
|
||||||
|
|
||||||
// start creating the weapon by calling startWeapon
|
|
||||||
let weapon1Start = Weapon.startWeapon(&builder)
|
|
||||||
Weapon.add(name: weapon1Name, &builder)
|
|
||||||
Weapon.add(damage: 3, &builder)
|
|
||||||
// end the object by passing the start point for the weapon 1
|
|
||||||
let sword = Weapon.endWeapon(&builder, start: weapon1Start)
|
|
||||||
|
|
||||||
let weapon2Start = Weapon.startWeapon(&builder)
|
|
||||||
Weapon.add(name: weapon2Name, &builder)
|
|
||||||
Weapon.add(damage: 5, &builder)
|
|
||||||
let axe = Weapon.endWeapon(&builder, start: weapon2Start)
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
import FlatBuffers
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
func run() {
|
|
||||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
|
||||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
|
||||||
|
|
||||||
let weapon1Name = builder.create(string: "Sword")
|
|
||||||
let weapon2Name = builder.create(string: "Axe")
|
|
||||||
|
|
||||||
// start creating the weapon by calling startWeapon
|
|
||||||
let weapon1Start = Weapon.startWeapon(&builder)
|
|
||||||
Weapon.add(name: weapon1Name, &builder)
|
|
||||||
Weapon.add(damage: 3, &builder)
|
|
||||||
// end the object by passing the start point for the weapon 1
|
|
||||||
let sword = Weapon.endWeapon(&builder, start: weapon1Start)
|
|
||||||
|
|
||||||
let weapon2Start = Weapon.startWeapon(&builder)
|
|
||||||
Weapon.add(name: weapon2Name, &builder)
|
|
||||||
Weapon.add(damage: 5, &builder)
|
|
||||||
let axe = Weapon.endWeapon(&builder, start: weapon2Start)
|
|
||||||
|
|
||||||
// Create a FlatBuffer `vector` that contains offsets to the sword and axe
|
|
||||||
// we created above.
|
|
||||||
let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
import FlatBuffers
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
func run() {
|
|
||||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
|
||||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
|
||||||
|
|
||||||
let weapon1Name = builder.create(string: "Sword")
|
|
||||||
let weapon2Name = builder.create(string: "Axe")
|
|
||||||
|
|
||||||
// start creating the weapon by calling startWeapon
|
|
||||||
let weapon1Start = Weapon.startWeapon(&builder)
|
|
||||||
Weapon.add(name: weapon1Name, &builder)
|
|
||||||
Weapon.add(damage: 3, &builder)
|
|
||||||
// end the object by passing the start point for the weapon 1
|
|
||||||
let sword = Weapon.endWeapon(&builder, start: weapon1Start)
|
|
||||||
|
|
||||||
let weapon2Start = Weapon.startWeapon(&builder)
|
|
||||||
Weapon.add(name: weapon2Name, &builder)
|
|
||||||
Weapon.add(damage: 5, &builder)
|
|
||||||
let axe = Weapon.endWeapon(&builder, start: weapon2Start)
|
|
||||||
|
|
||||||
// Create a FlatBuffer `vector` that contains offsets to the sword and axe
|
|
||||||
// we created above.
|
|
||||||
let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
|
|
||||||
|
|
||||||
// Name of the Monster.
|
|
||||||
let name = builder.create(string: "Orc")
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
import FlatBuffers
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
func run() {
|
|
||||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
|
||||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
|
||||||
|
|
||||||
let weapon1Name = builder.create(string: "Sword")
|
|
||||||
let weapon2Name = builder.create(string: "Axe")
|
|
||||||
|
|
||||||
// start creating the weapon by calling startWeapon
|
|
||||||
let weapon1Start = Weapon.startWeapon(&builder)
|
|
||||||
Weapon.add(name: weapon1Name, &builder)
|
|
||||||
Weapon.add(damage: 3, &builder)
|
|
||||||
// end the object by passing the start point for the weapon 1
|
|
||||||
let sword = Weapon.endWeapon(&builder, start: weapon1Start)
|
|
||||||
|
|
||||||
let weapon2Start = Weapon.startWeapon(&builder)
|
|
||||||
Weapon.add(name: weapon2Name, &builder)
|
|
||||||
Weapon.add(damage: 5, &builder)
|
|
||||||
let axe = Weapon.endWeapon(&builder, start: weapon2Start)
|
|
||||||
|
|
||||||
// Create a FlatBuffer `vector` that contains offsets to the sword and axe
|
|
||||||
// we created above.
|
|
||||||
let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
|
|
||||||
|
|
||||||
// Name of the Monster.
|
|
||||||
let name = builder.create(string: "Orc")
|
|
||||||
|
|
||||||
let pathOffset = fbb.createVector(ofStructs: [
|
|
||||||
Vec3(x: 0, y: 0),
|
|
||||||
Vec3(x: 5, y: 5),
|
|
||||||
])
|
|
||||||
|
|
||||||
// startVector(len, elementSize: MemoryLayout<Offset>.size)
|
|
||||||
// for o in offsets.reversed() {
|
|
||||||
// push(element: o)
|
|
||||||
// }
|
|
||||||
// endVector(len: len)
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
import FlatBuffers
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
func run() {
|
|
||||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
|
||||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
|
||||||
|
|
||||||
let weapon1Name = builder.create(string: "Sword")
|
|
||||||
let weapon2Name = builder.create(string: "Axe")
|
|
||||||
|
|
||||||
// start creating the weapon by calling startWeapon
|
|
||||||
let weapon1Start = Weapon.startWeapon(&builder)
|
|
||||||
Weapon.add(name: weapon1Name, &builder)
|
|
||||||
Weapon.add(damage: 3, &builder)
|
|
||||||
// end the object by passing the start point for the weapon 1
|
|
||||||
let sword = Weapon.endWeapon(&builder, start: weapon1Start)
|
|
||||||
|
|
||||||
let weapon2Start = Weapon.startWeapon(&builder)
|
|
||||||
Weapon.add(name: weapon2Name, &builder)
|
|
||||||
Weapon.add(damage: 5, &builder)
|
|
||||||
let axe = Weapon.endWeapon(&builder, start: weapon2Start)
|
|
||||||
|
|
||||||
// Create a FlatBuffer `vector` that contains offsets to the sword and axe
|
|
||||||
// we created above.
|
|
||||||
let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
|
|
||||||
|
|
||||||
// Name of the Monster.
|
|
||||||
let name = builder.create(string: "Orc")
|
|
||||||
|
|
||||||
let pathOffset = fbb.createVector(ofStructs: [
|
|
||||||
Vec3(x: 0, y: 0),
|
|
||||||
Vec3(x: 5, y: 5),
|
|
||||||
])
|
|
||||||
|
|
||||||
// startVector(len, elementSize: MemoryLayout<Offset>.size)
|
|
||||||
// for o in offsets.reversed() {
|
|
||||||
// push(element: o)
|
|
||||||
// }
|
|
||||||
// endVector(len: len)
|
|
||||||
|
|
||||||
let orc = Monster.createMonster(
|
|
||||||
&builder,
|
|
||||||
pos: Vec3(x: 1, y: 2),
|
|
||||||
hp: 300,
|
|
||||||
nameOffset: name,
|
|
||||||
color: .red,
|
|
||||||
weaponsVectorOffset: weaponsOffset,
|
|
||||||
equippedType: .weapon,
|
|
||||||
equippedOffset: axe,
|
|
||||||
pathOffset: pathOffset)
|
|
||||||
|
|
||||||
// let start = Monster.startMonster(&builder)
|
|
||||||
// Monster.add(pos: Vec3(x: 1, y: 2), &builder)
|
|
||||||
// Monster.add(hp: 300, &builder)
|
|
||||||
// Monster.add(name: name, &builder)
|
|
||||||
// Monster.add(color: .red, &builder)
|
|
||||||
// Monster.addVectorOf(weapons: weaponsOffset, &builder)
|
|
||||||
// Monster.add(equippedType: .weapon, &builder)
|
|
||||||
// Monster.addVectorOf(paths: weaponsOffset, &builder)
|
|
||||||
// Monster.add(equipped: axe, &builder)
|
|
||||||
// var orc = Monster.endMonster(&builder, start: start)
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 20 KiB |
@ -1,14 +0,0 @@
|
|||||||
@Tutorials(name: "Starting with FlatBuffers") {
|
|
||||||
@Intro(title: "Starting with FlatBuffers") {
|
|
||||||
FlatBuffers is an efficient cross platform serialization library for C++,
|
|
||||||
C#, C, Go, Java, Kotlin, JavaScript, Lobster, Lua, TypeScript, PHP, Python, Rust and Swift.
|
|
||||||
It was originally created at Google for game development and other performance-critical applications.
|
|
||||||
}
|
|
||||||
@Chapter(name: "Generating your code") {
|
|
||||||
Start by generating your first FlatBuffers objects.
|
|
||||||
@Image(source: tutorial_cover_image_1.png, alt: "A code structure for a base struct in flatbuffers")
|
|
||||||
@TutorialReference(tutorial: "doc:creating_flatbuffer_schema")
|
|
||||||
@TutorialReference(tutorial: "doc:create_your_first_buffer")
|
|
||||||
@TutorialReference(tutorial: "doc:reading_bytebuffer")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
@Tutorial(time: 5) {
|
|
||||||
@Intro(title: "After having our code generated") {
|
|
||||||
After generating the code from the previous section, we will know start creating our monster object.
|
|
||||||
We will create a monster object called orc.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Section(title: "Building your first buffer") {
|
|
||||||
@ContentAndMedia {}
|
|
||||||
@Steps {
|
|
||||||
@Step {
|
|
||||||
Starting with a new file, we will create our very first Flatbuffer.
|
|
||||||
@Code(name: "ViewController.swift", file: "swift_code_1.swift")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
First, we need to import ``FlatBuffers``
|
|
||||||
@Code(name: "ViewController.swift", file: "swift_code_2.swift")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
We need to create an instance of the `FlatBufferBuilder`, which will contain the buffer as it grows.
|
|
||||||
You can pass an initial size of the buffer (here 1024 bytes), which will grow automatically if needed.
|
|
||||||
@Code(name: "ViewController.swift", file: "swift_code_3.swift")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
After creating the builder, we can start serializing our data. Before we make our orc Monster,
|
|
||||||
let's create some Weapons: a Sword and an Axe. However we will start by naming our weapons as `Sword` and `Axe`
|
|
||||||
@Code(name: "ViewController.swift", file: "swift_code_4.swift")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
After naming the weapons, we will create two weapon objects with the damage that the weapon is going to deal.
|
|
||||||
That's done by calling the `start` Method on each table you will be creating, in this case its called `startWeapon`
|
|
||||||
and finished by calling `end`.
|
|
||||||
@Code(name: "ViewController.swift", file: "swift_code_5.swift")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
We will take our (Sword and Axe) serialized data and serialize their offsets as a vector of tables into our `ByteBuffer`.
|
|
||||||
So we can reference them later on from our Monster Object
|
|
||||||
@Code(name: "ViewController.swift", file: "swift_code_6.swift")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
We will add our Monster name as a string value just like we did with the weapons.
|
|
||||||
@Code(name: "ViewController.swift", file: "swift_code_7.swift")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Step {
|
|
||||||
We will create a path that our monster should be using while roaming in its den. To create a vector of paths we would us
|
|
||||||
`createVector(ofStructs: [])` which will take a Native `Swift` struct that has been padded to fit the `FlatBuffers` standards.
|
|
||||||
|
|
||||||
There are usually two ways of creating vectors in `FlatBuffers` which you can see in commented out code.
|
|
||||||
And thus there are multiple convenience methods that will cover all the bases
|
|
||||||
when trying to create a vector so that you dont have to create it with `start` and `end`
|
|
||||||
@Code(name: "ViewController.swift", file: "swift_code_8.swift")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Step {
|
|
||||||
Now to serialize our data into our `Monster` object. Which again there are two ways of doing, by calling the `create` method or
|
|
||||||
by serializing the objects yourself. What we added to our Monster were the `Equipped Type` and the `Equipped` union itself, which
|
|
||||||
allows the Monster to have the `Axe` as his equipped weapon.
|
|
||||||
|
|
||||||
Important: Unlike structs, you should not nest tables or other objects,
|
|
||||||
which is why we created all the `strings/vectors/tables` that this monster refers to before start.
|
|
||||||
If you try to create any of them between start and end, you will get an `assert`.
|
|
||||||
@Code(name: "ViewController.swift", file: "swift_code_9.swift")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Step {
|
|
||||||
Finally you can just finalize the buffer by calling `builder.finish` and get the Byte array from the buffer.
|
|
||||||
@Code(name: "ViewController.swift", file: "swift_code_10.swift")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
@Tutorial(time: 2) {
|
|
||||||
@Intro(title: "Creating a schema") {
|
|
||||||
You will need to have the FlatBuffer compiler to be installed on your device
|
|
||||||
}
|
|
||||||
|
|
||||||
@Section(title: "Creating a schema") {
|
|
||||||
@ContentAndMedia {}
|
|
||||||
@Steps {
|
|
||||||
@Step {
|
|
||||||
Start by creating a new empty folder called `monster.fbs`. We want to create a Monster table, that contains
|
|
||||||
position, color, and basic information about the monster.
|
|
||||||
@Code(name: "monster.fbs", file: "monster_step_1.fbs")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
We will start by adding our Color object. We will be using an enumerate, to represent this object
|
|
||||||
@Code(name: "monster.fbs", file: "monster_step_2.fbs")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
We will add a position object and will use a struct to represent that type of data. Where we will need the monsters
|
|
||||||
x and y positions.
|
|
||||||
@Code(name: "monster.fbs", file: "monster_step_3.fbs")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
Then we will be creating our Monster object of type table. This will contain the current position of our
|
|
||||||
monster and its color
|
|
||||||
@Code(name: "monster.fbs", file: "monster_step_4.fbs")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
Our Monster is missing a name, mana, hp, name, equipped Weapon, weapons, and path. We will be adding these
|
|
||||||
fields to our table with a proper data type for each. Example; weapons, and path would be a vector of data.
|
|
||||||
@Code(name: "monster.fbs", file: "monster_step_5.fbs")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
Now we are missing two data types here, `Weapon` and `Equipment`. And since Equipment can be a weapon, we will be using
|
|
||||||
a `Union` enumerate that can contain all the equipment that you would want your monster to have. And the weapon can simply
|
|
||||||
have a name and amount of damage
|
|
||||||
@Code(name: "monster.fbs", file: "monster_step_6.fbs")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
And to finalize our monster table, we can add a root type of type Monster.
|
|
||||||
Then run the command `flatc --swift monster.fbs`
|
|
||||||
Note: Make sure to import the file to your xcode project.
|
|
||||||
@Code(name: "monster.fbs", file: "monster_step_7.fbs")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
@Tutorial(time: 2) {
|
|
||||||
@Intro(title: "Reading ByteBuffers") {
|
|
||||||
After getting our ByteBuffer created, we can now read it.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Section(title: "Reading your first buffer") {
|
|
||||||
@ContentAndMedia {}
|
|
||||||
@Steps {
|
|
||||||
@Step {
|
|
||||||
After fetching the data from disk or network you need to access that data, and that can be done.
|
|
||||||
By simply calling `getCheckedRoot`, which checks if the data is valid before enabling you to read from a corrupt buffer.
|
|
||||||
however, if you are sure that the data is 100% correct you can simply call `getRoot`
|
|
||||||
@Code(name: "ViewController.swift", file: "swift_code_11.swift")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
Now since we have a Monster object, all the fields can be accessed by simply fetching the data. Note, Deprecated fields will not
|
|
||||||
show up
|
|
||||||
@Code(name: "ViewController.swift", file: "swift_code_12.swift")
|
|
||||||
}
|
|
||||||
@Step {
|
|
||||||
And you can access union types as easy as this
|
|
||||||
@Code(name: "ViewController.swift", file: "swift_code_13.swift")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Enum is a protocol that all flatbuffers enums should conform to
|
|
||||||
/// Since it allows us to get the actual `ByteSize` and `Value` from
|
|
||||||
/// a swift enum.
|
|
||||||
public protocol Enum {
|
|
||||||
/// associatedtype that the type of the enum should conform to
|
|
||||||
associatedtype T: Scalar & Verifiable
|
|
||||||
/// Size of the current associatedtype in the enum
|
|
||||||
static var byteSize: Int { get }
|
|
||||||
/// The current value the enum hosts
|
|
||||||
var value: T { get }
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Enum where Self: Verifiable {
|
|
||||||
|
|
||||||
/// Verifies that the current value is which the bounds of the buffer, and if
|
|
||||||
/// the current `Value` is aligned properly
|
|
||||||
/// - Parameters:
|
|
||||||
/// - verifier: Verifier that hosts the buffer
|
|
||||||
/// - position: Current position within the buffer
|
|
||||||
/// - type: The type of the object to be verified
|
|
||||||
/// - Throws: Errors coming from `inBuffer` function
|
|
||||||
public static func verify<T>(
|
|
||||||
_ verifier: inout Verifier,
|
|
||||||
at position: Int,
|
|
||||||
of type: T.Type) throws where T: Verifiable
|
|
||||||
{
|
|
||||||
try verifier.inBuffer(position: position, of: type.self)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// UnionEnum is a Protocol that allows us to create Union type of enums
|
|
||||||
/// and their value initializers. Since an `init` was required by
|
|
||||||
/// the verifier
|
|
||||||
public protocol UnionEnum: Enum {
|
|
||||||
init?(value: T) throws
|
|
||||||
}
|
|
@ -1,934 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// ``FlatBufferBuilder`` builds a `FlatBuffer` through manipulating its internal state.
|
|
||||||
///
|
|
||||||
/// This is done by creating a ``ByteBuffer`` that hosts the incoming data and
|
|
||||||
/// has a hardcoded growth limit of `2GiB` which is set by the Flatbuffers standards.
|
|
||||||
///
|
|
||||||
/// ```swift
|
|
||||||
/// var builder = FlatBufferBuilder()
|
|
||||||
/// ```
|
|
||||||
/// The builder should be always created as a variable, since it would be passed into the writers
|
|
||||||
///
|
|
||||||
@frozen
|
|
||||||
public struct FlatBufferBuilder {
|
|
||||||
|
|
||||||
/// Storage for the Vtables used in the buffer are stored in here, so they would be written later in EndTable
|
|
||||||
@usableFromInline internal var _vtableStorage = VTableStorage()
|
|
||||||
/// Flatbuffer data will be written into
|
|
||||||
@usableFromInline internal var _bb: ByteBuffer
|
|
||||||
|
|
||||||
/// Reference Vtables that were already written to the buffer
|
|
||||||
private var _vtables: [UOffset] = []
|
|
||||||
/// A check if the buffer is being written into by a different table
|
|
||||||
private var isNested = false
|
|
||||||
/// Dictonary that stores a map of all the strings that were written to the buffer
|
|
||||||
private var stringOffsetMap: [String: Offset] = [:]
|
|
||||||
/// A check to see if finish(::) was ever called to retreive data object
|
|
||||||
private var finished = false
|
|
||||||
/// A check to see if the buffer should serialize Default values
|
|
||||||
private var serializeDefaults: Bool
|
|
||||||
|
|
||||||
/// Current alignment for the buffer
|
|
||||||
var _minAlignment: Int = 0 {
|
|
||||||
didSet {
|
|
||||||
_bb.alignment = _minAlignment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gives a read access to the buffer's size
|
|
||||||
public var size: UOffset { _bb.size }
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
/// Data representation of the buffer
|
|
||||||
///
|
|
||||||
/// Should only be used after ``finish(offset:addPrefix:)`` is called
|
|
||||||
public var data: Data {
|
|
||||||
assert(finished, "Data shouldn't be called before finish()")
|
|
||||||
return Data(
|
|
||||||
bytes: _bb.memory.advanced(by: _bb.writerIndex),
|
|
||||||
count: _bb.capacity &- _bb.writerIndex)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Returns the underlying bytes in the ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// Note: This should be used with caution.
|
|
||||||
public var fullSizedByteArray: [UInt8] {
|
|
||||||
let ptr = UnsafeBufferPointer(
|
|
||||||
start: _bb.memory.assumingMemoryBound(to: UInt8.self),
|
|
||||||
count: _bb.capacity)
|
|
||||||
return Array(ptr)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the written bytes into the ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// Should only be used after ``finish(offset:addPrefix:)`` is called
|
|
||||||
public var sizedByteArray: [UInt8] {
|
|
||||||
assert(finished, "Data shouldn't be called before finish()")
|
|
||||||
return _bb.underlyingBytes
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the original ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// Returns the current buffer that was just created
|
|
||||||
/// with the offsets, and data written to it.
|
|
||||||
public var buffer: ByteBuffer { _bb }
|
|
||||||
|
|
||||||
/// Returns a newly created sized ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// returns a new buffer that is sized to the data written
|
|
||||||
/// to the main buffer
|
|
||||||
public var sizedBuffer: ByteBuffer {
|
|
||||||
assert(finished, "Data shouldn't be called before finish()")
|
|
||||||
return ByteBuffer(
|
|
||||||
memory: _bb.memory.advanced(by: _bb.reader),
|
|
||||||
count: Int(_bb.size))
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Init
|
|
||||||
|
|
||||||
/// Initialize the buffer with a size
|
|
||||||
/// - Parameters:
|
|
||||||
/// - initialSize: Initial size for the buffer
|
|
||||||
/// - force: Allows default to be serialized into the buffer
|
|
||||||
///
|
|
||||||
/// This initializes a new builder with an initialSize that would initialize
|
|
||||||
/// a new ``ByteBuffer``. ``FlatBufferBuilder`` by default doesnt serialize defaults
|
|
||||||
/// however the builder can be force by passing true for `serializeDefaults`
|
|
||||||
public init(
|
|
||||||
initialSize: Int32 = 1024,
|
|
||||||
serializeDefaults force: Bool = false)
|
|
||||||
{
|
|
||||||
assert(initialSize > 0, "Size should be greater than zero!")
|
|
||||||
guard isLitteEndian else {
|
|
||||||
fatalError(
|
|
||||||
"Reading/Writing a buffer in big endian machine is not supported on swift")
|
|
||||||
}
|
|
||||||
serializeDefaults = force
|
|
||||||
_bb = ByteBuffer(initialSize: Int(initialSize))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clears the builder and the buffer from the written data.
|
|
||||||
mutating public func clear() {
|
|
||||||
_minAlignment = 0
|
|
||||||
isNested = false
|
|
||||||
stringOffsetMap.removeAll(keepingCapacity: true)
|
|
||||||
_vtables.removeAll(keepingCapacity: true)
|
|
||||||
_vtableStorage.clear()
|
|
||||||
_bb.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Create Tables
|
|
||||||
|
|
||||||
/// Checks if the required fields were serialized into the buffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - table: offset for the table
|
|
||||||
/// - fields: Array of all the important fields to be serialized
|
|
||||||
///
|
|
||||||
/// *NOTE: Never call this function, this is only supposed to be called
|
|
||||||
/// by the generated code*
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func require(table: Offset, fields: [Int32]) {
|
|
||||||
for field in fields {
|
|
||||||
let start = _bb.capacity &- Int(table.o)
|
|
||||||
let startTable = start &- Int(_bb.read(def: Int32.self, position: start))
|
|
||||||
let isOkay = _bb.read(
|
|
||||||
def: VOffset.self,
|
|
||||||
position: startTable &+ Int(field)) != 0
|
|
||||||
assert(isOkay, "Flatbuffers requires the following field")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finished the buffer by adding the file id and then calling finish
|
|
||||||
/// - Parameters:
|
|
||||||
/// - offset: Offset of the table
|
|
||||||
/// - fileId: Takes the fileId
|
|
||||||
/// - prefix: if false it wont add the size of the buffer
|
|
||||||
///
|
|
||||||
/// ``finish(offset:fileId:addPrefix:)`` should be called at the end of creating
|
|
||||||
/// a table
|
|
||||||
/// ```swift
|
|
||||||
/// var root = SomeObject
|
|
||||||
/// .createObject(&builder,
|
|
||||||
/// name: nameOffset)
|
|
||||||
/// builder.finish(
|
|
||||||
/// offset: root,
|
|
||||||
/// fileId: "ax1a",
|
|
||||||
/// addPrefix: true)
|
|
||||||
/// ```
|
|
||||||
/// File id would append a file id name at the end of the written bytes before,
|
|
||||||
/// finishing the buffer.
|
|
||||||
///
|
|
||||||
/// Whereas, if `addPrefix` is true, the written bytes would
|
|
||||||
/// include the size of the current buffer.
|
|
||||||
mutating public func finish(
|
|
||||||
offset: Offset,
|
|
||||||
fileId: String,
|
|
||||||
addPrefix prefix: Bool = false)
|
|
||||||
{
|
|
||||||
let size = MemoryLayout<UOffset>.size
|
|
||||||
preAlign(
|
|
||||||
len: size &+ (prefix ? size : 0) &+ FileIdLength,
|
|
||||||
alignment: _minAlignment)
|
|
||||||
assert(fileId.count == FileIdLength, "Flatbuffers requires file id to be 4")
|
|
||||||
_bb.push(string: fileId, len: 4)
|
|
||||||
finish(offset: offset, addPrefix: prefix)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finished the buffer by adding the file id, offset, and prefix to it.
|
|
||||||
/// - Parameters:
|
|
||||||
/// - offset: Offset of the table
|
|
||||||
/// - prefix: if false it wont add the size of the buffer
|
|
||||||
///
|
|
||||||
/// ``finish(offset:addPrefix:)`` should be called at the end of creating
|
|
||||||
/// a table
|
|
||||||
/// ```swift
|
|
||||||
/// var root = SomeObject
|
|
||||||
/// .createObject(&builder,
|
|
||||||
/// name: nameOffset)
|
|
||||||
/// builder.finish(
|
|
||||||
/// offset: root,
|
|
||||||
/// addPrefix: true)
|
|
||||||
/// ```
|
|
||||||
/// If `addPrefix` is true, the written bytes would
|
|
||||||
/// include the size of the current buffer.
|
|
||||||
mutating public func finish(
|
|
||||||
offset: Offset,
|
|
||||||
addPrefix prefix: Bool = false)
|
|
||||||
{
|
|
||||||
notNested()
|
|
||||||
let size = MemoryLayout<UOffset>.size
|
|
||||||
preAlign(len: size &+ (prefix ? size : 0), alignment: _minAlignment)
|
|
||||||
push(element: refer(to: offset.o))
|
|
||||||
if prefix { push(element: _bb.size) }
|
|
||||||
_vtableStorage.clear()
|
|
||||||
finished = true
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ``startTable(with:)`` will let the builder know, that a new object is being serialized.
|
|
||||||
///
|
|
||||||
/// The function will fatalerror if called while there is another object being serialized.
|
|
||||||
/// ```swift
|
|
||||||
/// let start = Monster
|
|
||||||
/// .startMonster(&fbb)
|
|
||||||
/// ```
|
|
||||||
/// - Parameter numOfFields: Number of elements to be written to the buffer
|
|
||||||
/// - Returns: Offset of the newly started table
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func startTable(with numOfFields: Int) -> UOffset {
|
|
||||||
notNested()
|
|
||||||
isNested = true
|
|
||||||
_vtableStorage.start(count: numOfFields)
|
|
||||||
return _bb.size
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ``endTable(at:)`` will let the ``FlatBufferBuilder`` know that the
|
|
||||||
/// object that's written to it is completed
|
|
||||||
///
|
|
||||||
/// This would be called after all the elements are serialized,
|
|
||||||
/// it will add the current vtable into the ``ByteBuffer``.
|
|
||||||
/// The functions will `fatalError` in case the object is called
|
|
||||||
/// without ``startTable(with:)``, or the object has exceeded the limit of 2GB.
|
|
||||||
///
|
|
||||||
/// - Parameter startOffset:Start point of the object written
|
|
||||||
/// - returns: The root of the table
|
|
||||||
mutating public func endTable(at startOffset: UOffset) -> UOffset {
|
|
||||||
assert(isNested, "Calling endtable without calling starttable")
|
|
||||||
let sizeofVoffset = MemoryLayout<VOffset>.size
|
|
||||||
let vTableOffset = push(element: SOffset(0))
|
|
||||||
|
|
||||||
let tableObjectSize = vTableOffset &- startOffset
|
|
||||||
assert(tableObjectSize < 0x10000, "Buffer can't grow beyond 2 Gigabytes")
|
|
||||||
let _max = Int(_vtableStorage.maxOffset) &+ sizeofVoffset
|
|
||||||
|
|
||||||
_bb.fill(padding: _max)
|
|
||||||
_bb.write(
|
|
||||||
value: VOffset(tableObjectSize),
|
|
||||||
index: _bb.writerIndex &+ sizeofVoffset,
|
|
||||||
direct: true)
|
|
||||||
_bb.write(value: VOffset(_max), index: _bb.writerIndex, direct: true)
|
|
||||||
|
|
||||||
var itr = 0
|
|
||||||
while itr < _vtableStorage.writtenIndex {
|
|
||||||
let loaded = _vtableStorage.load(at: itr)
|
|
||||||
itr = itr &+ _vtableStorage.size
|
|
||||||
guard loaded.offset != 0 else { continue }
|
|
||||||
let _index = (_bb.writerIndex &+ Int(loaded.position))
|
|
||||||
_bb.write(
|
|
||||||
value: VOffset(vTableOffset &- loaded.offset),
|
|
||||||
index: _index,
|
|
||||||
direct: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
_vtableStorage.clear()
|
|
||||||
let vt_use = _bb.size
|
|
||||||
|
|
||||||
var isAlreadyAdded: Int?
|
|
||||||
|
|
||||||
let vt2 = _bb.memory.advanced(by: _bb.writerIndex)
|
|
||||||
let len2 = vt2.load(fromByteOffset: 0, as: Int16.self)
|
|
||||||
|
|
||||||
for table in _vtables {
|
|
||||||
let position = _bb.capacity &- Int(table)
|
|
||||||
let vt1 = _bb.memory.advanced(by: position)
|
|
||||||
let len1 = _bb.read(def: Int16.self, position: position)
|
|
||||||
if len2 != len1 || 0 != memcmp(vt1, vt2, Int(len2)) { continue }
|
|
||||||
|
|
||||||
isAlreadyAdded = Int(table)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if let offset = isAlreadyAdded {
|
|
||||||
let vTableOff = Int(vTableOffset)
|
|
||||||
let space = _bb.capacity &- vTableOff
|
|
||||||
_bb.write(value: Int32(offset &- vTableOff), index: space, direct: true)
|
|
||||||
_bb.pop(_bb.capacity &- space)
|
|
||||||
} else {
|
|
||||||
_bb.write(value: Int32(vt_use &- vTableOffset), index: Int(vTableOffset))
|
|
||||||
_vtables.append(_bb.size)
|
|
||||||
}
|
|
||||||
isNested = false
|
|
||||||
return vTableOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Builds Buffer
|
|
||||||
|
|
||||||
/// Asserts to see if the object is not nested
|
|
||||||
@inline(__always)
|
|
||||||
@usableFromInline
|
|
||||||
mutating internal func notNested() {
|
|
||||||
assert(!isNested, "Object serialization must not be nested")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Changes the minimuim alignment of the buffer
|
|
||||||
/// - Parameter size: size of the current alignment
|
|
||||||
@inline(__always)
|
|
||||||
@usableFromInline
|
|
||||||
mutating internal func minAlignment(size: Int) {
|
|
||||||
if size > _minAlignment {
|
|
||||||
_minAlignment = size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the padding for the current element
|
|
||||||
/// - Parameters:
|
|
||||||
/// - bufSize: Current size of the buffer + the offset of the object to be written
|
|
||||||
/// - elementSize: Element size
|
|
||||||
@inline(__always)
|
|
||||||
@usableFromInline
|
|
||||||
mutating internal func padding(
|
|
||||||
bufSize: UInt32,
|
|
||||||
elementSize: UInt32) -> UInt32
|
|
||||||
{
|
|
||||||
((~bufSize) &+ 1) & (elementSize - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Prealigns the buffer before writting a new object into the buffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - len:Length of the object
|
|
||||||
/// - alignment: Alignment type
|
|
||||||
@inline(__always)
|
|
||||||
@usableFromInline
|
|
||||||
mutating internal func preAlign(len: Int, alignment: Int) {
|
|
||||||
minAlignment(size: alignment)
|
|
||||||
_bb.fill(padding: Int(padding(
|
|
||||||
bufSize: _bb.size &+ UOffset(len),
|
|
||||||
elementSize: UOffset(alignment))))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Prealigns the buffer before writting a new object into the buffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - len: Length of the object
|
|
||||||
/// - type: Type of the object to be written
|
|
||||||
@inline(__always)
|
|
||||||
@usableFromInline
|
|
||||||
mutating internal func preAlign<T: Scalar>(len: Int, type: T.Type) {
|
|
||||||
preAlign(len: len, alignment: MemoryLayout<T>.size)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Refers to an object that's written in the buffer
|
|
||||||
/// - Parameter off: the objects index value
|
|
||||||
@inline(__always)
|
|
||||||
@usableFromInline
|
|
||||||
mutating internal func refer(to off: UOffset) -> UOffset {
|
|
||||||
let size = MemoryLayout<UOffset>.size
|
|
||||||
preAlign(len: size, alignment: size)
|
|
||||||
return _bb.size &- off &+ UInt32(size)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Tracks the elements written into the buffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - offset: The offset of the element witten
|
|
||||||
/// - position: The position of the element
|
|
||||||
@inline(__always)
|
|
||||||
@usableFromInline
|
|
||||||
mutating internal func track(offset: UOffset, at position: VOffset) {
|
|
||||||
_vtableStorage.add(loc: FieldLoc(offset: offset, position: position))
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Inserting Vectors
|
|
||||||
|
|
||||||
/// ``startVector(_:elementSize:)`` creates a new vector within buffer
|
|
||||||
///
|
|
||||||
/// The function checks if there is a current object being written, if
|
|
||||||
/// the check passes it creates a buffer alignment of `length * elementSize`
|
|
||||||
/// ```swift
|
|
||||||
/// builder.startVector(
|
|
||||||
/// int32Values.count, elementSize: 4)
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - len: Length of vector to be created
|
|
||||||
/// - elementSize: Size of object type to be written
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func startVector(_ len: Int, elementSize: Int) {
|
|
||||||
notNested()
|
|
||||||
isNested = true
|
|
||||||
preAlign(len: len &* elementSize, type: UOffset.self)
|
|
||||||
preAlign(len: len &* elementSize, alignment: elementSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ``endVector(len:)`` ends the currently created vector
|
|
||||||
///
|
|
||||||
/// Calling ``endVector(len:)`` requires the length, of the current
|
|
||||||
/// vector. The length would be pushed to indicate the count of numbers
|
|
||||||
/// within the vector. If ``endVector(len:)`` is called without
|
|
||||||
/// ``startVector(_:elementSize:)`` it asserts.
|
|
||||||
///
|
|
||||||
/// ```swift
|
|
||||||
/// let vectorOffset = builder.
|
|
||||||
/// endVector(len: int32Values.count)
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// - Parameter len: Length of the buffer
|
|
||||||
/// - Returns: Returns the current ``Offset`` in the ``ByteBuffer``
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func endVector(len: Int) -> Offset {
|
|
||||||
assert(isNested, "Calling endVector without calling startVector")
|
|
||||||
isNested = false
|
|
||||||
return Offset(offset: push(element: Int32(len)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a vector of type ``Scalar`` into the ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// ``createVector(_:)-4swl0`` writes a vector of type Scalars into
|
|
||||||
/// ``ByteBuffer``. This is a convenient method instead of calling,
|
|
||||||
/// ``startVector(_:elementSize:)`` and then ``endVector(len:)``
|
|
||||||
/// ```swift
|
|
||||||
/// let vectorOffset = builder.
|
|
||||||
/// createVector([1, 2, 3, 4])
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// The underlying implementation simply calls ``createVector(_:size:)-4lhrv``
|
|
||||||
///
|
|
||||||
/// - Parameter elements: elements to be written into the buffer
|
|
||||||
/// - returns: ``Offset`` of the vector
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func createVector<T: Scalar>(_ elements: [T]) -> Offset {
|
|
||||||
createVector(elements, size: elements.count)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a vector of type Scalar in the buffer
|
|
||||||
///
|
|
||||||
/// ``createVector(_:)-4swl0`` writes a vector of type Scalars into
|
|
||||||
/// ``ByteBuffer``. This is a convenient method instead of calling,
|
|
||||||
/// ``startVector(_:elementSize:)`` and then ``endVector(len:)``
|
|
||||||
/// ```swift
|
|
||||||
/// let vectorOffset = builder.
|
|
||||||
/// createVector([1, 2, 3, 4], size: 4)
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// - Parameter elements: Elements to be written into the buffer
|
|
||||||
/// - Parameter size: Count of elements
|
|
||||||
/// - returns: ``Offset`` of the vector
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func createVector<T: Scalar>(
|
|
||||||
_ elements: [T],
|
|
||||||
size: Int) -> Offset
|
|
||||||
{
|
|
||||||
let size = size
|
|
||||||
startVector(size, elementSize: MemoryLayout<T>.size)
|
|
||||||
_bb.push(elements: elements)
|
|
||||||
return endVector(len: size)
|
|
||||||
}
|
|
||||||
|
|
||||||
#if swift(>=5.0) && !os(WASI)
|
|
||||||
@inline(__always)
|
|
||||||
/// Creates a vector of bytes in the buffer.
|
|
||||||
///
|
|
||||||
/// Allows creating a vector from `Data` without copying to a `[UInt8]`
|
|
||||||
///
|
|
||||||
/// - Parameter bytes: bytes to be written into the buffer
|
|
||||||
/// - Returns: ``Offset`` of the vector
|
|
||||||
mutating public func createVector(bytes: ContiguousBytes) -> Offset {
|
|
||||||
let size = bytes.withUnsafeBytes { ptr in ptr.count }
|
|
||||||
startVector(size, elementSize: MemoryLayout<UInt8>.size)
|
|
||||||
_bb.push(bytes: bytes)
|
|
||||||
return endVector(len: size)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Creates a vector of type ``Enum`` into the ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// ``createVector(_:)-9h189`` writes a vector of type ``Enum`` into
|
|
||||||
/// ``ByteBuffer``. This is a convenient method instead of calling,
|
|
||||||
/// ``startVector(_:elementSize:)`` and then ``endVector(len:)``
|
|
||||||
/// ```swift
|
|
||||||
/// let vectorOffset = builder.
|
|
||||||
/// createVector([.swift, .cpp])
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// The underlying implementation simply calls ``createVector(_:size:)-7cx6z``
|
|
||||||
///
|
|
||||||
/// - Parameter elements: elements to be written into the buffer
|
|
||||||
/// - returns: ``Offset`` of the vector
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func createVector<T: Enum>(_ elements: [T]) -> Offset {
|
|
||||||
createVector(elements, size: elements.count)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a vector of type ``Enum`` into the ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// ``createVector(_:)-9h189`` writes a vector of type ``Enum`` into
|
|
||||||
/// ``ByteBuffer``. This is a convenient method instead of calling,
|
|
||||||
/// ``startVector(_:elementSize:)`` and then ``endVector(len:)``
|
|
||||||
/// ```swift
|
|
||||||
/// let vectorOffset = builder.
|
|
||||||
/// createVector([.swift, .cpp])
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// - Parameter elements: Elements to be written into the buffer
|
|
||||||
/// - Parameter size: Count of elements
|
|
||||||
/// - returns: ``Offset`` of the vector
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func createVector<T: Enum>(
|
|
||||||
_ elements: [T],
|
|
||||||
size: Int) -> Offset
|
|
||||||
{
|
|
||||||
let size = size
|
|
||||||
startVector(size, elementSize: T.byteSize)
|
|
||||||
for e in elements.reversed() {
|
|
||||||
_bb.push(value: e.value, len: T.byteSize)
|
|
||||||
}
|
|
||||||
return endVector(len: size)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a vector of already written offsets
|
|
||||||
///
|
|
||||||
/// ``createVector(ofOffsets:)`` creates a vector of ``Offset`` into
|
|
||||||
/// ``ByteBuffer``. This is a convenient method instead of calling,
|
|
||||||
/// ``startVector(_:elementSize:)`` and then ``endVector(len:)``.
|
|
||||||
///
|
|
||||||
/// The underlying implementation simply calls ``createVector(ofOffsets:len:)``
|
|
||||||
///
|
|
||||||
/// ```swift
|
|
||||||
/// let namesOffsets = builder.
|
|
||||||
/// createVector(ofOffsets: [name1, name2])
|
|
||||||
/// ```
|
|
||||||
/// - Parameter offsets: Array of offsets of type ``Offset``
|
|
||||||
/// - returns: ``Offset`` of the vector
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func createVector(ofOffsets offsets: [Offset]) -> Offset {
|
|
||||||
createVector(ofOffsets: offsets, len: offsets.count)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a vector of already written offsets
|
|
||||||
///
|
|
||||||
/// ``createVector(ofOffsets:)`` creates a vector of ``Offset`` into
|
|
||||||
/// ``ByteBuffer``. This is a convenient method instead of calling,
|
|
||||||
/// ``startVector(_:elementSize:)`` and then ``endVector(len:)``
|
|
||||||
///
|
|
||||||
/// ```swift
|
|
||||||
/// let namesOffsets = builder.
|
|
||||||
/// createVector(ofOffsets: [name1, name2])
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// - Parameter offsets: Array of offsets of type ``Offset``
|
|
||||||
/// - Parameter size: Count of elements
|
|
||||||
/// - returns: ``Offset`` of the vector
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func createVector(
|
|
||||||
ofOffsets offsets: [Offset],
|
|
||||||
len: Int) -> Offset
|
|
||||||
{
|
|
||||||
startVector(len, elementSize: MemoryLayout<Offset>.size)
|
|
||||||
for o in offsets.reversed() {
|
|
||||||
push(element: o)
|
|
||||||
}
|
|
||||||
return endVector(len: len)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a vector of strings
|
|
||||||
///
|
|
||||||
/// ``createVector(ofStrings:)`` creates a vector of `String` into
|
|
||||||
/// ``ByteBuffer``. This is a convenient method instead of manually
|
|
||||||
/// creating the string offsets, you simply pass it to this function
|
|
||||||
/// and it would write the strings into the ``ByteBuffer``.
|
|
||||||
/// After that it calls ``createVector(ofOffsets:)``
|
|
||||||
///
|
|
||||||
/// ```swift
|
|
||||||
/// let namesOffsets = builder.
|
|
||||||
/// createVector(ofStrings: ["Name", "surname"])
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// - Parameter str: Array of string
|
|
||||||
/// - returns: ``Offset`` of the vector
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func createVector(ofStrings str: [String]) -> Offset {
|
|
||||||
var offsets: [Offset] = []
|
|
||||||
for s in str {
|
|
||||||
offsets.append(create(string: s))
|
|
||||||
}
|
|
||||||
return createVector(ofOffsets: offsets)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a vector of type ``NativeStruct``.
|
|
||||||
///
|
|
||||||
/// Any swift struct in the generated code, should confirm to
|
|
||||||
/// ``NativeStruct``. Since the generated swift structs are padded
|
|
||||||
/// to the `FlatBuffers` standards.
|
|
||||||
///
|
|
||||||
/// ```swift
|
|
||||||
/// let offsets = builder.
|
|
||||||
/// createVector(ofStructs: [NativeStr(num: 1), NativeStr(num: 2)])
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// - Parameter structs: A vector of ``NativeStruct``
|
|
||||||
/// - Returns: ``Offset`` of the vector
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func createVector<T: NativeStruct>(ofStructs structs: [T])
|
|
||||||
-> Offset
|
|
||||||
{
|
|
||||||
startVector(
|
|
||||||
structs.count * MemoryLayout<T>.size,
|
|
||||||
elementSize: MemoryLayout<T>.alignment)
|
|
||||||
_bb.push(elements: structs)
|
|
||||||
return endVector(len: structs.count)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Inserting Structs
|
|
||||||
|
|
||||||
/// Writes a ``NativeStruct`` into the ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// Adds a native struct that's build and padded according
|
|
||||||
/// to `FlatBuffers` standards. with a predefined position.
|
|
||||||
///
|
|
||||||
/// ```swift
|
|
||||||
/// let offset = builder.create(
|
|
||||||
/// struct: NativeStr(num: 1),
|
|
||||||
/// position: 10)
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - s: ``NativeStruct`` to be inserted into the ``ByteBuffer``
|
|
||||||
/// - position: The predefined position of the object
|
|
||||||
/// - Returns: ``Offset`` of written struct
|
|
||||||
@inline(__always)
|
|
||||||
@discardableResult
|
|
||||||
mutating public func create<T: NativeStruct>(
|
|
||||||
struct s: T, position: VOffset) -> Offset
|
|
||||||
{
|
|
||||||
let offset = create(struct: s)
|
|
||||||
_vtableStorage.add(loc: FieldLoc(
|
|
||||||
offset: _bb.size,
|
|
||||||
position: VOffset(position)))
|
|
||||||
return offset
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a ``NativeStruct`` into the ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// Adds a native struct that's build and padded according
|
|
||||||
/// to `FlatBuffers` standards, directly into the buffer without
|
|
||||||
/// a predefined position.
|
|
||||||
///
|
|
||||||
/// ```swift
|
|
||||||
/// let offset = builder.create(
|
|
||||||
/// struct: NativeStr(num: 1))
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - s: ``NativeStruct`` to be inserted into the ``ByteBuffer``
|
|
||||||
/// - Returns: ``Offset`` of written struct
|
|
||||||
@inline(__always)
|
|
||||||
@discardableResult
|
|
||||||
mutating public func create<T: NativeStruct>(
|
|
||||||
struct s: T) -> Offset
|
|
||||||
{
|
|
||||||
let size = MemoryLayout<T>.size
|
|
||||||
preAlign(len: size, alignment: MemoryLayout<T>.alignment)
|
|
||||||
_bb.push(struct: s, size: size)
|
|
||||||
return Offset(offset: _bb.size)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Inserting Strings
|
|
||||||
|
|
||||||
/// Insets a string into the buffer of type `UTF8`
|
|
||||||
///
|
|
||||||
/// Adds a swift string into ``ByteBuffer`` by encoding it
|
|
||||||
/// using `UTF8`
|
|
||||||
///
|
|
||||||
/// ```swift
|
|
||||||
/// let nameOffset = builder
|
|
||||||
/// .create(string: "welcome")
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// - Parameter str: String to be serialized
|
|
||||||
/// - returns: ``Offset`` of inserted string
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func create(string str: String?) -> Offset {
|
|
||||||
guard let str = str else { return Offset() }
|
|
||||||
let len = str.utf8.count
|
|
||||||
notNested()
|
|
||||||
preAlign(len: len &+ 1, type: UOffset.self)
|
|
||||||
_bb.fill(padding: 1)
|
|
||||||
_bb.push(string: str, len: len)
|
|
||||||
push(element: UOffset(len))
|
|
||||||
return Offset(offset: _bb.size)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Insets a shared string into the buffer of type `UTF8`
|
|
||||||
///
|
|
||||||
/// Adds a swift string into ``ByteBuffer`` by encoding it
|
|
||||||
/// using `UTF8`. The function will check if the string,
|
|
||||||
/// is already written to the ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// ```swift
|
|
||||||
/// let nameOffset = builder
|
|
||||||
/// .createShared(string: "welcome")
|
|
||||||
///
|
|
||||||
///
|
|
||||||
/// let secondOffset = builder
|
|
||||||
/// .createShared(string: "welcome")
|
|
||||||
///
|
|
||||||
/// assert(nameOffset.o == secondOffset.o)
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// - Parameter str: String to be serialized
|
|
||||||
/// - returns: ``Offset`` of inserted string
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func createShared(string str: String?) -> Offset {
|
|
||||||
guard let str = str else { return Offset() }
|
|
||||||
if let offset = stringOffsetMap[str] {
|
|
||||||
return offset
|
|
||||||
}
|
|
||||||
let offset = create(string: str)
|
|
||||||
stringOffsetMap[str] = offset
|
|
||||||
return offset
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Inseting offsets
|
|
||||||
|
|
||||||
/// Writes the ``Offset`` of an already written table
|
|
||||||
///
|
|
||||||
/// Writes the ``Offset`` of a table if not empty into the
|
|
||||||
/// ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - offset: ``Offset`` of another object to be written
|
|
||||||
/// - position: The predefined position of the object
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func add(offset: Offset, at position: VOffset) {
|
|
||||||
if offset.isEmpty { return }
|
|
||||||
add(element: refer(to: offset.o), def: 0, at: position)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Pushes a value of type ``Offset`` into the ``ByteBuffer``
|
|
||||||
/// - Parameter o: ``Offset``
|
|
||||||
/// - returns: Current position of the ``Offset``
|
|
||||||
@inline(__always)
|
|
||||||
@discardableResult
|
|
||||||
mutating public func push(element o: Offset) -> UOffset {
|
|
||||||
push(element: refer(to: o.o))
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Inserting Scalars to Buffer
|
|
||||||
|
|
||||||
/// Writes a ``Scalar`` value into ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// ``add(element:def:at:)`` takes in a default value, and current value
|
|
||||||
/// and the position within the `VTable`. The default value would not
|
|
||||||
/// be serialized if the value is the same as the current value or
|
|
||||||
/// `serializeDefaults` is equal to false.
|
|
||||||
///
|
|
||||||
/// If serializing defaults is important ``init(initialSize:serializeDefaults:)``,
|
|
||||||
/// passing true for `serializeDefaults` would do the job.
|
|
||||||
///
|
|
||||||
/// ```swift
|
|
||||||
/// // Adds 10 to the buffer
|
|
||||||
/// builder.add(element: Int(10), def: 1, position 12)
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// *NOTE: Never call this manually*
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - element: Element to insert
|
|
||||||
/// - def: Default value for that element
|
|
||||||
/// - position: The predefined position of the element
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func add<T: Scalar>(
|
|
||||||
element: T,
|
|
||||||
def: T,
|
|
||||||
at position: VOffset)
|
|
||||||
{
|
|
||||||
if element == def && !serializeDefaults { return }
|
|
||||||
track(offset: push(element: element), at: position)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a optional ``Scalar`` value into ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// Takes an optional value to be written into the ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// *NOTE: Never call this manually*
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - element: Optional element of type scalar
|
|
||||||
/// - position: The predefined position of the element
|
|
||||||
@inline(__always)
|
|
||||||
mutating public func add<T: Scalar>(element: T?, at position: VOffset) {
|
|
||||||
guard let element = element else { return }
|
|
||||||
track(offset: push(element: element), at: position)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Pushes a values of type ``Scalar`` into the ``ByteBuffer``
|
|
||||||
///
|
|
||||||
/// *NOTE: Never call this manually*
|
|
||||||
///
|
|
||||||
/// - Parameter element: Element to insert
|
|
||||||
/// - returns: Postion of the Element
|
|
||||||
@inline(__always)
|
|
||||||
@discardableResult
|
|
||||||
mutating public func push<T: Scalar>(element: T) -> UOffset {
|
|
||||||
let size = MemoryLayout<T>.size
|
|
||||||
preAlign(
|
|
||||||
len: size,
|
|
||||||
alignment: size)
|
|
||||||
_bb.push(value: element, len: size)
|
|
||||||
return _bb.size
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension FlatBufferBuilder: CustomDebugStringConvertible {
|
|
||||||
|
|
||||||
public var debugDescription: String {
|
|
||||||
"""
|
|
||||||
buffer debug:
|
|
||||||
\(_bb)
|
|
||||||
builder debug:
|
|
||||||
{ finished: \(finished), serializeDefaults: \(serializeDefaults), isNested: \(isNested) }
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
|
|
||||||
/// VTableStorage is a class to contain the VTable buffer that would be serialized into buffer
|
|
||||||
@usableFromInline
|
|
||||||
internal class VTableStorage {
|
|
||||||
/// Memory check since deallocating each time we want to clear would be expensive
|
|
||||||
/// and memory leaks would happen if we dont deallocate the first allocated memory.
|
|
||||||
/// memory is promised to be available before adding `FieldLoc`
|
|
||||||
private var memoryInUse = false
|
|
||||||
/// Size of FieldLoc in memory
|
|
||||||
let size = MemoryLayout<FieldLoc>.stride
|
|
||||||
/// Memeory buffer
|
|
||||||
var memory: UnsafeMutableRawBufferPointer!
|
|
||||||
/// Capacity of the current buffer
|
|
||||||
var capacity: Int = 0
|
|
||||||
/// Maximuim offset written to the class
|
|
||||||
var maxOffset: VOffset = 0
|
|
||||||
/// number of fields written into the buffer
|
|
||||||
var numOfFields: Int = 0
|
|
||||||
/// Last written Index
|
|
||||||
var writtenIndex: Int = 0
|
|
||||||
|
|
||||||
/// Creates the memory to store the buffer in
|
|
||||||
@usableFromInline
|
|
||||||
@inline(__always)
|
|
||||||
init() {
|
|
||||||
memory = UnsafeMutableRawBufferPointer.allocate(
|
|
||||||
byteCount: 0,
|
|
||||||
alignment: 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
deinit {
|
|
||||||
memory.deallocate()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds a buffer with byte count of fieldloc.size * count of field numbers
|
|
||||||
/// - Parameter count: number of fields to be written
|
|
||||||
@inline(__always)
|
|
||||||
func start(count: Int) {
|
|
||||||
assert(count >= 0, "number of fields should NOT be negative")
|
|
||||||
let capacity = count &* size
|
|
||||||
ensure(space: capacity)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds a FieldLoc into the buffer, which would track how many have been written,
|
|
||||||
/// and max offset
|
|
||||||
/// - Parameter loc: Location of encoded element
|
|
||||||
@inline(__always)
|
|
||||||
func add(loc: FieldLoc) {
|
|
||||||
memory.baseAddress?.advanced(by: writtenIndex).storeBytes(
|
|
||||||
of: loc,
|
|
||||||
as: FieldLoc.self)
|
|
||||||
writtenIndex = writtenIndex &+ size
|
|
||||||
numOfFields = numOfFields &+ 1
|
|
||||||
maxOffset = max(loc.position, maxOffset)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clears the data stored related to the encoded buffer
|
|
||||||
@inline(__always)
|
|
||||||
func clear() {
|
|
||||||
maxOffset = 0
|
|
||||||
numOfFields = 0
|
|
||||||
writtenIndex = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ensure that the buffer has enough space instead of recreating the buffer each time.
|
|
||||||
/// - Parameter space: space required for the new vtable
|
|
||||||
@inline(__always)
|
|
||||||
func ensure(space: Int) {
|
|
||||||
guard space &+ writtenIndex > capacity else { return }
|
|
||||||
memory.deallocate()
|
|
||||||
memory = UnsafeMutableRawBufferPointer.allocate(
|
|
||||||
byteCount: space,
|
|
||||||
alignment: size)
|
|
||||||
capacity = space
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Loads an object of type `FieldLoc` from buffer memory
|
|
||||||
/// - Parameter index: index of element
|
|
||||||
/// - Returns: a FieldLoc at index
|
|
||||||
@inline(__always)
|
|
||||||
func load(at index: Int) -> FieldLoc {
|
|
||||||
memory.load(fromByteOffset: index, as: FieldLoc.self)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
internal struct FieldLoc {
|
|
||||||
var offset: UOffset
|
|
||||||
var position: VOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// NativeStruct is a protocol that indicates if the struct is a native `swift` struct
|
|
||||||
/// since now we will be serializing native structs into the buffer.
|
|
||||||
public protocol NativeStruct {}
|
|
||||||
|
|
||||||
/// FlatbuffersInitializable is a protocol that allows any object to be
|
|
||||||
/// Initialized from a ByteBuffer
|
|
||||||
public protocol FlatbuffersInitializable {
|
|
||||||
/// Any flatbuffers object that confirms to this protocol is going to be
|
|
||||||
/// initializable through this initializer
|
|
||||||
init(_ bb: ByteBuffer, o: Int32)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// FlatbufferObject structures all the Flatbuffers objects
|
|
||||||
public protocol FlatBufferObject: FlatbuffersInitializable {
|
|
||||||
var __buffer: ByteBuffer! { get }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ``ObjectAPIPacker`` is a protocol that allows object to pack and unpack from a
|
|
||||||
/// ``NativeObject`` to a flatbuffers Object and vice versa.
|
|
||||||
public protocol ObjectAPIPacker {
|
|
||||||
/// associatedtype to the object that should be unpacked.
|
|
||||||
associatedtype T
|
|
||||||
|
|
||||||
/// ``pack(_:obj:)-3ptws`` tries to pacs the variables of a native Object into the `ByteBuffer` by using
|
|
||||||
/// a FlatBufferBuilder
|
|
||||||
/// - Parameters:
|
|
||||||
/// - builder: FlatBufferBuilder that will host incoming data
|
|
||||||
/// - obj: Object of associatedtype to the current implementer
|
|
||||||
///
|
|
||||||
/// ``pack(_:obj:)-3ptws`` can be called by passing through an already initialized ``FlatBufferBuilder``
|
|
||||||
/// or it can be called by using the public API that will create a new ``FlatBufferBuilder``
|
|
||||||
static func pack(_ builder: inout FlatBufferBuilder, obj: inout T?) -> Offset
|
|
||||||
|
|
||||||
/// ``pack(_:obj:)-20ipk`` packs the variables of a native Object into the `ByteBuffer` by using
|
|
||||||
/// the FlatBufferBuilder
|
|
||||||
/// - Parameters:
|
|
||||||
/// - builder: FlatBufferBuilder that will host incoming data
|
|
||||||
/// - obj: Object of associatedtype to the current implementer
|
|
||||||
///
|
|
||||||
/// ``pack(_:obj:)-20ipk`` can be called by passing through an already initialized ``FlatBufferBuilder``
|
|
||||||
/// or it can be called by using the public API that will create a new ``FlatBufferBuilder``
|
|
||||||
static func pack(_ builder: inout FlatBufferBuilder, obj: inout T) -> Offset
|
|
||||||
|
|
||||||
/// ``unpack()`` unpacks a ``FlatBuffers`` object into a Native swift object.
|
|
||||||
mutating func unpack() -> T
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// FlatBuffersUtils hosts some utility functions that might be useful
|
|
||||||
public enum FlatBuffersUtils {
|
|
||||||
|
|
||||||
/// Gets the size of the prefix
|
|
||||||
/// - Parameter bb: Flatbuffer object
|
|
||||||
public static func getSizePrefix(bb: ByteBuffer) -> Int32 {
|
|
||||||
bb.read(def: Int32.self, position: bb.reader)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Removes the prefix by duplicating the Flatbuffer this call is expensive since its
|
|
||||||
/// creates a new buffer use `readPrefixedSizeCheckedRoot` instead
|
|
||||||
/// unless a completely new buffer is required
|
|
||||||
/// - Parameter bb: Flatbuffer object
|
|
||||||
///
|
|
||||||
///
|
|
||||||
public static func removeSizePrefix(bb: ByteBuffer) -> ByteBuffer {
|
|
||||||
bb.duplicate(removing: MemoryLayout<Int32>.size)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Collection of thrown from the Flatbuffer verifier
|
|
||||||
public enum FlatbuffersErrors: Error, Equatable {
|
|
||||||
|
|
||||||
/// Thrown when verifying a file id that doesnt match buffer id
|
|
||||||
case bufferIdDidntMatchPassedId
|
|
||||||
/// Prefixed size doesnt match the current (readable) buffer size
|
|
||||||
case prefixedSizeNotEqualToBufferSize
|
|
||||||
/// Thrown when buffer is bigger than the allowed 2GiB
|
|
||||||
case exceedsMaxSizeAllowed
|
|
||||||
/// Thrown when there is an missaligned pointer at position
|
|
||||||
/// of type
|
|
||||||
case missAlignedPointer(position: Int, type: String)
|
|
||||||
/// Thrown when trying to read a value that goes out of the
|
|
||||||
/// current buffer bounds
|
|
||||||
case outOfBounds(position: UInt, end: Int)
|
|
||||||
/// Thrown when the signed offset is out of the bounds of the
|
|
||||||
/// current buffer
|
|
||||||
case signedOffsetOutOfBounds(offset: Int, position: Int)
|
|
||||||
/// Thrown when a required field doesnt exist within the buffer
|
|
||||||
case requiredFieldDoesntExist(position: VOffset, name: String)
|
|
||||||
/// Thrown when a string is missing its NULL Terminator `\0`,
|
|
||||||
/// this can be disabled in the `VerifierOptions`
|
|
||||||
case missingNullTerminator(position: Int, str: String?)
|
|
||||||
/// Thrown when the verifier has reached the maximum tables allowed,
|
|
||||||
/// this can be disabled in the `VerifierOptions`
|
|
||||||
case maximumTables
|
|
||||||
/// Thrown when the verifier has reached the maximum depth allowed,
|
|
||||||
/// this can be disabled in the `VerifierOptions`
|
|
||||||
case maximumDepth
|
|
||||||
/// Thrown when the verifier is presented with an unknown union case
|
|
||||||
case unknownUnionCase
|
|
||||||
/// thrown when a value for a union is not found within the buffer
|
|
||||||
case valueNotFound(key: Int?, keyName: String, field: Int?, fieldName: String)
|
|
||||||
/// thrown when the size of the keys vector doesnt match fields vector
|
|
||||||
case unionVectorSize(
|
|
||||||
keyVectorSize: Int,
|
|
||||||
fieldVectorSize: Int,
|
|
||||||
unionKeyName: String,
|
|
||||||
fieldName: String)
|
|
||||||
case apparentSizeTooLarge
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
|
|
||||||
extension FlatbuffersErrors {
|
|
||||||
public static func == (
|
|
||||||
lhs: FlatbuffersErrors,
|
|
||||||
rhs: FlatbuffersErrors) -> Bool
|
|
||||||
{
|
|
||||||
lhs.localizedDescription == rhs.localizedDescription
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extension Int {
|
|
||||||
|
|
||||||
/// Moves the current int into the nearest power of two
|
|
||||||
///
|
|
||||||
/// This is used since the UnsafeMutableRawPointer will face issues when writing/reading
|
|
||||||
/// if the buffer alignment exceeds that actual size of the buffer
|
|
||||||
var convertToPowerofTwo: Int {
|
|
||||||
guard self > 0 else { return 1 }
|
|
||||||
var n = UOffset(self)
|
|
||||||
|
|
||||||
#if arch(arm) || arch(i386)
|
|
||||||
let max = UInt32(Int.max)
|
|
||||||
#else
|
|
||||||
let max = UInt32.max
|
|
||||||
#endif
|
|
||||||
|
|
||||||
n -= 1
|
|
||||||
n |= n >> 1
|
|
||||||
n |= n >> 2
|
|
||||||
n |= n >> 4
|
|
||||||
n |= n >> 8
|
|
||||||
n |= n >> 16
|
|
||||||
if n != max {
|
|
||||||
n += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return Int(n)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// FlatBufferGRPCMessage protocol that should allow us to invoke
|
|
||||||
/// initializers directly from the GRPC generated code
|
|
||||||
public protocol FlatBufferGRPCMessage {
|
|
||||||
|
|
||||||
/// Raw pointer which would be pointing to the beginning of the readable bytes
|
|
||||||
var rawPointer: UnsafeMutableRawPointer { get }
|
|
||||||
|
|
||||||
/// Size of readable bytes in the buffer
|
|
||||||
var size: Int { get }
|
|
||||||
|
|
||||||
init(byteBuffer: ByteBuffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Message is a wrapper around Buffers to to able to send Flatbuffers `Buffers` through the
|
|
||||||
/// GRPC library
|
|
||||||
public struct Message<T: FlatBufferObject>: FlatBufferGRPCMessage {
|
|
||||||
internal var buffer: ByteBuffer
|
|
||||||
|
|
||||||
/// Returns the an object of type T that would be read from the buffer
|
|
||||||
public var object: T {
|
|
||||||
T.init(
|
|
||||||
buffer,
|
|
||||||
o: Int32(buffer.read(def: UOffset.self, position: buffer.reader)) +
|
|
||||||
Int32(buffer.reader))
|
|
||||||
}
|
|
||||||
|
|
||||||
public var rawPointer: UnsafeMutableRawPointer {
|
|
||||||
buffer.memory.advanced(by: buffer.reader) }
|
|
||||||
|
|
||||||
public var size: Int { Int(buffer.size) }
|
|
||||||
|
|
||||||
/// Initializes the message with the type Flatbuffer.Bytebuffer that is transmitted over
|
|
||||||
/// GRPC
|
|
||||||
/// - Parameter byteBuffer: Flatbuffer ByteBuffer object
|
|
||||||
public init(byteBuffer: ByteBuffer) {
|
|
||||||
buffer = byteBuffer
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initializes the message by copying the buffer to the message to be sent.
|
|
||||||
/// from the builder
|
|
||||||
/// - Parameter builder: FlatbufferBuilder that has the bytes created in
|
|
||||||
/// - Note: Use `builder.finish(offset)` before passing the builder without prefixing anything to it
|
|
||||||
public init(builder: inout FlatBufferBuilder) {
|
|
||||||
buffer = builder.sizedBuffer
|
|
||||||
builder.clear()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Mutable is a protocol that allows us to mutate Scalar values within a ``ByteBuffer``
|
|
||||||
public protocol Mutable {
|
|
||||||
/// makes Flatbuffer accessed within the Protocol
|
|
||||||
var bb: ByteBuffer { get }
|
|
||||||
/// makes position of the ``Table``/``struct`` accessed within the Protocol
|
|
||||||
var postion: Int32 { get }
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Mutable {
|
|
||||||
|
|
||||||
/// Mutates the memory in the buffer, this is only called from the access function of ``Table`` and ``struct``
|
|
||||||
/// - Parameters:
|
|
||||||
/// - value: New value to be inserted to the buffer
|
|
||||||
/// - index: index of the Element
|
|
||||||
func mutate<T: Scalar>(value: T, o: Int32) -> Bool {
|
|
||||||
guard o != 0 else { return false }
|
|
||||||
bb.write(value: value, index: Int(o), direct: true)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Mutable where Self == Table {
|
|
||||||
|
|
||||||
/// Mutates a value by calling mutate with respect to the position in a ``Table``
|
|
||||||
/// - Parameters:
|
|
||||||
/// - value: New value to be inserted to the buffer
|
|
||||||
/// - index: index of the Element
|
|
||||||
public func mutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
|
|
||||||
guard index != 0 else { return false }
|
|
||||||
return mutate(value: value, o: index + postion)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Directly mutates the element by calling mutate
|
|
||||||
///
|
|
||||||
/// Mutates the Element at index ignoring the current position by calling mutate
|
|
||||||
/// - Parameters:
|
|
||||||
/// - value: New value to be inserted to the buffer
|
|
||||||
/// - index: index of the Element
|
|
||||||
public func directMutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
|
|
||||||
mutate(value: value, o: index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Mutable where Self == Struct {
|
|
||||||
|
|
||||||
/// Mutates a value by calling mutate with respect to the position in the struct
|
|
||||||
/// - Parameters:
|
|
||||||
/// - value: New value to be inserted to the buffer
|
|
||||||
/// - index: index of the Element
|
|
||||||
public func mutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
|
|
||||||
mutate(value: value, o: index + postion)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Directly mutates the element by calling mutate
|
|
||||||
///
|
|
||||||
/// Mutates the Element at index ignoring the current position by calling mutate
|
|
||||||
/// - Parameters:
|
|
||||||
/// - value: New value to be inserted to the buffer
|
|
||||||
/// - index: index of the Element
|
|
||||||
public func directMutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
|
|
||||||
mutate(value: value, o: index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Struct: Mutable {}
|
|
||||||
extension Table: Mutable {}
|
|
@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// NativeObject is a protocol that all of the `Object-API` generated code should be
|
|
||||||
/// conforming to since it allows developers the ease of use to pack and unpack their
|
|
||||||
/// Flatbuffers objects
|
|
||||||
public protocol NativeObject {}
|
|
||||||
|
|
||||||
extension NativeObject {
|
|
||||||
|
|
||||||
/// Serialize is a helper function that serailizes the data from the Object API to a bytebuffer directly th
|
|
||||||
/// - Parameter type: Type of the Flatbuffer object
|
|
||||||
/// - Returns: returns the encoded sized ByteBuffer
|
|
||||||
public func serialize<T: ObjectAPIPacker>(type: T.Type) -> ByteBuffer
|
|
||||||
where T.T == Self
|
|
||||||
{
|
|
||||||
var builder = FlatBufferBuilder(initialSize: 1024)
|
|
||||||
return serialize(builder: &builder, type: type.self)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serialize is a helper function that serailizes the data from the Object API to a bytebuffer directly.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - builder: A FlatBufferBuilder
|
|
||||||
/// - type: Type of the Flatbuffer object
|
|
||||||
/// - Returns: returns the encoded sized ByteBuffer
|
|
||||||
/// - Note: The `serialize(builder:type)` can be considered as a function that allows you to create smaller builder instead of the default `1024`.
|
|
||||||
/// It can be considered less expensive in terms of memory allocation
|
|
||||||
public func serialize<T: ObjectAPIPacker>(
|
|
||||||
builder: inout FlatBufferBuilder,
|
|
||||||
type: T.Type) -> ByteBuffer where T.T == Self
|
|
||||||
{
|
|
||||||
var s = self
|
|
||||||
let root = type.pack(&builder, obj: &s)
|
|
||||||
builder.finish(offset: root)
|
|
||||||
return builder.sizedBuffer
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Offset object for all the Objects that are written into the buffer
|
|
||||||
public struct Offset {
|
|
||||||
/// Offset of the object in the buffer
|
|
||||||
public var o: UOffset
|
|
||||||
/// Returns false if the offset is equal to zero
|
|
||||||
public var isEmpty: Bool { o == 0 }
|
|
||||||
|
|
||||||
public init(offset: UOffset) { o = offset }
|
|
||||||
public init() { o = 0 }
|
|
||||||
}
|
|
@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Takes in a prefixed sized buffer, where the prefixed size would be skipped.
|
|
||||||
/// And would verify that the buffer passed is a valid `Flatbuffers` Object.
|
|
||||||
/// - Parameters:
|
|
||||||
/// - byteBuffer: Buffer that needs to be checked and read
|
|
||||||
/// - options: Verifier options
|
|
||||||
/// - Throws: FlatbuffersErrors
|
|
||||||
/// - Returns: Returns a valid, checked Flatbuffers object
|
|
||||||
///
|
|
||||||
/// ``getPrefixedSizeCheckedRoot(byteBuffer:options:)`` would skip the first Bytes in
|
|
||||||
/// the ``ByteBuffer`` and verifies the buffer by calling ``getCheckedRoot(byteBuffer:options:)``
|
|
||||||
public func getPrefixedSizeCheckedRoot<T: FlatBufferObject & Verifiable>(
|
|
||||||
byteBuffer: inout ByteBuffer,
|
|
||||||
fileId: String? = nil,
|
|
||||||
options: VerifierOptions = .init()) throws -> T
|
|
||||||
{
|
|
||||||
byteBuffer.skipPrefix()
|
|
||||||
return try getCheckedRoot(
|
|
||||||
byteBuffer: &byteBuffer,
|
|
||||||
fileId: fileId,
|
|
||||||
options: options)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Takes in a prefixed sized buffer, where we check if the sized buffer is equal to prefix size.
|
|
||||||
/// And would verify that the buffer passed is a valid `Flatbuffers` Object.
|
|
||||||
/// - Parameters:
|
|
||||||
/// - byteBuffer: Buffer that needs to be checked and read
|
|
||||||
/// - options: Verifier options
|
|
||||||
/// - Throws: FlatbuffersErrors
|
|
||||||
/// - Returns: Returns a valid, checked Flatbuffers object
|
|
||||||
///
|
|
||||||
/// ``getPrefixedSizeCheckedRoot(byteBuffer:options:)`` would skip the first Bytes in
|
|
||||||
/// the ``ByteBuffer`` and verifies the buffer by calling ``getCheckedRoot(byteBuffer:options:)``
|
|
||||||
public func getCheckedPrefixedSizeRoot<T: FlatBufferObject & Verifiable>(
|
|
||||||
byteBuffer: inout ByteBuffer,
|
|
||||||
fileId: String? = nil,
|
|
||||||
options: VerifierOptions = .init()) throws -> T
|
|
||||||
{
|
|
||||||
let prefix = byteBuffer.skipPrefix()
|
|
||||||
if prefix != byteBuffer.size {
|
|
||||||
throw FlatbuffersErrors.prefixedSizeNotEqualToBufferSize
|
|
||||||
}
|
|
||||||
return try getCheckedRoot(
|
|
||||||
byteBuffer: &byteBuffer,
|
|
||||||
fileId: fileId,
|
|
||||||
options: options)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Takes in a prefixed sized buffer, where the prefixed size would be skipped.
|
|
||||||
/// Returns a `NON-Checked` flatbuffers object
|
|
||||||
/// - Parameter byteBuffer: Buffer that contains data
|
|
||||||
/// - Returns: Returns a Flatbuffers object
|
|
||||||
///
|
|
||||||
/// ``getPrefixedSizeCheckedRoot(byteBuffer:options:)`` would skip the first Bytes in
|
|
||||||
/// the ``ByteBuffer`` and then calls ``getRoot(byteBuffer:)``
|
|
||||||
public func getPrefixedSizeRoot<T: FlatBufferObject>(byteBuffer: inout ByteBuffer)
|
|
||||||
-> T
|
|
||||||
{
|
|
||||||
byteBuffer.skipPrefix()
|
|
||||||
return getRoot(byteBuffer: &byteBuffer)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Verifies that the buffer passed is a valid `Flatbuffers` Object.
|
|
||||||
/// - Parameters:
|
|
||||||
/// - byteBuffer: Buffer that needs to be checked and read
|
|
||||||
/// - options: Verifier options
|
|
||||||
/// - Throws: FlatbuffersErrors
|
|
||||||
/// - Returns: Returns a valid, checked Flatbuffers object
|
|
||||||
///
|
|
||||||
/// ``getCheckedRoot(byteBuffer:options:)`` Takes in a ``ByteBuffer`` and verifies
|
|
||||||
/// that by creating a ``Verifier`` and checkes if all the `Bytes` and correctly aligned
|
|
||||||
/// and within the ``ByteBuffer`` range.
|
|
||||||
public func getCheckedRoot<T: FlatBufferObject & Verifiable>(
|
|
||||||
byteBuffer: inout ByteBuffer,
|
|
||||||
fileId: String? = nil,
|
|
||||||
options: VerifierOptions = .init()) throws -> T
|
|
||||||
{
|
|
||||||
var verifier = try Verifier(buffer: &byteBuffer, options: options)
|
|
||||||
if let fileId = fileId {
|
|
||||||
try verifier.verify(id: fileId)
|
|
||||||
}
|
|
||||||
try ForwardOffset<T>.verify(&verifier, at: 0, of: T.self)
|
|
||||||
return T.init(
|
|
||||||
byteBuffer,
|
|
||||||
o: Int32(byteBuffer.read(def: UOffset.self, position: byteBuffer.reader)) +
|
|
||||||
Int32(byteBuffer.reader))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a `NON-Checked` flatbuffers object
|
|
||||||
/// - Parameter byteBuffer: Buffer that contains data
|
|
||||||
/// - Returns: Returns a Flatbuffers object
|
|
||||||
public func getRoot<T: FlatBufferObject>(byteBuffer: inout ByteBuffer) -> T {
|
|
||||||
T.init(
|
|
||||||
byteBuffer,
|
|
||||||
o: Int32(byteBuffer.read(def: UOffset.self, position: byteBuffer.reader)) +
|
|
||||||
Int32(byteBuffer.reader))
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extension String: Verifiable {
|
|
||||||
|
|
||||||
/// Verifies that the current value is which the bounds of the buffer, and if
|
|
||||||
/// the current `Value` is aligned properly
|
|
||||||
/// - Parameters:
|
|
||||||
/// - verifier: Verifier that hosts the buffer
|
|
||||||
/// - position: Current position within the buffer
|
|
||||||
/// - type: The type of the object to be verified
|
|
||||||
/// - Throws: Errors coming from `inBuffer`, `missingNullTerminator` and `outOfBounds`
|
|
||||||
public static func verify<T>(
|
|
||||||
_ verifier: inout Verifier,
|
|
||||||
at position: Int,
|
|
||||||
of type: T.Type) throws where T: Verifiable
|
|
||||||
{
|
|
||||||
|
|
||||||
let range = try String.verifyRange(&verifier, at: position, of: UInt8.self)
|
|
||||||
/// Safe &+ since we already check for overflow in verify range
|
|
||||||
let stringLen = range.start &+ range.count
|
|
||||||
|
|
||||||
if stringLen >= verifier.capacity {
|
|
||||||
throw FlatbuffersErrors.outOfBounds(
|
|
||||||
position: UInt(clamping: stringLen.magnitude),
|
|
||||||
end: verifier.capacity)
|
|
||||||
}
|
|
||||||
|
|
||||||
let isNullTerminated = verifier._buffer.read(
|
|
||||||
def: UInt8.self,
|
|
||||||
position: stringLen) == 0
|
|
||||||
|
|
||||||
if !verifier._options._ignoreMissingNullTerminators && !isNullTerminated {
|
|
||||||
let str = verifier._buffer.readString(at: range.start, count: range.count)
|
|
||||||
throw FlatbuffersErrors.missingNullTerminator(
|
|
||||||
position: position,
|
|
||||||
str: str)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension String: FlatbuffersInitializable {
|
|
||||||
|
|
||||||
/// Initailizes a string from a Flatbuffers ByteBuffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - bb: ByteBuffer containing the readable string
|
|
||||||
/// - o: Current position
|
|
||||||
public init(_ bb: ByteBuffer, o: Int32) {
|
|
||||||
let v = Int(o)
|
|
||||||
let count = bb.read(def: Int32.self, position: v)
|
|
||||||
self = bb.readString(
|
|
||||||
at: MemoryLayout<Int32>.size + v,
|
|
||||||
count: Int(count)) ?? ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension String: ObjectAPIPacker {
|
|
||||||
|
|
||||||
public static func pack(
|
|
||||||
_ builder: inout FlatBufferBuilder,
|
|
||||||
obj: inout String?) -> Offset
|
|
||||||
{
|
|
||||||
guard var obj = obj else { return Offset() }
|
|
||||||
return pack(&builder, obj: &obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func pack(
|
|
||||||
_ builder: inout FlatBufferBuilder,
|
|
||||||
obj: inout String) -> Offset
|
|
||||||
{
|
|
||||||
builder.create(string: obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
public mutating func unpack() -> String {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension String: NativeObject {
|
|
||||||
|
|
||||||
public func serialize<T: ObjectAPIPacker>(type: T.Type) -> ByteBuffer
|
|
||||||
where T.T == Self
|
|
||||||
{
|
|
||||||
fatalError("serialize should never be called from string directly")
|
|
||||||
}
|
|
||||||
|
|
||||||
public func serialize<T: ObjectAPIPacker>(
|
|
||||||
builder: inout FlatBufferBuilder,
|
|
||||||
type: T.Type) -> ByteBuffer where T.T == Self
|
|
||||||
{
|
|
||||||
fatalError("serialize should never be called from string directly")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Struct is a representation of a mutable `Flatbuffers` struct
|
|
||||||
/// since native structs are value types and cant be mutated
|
|
||||||
@frozen
|
|
||||||
public struct Struct {
|
|
||||||
|
|
||||||
/// Hosting Bytebuffer
|
|
||||||
public private(set) var bb: ByteBuffer
|
|
||||||
/// Current position of the struct
|
|
||||||
public private(set) var postion: Int32
|
|
||||||
|
|
||||||
/// Initializer for a mutable flatbuffers struct
|
|
||||||
/// - Parameters:
|
|
||||||
/// - bb: Current hosting Bytebuffer
|
|
||||||
/// - position: Current position for the struct in the ByteBuffer
|
|
||||||
public init(bb: ByteBuffer, position: Int32 = 0) {
|
|
||||||
self.bb = bb
|
|
||||||
postion = position
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads data from the buffer directly at offset O
|
|
||||||
/// - Parameters:
|
|
||||||
/// - type: Type of data to be read
|
|
||||||
/// - o: Current offset of the data
|
|
||||||
/// - Returns: Data of Type T that conforms to type Scalar
|
|
||||||
public func readBuffer<T: Scalar>(of type: T.Type, at o: Int32) -> T {
|
|
||||||
let r = bb.read(def: T.self, position: Int(o + postion))
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,240 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// `Table` is a Flatbuffers object that can read,
|
|
||||||
/// mutate scalar fields within a valid flatbuffers buffer
|
|
||||||
@frozen
|
|
||||||
public struct Table {
|
|
||||||
|
|
||||||
/// Hosting Bytebuffer
|
|
||||||
public private(set) var bb: ByteBuffer
|
|
||||||
/// Current position of the table within the buffer
|
|
||||||
public private(set) var postion: Int32
|
|
||||||
|
|
||||||
/// Initializer for the table interface to allow generated code to read
|
|
||||||
/// data from memory
|
|
||||||
/// - Parameters:
|
|
||||||
/// - bb: ByteBuffer that stores data
|
|
||||||
/// - position: Current table position
|
|
||||||
/// - Note: This will `CRASH` if read on a big endian machine
|
|
||||||
public init(bb: ByteBuffer, position: Int32 = 0) {
|
|
||||||
guard isLitteEndian else {
|
|
||||||
fatalError(
|
|
||||||
"Reading/Writing a buffer in big endian machine is not supported on swift")
|
|
||||||
}
|
|
||||||
self.bb = bb
|
|
||||||
postion = position
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the offset of the current field within the buffer by reading
|
|
||||||
/// the vtable
|
|
||||||
/// - Parameter o: current offset
|
|
||||||
/// - Returns: offset of field within buffer
|
|
||||||
public func offset(_ o: Int32) -> Int32 {
|
|
||||||
let vtable = postion - bb.read(def: Int32.self, position: Int(postion))
|
|
||||||
return o < bb
|
|
||||||
.read(def: VOffset.self, position: Int(vtable)) ? Int32(bb.read(
|
|
||||||
def: Int16.self,
|
|
||||||
position: Int(vtable + o))) : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the indirect offset of the current stored object
|
|
||||||
/// (applicable only for object arrays)
|
|
||||||
/// - Parameter o: current offset
|
|
||||||
/// - Returns: offset of field within buffer
|
|
||||||
public func indirect(_ o: Int32) -> Int32 {
|
|
||||||
o + bb.read(def: Int32.self, position: Int(o))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// String reads from the buffer with respect to position of the current table.
|
|
||||||
/// - Parameter offset: Offset of the string
|
|
||||||
public func string(at offset: Int32) -> String? {
|
|
||||||
directString(at: offset + postion)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Direct string reads from the buffer disregarding the position of the table.
|
|
||||||
/// It would be preferable to use string unless the current position of the table
|
|
||||||
/// is not needed
|
|
||||||
/// - Parameter offset: Offset of the string
|
|
||||||
public func directString(at offset: Int32) -> String? {
|
|
||||||
var offset = offset
|
|
||||||
offset += bb.read(def: Int32.self, position: Int(offset))
|
|
||||||
let count = bb.read(def: Int32.self, position: Int(offset))
|
|
||||||
let position = Int(offset) + MemoryLayout<Int32>.size
|
|
||||||
return bb.readString(at: position, count: Int(count))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads from the buffer with respect to the position in the table.
|
|
||||||
/// - Parameters:
|
|
||||||
/// - type: Type of Element that needs to be read from the buffer
|
|
||||||
/// - o: Offset of the Element
|
|
||||||
public func readBuffer<T>(of type: T.Type, at o: Int32) -> T {
|
|
||||||
directRead(of: T.self, offset: o + postion)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads from the buffer disregarding the position of the table.
|
|
||||||
/// It would be used when reading from an
|
|
||||||
/// ```
|
|
||||||
/// let offset = __t.offset(10)
|
|
||||||
/// //Only used when the we already know what is the
|
|
||||||
/// // position in the table since __t.vector(at:)
|
|
||||||
/// // returns the index with respect to the position
|
|
||||||
/// __t.directRead(of: Byte.self,
|
|
||||||
/// offset: __t.vector(at: offset) + index * 1)
|
|
||||||
/// ```
|
|
||||||
/// - Parameters:
|
|
||||||
/// - type: Type of Element that needs to be read from the buffer
|
|
||||||
/// - o: Offset of the Element
|
|
||||||
public func directRead<T>(of type: T.Type, offset o: Int32) -> T {
|
|
||||||
let r = bb.read(def: T.self, position: Int(o))
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns that current `Union` object at a specific offset
|
|
||||||
/// by adding offset to the current position of table
|
|
||||||
/// - Parameter o: offset
|
|
||||||
/// - Returns: A flatbuffers object
|
|
||||||
public func union<T: FlatbuffersInitializable>(_ o: Int32) -> T {
|
|
||||||
let o = o + postion
|
|
||||||
return directUnion(o)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a direct `Union` object at a specific offset
|
|
||||||
/// - Parameter o: offset
|
|
||||||
/// - Returns: A flatbuffers object
|
|
||||||
public func directUnion<T: FlatbuffersInitializable>(_ o: Int32) -> T {
|
|
||||||
T.init(bb, o: o + bb.read(def: Int32.self, position: Int(o)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a vector of type T at a specific offset
|
|
||||||
/// This should only be used by `Scalars`
|
|
||||||
/// - Parameter off: Readable offset
|
|
||||||
/// - Returns: Returns a vector of type [T]
|
|
||||||
public func getVector<T>(at off: Int32) -> [T]? {
|
|
||||||
let o = offset(off)
|
|
||||||
guard o != 0 else { return nil }
|
|
||||||
return bb.readSlice(index: Int(vector(at: o)), count: Int(vector(count: o)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Vector count gets the count of Elements within the array
|
|
||||||
/// - Parameter o: start offset of the vector
|
|
||||||
/// - returns: Count of elements
|
|
||||||
public func vector(count o: Int32) -> Int32 {
|
|
||||||
var o = o
|
|
||||||
o += postion
|
|
||||||
o += bb.read(def: Int32.self, position: Int(o))
|
|
||||||
return bb.read(def: Int32.self, position: Int(o))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Vector start index in the buffer
|
|
||||||
/// - Parameter o:start offset of the vector
|
|
||||||
/// - returns: the start index of the vector
|
|
||||||
public func vector(at o: Int32) -> Int32 {
|
|
||||||
var o = o
|
|
||||||
o += postion
|
|
||||||
return o + bb.read(def: Int32.self, position: Int(o)) + 4
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reading an indirect offset of a table.
|
|
||||||
/// - Parameters:
|
|
||||||
/// - o: position within the buffer
|
|
||||||
/// - fbb: ByteBuffer
|
|
||||||
/// - Returns: table offset
|
|
||||||
static public func indirect(_ o: Int32, _ fbb: ByteBuffer) -> Int32 {
|
|
||||||
o + fbb.read(def: Int32.self, position: Int(o))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a vtable value according to an table Offset and a field offset
|
|
||||||
/// - Parameters:
|
|
||||||
/// - o: offset relative to entire buffer
|
|
||||||
/// - vOffset: Field offset within a vtable
|
|
||||||
/// - fbb: ByteBuffer
|
|
||||||
/// - Returns: an position of a field
|
|
||||||
static public func offset(
|
|
||||||
_ o: Int32,
|
|
||||||
vOffset: Int32,
|
|
||||||
fbb: ByteBuffer) -> Int32
|
|
||||||
{
|
|
||||||
let vTable = Int32(fbb.capacity) - o
|
|
||||||
return vTable + Int32(fbb.read(
|
|
||||||
def: Int16.self,
|
|
||||||
position: Int(vTable + vOffset - fbb.read(
|
|
||||||
def: Int32.self,
|
|
||||||
position: Int(vTable)))))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compares two objects at offset A and offset B within a ByteBuffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - off1: first offset to compare
|
|
||||||
/// - off2: second offset to compare
|
|
||||||
/// - fbb: Bytebuffer
|
|
||||||
/// - Returns: returns the difference between
|
|
||||||
static public func compare(
|
|
||||||
_ off1: Int32,
|
|
||||||
_ off2: Int32,
|
|
||||||
fbb: ByteBuffer) -> Int32
|
|
||||||
{
|
|
||||||
let memorySize = Int32(MemoryLayout<Int32>.size)
|
|
||||||
let _off1 = off1 + fbb.read(def: Int32.self, position: Int(off1))
|
|
||||||
let _off2 = off2 + fbb.read(def: Int32.self, position: Int(off2))
|
|
||||||
let len1 = fbb.read(def: Int32.self, position: Int(_off1))
|
|
||||||
let len2 = fbb.read(def: Int32.self, position: Int(_off2))
|
|
||||||
let startPos1 = _off1 + memorySize
|
|
||||||
let startPos2 = _off2 + memorySize
|
|
||||||
let minValue = min(len1, len2)
|
|
||||||
for i in 0...minValue {
|
|
||||||
let b1 = fbb.read(def: Int8.self, position: Int(i + startPos1))
|
|
||||||
let b2 = fbb.read(def: Int8.self, position: Int(i + startPos2))
|
|
||||||
if b1 != b2 {
|
|
||||||
return Int32(b2 - b1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return len1 - len2
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compares two objects at offset A and array of `Bytes` within a ByteBuffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - off1: Offset to compare to
|
|
||||||
/// - key: bytes array to compare to
|
|
||||||
/// - fbb: Bytebuffer
|
|
||||||
/// - Returns: returns the difference between
|
|
||||||
static public func compare(
|
|
||||||
_ off1: Int32,
|
|
||||||
_ key: [Byte],
|
|
||||||
fbb: ByteBuffer) -> Int32
|
|
||||||
{
|
|
||||||
let memorySize = Int32(MemoryLayout<Int32>.size)
|
|
||||||
let _off1 = off1 + fbb.read(def: Int32.self, position: Int(off1))
|
|
||||||
let len1 = fbb.read(def: Int32.self, position: Int(_off1))
|
|
||||||
let len2 = Int32(key.count)
|
|
||||||
let startPos1 = _off1 + memorySize
|
|
||||||
let minValue = min(len1, len2)
|
|
||||||
for i in 0..<minValue {
|
|
||||||
let b = fbb.read(def: Int8.self, position: Int(i + startPos1))
|
|
||||||
let byte = key[Int(i)]
|
|
||||||
if b != byte {
|
|
||||||
return Int32(b - Int8(byte))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return len1 - len2
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,207 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// `TableVerifier` verifies a table object is within a provided memory.
|
|
||||||
/// It checks if all the objects for a specific generated table, are within
|
|
||||||
/// the bounds of the buffer, aligned.
|
|
||||||
public struct TableVerifier {
|
|
||||||
|
|
||||||
/// position of current table in `ByteBuffer`
|
|
||||||
fileprivate var _position: Int
|
|
||||||
|
|
||||||
/// Current VTable position
|
|
||||||
fileprivate var _vtable: Int
|
|
||||||
|
|
||||||
/// Length of current VTable
|
|
||||||
fileprivate var _vtableLength: Int
|
|
||||||
|
|
||||||
/// `Verifier` object created in the base verifable call.
|
|
||||||
fileprivate var _verifier: Verifier
|
|
||||||
|
|
||||||
/// Creates a `TableVerifier` verifier that allows the Flatbuffer object
|
|
||||||
/// to verify the buffer before accessing any of the data.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - position: Current table Position
|
|
||||||
/// - vtable: Current `VTable` position
|
|
||||||
/// - vtableLength: Current `VTable` length
|
|
||||||
/// - verifier: `Verifier` Object that caches the data of the verifiable object
|
|
||||||
internal init(
|
|
||||||
position: Int,
|
|
||||||
vtable: Int,
|
|
||||||
vtableLength: Int,
|
|
||||||
verifier: inout Verifier)
|
|
||||||
{
|
|
||||||
_position = position
|
|
||||||
_vtable = vtable
|
|
||||||
_vtableLength = vtableLength
|
|
||||||
_verifier = verifier
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Dereference the current object position from the `VTable`
|
|
||||||
/// - Parameter field: Current VTable refrence to position.
|
|
||||||
/// - Throws: A `FlatbuffersErrors` incase the voffset is not aligned/outOfBounds/apparentSizeTooLarge
|
|
||||||
/// - Returns: An optional position for current field
|
|
||||||
internal mutating func dereference(_ field: VOffset) throws -> Int? {
|
|
||||||
if field >= _vtableLength {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reading the offset for the field needs to be read.
|
|
||||||
let offset: VOffset = try _verifier.getValue(
|
|
||||||
at: Int(clamping: _vtable &+ Int(field)))
|
|
||||||
|
|
||||||
if offset > 0 {
|
|
||||||
return Int(clamping: _position &+ Int(offset))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Visits all the fields within the table to validate the integrity
|
|
||||||
/// of the data
|
|
||||||
/// - Parameters:
|
|
||||||
/// - field: voffset of the current field to be read
|
|
||||||
/// - fieldName: fieldname to report data Errors.
|
|
||||||
/// - required: If the field has to be available in the buffer
|
|
||||||
/// - type: Type of field to be read
|
|
||||||
/// - Throws: A `FlatbuffersErrors` where the field is corrupt
|
|
||||||
public mutating func visit<T>(
|
|
||||||
field: VOffset,
|
|
||||||
fieldName: String,
|
|
||||||
required: Bool,
|
|
||||||
type: T.Type) throws where T: Verifiable
|
|
||||||
{
|
|
||||||
let derefValue = try dereference(field)
|
|
||||||
|
|
||||||
if let value = derefValue {
|
|
||||||
try T.verify(&_verifier, at: value, of: T.self)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if required {
|
|
||||||
throw FlatbuffersErrors.requiredFieldDoesntExist(
|
|
||||||
position: field,
|
|
||||||
name: fieldName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Visits all the fields for a union object within the table to
|
|
||||||
/// validate the integrity of the data
|
|
||||||
/// - Parameters:
|
|
||||||
/// - key: Current Key Voffset
|
|
||||||
/// - field: Current field Voffset
|
|
||||||
/// - unionKeyName: Union key name
|
|
||||||
/// - fieldName: Field key name
|
|
||||||
/// - required: indicates if an object is required to be present
|
|
||||||
/// - completion: Completion is a handler that WILL be called in the generated
|
|
||||||
/// - Throws: A `FlatbuffersErrors` where the field is corrupt
|
|
||||||
public mutating func visit<T>(
|
|
||||||
unionKey key: VOffset,
|
|
||||||
unionField field: VOffset,
|
|
||||||
unionKeyName: String,
|
|
||||||
fieldName: String,
|
|
||||||
required: Bool,
|
|
||||||
completion: @escaping (inout Verifier, T, Int) throws -> Void) throws
|
|
||||||
where T: UnionEnum
|
|
||||||
{
|
|
||||||
let keyPos = try dereference(key)
|
|
||||||
let valPos = try dereference(field)
|
|
||||||
|
|
||||||
if keyPos == nil && valPos == nil {
|
|
||||||
if required {
|
|
||||||
throw FlatbuffersErrors.requiredFieldDoesntExist(
|
|
||||||
position: key,
|
|
||||||
name: unionKeyName)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if let _key = keyPos,
|
|
||||||
let _val = valPos
|
|
||||||
{
|
|
||||||
/// verifiying that the key is within the buffer
|
|
||||||
try T.T.verify(&_verifier, at: _key, of: T.T.self)
|
|
||||||
guard let _enum = try T.init(value: _verifier._buffer.read(
|
|
||||||
def: T.T.self,
|
|
||||||
position: _key)) else
|
|
||||||
{
|
|
||||||
throw FlatbuffersErrors.unknownUnionCase
|
|
||||||
}
|
|
||||||
/// we are assuming that Unions will always be of type Uint8
|
|
||||||
try completion(
|
|
||||||
&_verifier,
|
|
||||||
_enum,
|
|
||||||
_val)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
throw FlatbuffersErrors.valueNotFound(
|
|
||||||
key: keyPos,
|
|
||||||
keyName: unionKeyName,
|
|
||||||
field: valPos,
|
|
||||||
fieldName: fieldName)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Visits and validates all the objects within a union vector
|
|
||||||
/// - Parameters:
|
|
||||||
/// - key: Current Key Voffset
|
|
||||||
/// - field: Current field Voffset
|
|
||||||
/// - unionKeyName: Union key name
|
|
||||||
/// - fieldName: Field key name
|
|
||||||
/// - required: indicates if an object is required to be present
|
|
||||||
/// - completion: Completion is a handler that WILL be called in the generated
|
|
||||||
/// - Throws: A `FlatbuffersErrors` where the field is corrupt
|
|
||||||
public mutating func visitUnionVector<T>(
|
|
||||||
unionKey key: VOffset,
|
|
||||||
unionField field: VOffset,
|
|
||||||
unionKeyName: String,
|
|
||||||
fieldName: String,
|
|
||||||
required: Bool,
|
|
||||||
completion: @escaping (inout Verifier, T, Int) throws -> Void) throws
|
|
||||||
where T: UnionEnum
|
|
||||||
{
|
|
||||||
let keyVectorPosition = try dereference(key)
|
|
||||||
let offsetVectorPosition = try dereference(field)
|
|
||||||
|
|
||||||
if let keyPos = keyVectorPosition,
|
|
||||||
let valPos = offsetVectorPosition
|
|
||||||
{
|
|
||||||
try UnionVector<T>.verify(
|
|
||||||
&_verifier,
|
|
||||||
keyPosition: keyPos,
|
|
||||||
fieldPosition: valPos,
|
|
||||||
unionKeyName: unionKeyName,
|
|
||||||
fieldName: fieldName,
|
|
||||||
completion: completion)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if required {
|
|
||||||
throw FlatbuffersErrors.requiredFieldDoesntExist(
|
|
||||||
position: field,
|
|
||||||
name: fieldName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finishs the current Table verifier, and subtracts the current
|
|
||||||
/// table from the incremented depth.
|
|
||||||
public mutating func finish() {
|
|
||||||
_verifier.finish()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// `VerifierOptions` is a set of options to verify a flatbuffer
|
|
||||||
public struct VerifierOptions {
|
|
||||||
|
|
||||||
/// Maximum `Apparent` size if the buffer can be expanded into a DAG tree
|
|
||||||
internal var _maxApparentSize: UOffset
|
|
||||||
|
|
||||||
/// Maximum table count allowed in a buffer
|
|
||||||
internal var _maxTableCount: UOffset
|
|
||||||
|
|
||||||
/// Maximum depth allowed in a buffer
|
|
||||||
internal var _maxDepth: UOffset
|
|
||||||
|
|
||||||
/// Ignoring missing null terminals in strings
|
|
||||||
internal var _ignoreMissingNullTerminators: Bool
|
|
||||||
|
|
||||||
/// initializes the set of options for the verifier
|
|
||||||
/// - Parameters:
|
|
||||||
/// - maxDepth: Maximum depth allowed in a buffer
|
|
||||||
/// - maxTableCount: Maximum table count allowed in a buffer
|
|
||||||
/// - maxApparentSize: Maximum `Apparent` size if the buffer can be expanded into a DAG tree
|
|
||||||
/// - ignoreMissingNullTerminators: Ignoring missing null terminals in strings *Currently not supported in swift*
|
|
||||||
public init(
|
|
||||||
maxDepth: UOffset = 64,
|
|
||||||
maxTableCount: UOffset = 1000000,
|
|
||||||
maxApparentSize: UOffset = 1 << 31,
|
|
||||||
ignoreMissingNullTerminators: Bool = false)
|
|
||||||
{
|
|
||||||
_maxDepth = maxDepth
|
|
||||||
_maxTableCount = maxTableCount
|
|
||||||
_maxApparentSize = maxApparentSize
|
|
||||||
_ignoreMissingNullTerminators = ignoreMissingNullTerminators
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,217 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Verifiable is a protocol all swift flatbuffers object should conform to,
|
|
||||||
/// since swift is similar to `cpp` and `rust` where the data is read directly
|
|
||||||
/// from `unsafeMemory` thus the need to verify if the buffer received is a valid one
|
|
||||||
public protocol Verifiable {
|
|
||||||
|
|
||||||
/// Verifies that the current value is which the bounds of the buffer, and if
|
|
||||||
/// the current `Value` is aligned properly
|
|
||||||
/// - Parameters:
|
|
||||||
/// - verifier: Verifier that hosts the buffer
|
|
||||||
/// - position: Current position within the buffer
|
|
||||||
/// - type: The type of the object to be verified
|
|
||||||
/// - Throws: Errors coming from `inBuffer` function
|
|
||||||
static func verify<T>(
|
|
||||||
_ verifier: inout Verifier,
|
|
||||||
at position: Int,
|
|
||||||
of type: T.Type) throws where T: Verifiable
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Verifiable {
|
|
||||||
|
|
||||||
/// Verifies if the current range to be read is within the bounds of the buffer,
|
|
||||||
/// and if the range is properly aligned
|
|
||||||
/// - Parameters:
|
|
||||||
/// - verifier: Verifier that hosts the buffer
|
|
||||||
/// - position: Current position within the buffer
|
|
||||||
/// - type: The type of the object to be verified
|
|
||||||
/// - Throws: Erros thrown from `isAligned` & `rangeInBuffer`
|
|
||||||
/// - Returns: a tuple of the start position and the count of objects within the range
|
|
||||||
@discardableResult
|
|
||||||
public static func verifyRange<T>(
|
|
||||||
_ verifier: inout Verifier,
|
|
||||||
at position: Int, of type: T.Type) throws -> (start: Int, count: Int)
|
|
||||||
{
|
|
||||||
let len: UOffset = try verifier.getValue(at: position)
|
|
||||||
let intLen = Int(len)
|
|
||||||
let start = Int(clamping: (position &+ MemoryLayout<Int32>.size).magnitude)
|
|
||||||
try verifier.isAligned(position: start, type: type.self)
|
|
||||||
try verifier.rangeInBuffer(position: start, size: intLen)
|
|
||||||
return (start, intLen)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Verifiable where Self: Scalar {
|
|
||||||
|
|
||||||
/// Verifies that the current value is which the bounds of the buffer, and if
|
|
||||||
/// the current `Value` is aligned properly
|
|
||||||
/// - Parameters:
|
|
||||||
/// - verifier: Verifier that hosts the buffer
|
|
||||||
/// - position: Current position within the buffer
|
|
||||||
/// - type: The type of the object to be verified
|
|
||||||
/// - Throws: Errors coming from `inBuffer` function
|
|
||||||
public static func verify<T>(
|
|
||||||
_ verifier: inout Verifier,
|
|
||||||
at position: Int,
|
|
||||||
of type: T.Type) throws where T: Verifiable
|
|
||||||
{
|
|
||||||
try verifier.inBuffer(position: position, of: type.self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - ForwardOffset
|
|
||||||
|
|
||||||
/// ForwardOffset is a container to wrap around the Generic type to be verified
|
|
||||||
/// from the flatbuffers object.
|
|
||||||
public enum ForwardOffset<U>: Verifiable where U: Verifiable {
|
|
||||||
|
|
||||||
/// Verifies that the current value is which the bounds of the buffer, and if
|
|
||||||
/// the current `Value` is aligned properly
|
|
||||||
/// - Parameters:
|
|
||||||
/// - verifier: Verifier that hosts the buffer
|
|
||||||
/// - position: Current position within the buffer
|
|
||||||
/// - type: The type of the object to be verified
|
|
||||||
/// - Throws: Errors coming from `inBuffer` function
|
|
||||||
public static func verify<T>(
|
|
||||||
_ verifier: inout Verifier,
|
|
||||||
at position: Int,
|
|
||||||
of type: T.Type) throws where T: Verifiable
|
|
||||||
{
|
|
||||||
let offset: UOffset = try verifier.getValue(at: position)
|
|
||||||
let nextOffset = Int(clamping: (Int(offset) &+ position).magnitude)
|
|
||||||
try U.verify(&verifier, at: nextOffset, of: U.self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Vector
|
|
||||||
|
|
||||||
/// Vector is a container to wrap around the Generic type to be verified
|
|
||||||
/// from the flatbuffers object.
|
|
||||||
public enum Vector<U, S>: Verifiable where U: Verifiable, S: Verifiable {
|
|
||||||
|
|
||||||
/// Verifies that the current value is which the bounds of the buffer, and if
|
|
||||||
/// the current `Value` is aligned properly
|
|
||||||
/// - Parameters:
|
|
||||||
/// - verifier: Verifier that hosts the buffer
|
|
||||||
/// - position: Current position within the buffer
|
|
||||||
/// - type: The type of the object to be verified
|
|
||||||
/// - Throws: Errors coming from `inBuffer` function
|
|
||||||
public static func verify<T>(
|
|
||||||
_ verifier: inout Verifier,
|
|
||||||
at position: Int,
|
|
||||||
of type: T.Type) throws where T: Verifiable
|
|
||||||
{
|
|
||||||
/// checks if the next verification type S is equal to U of type forwardOffset
|
|
||||||
/// This had to be done since I couldnt find a solution for duplicate call functions
|
|
||||||
/// A fix will be appreciated
|
|
||||||
if U.self is ForwardOffset<S>.Type {
|
|
||||||
let range = try verifyRange(&verifier, at: position, of: UOffset.self)
|
|
||||||
for index in stride(
|
|
||||||
from: range.start,
|
|
||||||
to: Int(
|
|
||||||
clamping: range
|
|
||||||
.start &+ (range.count &* MemoryLayout<Int32>.size)),
|
|
||||||
by: MemoryLayout<UOffset>.size)
|
|
||||||
{
|
|
||||||
try U.verify(&verifier, at: index, of: U.self)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try S.verifyRange(&verifier, at: position, of: S.self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - UnionVector
|
|
||||||
|
|
||||||
/// UnionVector is a container to wrap around the Generic type to be verified
|
|
||||||
/// from the flatbuffers object.
|
|
||||||
public enum UnionVector<S> where S: UnionEnum {
|
|
||||||
|
|
||||||
/// Completion handler for the function Verify, that passes the verifier
|
|
||||||
/// enum type and position of union field
|
|
||||||
public typealias Completion = (inout Verifier, S, Int) throws -> Void
|
|
||||||
|
|
||||||
/// Verifies if the current range to be read is within the bounds of the buffer,
|
|
||||||
/// and if the range is properly aligned. It also verifies if the union type is a
|
|
||||||
/// *valid/supported* union type.
|
|
||||||
/// - Parameters:
|
|
||||||
/// - verifier: Verifier that hosts the buffer
|
|
||||||
/// - keyPosition: Current union key position within the buffer
|
|
||||||
/// - fieldPosition: Current union field position within the buffer
|
|
||||||
/// - unionKeyName: Name of key to written if error is presented
|
|
||||||
/// - fieldName: Name of field to written if error is presented
|
|
||||||
/// - completion: Completion is a handler that WILL be called in the generated
|
|
||||||
/// code to verify the actual objects
|
|
||||||
/// - Throws: FlatbuffersErrors
|
|
||||||
public static func verify(
|
|
||||||
_ verifier: inout Verifier,
|
|
||||||
keyPosition: Int,
|
|
||||||
fieldPosition: Int,
|
|
||||||
unionKeyName: String,
|
|
||||||
fieldName: String,
|
|
||||||
completion: @escaping Completion) throws
|
|
||||||
{
|
|
||||||
/// Get offset for union key vectors and offset vectors
|
|
||||||
let keyOffset: UOffset = try verifier.getValue(at: keyPosition)
|
|
||||||
let fieldOffset: UOffset = try verifier.getValue(at: fieldPosition)
|
|
||||||
|
|
||||||
/// Check if values are within the buffer, returns the start position of vectors, and vector counts
|
|
||||||
/// Using &+ is safe since we already verified that the value is within the buffer, where the max is
|
|
||||||
/// going to be 2Gib and swift supports Int64 by default
|
|
||||||
let keysRange = try S.T.verifyRange(
|
|
||||||
&verifier,
|
|
||||||
at: Int(keyOffset) &+ keyPosition,
|
|
||||||
of: S.T.self)
|
|
||||||
let offsetsRange = try UOffset.verifyRange(
|
|
||||||
&verifier,
|
|
||||||
at: Int(fieldOffset) &+ fieldPosition,
|
|
||||||
of: UOffset.self)
|
|
||||||
|
|
||||||
guard keysRange.count == offsetsRange.count else {
|
|
||||||
throw FlatbuffersErrors.unionVectorSize(
|
|
||||||
keyVectorSize: keysRange.count,
|
|
||||||
fieldVectorSize: offsetsRange.count,
|
|
||||||
unionKeyName: unionKeyName,
|
|
||||||
fieldName: fieldName)
|
|
||||||
}
|
|
||||||
|
|
||||||
var count = 0
|
|
||||||
/// Iterate over the vector of keys and offsets.
|
|
||||||
while count < keysRange.count {
|
|
||||||
|
|
||||||
/// index of readable enum value in array
|
|
||||||
let keysIndex = MemoryLayout<S.T>.size * count
|
|
||||||
guard let _enum = try S.init(value: verifier._buffer.read(
|
|
||||||
def: S.T.self,
|
|
||||||
position: keysRange.start + keysIndex)) else
|
|
||||||
{
|
|
||||||
throw FlatbuffersErrors.unknownUnionCase
|
|
||||||
}
|
|
||||||
/// index of readable offset value in array
|
|
||||||
let fieldIndex = MemoryLayout<UOffset>.size * count
|
|
||||||
try completion(&verifier, _enum, offsetsRange.start + fieldIndex)
|
|
||||||
count += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,217 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !os(WASI)
|
|
||||||
import Foundation
|
|
||||||
#else
|
|
||||||
import SwiftOverlayShims
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Verifier that check if the buffer passed into it is a valid,
|
|
||||||
/// safe, aligned Flatbuffers object since swift read from `unsafeMemory`
|
|
||||||
public struct Verifier {
|
|
||||||
|
|
||||||
/// Flag to check for alignment if true
|
|
||||||
fileprivate let _checkAlignment: Bool
|
|
||||||
/// Capacity of the current buffer
|
|
||||||
fileprivate var _capacity: Int
|
|
||||||
/// Current ApparentSize
|
|
||||||
fileprivate var _apparentSize: UOffset = 0
|
|
||||||
/// Amount of tables present within a buffer
|
|
||||||
fileprivate var _tableCount = 0
|
|
||||||
|
|
||||||
/// Capacity of the buffer
|
|
||||||
internal var capacity: Int { _capacity }
|
|
||||||
/// Current reached depth within the buffer
|
|
||||||
internal var _depth = 0
|
|
||||||
/// Current verifiable ByteBuffer
|
|
||||||
internal var _buffer: ByteBuffer
|
|
||||||
/// Options for verification
|
|
||||||
internal let _options: VerifierOptions
|
|
||||||
|
|
||||||
/// Initializer for the verifier
|
|
||||||
/// - Parameters:
|
|
||||||
/// - buffer: Bytebuffer that is required to be verified
|
|
||||||
/// - options: `VerifierOptions` that set the rule for some of the verification done
|
|
||||||
/// - checkAlignment: If alignment check is required to be preformed
|
|
||||||
/// - Throws: `exceedsMaxSizeAllowed` if capacity of the buffer is more than 2GiB
|
|
||||||
public init(
|
|
||||||
buffer: inout ByteBuffer,
|
|
||||||
options: VerifierOptions = .init(),
|
|
||||||
checkAlignment: Bool = true) throws
|
|
||||||
{
|
|
||||||
guard buffer.capacity < FlatBufferMaxSize else {
|
|
||||||
throw FlatbuffersErrors.exceedsMaxSizeAllowed
|
|
||||||
}
|
|
||||||
|
|
||||||
_buffer = buffer
|
|
||||||
_capacity = buffer.capacity
|
|
||||||
_checkAlignment = checkAlignment
|
|
||||||
_options = options
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resets the verifier to initial state
|
|
||||||
public mutating func reset() {
|
|
||||||
_depth = 0
|
|
||||||
_tableCount = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks if the value of type `T` is aligned properly in the buffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - position: Current position
|
|
||||||
/// - type: Type of value to check
|
|
||||||
/// - Throws: `missAlignedPointer` if the pointer is not aligned properly
|
|
||||||
public mutating func isAligned<T>(position: Int, type: T.Type) throws {
|
|
||||||
|
|
||||||
/// If check alignment is false this mutating function doesnt continue
|
|
||||||
if !_checkAlignment { return }
|
|
||||||
|
|
||||||
/// advance pointer to position X
|
|
||||||
let ptr = _buffer._storage.memory.advanced(by: position)
|
|
||||||
/// Check if the pointer is aligned
|
|
||||||
if Int(bitPattern: ptr) & (MemoryLayout<T>.alignment &- 1) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
throw FlatbuffersErrors.missAlignedPointer(
|
|
||||||
position: position,
|
|
||||||
type: String(describing: T.self))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks if the value of Size "X" is within the range of the buffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - position: Current postion to be read
|
|
||||||
/// - size: `Byte` Size of readable object within the buffer
|
|
||||||
/// - Throws: `outOfBounds` if the value is out of the bounds of the buffer
|
|
||||||
/// and `apparentSizeTooLarge` if the apparent size is bigger than the one specified
|
|
||||||
/// in `VerifierOptions`
|
|
||||||
public mutating func rangeInBuffer(position: Int, size: Int) throws {
|
|
||||||
let end = UInt(clamping: (position &+ size).magnitude)
|
|
||||||
if end > _buffer.capacity {
|
|
||||||
throw FlatbuffersErrors.outOfBounds(position: end, end: capacity)
|
|
||||||
}
|
|
||||||
_apparentSize = _apparentSize &+ UInt32(size)
|
|
||||||
if _apparentSize > _options._maxApparentSize {
|
|
||||||
throw FlatbuffersErrors.apparentSizeTooLarge
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Validates if a value of type `T` is aligned and within the bounds of
|
|
||||||
/// the buffer
|
|
||||||
/// - Parameters:
|
|
||||||
/// - position: Current readable position
|
|
||||||
/// - type: Type of value to check
|
|
||||||
/// - Throws: FlatbuffersErrors
|
|
||||||
public mutating func inBuffer<T>(position: Int, of type: T.Type) throws {
|
|
||||||
try isAligned(position: position, type: type)
|
|
||||||
try rangeInBuffer(position: position, size: MemoryLayout<T>.size)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Visits a table at the current position and validates if the table meets
|
|
||||||
/// the rules specified in the `VerifierOptions`
|
|
||||||
/// - Parameter position: Current position to be read
|
|
||||||
/// - Throws: FlatbuffersErrors
|
|
||||||
/// - Returns: A `TableVerifier` at the current readable table
|
|
||||||
public mutating func visitTable(at position: Int) throws -> TableVerifier {
|
|
||||||
let vtablePosition = try derefOffset(position: position)
|
|
||||||
let vtableLength: VOffset = try getValue(at: vtablePosition)
|
|
||||||
|
|
||||||
let length = Int(vtableLength)
|
|
||||||
try isAligned(
|
|
||||||
position: Int(clamping: (vtablePosition + length).magnitude),
|
|
||||||
type: VOffset.self)
|
|
||||||
try rangeInBuffer(position: vtablePosition, size: length)
|
|
||||||
|
|
||||||
_tableCount += 1
|
|
||||||
|
|
||||||
if _tableCount > _options._maxTableCount {
|
|
||||||
throw FlatbuffersErrors.maximumTables
|
|
||||||
}
|
|
||||||
|
|
||||||
_depth += 1
|
|
||||||
|
|
||||||
if _depth > _options._maxDepth {
|
|
||||||
throw FlatbuffersErrors.maximumDepth
|
|
||||||
}
|
|
||||||
|
|
||||||
return TableVerifier(
|
|
||||||
position: position,
|
|
||||||
vtable: vtablePosition,
|
|
||||||
vtableLength: length,
|
|
||||||
verifier: &self)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Validates if a value of type `T` is within the buffer and returns it
|
|
||||||
/// - Parameter position: Current position to be read
|
|
||||||
/// - Throws: `inBuffer` errors
|
|
||||||
/// - Returns: a value of type `T` usually a `VTable` or a table offset
|
|
||||||
internal mutating func getValue<T>(at position: Int) throws -> T {
|
|
||||||
try inBuffer(position: position, of: T.self)
|
|
||||||
return _buffer.read(def: T.self, position: position)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// derefrences an offset within a vtable to get the position of the field
|
|
||||||
/// in the bytebuffer
|
|
||||||
/// - Parameter position: Current readable position
|
|
||||||
/// - Throws: `inBuffer` errors & `signedOffsetOutOfBounds`
|
|
||||||
/// - Returns: Current readable position for a field
|
|
||||||
@inline(__always)
|
|
||||||
internal mutating func derefOffset(position: Int) throws -> Int {
|
|
||||||
try inBuffer(position: position, of: Int32.self)
|
|
||||||
|
|
||||||
let offset = _buffer.read(def: Int32.self, position: position)
|
|
||||||
// switching to int32 since swift's default Int is int64
|
|
||||||
// this should be safe since we already checked if its within
|
|
||||||
// the buffer
|
|
||||||
let _int32Position = UInt32(position)
|
|
||||||
|
|
||||||
let reportedOverflow: (partialValue: UInt32, overflow: Bool)
|
|
||||||
if offset > 0 {
|
|
||||||
reportedOverflow = _int32Position
|
|
||||||
.subtractingReportingOverflow(offset.magnitude)
|
|
||||||
} else {
|
|
||||||
reportedOverflow = _int32Position
|
|
||||||
.addingReportingOverflow(offset.magnitude)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// since `subtractingReportingOverflow` & `addingReportingOverflow` returns true,
|
|
||||||
/// if there is overflow we return failure
|
|
||||||
if reportedOverflow.overflow || reportedOverflow.partialValue > _buffer
|
|
||||||
.capacity
|
|
||||||
{
|
|
||||||
throw FlatbuffersErrors.signedOffsetOutOfBounds(
|
|
||||||
offset: Int(offset),
|
|
||||||
position: position)
|
|
||||||
}
|
|
||||||
|
|
||||||
return Int(reportedOverflow.partialValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// finishes the current iteration of verification on an object
|
|
||||||
internal mutating func finish() {
|
|
||||||
_depth -= 1
|
|
||||||
}
|
|
||||||
|
|
||||||
mutating func verify(id: String) throws {
|
|
||||||
let size = MemoryLayout<Int32>.size
|
|
||||||
let str = _buffer.readString(at: size, count: size)
|
|
||||||
if id == str {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
throw FlatbuffersErrors.bufferIdDidntMatchPassedId
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user