1*890232f2SAndroid Build Coastguard Worker<?php 2*890232f2SAndroid Build Coastguard Worker/* 3*890232f2SAndroid Build Coastguard Worker * Copyright 2015 Google Inc. 4*890232f2SAndroid Build Coastguard Worker * 5*890232f2SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 6*890232f2SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 7*890232f2SAndroid Build Coastguard Worker * You may obtain a copy of the License at 8*890232f2SAndroid Build Coastguard Worker * 9*890232f2SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 10*890232f2SAndroid Build Coastguard Worker * 11*890232f2SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 12*890232f2SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 13*890232f2SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*890232f2SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 15*890232f2SAndroid Build Coastguard Worker * limitations under the License. 16*890232f2SAndroid Build Coastguard Worker */ 17*890232f2SAndroid Build Coastguard Worker 18*890232f2SAndroid Build Coastguard Worker/// @file 19*890232f2SAndroid Build Coastguard Worker/// @addtogroup flatbuffers_php_api 20*890232f2SAndroid Build Coastguard Worker/// @{ 21*890232f2SAndroid Build Coastguard Worker 22*890232f2SAndroid Build Coastguard Workernamespace Google\FlatBuffers; 23*890232f2SAndroid Build Coastguard Worker 24*890232f2SAndroid Build Coastguard Workerfinal class FlatbufferBuilder 25*890232f2SAndroid Build Coastguard Worker{ 26*890232f2SAndroid Build Coastguard Worker /** 27*890232f2SAndroid Build Coastguard Worker * Internal ByteBuffer for the FlatBuffer data. 28*890232f2SAndroid Build Coastguard Worker * @var ByteBuffer $bb 29*890232f2SAndroid Build Coastguard Worker */ 30*890232f2SAndroid Build Coastguard Worker public $bb; 31*890232f2SAndroid Build Coastguard Worker 32*890232f2SAndroid Build Coastguard Worker /// @cond FLATBUFFERS_INTERNAL 33*890232f2SAndroid Build Coastguard Worker /** 34*890232f2SAndroid Build Coastguard Worker * @var int $space 35*890232f2SAndroid Build Coastguard Worker */ 36*890232f2SAndroid Build Coastguard Worker protected $space; 37*890232f2SAndroid Build Coastguard Worker 38*890232f2SAndroid Build Coastguard Worker /** 39*890232f2SAndroid Build Coastguard Worker * @var int $minalign 40*890232f2SAndroid Build Coastguard Worker */ 41*890232f2SAndroid Build Coastguard Worker protected $minalign = 1; 42*890232f2SAndroid Build Coastguard Worker 43*890232f2SAndroid Build Coastguard Worker /** 44*890232f2SAndroid Build Coastguard Worker * @var array $vtable 45*890232f2SAndroid Build Coastguard Worker */ 46*890232f2SAndroid Build Coastguard Worker protected $vtable; 47*890232f2SAndroid Build Coastguard Worker 48*890232f2SAndroid Build Coastguard Worker /** 49*890232f2SAndroid Build Coastguard Worker * @var int $vtable_in_use 50*890232f2SAndroid Build Coastguard Worker */ 51*890232f2SAndroid Build Coastguard Worker protected $vtable_in_use = 0; 52*890232f2SAndroid Build Coastguard Worker 53*890232f2SAndroid Build Coastguard Worker /** 54*890232f2SAndroid Build Coastguard Worker * @var bool $nested 55*890232f2SAndroid Build Coastguard Worker */ 56*890232f2SAndroid Build Coastguard Worker protected $nested = false; 57*890232f2SAndroid Build Coastguard Worker 58*890232f2SAndroid Build Coastguard Worker /** 59*890232f2SAndroid Build Coastguard Worker * @var int $object_start 60*890232f2SAndroid Build Coastguard Worker */ 61*890232f2SAndroid Build Coastguard Worker protected $object_start; 62*890232f2SAndroid Build Coastguard Worker 63*890232f2SAndroid Build Coastguard Worker /** 64*890232f2SAndroid Build Coastguard Worker * @var array $vtables 65*890232f2SAndroid Build Coastguard Worker */ 66*890232f2SAndroid Build Coastguard Worker protected $vtables = array(); 67*890232f2SAndroid Build Coastguard Worker 68*890232f2SAndroid Build Coastguard Worker /** 69*890232f2SAndroid Build Coastguard Worker * @var int $num_vtables 70*890232f2SAndroid Build Coastguard Worker */ 71*890232f2SAndroid Build Coastguard Worker protected $num_vtables = 0; 72*890232f2SAndroid Build Coastguard Worker 73*890232f2SAndroid Build Coastguard Worker /** 74*890232f2SAndroid Build Coastguard Worker * @var int $vector_num_elems 75*890232f2SAndroid Build Coastguard Worker */ 76*890232f2SAndroid Build Coastguard Worker protected $vector_num_elems = 0; 77*890232f2SAndroid Build Coastguard Worker 78*890232f2SAndroid Build Coastguard Worker /** 79*890232f2SAndroid Build Coastguard Worker * @var bool $force_defaults 80*890232f2SAndroid Build Coastguard Worker */ 81*890232f2SAndroid Build Coastguard Worker protected $force_defaults = false; 82*890232f2SAndroid Build Coastguard Worker /// @endcond 83*890232f2SAndroid Build Coastguard Worker 84*890232f2SAndroid Build Coastguard Worker /** 85*890232f2SAndroid Build Coastguard Worker * Create a FlatBufferBuilder with a given initial size. 86*890232f2SAndroid Build Coastguard Worker * 87*890232f2SAndroid Build Coastguard Worker * @param $initial_size initial byte buffer size. 88*890232f2SAndroid Build Coastguard Worker */ 89*890232f2SAndroid Build Coastguard Worker public function __construct($initial_size) 90*890232f2SAndroid Build Coastguard Worker { 91*890232f2SAndroid Build Coastguard Worker if ($initial_size <= 0) { 92*890232f2SAndroid Build Coastguard Worker $initial_size = 1; 93*890232f2SAndroid Build Coastguard Worker } 94*890232f2SAndroid Build Coastguard Worker $this->space = $initial_size; 95*890232f2SAndroid Build Coastguard Worker $this->bb = $this->newByteBuffer($initial_size); 96*890232f2SAndroid Build Coastguard Worker } 97*890232f2SAndroid Build Coastguard Worker 98*890232f2SAndroid Build Coastguard Worker /// @cond FLATBUFFERS_INTERNAL 99*890232f2SAndroid Build Coastguard Worker /** 100*890232f2SAndroid Build Coastguard Worker * create new bytebuffer 101*890232f2SAndroid Build Coastguard Worker * 102*890232f2SAndroid Build Coastguard Worker * @param $size 103*890232f2SAndroid Build Coastguard Worker * @return ByteBuffer 104*890232f2SAndroid Build Coastguard Worker */ 105*890232f2SAndroid Build Coastguard Worker private function newByteBuffer($size) 106*890232f2SAndroid Build Coastguard Worker { 107*890232f2SAndroid Build Coastguard Worker return new ByteBuffer($size); 108*890232f2SAndroid Build Coastguard Worker } 109*890232f2SAndroid Build Coastguard Worker 110*890232f2SAndroid Build Coastguard Worker /** 111*890232f2SAndroid Build Coastguard Worker * Returns the current ByteBuffer offset. 112*890232f2SAndroid Build Coastguard Worker * 113*890232f2SAndroid Build Coastguard Worker * @return int 114*890232f2SAndroid Build Coastguard Worker */ 115*890232f2SAndroid Build Coastguard Worker public function offset() 116*890232f2SAndroid Build Coastguard Worker { 117*890232f2SAndroid Build Coastguard Worker return $this->bb->capacity() - $this->space; 118*890232f2SAndroid Build Coastguard Worker } 119*890232f2SAndroid Build Coastguard Worker 120*890232f2SAndroid Build Coastguard Worker /** 121*890232f2SAndroid Build Coastguard Worker * padding buffer 122*890232f2SAndroid Build Coastguard Worker * 123*890232f2SAndroid Build Coastguard Worker * @param $byte_size 124*890232f2SAndroid Build Coastguard Worker */ 125*890232f2SAndroid Build Coastguard Worker public function pad($byte_size) 126*890232f2SAndroid Build Coastguard Worker { 127*890232f2SAndroid Build Coastguard Worker for ($i = 0; $i < $byte_size; $i++) { 128*890232f2SAndroid Build Coastguard Worker $this->bb->putByte(--$this->space, "\0"); 129*890232f2SAndroid Build Coastguard Worker } 130*890232f2SAndroid Build Coastguard Worker } 131*890232f2SAndroid Build Coastguard Worker 132*890232f2SAndroid Build Coastguard Worker /** 133*890232f2SAndroid Build Coastguard Worker * prepare bytebuffer 134*890232f2SAndroid Build Coastguard Worker * 135*890232f2SAndroid Build Coastguard Worker * @param $size 136*890232f2SAndroid Build Coastguard Worker * @param $additional_bytes 137*890232f2SAndroid Build Coastguard Worker * @throws \Exception 138*890232f2SAndroid Build Coastguard Worker */ 139*890232f2SAndroid Build Coastguard Worker public function prep($size, $additional_bytes) 140*890232f2SAndroid Build Coastguard Worker { 141*890232f2SAndroid Build Coastguard Worker if ($size > $this->minalign) { 142*890232f2SAndroid Build Coastguard Worker $this->minalign = $size; 143*890232f2SAndroid Build Coastguard Worker } 144*890232f2SAndroid Build Coastguard Worker 145*890232f2SAndroid Build Coastguard Worker $align_size = ((~($this->bb->capacity() - $this->space + $additional_bytes)) + 1) & ($size - 1); 146*890232f2SAndroid Build Coastguard Worker while ($this->space < $align_size + $size + $additional_bytes) { 147*890232f2SAndroid Build Coastguard Worker $old_buf_size = $this->bb->capacity(); 148*890232f2SAndroid Build Coastguard Worker $this->bb = $this->growByteBuffer($this->bb); 149*890232f2SAndroid Build Coastguard Worker $this->space += $this->bb->capacity() - $old_buf_size; 150*890232f2SAndroid Build Coastguard Worker } 151*890232f2SAndroid Build Coastguard Worker 152*890232f2SAndroid Build Coastguard Worker $this->pad($align_size); 153*890232f2SAndroid Build Coastguard Worker } 154*890232f2SAndroid Build Coastguard Worker 155*890232f2SAndroid Build Coastguard Worker /** 156*890232f2SAndroid Build Coastguard Worker * @param ByteBuffer $bb 157*890232f2SAndroid Build Coastguard Worker * @return ByteBuffer 158*890232f2SAndroid Build Coastguard Worker * @throws \Exception 159*890232f2SAndroid Build Coastguard Worker */ 160*890232f2SAndroid Build Coastguard Worker private static function growByteBuffer(ByteBuffer $bb) 161*890232f2SAndroid Build Coastguard Worker { 162*890232f2SAndroid Build Coastguard Worker $old_buf_size = $bb->capacity(); 163*890232f2SAndroid Build Coastguard Worker if (($old_buf_size & 0xC0000000) != 0) { 164*890232f2SAndroid Build Coastguard Worker throw new \Exception("FlatBuffers: cannot grow buffer beyond 2 gigabytes"); 165*890232f2SAndroid Build Coastguard Worker } 166*890232f2SAndroid Build Coastguard Worker $new_buf_size = $old_buf_size << 1; 167*890232f2SAndroid Build Coastguard Worker 168*890232f2SAndroid Build Coastguard Worker $bb->setPosition(0); 169*890232f2SAndroid Build Coastguard Worker $nbb = new ByteBuffer($new_buf_size); 170*890232f2SAndroid Build Coastguard Worker 171*890232f2SAndroid Build Coastguard Worker $nbb->setPosition($new_buf_size - $old_buf_size); 172*890232f2SAndroid Build Coastguard Worker 173*890232f2SAndroid Build Coastguard Worker // TODO(chobie): is this little bit faster? 174*890232f2SAndroid Build Coastguard Worker //$nbb->_buffer = substr_replace($nbb->_buffer, $bb->_buffer, $new_buf_size - $old_buf_size, strlen($bb->_buffer)); 175*890232f2SAndroid Build Coastguard Worker for ($i = $new_buf_size - $old_buf_size, $j = 0; $j < strlen($bb->_buffer); $i++, $j++) { 176*890232f2SAndroid Build Coastguard Worker $nbb->_buffer[$i] = $bb->_buffer[$j]; 177*890232f2SAndroid Build Coastguard Worker } 178*890232f2SAndroid Build Coastguard Worker 179*890232f2SAndroid Build Coastguard Worker return $nbb; 180*890232f2SAndroid Build Coastguard Worker } 181*890232f2SAndroid Build Coastguard Worker 182*890232f2SAndroid Build Coastguard Worker /** 183*890232f2SAndroid Build Coastguard Worker * @param $x 184*890232f2SAndroid Build Coastguard Worker */ 185*890232f2SAndroid Build Coastguard Worker public function putBool($x) 186*890232f2SAndroid Build Coastguard Worker { 187*890232f2SAndroid Build Coastguard Worker $this->bb->put($this->space -= 1, chr((int)(bool)($x))); 188*890232f2SAndroid Build Coastguard Worker } 189*890232f2SAndroid Build Coastguard Worker 190*890232f2SAndroid Build Coastguard Worker /** 191*890232f2SAndroid Build Coastguard Worker * @param $x 192*890232f2SAndroid Build Coastguard Worker */ 193*890232f2SAndroid Build Coastguard Worker public function putByte($x) 194*890232f2SAndroid Build Coastguard Worker { 195*890232f2SAndroid Build Coastguard Worker $this->bb->put($this->space -= 1, chr($x)); 196*890232f2SAndroid Build Coastguard Worker } 197*890232f2SAndroid Build Coastguard Worker 198*890232f2SAndroid Build Coastguard Worker /** 199*890232f2SAndroid Build Coastguard Worker * @param $x 200*890232f2SAndroid Build Coastguard Worker */ 201*890232f2SAndroid Build Coastguard Worker public function putSbyte($x) 202*890232f2SAndroid Build Coastguard Worker { 203*890232f2SAndroid Build Coastguard Worker $this->bb->put($this->space -= 1, chr($x)); 204*890232f2SAndroid Build Coastguard Worker } 205*890232f2SAndroid Build Coastguard Worker 206*890232f2SAndroid Build Coastguard Worker /** 207*890232f2SAndroid Build Coastguard Worker * @param $x 208*890232f2SAndroid Build Coastguard Worker */ 209*890232f2SAndroid Build Coastguard Worker public function putShort($x) 210*890232f2SAndroid Build Coastguard Worker { 211*890232f2SAndroid Build Coastguard Worker $this->bb->putShort($this->space -= 2, $x); 212*890232f2SAndroid Build Coastguard Worker } 213*890232f2SAndroid Build Coastguard Worker 214*890232f2SAndroid Build Coastguard Worker /** 215*890232f2SAndroid Build Coastguard Worker * @param $x 216*890232f2SAndroid Build Coastguard Worker */ 217*890232f2SAndroid Build Coastguard Worker public function putUshort($x) 218*890232f2SAndroid Build Coastguard Worker { 219*890232f2SAndroid Build Coastguard Worker $this->bb->putUshort($this->space -= 2, $x); 220*890232f2SAndroid Build Coastguard Worker } 221*890232f2SAndroid Build Coastguard Worker 222*890232f2SAndroid Build Coastguard Worker /** 223*890232f2SAndroid Build Coastguard Worker * @param $x 224*890232f2SAndroid Build Coastguard Worker */ 225*890232f2SAndroid Build Coastguard Worker public function putInt($x) 226*890232f2SAndroid Build Coastguard Worker { 227*890232f2SAndroid Build Coastguard Worker $this->bb->putInt($this->space -= 4, $x); 228*890232f2SAndroid Build Coastguard Worker } 229*890232f2SAndroid Build Coastguard Worker 230*890232f2SAndroid Build Coastguard Worker /** 231*890232f2SAndroid Build Coastguard Worker * @param $x 232*890232f2SAndroid Build Coastguard Worker */ 233*890232f2SAndroid Build Coastguard Worker public function putUint($x) 234*890232f2SAndroid Build Coastguard Worker { 235*890232f2SAndroid Build Coastguard Worker if ($x > PHP_INT_MAX) { 236*890232f2SAndroid Build Coastguard Worker throw new \InvalidArgumentException("your platform can't handle uint correctly. use 64bit machine."); 237*890232f2SAndroid Build Coastguard Worker } 238*890232f2SAndroid Build Coastguard Worker 239*890232f2SAndroid Build Coastguard Worker $this->bb->putUint($this->space -= 4, $x); 240*890232f2SAndroid Build Coastguard Worker } 241*890232f2SAndroid Build Coastguard Worker 242*890232f2SAndroid Build Coastguard Worker /** 243*890232f2SAndroid Build Coastguard Worker * @param $x 244*890232f2SAndroid Build Coastguard Worker */ 245*890232f2SAndroid Build Coastguard Worker public function putLong($x) 246*890232f2SAndroid Build Coastguard Worker { 247*890232f2SAndroid Build Coastguard Worker if ($x > PHP_INT_MAX) { 248*890232f2SAndroid Build Coastguard Worker throw new \InvalidArgumentException("Your platform can't handle long correctly. Use a 64bit machine."); 249*890232f2SAndroid Build Coastguard Worker } 250*890232f2SAndroid Build Coastguard Worker 251*890232f2SAndroid Build Coastguard Worker $this->bb->putLong($this->space -= 8, $x); 252*890232f2SAndroid Build Coastguard Worker } 253*890232f2SAndroid Build Coastguard Worker 254*890232f2SAndroid Build Coastguard Worker /** 255*890232f2SAndroid Build Coastguard Worker * @param $x 256*890232f2SAndroid Build Coastguard Worker */ 257*890232f2SAndroid Build Coastguard Worker public function putUlong($x) 258*890232f2SAndroid Build Coastguard Worker { 259*890232f2SAndroid Build Coastguard Worker if ($x > PHP_INT_MAX) { 260*890232f2SAndroid Build Coastguard Worker throw new \InvalidArgumentException("Your platform can't handle ulong correctly. This is a php limitation. Please wait for the extension release."); 261*890232f2SAndroid Build Coastguard Worker } 262*890232f2SAndroid Build Coastguard Worker 263*890232f2SAndroid Build Coastguard Worker $this->bb->putUlong($this->space -= 8, $x); 264*890232f2SAndroid Build Coastguard Worker } 265*890232f2SAndroid Build Coastguard Worker 266*890232f2SAndroid Build Coastguard Worker /** 267*890232f2SAndroid Build Coastguard Worker * @param $x 268*890232f2SAndroid Build Coastguard Worker */ 269*890232f2SAndroid Build Coastguard Worker public function putFloat($x) 270*890232f2SAndroid Build Coastguard Worker { 271*890232f2SAndroid Build Coastguard Worker $this->bb->putFloat($this->space -= 4, $x); 272*890232f2SAndroid Build Coastguard Worker } 273*890232f2SAndroid Build Coastguard Worker 274*890232f2SAndroid Build Coastguard Worker /** 275*890232f2SAndroid Build Coastguard Worker * @param $x 276*890232f2SAndroid Build Coastguard Worker */ 277*890232f2SAndroid Build Coastguard Worker public function putDouble($x) 278*890232f2SAndroid Build Coastguard Worker { 279*890232f2SAndroid Build Coastguard Worker $this->bb->putDouble($this->space -= 8, $x); 280*890232f2SAndroid Build Coastguard Worker } 281*890232f2SAndroid Build Coastguard Worker 282*890232f2SAndroid Build Coastguard Worker /** 283*890232f2SAndroid Build Coastguard Worker * @param $off 284*890232f2SAndroid Build Coastguard Worker */ 285*890232f2SAndroid Build Coastguard Worker public function putOffset($off) 286*890232f2SAndroid Build Coastguard Worker { 287*890232f2SAndroid Build Coastguard Worker $new_off = $this->offset() - $off + Constants::SIZEOF_INT; 288*890232f2SAndroid Build Coastguard Worker $this->putInt($new_off); 289*890232f2SAndroid Build Coastguard Worker } 290*890232f2SAndroid Build Coastguard Worker /// @endcond 291*890232f2SAndroid Build Coastguard Worker 292*890232f2SAndroid Build Coastguard Worker /** 293*890232f2SAndroid Build Coastguard Worker * Add a `bool` to the buffer, properly aligned, and grows the buffer (if necessary). 294*890232f2SAndroid Build Coastguard Worker * @param $x The `bool` to add to the buffer. 295*890232f2SAndroid Build Coastguard Worker */ 296*890232f2SAndroid Build Coastguard Worker public function addBool($x) 297*890232f2SAndroid Build Coastguard Worker { 298*890232f2SAndroid Build Coastguard Worker $this->prep(1, 0); 299*890232f2SAndroid Build Coastguard Worker $this->putBool($x); 300*890232f2SAndroid Build Coastguard Worker } 301*890232f2SAndroid Build Coastguard Worker 302*890232f2SAndroid Build Coastguard Worker /** 303*890232f2SAndroid Build Coastguard Worker * Add a `byte` to the buffer, properly aligned, and grows the buffer (if necessary). 304*890232f2SAndroid Build Coastguard Worker * @param $x The `byte` to add to the buffer. 305*890232f2SAndroid Build Coastguard Worker */ 306*890232f2SAndroid Build Coastguard Worker public function addByte($x) 307*890232f2SAndroid Build Coastguard Worker { 308*890232f2SAndroid Build Coastguard Worker $this->prep(1, 0); 309*890232f2SAndroid Build Coastguard Worker $this->putByte($x); 310*890232f2SAndroid Build Coastguard Worker } 311*890232f2SAndroid Build Coastguard Worker 312*890232f2SAndroid Build Coastguard Worker /** 313*890232f2SAndroid Build Coastguard Worker * Add a `signed byte` to the buffer, properly aligned, and grows the buffer (if necessary). 314*890232f2SAndroid Build Coastguard Worker * @param $x The `signed byte` to add to the buffer. 315*890232f2SAndroid Build Coastguard Worker */ 316*890232f2SAndroid Build Coastguard Worker public function addSbyte($x) 317*890232f2SAndroid Build Coastguard Worker { 318*890232f2SAndroid Build Coastguard Worker $this->prep(1, 0); 319*890232f2SAndroid Build Coastguard Worker $this->putSbyte($x); 320*890232f2SAndroid Build Coastguard Worker } 321*890232f2SAndroid Build Coastguard Worker 322*890232f2SAndroid Build Coastguard Worker /** 323*890232f2SAndroid Build Coastguard Worker * Add a `short` to the buffer, properly aligned, and grows the buffer (if necessary). 324*890232f2SAndroid Build Coastguard Worker * @param $x The `short` to add to the buffer. 325*890232f2SAndroid Build Coastguard Worker */ 326*890232f2SAndroid Build Coastguard Worker public function addShort($x) 327*890232f2SAndroid Build Coastguard Worker { 328*890232f2SAndroid Build Coastguard Worker $this->prep(2, 0); 329*890232f2SAndroid Build Coastguard Worker $this->putShort($x); 330*890232f2SAndroid Build Coastguard Worker } 331*890232f2SAndroid Build Coastguard Worker 332*890232f2SAndroid Build Coastguard Worker /** 333*890232f2SAndroid Build Coastguard Worker * Add an `unsigned short` to the buffer, properly aligned, and grows the buffer (if necessary). 334*890232f2SAndroid Build Coastguard Worker * @param $x The `unsigned short` to add to the buffer. 335*890232f2SAndroid Build Coastguard Worker */ 336*890232f2SAndroid Build Coastguard Worker public function addUshort($x) 337*890232f2SAndroid Build Coastguard Worker { 338*890232f2SAndroid Build Coastguard Worker $this->prep(2, 0); 339*890232f2SAndroid Build Coastguard Worker $this->putUshort($x); 340*890232f2SAndroid Build Coastguard Worker } 341*890232f2SAndroid Build Coastguard Worker 342*890232f2SAndroid Build Coastguard Worker /** 343*890232f2SAndroid Build Coastguard Worker * Add an `int` to the buffer, properly aligned, and grows the buffer (if necessary). 344*890232f2SAndroid Build Coastguard Worker * @param $x The `int` to add to the buffer. 345*890232f2SAndroid Build Coastguard Worker */ 346*890232f2SAndroid Build Coastguard Worker public function addInt($x) 347*890232f2SAndroid Build Coastguard Worker { 348*890232f2SAndroid Build Coastguard Worker $this->prep(4, 0); 349*890232f2SAndroid Build Coastguard Worker $this->putInt($x); 350*890232f2SAndroid Build Coastguard Worker } 351*890232f2SAndroid Build Coastguard Worker 352*890232f2SAndroid Build Coastguard Worker /** 353*890232f2SAndroid Build Coastguard Worker * Add an `unsigned int` to the buffer, properly aligned, and grows the buffer (if necessary). 354*890232f2SAndroid Build Coastguard Worker * @param $x The `unsigned int` to add to the buffer. 355*890232f2SAndroid Build Coastguard Worker */ 356*890232f2SAndroid Build Coastguard Worker public function addUint($x) 357*890232f2SAndroid Build Coastguard Worker { 358*890232f2SAndroid Build Coastguard Worker $this->prep(4, 0); 359*890232f2SAndroid Build Coastguard Worker $this->putUint($x); 360*890232f2SAndroid Build Coastguard Worker } 361*890232f2SAndroid Build Coastguard Worker 362*890232f2SAndroid Build Coastguard Worker /** 363*890232f2SAndroid Build Coastguard Worker * Add a `long` to the buffer, properly aligned, and grows the buffer (if necessary). 364*890232f2SAndroid Build Coastguard Worker * @param $x The `long` to add to the buffer. 365*890232f2SAndroid Build Coastguard Worker */ 366*890232f2SAndroid Build Coastguard Worker public function addLong($x) 367*890232f2SAndroid Build Coastguard Worker { 368*890232f2SAndroid Build Coastguard Worker $this->prep(8, 0); 369*890232f2SAndroid Build Coastguard Worker $this->putLong($x); 370*890232f2SAndroid Build Coastguard Worker } 371*890232f2SAndroid Build Coastguard Worker 372*890232f2SAndroid Build Coastguard Worker /** 373*890232f2SAndroid Build Coastguard Worker * Add an `unsigned long` to the buffer, properly aligned, and grows the buffer (if necessary). 374*890232f2SAndroid Build Coastguard Worker * @param $x The `unsigned long` to add to the buffer. 375*890232f2SAndroid Build Coastguard Worker */ 376*890232f2SAndroid Build Coastguard Worker public function addUlong($x) 377*890232f2SAndroid Build Coastguard Worker { 378*890232f2SAndroid Build Coastguard Worker $this->prep(8, 0); 379*890232f2SAndroid Build Coastguard Worker $this->putUlong($x); 380*890232f2SAndroid Build Coastguard Worker } 381*890232f2SAndroid Build Coastguard Worker 382*890232f2SAndroid Build Coastguard Worker /** 383*890232f2SAndroid Build Coastguard Worker * Add a `float` to the buffer, properly aligned, and grows the buffer (if necessary). 384*890232f2SAndroid Build Coastguard Worker * @param $x The `float` to add to the buffer. 385*890232f2SAndroid Build Coastguard Worker */ 386*890232f2SAndroid Build Coastguard Worker public function addFloat($x) 387*890232f2SAndroid Build Coastguard Worker { 388*890232f2SAndroid Build Coastguard Worker $this->prep(4, 0); 389*890232f2SAndroid Build Coastguard Worker $this->putFloat($x); 390*890232f2SAndroid Build Coastguard Worker } 391*890232f2SAndroid Build Coastguard Worker 392*890232f2SAndroid Build Coastguard Worker /** 393*890232f2SAndroid Build Coastguard Worker * Add a `double` to the buffer, properly aligned, and grows the buffer (if necessary). 394*890232f2SAndroid Build Coastguard Worker * @param $x The `double` to add to the buffer. 395*890232f2SAndroid Build Coastguard Worker */ 396*890232f2SAndroid Build Coastguard Worker public function addDouble($x) 397*890232f2SAndroid Build Coastguard Worker { 398*890232f2SAndroid Build Coastguard Worker $this->prep(8, 0); 399*890232f2SAndroid Build Coastguard Worker $this->putDouble($x); 400*890232f2SAndroid Build Coastguard Worker } 401*890232f2SAndroid Build Coastguard Worker 402*890232f2SAndroid Build Coastguard Worker /// @cond FLATBUFFERS_INTERNAL 403*890232f2SAndroid Build Coastguard Worker /** 404*890232f2SAndroid Build Coastguard Worker * @param $o 405*890232f2SAndroid Build Coastguard Worker * @param $x 406*890232f2SAndroid Build Coastguard Worker * @param $d 407*890232f2SAndroid Build Coastguard Worker */ 408*890232f2SAndroid Build Coastguard Worker public function addBoolX($o, $x, $d) 409*890232f2SAndroid Build Coastguard Worker { 410*890232f2SAndroid Build Coastguard Worker if ($this->force_defaults || $x != $d) { 411*890232f2SAndroid Build Coastguard Worker $this->addBool($x); 412*890232f2SAndroid Build Coastguard Worker $this->slot($o); 413*890232f2SAndroid Build Coastguard Worker } 414*890232f2SAndroid Build Coastguard Worker } 415*890232f2SAndroid Build Coastguard Worker 416*890232f2SAndroid Build Coastguard Worker /** 417*890232f2SAndroid Build Coastguard Worker * @param $o 418*890232f2SAndroid Build Coastguard Worker * @param $x 419*890232f2SAndroid Build Coastguard Worker * @param $d 420*890232f2SAndroid Build Coastguard Worker */ 421*890232f2SAndroid Build Coastguard Worker public function addByteX($o, $x, $d) 422*890232f2SAndroid Build Coastguard Worker { 423*890232f2SAndroid Build Coastguard Worker if ($this->force_defaults || $x != $d) { 424*890232f2SAndroid Build Coastguard Worker $this->addByte($x); 425*890232f2SAndroid Build Coastguard Worker $this->slot($o); 426*890232f2SAndroid Build Coastguard Worker } 427*890232f2SAndroid Build Coastguard Worker } 428*890232f2SAndroid Build Coastguard Worker 429*890232f2SAndroid Build Coastguard Worker /** 430*890232f2SAndroid Build Coastguard Worker * @param $o 431*890232f2SAndroid Build Coastguard Worker * @param $x 432*890232f2SAndroid Build Coastguard Worker * @param $d 433*890232f2SAndroid Build Coastguard Worker */ 434*890232f2SAndroid Build Coastguard Worker public function addSbyteX($o, $x, $d) 435*890232f2SAndroid Build Coastguard Worker { 436*890232f2SAndroid Build Coastguard Worker if ($this->force_defaults || $x != $d) { 437*890232f2SAndroid Build Coastguard Worker $this->addSbyte($x); 438*890232f2SAndroid Build Coastguard Worker $this->slot($o); 439*890232f2SAndroid Build Coastguard Worker } 440*890232f2SAndroid Build Coastguard Worker } 441*890232f2SAndroid Build Coastguard Worker 442*890232f2SAndroid Build Coastguard Worker /** 443*890232f2SAndroid Build Coastguard Worker * @param $o 444*890232f2SAndroid Build Coastguard Worker * @param $x 445*890232f2SAndroid Build Coastguard Worker * @param $d 446*890232f2SAndroid Build Coastguard Worker */ 447*890232f2SAndroid Build Coastguard Worker public function addShortX($o, $x, $d) 448*890232f2SAndroid Build Coastguard Worker { 449*890232f2SAndroid Build Coastguard Worker if ($this->force_defaults || $x != $d) { 450*890232f2SAndroid Build Coastguard Worker $this->addShort($x); 451*890232f2SAndroid Build Coastguard Worker $this->slot($o); 452*890232f2SAndroid Build Coastguard Worker } 453*890232f2SAndroid Build Coastguard Worker } 454*890232f2SAndroid Build Coastguard Worker 455*890232f2SAndroid Build Coastguard Worker /** 456*890232f2SAndroid Build Coastguard Worker * @param $o 457*890232f2SAndroid Build Coastguard Worker * @param $x 458*890232f2SAndroid Build Coastguard Worker * @param $d 459*890232f2SAndroid Build Coastguard Worker */ 460*890232f2SAndroid Build Coastguard Worker public function addUshortX($o, $x, $d) 461*890232f2SAndroid Build Coastguard Worker { 462*890232f2SAndroid Build Coastguard Worker if ($this->force_defaults || $x != $d) { 463*890232f2SAndroid Build Coastguard Worker $this->addUshort($x); 464*890232f2SAndroid Build Coastguard Worker $this->slot($o); 465*890232f2SAndroid Build Coastguard Worker } 466*890232f2SAndroid Build Coastguard Worker } 467*890232f2SAndroid Build Coastguard Worker 468*890232f2SAndroid Build Coastguard Worker /** 469*890232f2SAndroid Build Coastguard Worker * @param $o 470*890232f2SAndroid Build Coastguard Worker * @param $x 471*890232f2SAndroid Build Coastguard Worker * @param $d 472*890232f2SAndroid Build Coastguard Worker */ 473*890232f2SAndroid Build Coastguard Worker public function addIntX($o, $x, $d) 474*890232f2SAndroid Build Coastguard Worker { 475*890232f2SAndroid Build Coastguard Worker if ($this->force_defaults || $x != $d) { 476*890232f2SAndroid Build Coastguard Worker $this->addInt($x); 477*890232f2SAndroid Build Coastguard Worker $this->slot($o); 478*890232f2SAndroid Build Coastguard Worker } 479*890232f2SAndroid Build Coastguard Worker } 480*890232f2SAndroid Build Coastguard Worker 481*890232f2SAndroid Build Coastguard Worker /** 482*890232f2SAndroid Build Coastguard Worker * @param $o 483*890232f2SAndroid Build Coastguard Worker * @param $x 484*890232f2SAndroid Build Coastguard Worker * @param $d 485*890232f2SAndroid Build Coastguard Worker */ 486*890232f2SAndroid Build Coastguard Worker public function addUintX($o, $x, $d) 487*890232f2SAndroid Build Coastguard Worker { 488*890232f2SAndroid Build Coastguard Worker if ($this->force_defaults || $x != $d) { 489*890232f2SAndroid Build Coastguard Worker $this->addUint($x); 490*890232f2SAndroid Build Coastguard Worker $this->slot($o); 491*890232f2SAndroid Build Coastguard Worker } 492*890232f2SAndroid Build Coastguard Worker } 493*890232f2SAndroid Build Coastguard Worker 494*890232f2SAndroid Build Coastguard Worker /** 495*890232f2SAndroid Build Coastguard Worker * @param $o 496*890232f2SAndroid Build Coastguard Worker * @param $x 497*890232f2SAndroid Build Coastguard Worker * @param $d 498*890232f2SAndroid Build Coastguard Worker */ 499*890232f2SAndroid Build Coastguard Worker public function addLongX($o, $x, $d) 500*890232f2SAndroid Build Coastguard Worker { 501*890232f2SAndroid Build Coastguard Worker if ($this->force_defaults || $x != $d) { 502*890232f2SAndroid Build Coastguard Worker $this->addLong($x); 503*890232f2SAndroid Build Coastguard Worker $this->slot($o); 504*890232f2SAndroid Build Coastguard Worker } 505*890232f2SAndroid Build Coastguard Worker } 506*890232f2SAndroid Build Coastguard Worker 507*890232f2SAndroid Build Coastguard Worker /** 508*890232f2SAndroid Build Coastguard Worker * @param $o 509*890232f2SAndroid Build Coastguard Worker * @param $x 510*890232f2SAndroid Build Coastguard Worker * @param $d 511*890232f2SAndroid Build Coastguard Worker */ 512*890232f2SAndroid Build Coastguard Worker public function addUlongX($o, $x, $d) 513*890232f2SAndroid Build Coastguard Worker { 514*890232f2SAndroid Build Coastguard Worker if ($this->force_defaults || $x != $d) { 515*890232f2SAndroid Build Coastguard Worker $this->addUlong($x); 516*890232f2SAndroid Build Coastguard Worker $this->slot($o); 517*890232f2SAndroid Build Coastguard Worker } 518*890232f2SAndroid Build Coastguard Worker } 519*890232f2SAndroid Build Coastguard Worker 520*890232f2SAndroid Build Coastguard Worker 521*890232f2SAndroid Build Coastguard Worker /** 522*890232f2SAndroid Build Coastguard Worker * @param $o 523*890232f2SAndroid Build Coastguard Worker * @param $x 524*890232f2SAndroid Build Coastguard Worker * @param $d 525*890232f2SAndroid Build Coastguard Worker */ 526*890232f2SAndroid Build Coastguard Worker public function addFloatX($o, $x, $d) 527*890232f2SAndroid Build Coastguard Worker { 528*890232f2SAndroid Build Coastguard Worker if ($this->force_defaults || $x != $d) { 529*890232f2SAndroid Build Coastguard Worker $this->addFloat($x); 530*890232f2SAndroid Build Coastguard Worker $this->slot($o); 531*890232f2SAndroid Build Coastguard Worker } 532*890232f2SAndroid Build Coastguard Worker } 533*890232f2SAndroid Build Coastguard Worker 534*890232f2SAndroid Build Coastguard Worker /** 535*890232f2SAndroid Build Coastguard Worker * @param $o 536*890232f2SAndroid Build Coastguard Worker * @param $x 537*890232f2SAndroid Build Coastguard Worker * @param $d 538*890232f2SAndroid Build Coastguard Worker */ 539*890232f2SAndroid Build Coastguard Worker public function addDoubleX($o, $x, $d) 540*890232f2SAndroid Build Coastguard Worker { 541*890232f2SAndroid Build Coastguard Worker if ($this->force_defaults || $x != $d) { 542*890232f2SAndroid Build Coastguard Worker $this->addDouble($x); 543*890232f2SAndroid Build Coastguard Worker $this->slot($o); 544*890232f2SAndroid Build Coastguard Worker } 545*890232f2SAndroid Build Coastguard Worker } 546*890232f2SAndroid Build Coastguard Worker 547*890232f2SAndroid Build Coastguard Worker /** 548*890232f2SAndroid Build Coastguard Worker * @param $o 549*890232f2SAndroid Build Coastguard Worker * @param $x 550*890232f2SAndroid Build Coastguard Worker * @param $d 551*890232f2SAndroid Build Coastguard Worker * @throws \Exception 552*890232f2SAndroid Build Coastguard Worker */ 553*890232f2SAndroid Build Coastguard Worker public function addOffsetX($o, $x, $d) 554*890232f2SAndroid Build Coastguard Worker { 555*890232f2SAndroid Build Coastguard Worker if ($this->force_defaults || $x != $d) { 556*890232f2SAndroid Build Coastguard Worker $this->addOffset($x); 557*890232f2SAndroid Build Coastguard Worker $this->slot($o); 558*890232f2SAndroid Build Coastguard Worker } 559*890232f2SAndroid Build Coastguard Worker } 560*890232f2SAndroid Build Coastguard Worker /// @endcond 561*890232f2SAndroid Build Coastguard Worker 562*890232f2SAndroid Build Coastguard Worker /** 563*890232f2SAndroid Build Coastguard Worker * Adds on offset, relative to where it will be written. 564*890232f2SAndroid Build Coastguard Worker * @param $off The offset to add to the buffer. 565*890232f2SAndroid Build Coastguard Worker * @throws \Exception Throws an exception if `$off` is greater than the underlying ByteBuffer's 566*890232f2SAndroid Build Coastguard Worker * offest. 567*890232f2SAndroid Build Coastguard Worker */ 568*890232f2SAndroid Build Coastguard Worker public function addOffset($off) 569*890232f2SAndroid Build Coastguard Worker { 570*890232f2SAndroid Build Coastguard Worker $this->prep(Constants::SIZEOF_INT, 0); // Ensure alignment is already done 571*890232f2SAndroid Build Coastguard Worker if ($off > $this->offset()) { 572*890232f2SAndroid Build Coastguard Worker throw new \Exception(""); 573*890232f2SAndroid Build Coastguard Worker } 574*890232f2SAndroid Build Coastguard Worker $this->putOffset($off); 575*890232f2SAndroid Build Coastguard Worker } 576*890232f2SAndroid Build Coastguard Worker 577*890232f2SAndroid Build Coastguard Worker /// @cond FLATBUFFERS_INTERNAL 578*890232f2SAndroid Build Coastguard Worker /** 579*890232f2SAndroid Build Coastguard Worker * @param $elem_size 580*890232f2SAndroid Build Coastguard Worker * @param $num_elems 581*890232f2SAndroid Build Coastguard Worker * @param $alignment 582*890232f2SAndroid Build Coastguard Worker * @throws \Exception 583*890232f2SAndroid Build Coastguard Worker */ 584*890232f2SAndroid Build Coastguard Worker public function startVector($elem_size, $num_elems, $alignment) 585*890232f2SAndroid Build Coastguard Worker { 586*890232f2SAndroid Build Coastguard Worker $this->notNested(); 587*890232f2SAndroid Build Coastguard Worker $this->vector_num_elems = $num_elems; 588*890232f2SAndroid Build Coastguard Worker $this->prep(Constants::SIZEOF_INT, $elem_size * $num_elems); 589*890232f2SAndroid Build Coastguard Worker $this->prep($alignment, $elem_size * $num_elems); // Just in case alignemnt > int; 590*890232f2SAndroid Build Coastguard Worker } 591*890232f2SAndroid Build Coastguard Worker 592*890232f2SAndroid Build Coastguard Worker /** 593*890232f2SAndroid Build Coastguard Worker * @return int 594*890232f2SAndroid Build Coastguard Worker */ 595*890232f2SAndroid Build Coastguard Worker public function endVector() 596*890232f2SAndroid Build Coastguard Worker { 597*890232f2SAndroid Build Coastguard Worker $this->putUint($this->vector_num_elems); 598*890232f2SAndroid Build Coastguard Worker return $this->offset(); 599*890232f2SAndroid Build Coastguard Worker } 600*890232f2SAndroid Build Coastguard Worker 601*890232f2SAndroid Build Coastguard Worker protected function is_utf8($bytes) 602*890232f2SAndroid Build Coastguard Worker { 603*890232f2SAndroid Build Coastguard Worker if (function_exists('mb_detect_encoding')) { 604*890232f2SAndroid Build Coastguard Worker return (bool) mb_detect_encoding($bytes, 'UTF-8', true); 605*890232f2SAndroid Build Coastguard Worker } 606*890232f2SAndroid Build Coastguard Worker 607*890232f2SAndroid Build Coastguard Worker $len = strlen($bytes); 608*890232f2SAndroid Build Coastguard Worker if ($len < 1) { 609*890232f2SAndroid Build Coastguard Worker /* NOTE: always return 1 when passed string is null */ 610*890232f2SAndroid Build Coastguard Worker return true; 611*890232f2SAndroid Build Coastguard Worker } 612*890232f2SAndroid Build Coastguard Worker 613*890232f2SAndroid Build Coastguard Worker for ($j = 0, $i = 0; $i < $len; $i++) { 614*890232f2SAndroid Build Coastguard Worker // check ACII 615*890232f2SAndroid Build Coastguard Worker if ($bytes[$j] == "\x09" || 616*890232f2SAndroid Build Coastguard Worker $bytes[$j] == "\x0A" || 617*890232f2SAndroid Build Coastguard Worker $bytes[$j] == "\x0D" || 618*890232f2SAndroid Build Coastguard Worker ($bytes[$j] >= "\x20" && $bytes[$j] <= "\x7E")) { 619*890232f2SAndroid Build Coastguard Worker $j++; 620*890232f2SAndroid Build Coastguard Worker continue; 621*890232f2SAndroid Build Coastguard Worker } 622*890232f2SAndroid Build Coastguard Worker 623*890232f2SAndroid Build Coastguard Worker /* non-overlong 2-byte */ 624*890232f2SAndroid Build Coastguard Worker if ((($i+1) <= $len) && 625*890232f2SAndroid Build Coastguard Worker ($bytes[$j] >= "\xC2" && $bytes[$j] <= "\xDF" && 626*890232f2SAndroid Build Coastguard Worker ($bytes[$j+1] >= "\x80" && $bytes[$j+1] <= "\xBF"))) { 627*890232f2SAndroid Build Coastguard Worker $j += 2; 628*890232f2SAndroid Build Coastguard Worker $i++; 629*890232f2SAndroid Build Coastguard Worker continue; 630*890232f2SAndroid Build Coastguard Worker } 631*890232f2SAndroid Build Coastguard Worker 632*890232f2SAndroid Build Coastguard Worker /* excluding overlongs */ 633*890232f2SAndroid Build Coastguard Worker if ((($i + 2) <= $len) && 634*890232f2SAndroid Build Coastguard Worker $bytes[$j] == "\xE0" && 635*890232f2SAndroid Build Coastguard Worker ($bytes[$j+1] >= "\xA0" && $bytes[$j+1] <= "\xBF" && 636*890232f2SAndroid Build Coastguard Worker ($bytes[$j+2] >= "\x80" && $bytes[$j+2] <= "\xBF"))) { 637*890232f2SAndroid Build Coastguard Worker $bytes += 3; 638*890232f2SAndroid Build Coastguard Worker $i +=2; 639*890232f2SAndroid Build Coastguard Worker continue; 640*890232f2SAndroid Build Coastguard Worker } 641*890232f2SAndroid Build Coastguard Worker 642*890232f2SAndroid Build Coastguard Worker /* straight 3-byte */ 643*890232f2SAndroid Build Coastguard Worker if ((($i+2) <= $len) && 644*890232f2SAndroid Build Coastguard Worker (($bytes[$j] >= "\xE1" && $bytes[$j] <= "\xEC") || 645*890232f2SAndroid Build Coastguard Worker $bytes[$j] == "\xEE" || 646*890232f2SAndroid Build Coastguard Worker $bytes[$j] = "\xEF") && 647*890232f2SAndroid Build Coastguard Worker ($bytes[$j+1] >= "\x80" && $bytes[$j+1] <= "\xBF") && 648*890232f2SAndroid Build Coastguard Worker ($bytes[$j+2] >= "\x80" && $bytes[$j+2] <= "\xBF")) { 649*890232f2SAndroid Build Coastguard Worker $j += 3; 650*890232f2SAndroid Build Coastguard Worker $i += 2; 651*890232f2SAndroid Build Coastguard Worker continue; 652*890232f2SAndroid Build Coastguard Worker } 653*890232f2SAndroid Build Coastguard Worker 654*890232f2SAndroid Build Coastguard Worker /* excluding surrogates */ 655*890232f2SAndroid Build Coastguard Worker if ((($i+2) <= $len) && 656*890232f2SAndroid Build Coastguard Worker $bytes[$j] == "\xED" && 657*890232f2SAndroid Build Coastguard Worker ($bytes[$j+1] >= "\x80" && $bytes[$j+1] <= "\x9f" && 658*890232f2SAndroid Build Coastguard Worker ($bytes[$j+2] >= "\x80" && $bytes[$j+2] <= "\xBF"))) { 659*890232f2SAndroid Build Coastguard Worker $j += 3; 660*890232f2SAndroid Build Coastguard Worker $i += 2; 661*890232f2SAndroid Build Coastguard Worker continue; 662*890232f2SAndroid Build Coastguard Worker } 663*890232f2SAndroid Build Coastguard Worker 664*890232f2SAndroid Build Coastguard Worker /* planes 1-3 */ 665*890232f2SAndroid Build Coastguard Worker if ((($i + 3) <= $len) && 666*890232f2SAndroid Build Coastguard Worker $bytes[$j] == "\xF0" && 667*890232f2SAndroid Build Coastguard Worker ($bytes[$j+1] >= "\x90" && $bytes[$j+1] <= "\xBF") && 668*890232f2SAndroid Build Coastguard Worker ($bytes[$j+2] >= "\x80" && $bytes[$j+2] <= "\xBF") && 669*890232f2SAndroid Build Coastguard Worker ($bytes[$j+3] >= "\x80" && $bytes[$j+3] <= "\xBF")) { 670*890232f2SAndroid Build Coastguard Worker $j += 4; 671*890232f2SAndroid Build Coastguard Worker $i += 3; 672*890232f2SAndroid Build Coastguard Worker continue; 673*890232f2SAndroid Build Coastguard Worker } 674*890232f2SAndroid Build Coastguard Worker 675*890232f2SAndroid Build Coastguard Worker 676*890232f2SAndroid Build Coastguard Worker /* planes 4-15 */ 677*890232f2SAndroid Build Coastguard Worker if ((($i+3) <= $len) && 678*890232f2SAndroid Build Coastguard Worker $bytes[$j] >= "\xF1" && $bytes[$j] <= "\xF3" && 679*890232f2SAndroid Build Coastguard Worker $bytes[$j+1] >= "\x80" && $bytes[$j+1] <= "\xBF" && 680*890232f2SAndroid Build Coastguard Worker $bytes[$j+2] >= "\x80" && $bytes[$j+2] <= "\xBF" && 681*890232f2SAndroid Build Coastguard Worker $bytes[$j+3] >= "\x80" && $bytes[$j+3] <= "\xBF" 682*890232f2SAndroid Build Coastguard Worker ) { 683*890232f2SAndroid Build Coastguard Worker $j += 4; 684*890232f2SAndroid Build Coastguard Worker $i += 3; 685*890232f2SAndroid Build Coastguard Worker continue; 686*890232f2SAndroid Build Coastguard Worker } 687*890232f2SAndroid Build Coastguard Worker 688*890232f2SAndroid Build Coastguard Worker /* plane 16 */ 689*890232f2SAndroid Build Coastguard Worker if ((($i+3) <= $len) && 690*890232f2SAndroid Build Coastguard Worker $bytes[$j] == "\xF4" && 691*890232f2SAndroid Build Coastguard Worker ($bytes[$j+1] >= "\x80" && $bytes[$j+1] <= "\x8F") && 692*890232f2SAndroid Build Coastguard Worker ($bytes[$j+2] >= "\x80" && $bytes[$j+2] <= "\xBF") && 693*890232f2SAndroid Build Coastguard Worker ($bytes[$j+3] >= "\x80" && $bytes[$j+3] <= "\xBF") 694*890232f2SAndroid Build Coastguard Worker ) { 695*890232f2SAndroid Build Coastguard Worker $bytes += 4; 696*890232f2SAndroid Build Coastguard Worker $i += 3; 697*890232f2SAndroid Build Coastguard Worker continue; 698*890232f2SAndroid Build Coastguard Worker } 699*890232f2SAndroid Build Coastguard Worker 700*890232f2SAndroid Build Coastguard Worker 701*890232f2SAndroid Build Coastguard Worker return false; 702*890232f2SAndroid Build Coastguard Worker } 703*890232f2SAndroid Build Coastguard Worker 704*890232f2SAndroid Build Coastguard Worker return true; 705*890232f2SAndroid Build Coastguard Worker } 706*890232f2SAndroid Build Coastguard Worker /// @endcond 707*890232f2SAndroid Build Coastguard Worker 708*890232f2SAndroid Build Coastguard Worker /** 709*890232f2SAndroid Build Coastguard Worker * Encode the string `$s` in the buffer using UTF-8. 710*890232f2SAndroid Build Coastguard Worker * @param string $s The string to encode. 711*890232f2SAndroid Build Coastguard Worker * @return int The offset in the buffer where the encoded string starts. 712*890232f2SAndroid Build Coastguard Worker * @throws InvalidArgumentException Thrown if the input string `$s` is not 713*890232f2SAndroid Build Coastguard Worker * UTF-8. 714*890232f2SAndroid Build Coastguard Worker */ 715*890232f2SAndroid Build Coastguard Worker public function createString($s) 716*890232f2SAndroid Build Coastguard Worker { 717*890232f2SAndroid Build Coastguard Worker if (!$this->is_utf8($s)) { 718*890232f2SAndroid Build Coastguard Worker throw new \InvalidArgumentException("string must be utf-8 encoded value."); 719*890232f2SAndroid Build Coastguard Worker } 720*890232f2SAndroid Build Coastguard Worker 721*890232f2SAndroid Build Coastguard Worker $this->notNested(); 722*890232f2SAndroid Build Coastguard Worker $this->addByte(0); // null terminated 723*890232f2SAndroid Build Coastguard Worker $this->startVector(1, strlen($s), 1); 724*890232f2SAndroid Build Coastguard Worker $this->space -= strlen($s); 725*890232f2SAndroid Build Coastguard Worker for ($i = $this->space, $j = 0 ; $j < strlen($s) ; $i++, $j++) { 726*890232f2SAndroid Build Coastguard Worker $this->bb->_buffer[$i] = $s[$j]; 727*890232f2SAndroid Build Coastguard Worker } 728*890232f2SAndroid Build Coastguard Worker return $this->endVector(); 729*890232f2SAndroid Build Coastguard Worker } 730*890232f2SAndroid Build Coastguard Worker 731*890232f2SAndroid Build Coastguard Worker /// @cond FLATBUFFERS_INTERNAL 732*890232f2SAndroid Build Coastguard Worker /** 733*890232f2SAndroid Build Coastguard Worker * @throws \Exception 734*890232f2SAndroid Build Coastguard Worker */ 735*890232f2SAndroid Build Coastguard Worker public function notNested() 736*890232f2SAndroid Build Coastguard Worker { 737*890232f2SAndroid Build Coastguard Worker if ($this->nested) { 738*890232f2SAndroid Build Coastguard Worker throw new \Exception("FlatBuffers; object serialization must not be nested"); 739*890232f2SAndroid Build Coastguard Worker } 740*890232f2SAndroid Build Coastguard Worker } 741*890232f2SAndroid Build Coastguard Worker 742*890232f2SAndroid Build Coastguard Worker /** 743*890232f2SAndroid Build Coastguard Worker * @param $obj 744*890232f2SAndroid Build Coastguard Worker * @throws \Exception 745*890232f2SAndroid Build Coastguard Worker */ 746*890232f2SAndroid Build Coastguard Worker public function nested($obj) 747*890232f2SAndroid Build Coastguard Worker { 748*890232f2SAndroid Build Coastguard Worker if ($obj != $this->offset()) { 749*890232f2SAndroid Build Coastguard Worker throw new \Exception("FlatBuffers: struct must be serialized inline"); 750*890232f2SAndroid Build Coastguard Worker } 751*890232f2SAndroid Build Coastguard Worker } 752*890232f2SAndroid Build Coastguard Worker 753*890232f2SAndroid Build Coastguard Worker /** 754*890232f2SAndroid Build Coastguard Worker * @param $numfields 755*890232f2SAndroid Build Coastguard Worker * @throws \Exception 756*890232f2SAndroid Build Coastguard Worker */ 757*890232f2SAndroid Build Coastguard Worker public function startObject($numfields) 758*890232f2SAndroid Build Coastguard Worker { 759*890232f2SAndroid Build Coastguard Worker $this->notNested(); 760*890232f2SAndroid Build Coastguard Worker if ($this->vtable == null || count($this->vtable) < $numfields) { 761*890232f2SAndroid Build Coastguard Worker $this->vtable = array(); 762*890232f2SAndroid Build Coastguard Worker } 763*890232f2SAndroid Build Coastguard Worker 764*890232f2SAndroid Build Coastguard Worker $this->vtable_in_use = $numfields; 765*890232f2SAndroid Build Coastguard Worker for ($i = 0; $i < $numfields; $i++) { 766*890232f2SAndroid Build Coastguard Worker $this->vtable[$i] = 0; 767*890232f2SAndroid Build Coastguard Worker } 768*890232f2SAndroid Build Coastguard Worker 769*890232f2SAndroid Build Coastguard Worker $this->nested = true; 770*890232f2SAndroid Build Coastguard Worker $this->object_start = $this->offset(); 771*890232f2SAndroid Build Coastguard Worker } 772*890232f2SAndroid Build Coastguard Worker 773*890232f2SAndroid Build Coastguard Worker /** 774*890232f2SAndroid Build Coastguard Worker * @param $voffset 775*890232f2SAndroid Build Coastguard Worker * @param $x 776*890232f2SAndroid Build Coastguard Worker * @param $d 777*890232f2SAndroid Build Coastguard Worker * @throws \Exception 778*890232f2SAndroid Build Coastguard Worker */ 779*890232f2SAndroid Build Coastguard Worker public function addStructX($voffset, $x, $d) 780*890232f2SAndroid Build Coastguard Worker { 781*890232f2SAndroid Build Coastguard Worker if ($x != $d) { 782*890232f2SAndroid Build Coastguard Worker $this->nested($x); 783*890232f2SAndroid Build Coastguard Worker $this->slot($voffset); 784*890232f2SAndroid Build Coastguard Worker } 785*890232f2SAndroid Build Coastguard Worker } 786*890232f2SAndroid Build Coastguard Worker 787*890232f2SAndroid Build Coastguard Worker /** 788*890232f2SAndroid Build Coastguard Worker * @param $voffset 789*890232f2SAndroid Build Coastguard Worker * @param $x 790*890232f2SAndroid Build Coastguard Worker * @param $d 791*890232f2SAndroid Build Coastguard Worker * @throws \Exception 792*890232f2SAndroid Build Coastguard Worker */ 793*890232f2SAndroid Build Coastguard Worker public function addStruct($voffset, $x, $d) 794*890232f2SAndroid Build Coastguard Worker { 795*890232f2SAndroid Build Coastguard Worker if ($x != $d) { 796*890232f2SAndroid Build Coastguard Worker $this->nested($x); 797*890232f2SAndroid Build Coastguard Worker $this->slot($voffset); 798*890232f2SAndroid Build Coastguard Worker } 799*890232f2SAndroid Build Coastguard Worker } 800*890232f2SAndroid Build Coastguard Worker 801*890232f2SAndroid Build Coastguard Worker /** 802*890232f2SAndroid Build Coastguard Worker * @param $voffset 803*890232f2SAndroid Build Coastguard Worker */ 804*890232f2SAndroid Build Coastguard Worker public function slot($voffset) 805*890232f2SAndroid Build Coastguard Worker { 806*890232f2SAndroid Build Coastguard Worker $this->vtable[$voffset] = $this->offset(); 807*890232f2SAndroid Build Coastguard Worker } 808*890232f2SAndroid Build Coastguard Worker 809*890232f2SAndroid Build Coastguard Worker /** 810*890232f2SAndroid Build Coastguard Worker * @return int 811*890232f2SAndroid Build Coastguard Worker * @throws \Exception 812*890232f2SAndroid Build Coastguard Worker */ 813*890232f2SAndroid Build Coastguard Worker public function endObject() 814*890232f2SAndroid Build Coastguard Worker { 815*890232f2SAndroid Build Coastguard Worker if ($this->vtable == null || !$this->nested) { 816*890232f2SAndroid Build Coastguard Worker throw new \Exception("FlatBuffers: endObject called without startObject"); 817*890232f2SAndroid Build Coastguard Worker } 818*890232f2SAndroid Build Coastguard Worker 819*890232f2SAndroid Build Coastguard Worker $this->addInt(0); 820*890232f2SAndroid Build Coastguard Worker $vtableloc = $this->offset(); 821*890232f2SAndroid Build Coastguard Worker 822*890232f2SAndroid Build Coastguard Worker $i = $this->vtable_in_use -1; 823*890232f2SAndroid Build Coastguard Worker // Trim trailing zeroes. 824*890232f2SAndroid Build Coastguard Worker for (; $i >= 0 && $this->vtable[$i] == 0; $i--) {} 825*890232f2SAndroid Build Coastguard Worker $trimmed_size = $i + 1; 826*890232f2SAndroid Build Coastguard Worker for (; $i >= 0; $i--) { 827*890232f2SAndroid Build Coastguard Worker $off = ($this->vtable[$i] != 0) ? $vtableloc - $this->vtable[$i] : 0; 828*890232f2SAndroid Build Coastguard Worker $this->addShort($off); 829*890232f2SAndroid Build Coastguard Worker } 830*890232f2SAndroid Build Coastguard Worker 831*890232f2SAndroid Build Coastguard Worker $standard_fields = 2; // the fields below 832*890232f2SAndroid Build Coastguard Worker $this->addShort($vtableloc - $this->object_start); 833*890232f2SAndroid Build Coastguard Worker $this->addShort(($trimmed_size + $standard_fields) * Constants::SIZEOF_SHORT); 834*890232f2SAndroid Build Coastguard Worker 835*890232f2SAndroid Build Coastguard Worker // search for an existing vtable that matches the current one. 836*890232f2SAndroid Build Coastguard Worker $existing_vtable = 0; 837*890232f2SAndroid Build Coastguard Worker 838*890232f2SAndroid Build Coastguard Worker for ($i = 0; $i < $this->num_vtables; $i++) { 839*890232f2SAndroid Build Coastguard Worker $vt1 = $this->bb->capacity() - $this->vtables[$i]; 840*890232f2SAndroid Build Coastguard Worker $vt2 = $this->space; 841*890232f2SAndroid Build Coastguard Worker 842*890232f2SAndroid Build Coastguard Worker $len = $this->bb->getShort($vt1); 843*890232f2SAndroid Build Coastguard Worker 844*890232f2SAndroid Build Coastguard Worker if ($len == $this->bb->getShort($vt2)) { 845*890232f2SAndroid Build Coastguard Worker for ($j = Constants::SIZEOF_SHORT; $j < $len; $j += Constants::SIZEOF_SHORT) { 846*890232f2SAndroid Build Coastguard Worker if ($this->bb->getShort($vt1 + $j) != $this->bb->getShort($vt2 + $j)) { 847*890232f2SAndroid Build Coastguard Worker continue 2; 848*890232f2SAndroid Build Coastguard Worker } 849*890232f2SAndroid Build Coastguard Worker } 850*890232f2SAndroid Build Coastguard Worker $existing_vtable = $this->vtables[$i]; 851*890232f2SAndroid Build Coastguard Worker break; 852*890232f2SAndroid Build Coastguard Worker } 853*890232f2SAndroid Build Coastguard Worker } 854*890232f2SAndroid Build Coastguard Worker 855*890232f2SAndroid Build Coastguard Worker if ($existing_vtable != 0) { 856*890232f2SAndroid Build Coastguard Worker // Found a match: 857*890232f2SAndroid Build Coastguard Worker // Remove the current vtable 858*890232f2SAndroid Build Coastguard Worker $this->space = $this->bb->capacity() - $vtableloc; 859*890232f2SAndroid Build Coastguard Worker $this->bb->putInt($this->space, $existing_vtable - $vtableloc); 860*890232f2SAndroid Build Coastguard Worker } else { 861*890232f2SAndroid Build Coastguard Worker // No Match: 862*890232f2SAndroid Build Coastguard Worker // Add the location of the current vtable to the list of vtables 863*890232f2SAndroid Build Coastguard Worker if ($this->num_vtables == count($this->vtables)) { 864*890232f2SAndroid Build Coastguard Worker $vtables = $this->vtables; 865*890232f2SAndroid Build Coastguard Worker $this->vtables = array(); 866*890232f2SAndroid Build Coastguard Worker // copy of 867*890232f2SAndroid Build Coastguard Worker for ($i = 0; $i < count($vtables) * 2; $i++) { 868*890232f2SAndroid Build Coastguard Worker $this->vtables[$i] = ($i < count($vtables)) ? $vtables[$i] : 0; 869*890232f2SAndroid Build Coastguard Worker } 870*890232f2SAndroid Build Coastguard Worker } 871*890232f2SAndroid Build Coastguard Worker $this->vtables[$this->num_vtables++] = $this->offset(); 872*890232f2SAndroid Build Coastguard Worker $this->bb->putInt($this->bb->capacity() - $vtableloc, $this->offset() - $vtableloc); 873*890232f2SAndroid Build Coastguard Worker } 874*890232f2SAndroid Build Coastguard Worker 875*890232f2SAndroid Build Coastguard Worker $this->nested = false; 876*890232f2SAndroid Build Coastguard Worker $this->vtable = null; 877*890232f2SAndroid Build Coastguard Worker return $vtableloc; 878*890232f2SAndroid Build Coastguard Worker } 879*890232f2SAndroid Build Coastguard Worker 880*890232f2SAndroid Build Coastguard Worker /** 881*890232f2SAndroid Build Coastguard Worker * @param $table 882*890232f2SAndroid Build Coastguard Worker * @param $field 883*890232f2SAndroid Build Coastguard Worker * @throws \Exception 884*890232f2SAndroid Build Coastguard Worker */ 885*890232f2SAndroid Build Coastguard Worker public function required($table, $field) 886*890232f2SAndroid Build Coastguard Worker { 887*890232f2SAndroid Build Coastguard Worker $table_start = $this->bb->capacity() - $table; 888*890232f2SAndroid Build Coastguard Worker $vtable_start = $table_start - $this->bb->getInt($table_start); 889*890232f2SAndroid Build Coastguard Worker $ok = $this->bb->getShort($vtable_start + $field) != 0; 890*890232f2SAndroid Build Coastguard Worker 891*890232f2SAndroid Build Coastguard Worker if (!$ok) { 892*890232f2SAndroid Build Coastguard Worker throw new \Exception("FlatBuffers: field " . $field . " must be set"); 893*890232f2SAndroid Build Coastguard Worker } 894*890232f2SAndroid Build Coastguard Worker } 895*890232f2SAndroid Build Coastguard Worker /// @endcond 896*890232f2SAndroid Build Coastguard Worker 897*890232f2SAndroid Build Coastguard Worker /** 898*890232f2SAndroid Build Coastguard Worker * Finalize a buffer, pointing to the given `$root_table`. 899*890232f2SAndroid Build Coastguard Worker * @param $root_table An offest to be added to the buffer. 900*890232f2SAndroid Build Coastguard Worker * @param $file_identifier A FlatBuffer file identifier to be added to the 901*890232f2SAndroid Build Coastguard Worker * buffer before `$root_table`. This defaults to `null`. 902*890232f2SAndroid Build Coastguard Worker * @throws InvalidArgumentException Thrown if an invalid `$identifier` is 903*890232f2SAndroid Build Coastguard Worker * given, where its length is not equal to 904*890232f2SAndroid Build Coastguard Worker * `Constants::FILE_IDENTIFIER_LENGTH`. 905*890232f2SAndroid Build Coastguard Worker */ 906*890232f2SAndroid Build Coastguard Worker public function finish($root_table, $identifier = null) 907*890232f2SAndroid Build Coastguard Worker { 908*890232f2SAndroid Build Coastguard Worker if ($identifier == null) { 909*890232f2SAndroid Build Coastguard Worker $this->prep($this->minalign, Constants::SIZEOF_INT); 910*890232f2SAndroid Build Coastguard Worker $this->addOffset($root_table); 911*890232f2SAndroid Build Coastguard Worker $this->bb->setPosition($this->space); 912*890232f2SAndroid Build Coastguard Worker } else { 913*890232f2SAndroid Build Coastguard Worker $this->prep($this->minalign, Constants::SIZEOF_INT + Constants::FILE_IDENTIFIER_LENGTH); 914*890232f2SAndroid Build Coastguard Worker if (strlen($identifier) != Constants::FILE_IDENTIFIER_LENGTH) { 915*890232f2SAndroid Build Coastguard Worker throw new \InvalidArgumentException( 916*890232f2SAndroid Build Coastguard Worker sprintf("FlatBuffers: file identifier must be length %d", 917*890232f2SAndroid Build Coastguard Worker Constants::FILE_IDENTIFIER_LENGTH)); 918*890232f2SAndroid Build Coastguard Worker } 919*890232f2SAndroid Build Coastguard Worker 920*890232f2SAndroid Build Coastguard Worker for ($i = Constants::FILE_IDENTIFIER_LENGTH - 1; $i >= 0; 921*890232f2SAndroid Build Coastguard Worker $i--) { 922*890232f2SAndroid Build Coastguard Worker $this->addByte(ord($identifier[$i])); 923*890232f2SAndroid Build Coastguard Worker } 924*890232f2SAndroid Build Coastguard Worker $this->finish($root_table); 925*890232f2SAndroid Build Coastguard Worker } 926*890232f2SAndroid Build Coastguard Worker } 927*890232f2SAndroid Build Coastguard Worker 928*890232f2SAndroid Build Coastguard Worker /** 929*890232f2SAndroid Build Coastguard Worker * In order to save space, fields that are set to their default value don't 930*890232f2SAndroid Build Coastguard Worker * get serialized into the buffer. 931*890232f2SAndroid Build Coastguard Worker * @param bool $forceDefaults When set to `true`, always serializes default 932*890232f2SAndroid Build Coastguard Worker * values. 933*890232f2SAndroid Build Coastguard Worker */ 934*890232f2SAndroid Build Coastguard Worker public function forceDefaults($forceDefaults) 935*890232f2SAndroid Build Coastguard Worker { 936*890232f2SAndroid Build Coastguard Worker $this->force_defaults = $forceDefaults; 937*890232f2SAndroid Build Coastguard Worker } 938*890232f2SAndroid Build Coastguard Worker 939*890232f2SAndroid Build Coastguard Worker /** 940*890232f2SAndroid Build Coastguard Worker * Get the ByteBuffer representing the FlatBuffer. 941*890232f2SAndroid Build Coastguard Worker * @return ByteBuffer The ByteBuffer containing the FlatBuffer data. 942*890232f2SAndroid Build Coastguard Worker */ 943*890232f2SAndroid Build Coastguard Worker public function dataBuffer() 944*890232f2SAndroid Build Coastguard Worker { 945*890232f2SAndroid Build Coastguard Worker return $this->bb; 946*890232f2SAndroid Build Coastguard Worker } 947*890232f2SAndroid Build Coastguard Worker 948*890232f2SAndroid Build Coastguard Worker /// @cond FLATBUFFERS_INTERNAL 949*890232f2SAndroid Build Coastguard Worker /** 950*890232f2SAndroid Build Coastguard Worker * @return int 951*890232f2SAndroid Build Coastguard Worker */ 952*890232f2SAndroid Build Coastguard Worker public function dataStart() 953*890232f2SAndroid Build Coastguard Worker { 954*890232f2SAndroid Build Coastguard Worker return $this->space; 955*890232f2SAndroid Build Coastguard Worker } 956*890232f2SAndroid Build Coastguard Worker /// @endcond 957*890232f2SAndroid Build Coastguard Worker 958*890232f2SAndroid Build Coastguard Worker /** 959*890232f2SAndroid Build Coastguard Worker * Utility function to copy and return the FlatBuffer data from the 960*890232f2SAndroid Build Coastguard Worker * underlying ByteBuffer. 961*890232f2SAndroid Build Coastguard Worker * @return string A string (representing a byte[]) that contains a copy 962*890232f2SAndroid Build Coastguard Worker * of the FlatBuffer data. 963*890232f2SAndroid Build Coastguard Worker */ 964*890232f2SAndroid Build Coastguard Worker public function sizedByteArray() 965*890232f2SAndroid Build Coastguard Worker { 966*890232f2SAndroid Build Coastguard Worker $start = $this->space; 967*890232f2SAndroid Build Coastguard Worker $length = $this->bb->capacity() - $this->space; 968*890232f2SAndroid Build Coastguard Worker 969*890232f2SAndroid Build Coastguard Worker $result = str_repeat("\0", $length); 970*890232f2SAndroid Build Coastguard Worker $this->bb->setPosition($start); 971*890232f2SAndroid Build Coastguard Worker $this->bb->getX($result); 972*890232f2SAndroid Build Coastguard Worker 973*890232f2SAndroid Build Coastguard Worker return $result; 974*890232f2SAndroid Build Coastguard Worker } 975*890232f2SAndroid Build Coastguard Worker} 976*890232f2SAndroid Build Coastguard Worker 977*890232f2SAndroid Build Coastguard Worker/// @} 978