xref: /aosp_15_r20/external/flatbuffers/python/flatbuffers/table.py (revision 890232f25432b36107d06881e0a25aaa6b473652)
1*890232f2SAndroid Build Coastguard Worker# Copyright 2014 Google Inc. All rights reserved.
2*890232f2SAndroid Build Coastguard Worker#
3*890232f2SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*890232f2SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*890232f2SAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*890232f2SAndroid Build Coastguard Worker#
7*890232f2SAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
8*890232f2SAndroid Build Coastguard Worker#
9*890232f2SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*890232f2SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*890232f2SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*890232f2SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*890232f2SAndroid Build Coastguard Worker# limitations under the License.
14*890232f2SAndroid Build Coastguard Worker
15*890232f2SAndroid Build Coastguard Workerfrom . import encode
16*890232f2SAndroid Build Coastguard Workerfrom . import number_types as N
17*890232f2SAndroid Build Coastguard Worker
18*890232f2SAndroid Build Coastguard Worker
19*890232f2SAndroid Build Coastguard Workerclass Table(object):
20*890232f2SAndroid Build Coastguard Worker    """Table wraps a byte slice and provides read access to its data.
21*890232f2SAndroid Build Coastguard Worker
22*890232f2SAndroid Build Coastguard Worker    The variable `Pos` indicates the root of the FlatBuffers object therein."""
23*890232f2SAndroid Build Coastguard Worker
24*890232f2SAndroid Build Coastguard Worker    __slots__ = ("Bytes", "Pos")
25*890232f2SAndroid Build Coastguard Worker
26*890232f2SAndroid Build Coastguard Worker    def __init__(self, buf, pos):
27*890232f2SAndroid Build Coastguard Worker        N.enforce_number(pos, N.UOffsetTFlags)
28*890232f2SAndroid Build Coastguard Worker
29*890232f2SAndroid Build Coastguard Worker        self.Bytes = buf
30*890232f2SAndroid Build Coastguard Worker        self.Pos = pos
31*890232f2SAndroid Build Coastguard Worker
32*890232f2SAndroid Build Coastguard Worker    def Offset(self, vtableOffset):
33*890232f2SAndroid Build Coastguard Worker        """Offset provides access into the Table's vtable.
34*890232f2SAndroid Build Coastguard Worker
35*890232f2SAndroid Build Coastguard Worker        Deprecated fields are ignored by checking the vtable's length."""
36*890232f2SAndroid Build Coastguard Worker
37*890232f2SAndroid Build Coastguard Worker        vtable = self.Pos - self.Get(N.SOffsetTFlags, self.Pos)
38*890232f2SAndroid Build Coastguard Worker        vtableEnd = self.Get(N.VOffsetTFlags, vtable)
39*890232f2SAndroid Build Coastguard Worker        if vtableOffset < vtableEnd:
40*890232f2SAndroid Build Coastguard Worker            return self.Get(N.VOffsetTFlags, vtable + vtableOffset)
41*890232f2SAndroid Build Coastguard Worker        return 0
42*890232f2SAndroid Build Coastguard Worker
43*890232f2SAndroid Build Coastguard Worker    def Indirect(self, off):
44*890232f2SAndroid Build Coastguard Worker        """Indirect retrieves the relative offset stored at `offset`."""
45*890232f2SAndroid Build Coastguard Worker        N.enforce_number(off, N.UOffsetTFlags)
46*890232f2SAndroid Build Coastguard Worker        return off + encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
47*890232f2SAndroid Build Coastguard Worker
48*890232f2SAndroid Build Coastguard Worker    def String(self, off):
49*890232f2SAndroid Build Coastguard Worker        """String gets a string from data stored inside the flatbuffer."""
50*890232f2SAndroid Build Coastguard Worker        N.enforce_number(off, N.UOffsetTFlags)
51*890232f2SAndroid Build Coastguard Worker        off += encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
52*890232f2SAndroid Build Coastguard Worker        start = off + N.UOffsetTFlags.bytewidth
53*890232f2SAndroid Build Coastguard Worker        length = encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
54*890232f2SAndroid Build Coastguard Worker        return bytes(self.Bytes[start:start+length])
55*890232f2SAndroid Build Coastguard Worker
56*890232f2SAndroid Build Coastguard Worker    def VectorLen(self, off):
57*890232f2SAndroid Build Coastguard Worker        """VectorLen retrieves the length of the vector whose offset is stored
58*890232f2SAndroid Build Coastguard Worker           at "off" in this object."""
59*890232f2SAndroid Build Coastguard Worker        N.enforce_number(off, N.UOffsetTFlags)
60*890232f2SAndroid Build Coastguard Worker
61*890232f2SAndroid Build Coastguard Worker        off += self.Pos
62*890232f2SAndroid Build Coastguard Worker        off += encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
63*890232f2SAndroid Build Coastguard Worker        ret = encode.Get(N.UOffsetTFlags.packer_type, self.Bytes, off)
64*890232f2SAndroid Build Coastguard Worker        return ret
65*890232f2SAndroid Build Coastguard Worker
66*890232f2SAndroid Build Coastguard Worker    def Vector(self, off):
67*890232f2SAndroid Build Coastguard Worker        """Vector retrieves the start of data of the vector whose offset is
68*890232f2SAndroid Build Coastguard Worker           stored at "off" in this object."""
69*890232f2SAndroid Build Coastguard Worker        N.enforce_number(off, N.UOffsetTFlags)
70*890232f2SAndroid Build Coastguard Worker
71*890232f2SAndroid Build Coastguard Worker        off += self.Pos
72*890232f2SAndroid Build Coastguard Worker        x = off + self.Get(N.UOffsetTFlags, off)
73*890232f2SAndroid Build Coastguard Worker        # data starts after metadata containing the vector length
74*890232f2SAndroid Build Coastguard Worker        x += N.UOffsetTFlags.bytewidth
75*890232f2SAndroid Build Coastguard Worker        return x
76*890232f2SAndroid Build Coastguard Worker
77*890232f2SAndroid Build Coastguard Worker    def Union(self, t2, off):
78*890232f2SAndroid Build Coastguard Worker        """Union initializes any Table-derived type to point to the union at
79*890232f2SAndroid Build Coastguard Worker           the given offset."""
80*890232f2SAndroid Build Coastguard Worker        assert type(t2) is Table
81*890232f2SAndroid Build Coastguard Worker        N.enforce_number(off, N.UOffsetTFlags)
82*890232f2SAndroid Build Coastguard Worker
83*890232f2SAndroid Build Coastguard Worker        off += self.Pos
84*890232f2SAndroid Build Coastguard Worker        t2.Pos = off + self.Get(N.UOffsetTFlags, off)
85*890232f2SAndroid Build Coastguard Worker        t2.Bytes = self.Bytes
86*890232f2SAndroid Build Coastguard Worker
87*890232f2SAndroid Build Coastguard Worker    def Get(self, flags, off):
88*890232f2SAndroid Build Coastguard Worker        """
89*890232f2SAndroid Build Coastguard Worker        Get retrieves a value of the type specified by `flags`  at the
90*890232f2SAndroid Build Coastguard Worker        given offset.
91*890232f2SAndroid Build Coastguard Worker        """
92*890232f2SAndroid Build Coastguard Worker        N.enforce_number(off, N.UOffsetTFlags)
93*890232f2SAndroid Build Coastguard Worker        return flags.py_type(encode.Get(flags.packer_type, self.Bytes, off))
94*890232f2SAndroid Build Coastguard Worker
95*890232f2SAndroid Build Coastguard Worker    def GetSlot(self, slot, d, validator_flags):
96*890232f2SAndroid Build Coastguard Worker        N.enforce_number(slot, N.VOffsetTFlags)
97*890232f2SAndroid Build Coastguard Worker        if validator_flags is not None:
98*890232f2SAndroid Build Coastguard Worker            N.enforce_number(d, validator_flags)
99*890232f2SAndroid Build Coastguard Worker        off = self.Offset(slot)
100*890232f2SAndroid Build Coastguard Worker        if off == 0:
101*890232f2SAndroid Build Coastguard Worker            return d
102*890232f2SAndroid Build Coastguard Worker        return self.Get(validator_flags, self.Pos + off)
103*890232f2SAndroid Build Coastguard Worker
104*890232f2SAndroid Build Coastguard Worker    def GetVectorAsNumpy(self, flags, off):
105*890232f2SAndroid Build Coastguard Worker        """
106*890232f2SAndroid Build Coastguard Worker        GetVectorAsNumpy returns the vector that starts at `Vector(off)`
107*890232f2SAndroid Build Coastguard Worker        as a numpy array with the type specified by `flags`. The array is
108*890232f2SAndroid Build Coastguard Worker        a `view` into Bytes, so modifying the returned array will
109*890232f2SAndroid Build Coastguard Worker        modify Bytes in place.
110*890232f2SAndroid Build Coastguard Worker        """
111*890232f2SAndroid Build Coastguard Worker        offset = self.Vector(off)
112*890232f2SAndroid Build Coastguard Worker        length = self.VectorLen(off) # TODO: length accounts for bytewidth, right?
113*890232f2SAndroid Build Coastguard Worker        numpy_dtype = N.to_numpy_type(flags)
114*890232f2SAndroid Build Coastguard Worker        return encode.GetVectorAsNumpy(numpy_dtype, self.Bytes, length, offset)
115*890232f2SAndroid Build Coastguard Worker
116*890232f2SAndroid Build Coastguard Worker    def GetVOffsetTSlot(self, slot, d):
117*890232f2SAndroid Build Coastguard Worker        """
118*890232f2SAndroid Build Coastguard Worker        GetVOffsetTSlot retrieves the VOffsetT that the given vtable location
119*890232f2SAndroid Build Coastguard Worker        points to. If the vtable value is zero, the default value `d`
120*890232f2SAndroid Build Coastguard Worker        will be returned.
121*890232f2SAndroid Build Coastguard Worker        """
122*890232f2SAndroid Build Coastguard Worker
123*890232f2SAndroid Build Coastguard Worker        N.enforce_number(slot, N.VOffsetTFlags)
124*890232f2SAndroid Build Coastguard Worker        N.enforce_number(d, N.VOffsetTFlags)
125*890232f2SAndroid Build Coastguard Worker
126*890232f2SAndroid Build Coastguard Worker        off = self.Offset(slot)
127*890232f2SAndroid Build Coastguard Worker        if off == 0:
128*890232f2SAndroid Build Coastguard Worker                return d
129*890232f2SAndroid Build Coastguard Worker        return off
130