codekingpro/portable-devtools
115k
1# Copyright 2014 Google Inc. All rights reserved.2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7# http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.14 15from . import encode16from . import number_types as N17 18 19class Table(object):20 """Table wraps a byte slice and provides read access to its data.21 22 The variable `Pos` indicates the root of the FlatBuffers object therein.23 """24 25 __slots__ = ("Bytes", "Pos")26 27 def __init__(self, buf, pos):28 N.enforce_number(pos, N.UOffsetTFlags)29 30 self.Bytes = buf31 self.Pos = pos32 33 def Offset(self, vtableOffset):34 """Offset provides access into the Table's vtable.35 36 Deprecated fields are ignored by checking the vtable's length.37 """38 39 vtable = self.Pos - self.Get(N.SOffsetTFlags, self.Pos)40 vtableEnd = self.Get(N.VOffsetTFlags, vtable)41 if vtableOffset < vtableEnd:42 return self.Get(N.VOffsetTFlags, vtable + vtableOffset)43 return 044 45 def Indirect(self, off):46 """Indirect retrieves the relative offset stored at `offset`."""47 N.enforce_number(off, N.UOffsetTFlags)48 return off + encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)49 50 def String(self, off):51 """String gets a string from data stored inside the flatbuffer."""52 N.enforce_number(off, N.UOffsetTFlags)53 off += encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)54 start = off + N.UOffsetTFlags.bytewidth55 length = encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)56 return bytes(self.Bytes[start : start + length])57 58 def VectorLen(self, off):59 """VectorLen retrieves the length of the vector whose offset is stored60 61 at "off" in this object.62 """63 N.enforce_number(off, N.UOffsetTFlags)64 65 off += self.Pos66 off += encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)67 ret = encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)68 return ret69 70 def Vector(self, off):71 """Vector retrieves the start of data of the vector whose offset is72 73 stored at "off" in this object.74 """75 N.enforce_number(off, N.UOffsetTFlags)76 77 off += self.Pos78 x = off + self.Get(N.UOffsetTFlags, off)79 # data starts after metadata containing the vector length80 x += N.UOffsetTFlags.bytewidth81 return x82 83 def Union(self, t2, off):84 """Union initializes any Table-derived type to point to the union at85 86 the given offset.87 """88 assert type(t2) is Table89 N.enforce_number(off, N.UOffsetTFlags)90 91 off += self.Pos92 t2.Pos = off + self.Get(N.UOffsetTFlags, off)93 t2.Bytes = self.Bytes94 95 def Get(self, flags, off):96 """Get retrieves a value of the type specified by `flags` at the97 98 given offset.99 """100 N.enforce_number(off, N.UOffsetTFlags)101 return flags.py_type(encode.Get(flags.packer_type, self.Bytes, off))102 103 def GetSlot(self, slot, d, validator_flags):104 N.enforce_number(slot, N.VOffsetTFlags)105 if validator_flags is not None:106 N.enforce_number(d, validator_flags)107 off = self.Offset(slot)108 if off == 0:109 return d110 return self.Get(validator_flags, self.Pos + off)111 112 def GetVectorAsNumpy(self, flags, off):113 """GetVectorAsNumpy returns the vector that starts at `Vector(off)`114 115 as a numpy array with the type specified by `flags`. The array is116 a `view` into Bytes, so modifying the returned array will117 modify Bytes in place.118 """119 offset = self.Vector(off)120 length = self.VectorLen(off) # TODO: length accounts for bytewidth, right?121 numpy_dtype = N.to_numpy_type(flags)122 return encode.GetVectorAsNumpy(numpy_dtype, self.Bytes, length, offset)123 124 def GetArrayAsNumpy(self, flags, off, length):125 """GetArrayAsNumpy returns the array with fixed width that starts at `Vector(offset)`126 127 with length `length` as a numpy array with the type specified by `flags`.128 The129 array is a `view` into Bytes so modifying the returned will modify Bytes in130 place.131 """132 numpy_dtype = N.to_numpy_type(flags)133 return encode.GetVectorAsNumpy(numpy_dtype, self.Bytes, length, off)134 135 def GetVOffsetTSlot(self, slot, d):136 """GetVOffsetTSlot retrieves the VOffsetT that the given vtable location137 138 points to. If the vtable value is zero, the default value `d`139 will be returned.140 """141 142 N.enforce_number(slot, N.VOffsetTFlags)143 N.enforce_number(d, N.VOffsetTFlags)144 145 off = self.Offset(slot)146 if off == 0:147 return d148 return off149 