1<?php
2/*
3 * Copyright 2015 Google Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18namespace Google\FlatBuffers;
19
20abstract class Table
21{
22    /**
23     * @var int $bb_pos
24     */
25    protected $bb_pos;
26    /**
27     * @var ByteBuffer $bb
28     */
29    protected $bb;
30
31    public function __construct()
32    {
33    }
34
35    public function setByteBufferPos($pos)
36    {
37        $this->bb_pos = $pos;
38    }
39
40    public function setByteBuffer($bb)
41    {
42        $this->bb = $bb;
43    }
44
45    /**
46     * returns actual vtable offset
47     *
48     * @param $vtable_offset
49     * @return int offset > 0 means exist value. 0 means not exist
50     */
51    protected function __offset($vtable_offset)
52    {
53        $vtable = $this->bb_pos - $this->bb->getInt($this->bb_pos);
54        return $vtable_offset < $this->bb->getShort($vtable) ? $this->bb->getShort($vtable + $vtable_offset) : 0;
55    }
56
57    /**
58     * @param $offset
59     * @return mixed
60     */
61    protected function __indirect($offset)
62    {
63        return $offset + $this->bb->getInt($offset);
64    }
65
66    /**
67     * fetch utf8 encoded string.
68     *
69     * @param $offset
70     * @return string
71     */
72    protected function __string($offset)
73    {
74        $offset += $this->bb->getInt($offset);
75        $len = $this->bb->getInt($offset);
76        $startPos = $offset + Constants::SIZEOF_INT;
77        return substr($this->bb->_buffer, $startPos, $len);
78    }
79
80    /**
81     * @param $offset
82     * @return int
83     */
84    protected function __vector_len($offset)
85    {
86        $offset += $this->bb_pos;
87        $offset += $this->bb->getInt($offset);
88        return $this->bb->getInt($offset);
89    }
90
91    /**
92     * @param $offset
93     * @return int
94     */
95    protected function __vector($offset)
96    {
97        $offset += $this->bb_pos;
98        // data starts after the length
99        return $offset + $this->bb->getInt($offset) + Constants::SIZEOF_INT;
100    }
101
102    protected function __vector_as_bytes($vector_offset, $elem_size=1)
103    {
104        $o = $this->__offset($vector_offset);
105        if ($o == 0) {
106            return null;
107        }
108
109        return substr($this->bb->_buffer, $this->__vector($o), $this->__vector_len($o) * $elem_size);
110    }
111
112    /**
113     * @param Table $table
114     * @param int $offset
115     * @return Table
116     */
117    protected function __union($table, $offset)
118    {
119        $offset += $this->bb_pos;
120        $table->setByteBufferPos($offset + $this->bb->getInt($offset));
121        $table->setByteBuffer($this->bb);
122        return $table;
123    }
124
125    /**
126     * @param ByteBuffer $bb
127     * @param string $ident
128     * @return bool
129     * @throws \ArgumentException
130     */
131    protected static function __has_identifier($bb, $ident)
132    {
133        if (strlen($ident) != Constants::FILE_IDENTIFIER_LENGTH) {
134            throw new \ArgumentException("FlatBuffers: file identifier must be length "  . Constants::FILE_IDENTIFIER_LENGTH);
135        }
136
137        for ($i = 0; $i < 4; $i++) {
138            if ($ident[$i] != $bb->get($bb->getPosition() + Constants::SIZEOF_INT + $i)) {
139                return false;
140            }
141        }
142
143        return true;
144    }
145}
146