1<?php
2// manual load for testing. please use PSR style autoloader when you use flatbuffers.
3require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Constants.php"));
4require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "ByteBuffer.php"));
5require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "FlatbufferBuilder.php"));
6require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Table.php"));
7require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Struct.php"));
8foreach (glob(join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "MyGame", "Example", "*.php"))) as $file) {
9    require $file;
10}
11
12function main()
13{
14    /// Begin Test
15    $assert = new Assert();
16
17    // First, let's test reading a FlatBuffer generated by C++ code:
18    // This file was generated from monsterdata_test.json
19
20    // Now test it:
21    $data = file_get_contents('monsterdata_test.mon');
22    $bb = Google\FlatBuffers\ByteBuffer::wrap($data);
23    test_buffer($assert, $bb);
24
25    // Second, let's create a FlatBuffer from scratch in JavaScript, and test it also.
26    // We use an initial size of 1 to exercise the reallocation algorithm,
27    // normally a size larger than the typical FlatBuffer you generate would be
28    // better for performance.
29    $fbb = new Google\FlatBuffers\FlatBufferBuilder(1);
30
31    // We set up the same values as monsterdata.json:
32    $str = $fbb->createString("MyMonster");
33    $name = $fbb->createString('Fred');
34    \MyGame\Example\Monster::startMonster($fbb);
35    \MyGame\Example\Monster::addName($fbb, $name);
36    $enemy = \MyGame\Example\Monster::endMonster($fbb);
37
38    $inv = \MyGame\Example\Monster::CreateInventoryVector($fbb, array(0, 1, 2, 3, 4));
39
40    $fred = $fbb->createString('Fred');
41    \MyGame\Example\Monster::StartMonster($fbb);
42    \MyGame\Example\Monster::AddName($fbb, $fred);
43    $mon2 = \MyGame\Example\Monster::EndMonster($fbb);
44
45    \MyGame\Example\Monster::StartTest4Vector($fbb, 2);
46    \MyGame\Example\Test::CreateTest($fbb, 10, 20);
47    \MyGame\Example\Test::CreateTest($fbb, 30, 40);
48    $test4 = $fbb->endVector();
49
50    $testArrayOfString = \MyGame\Example\Monster::CreateTestarrayofstringVector($fbb, array(
51        $fbb->createString('test1'),
52        $fbb->createString('test2')
53    ));
54
55    \MyGame\Example\Monster::StartMonster($fbb);
56    \MyGame\Example\Monster::AddPos($fbb, \MyGame\Example\Vec3::CreateVec3($fbb,
57        1.0, 2.0, 3.0, //float
58        3.0, // double
59        \MyGame\Example\Color::Green,
60        5, //short
61        6));
62    \MyGame\Example\Monster::AddHp($fbb, 80);
63    \MyGame\Example\Monster::AddName($fbb, $str);
64    \MyGame\Example\Monster::AddInventory($fbb, $inv);
65    \MyGame\Example\Monster::AddTestType($fbb, \MyGame\Example\Any::Monster);
66    \MyGame\Example\Monster::AddTest($fbb, $mon2);
67    \MyGame\Example\Monster::AddTest4($fbb, $test4);
68    \MyGame\Example\Monster::AddTestarrayofstring($fbb, $testArrayOfString);
69    \MyGame\Example\Monster::AddEnemy($fbb, $enemy);
70    \MyGame\Example\Monster::AddTestbool($fbb, true);
71    $mon = \MyGame\Example\Monster::EndMonster($fbb);
72
73    \MyGame\Example\Monster::FinishMonsterBuffer($fbb, $mon);
74
75    // Test it:
76    test_buffer($assert, $fbb->dataBuffer());
77
78    testByteBuffer($assert);
79    fuzzTest1($assert);
80//    testUnicode($assert);
81
82    echo 'FlatBuffers php test: completed successfully' . PHP_EOL;
83}
84
85try {
86    main();
87    exit(0);
88} catch(Exception $e) {
89    printf("Fatal error: Uncaught exception '%s' with message '%s. in %s:%d\n", get_class($e), $e->getMessage(), $e->getFile(), $e->getLine());
90    printf("Stack trace:\n");
91    echo $e->getTraceAsString() . PHP_EOL;
92    printf("  thrown in in %s:%d\n", $e->getFile(), $e->getLine());
93
94    die(-1);
95}
96
97function test_buffer(Assert $assert, Google\FlatBuffers\ByteBuffer $bb) {
98
99    $assert->ok(MyGame\Example\Monster::MonsterBufferHasIdentifier($bb));
100    $monster = \MyGame\Example\Monster::GetRootAsMonster($bb);
101
102    $assert->strictEqual($monster->GetHp(), 80);
103    $assert->strictEqual($monster->GetMana(), 150); // default
104
105    $assert->strictEqual($monster->GetName(), 'MyMonster');
106
107    $pos = $monster->GetPos();
108    $assert->strictEqual($pos->GetX(), 1.0);
109    $assert->strictEqual($pos->GetY(), 2.0);
110    $assert->strictEqual($pos->GetZ(), 3.0);
111
112    $assert->Equal($pos->GetTest1(), 3.0);
113    $assert->strictEqual($pos->GetTest2(), \MyGame\Example\Color::Green);
114
115    $t = $pos->GetTest3();
116    $assert->strictEqual($t->GetA(), 5);
117    $assert->strictEqual($t->GetB(), 6);
118    $assert->strictEqual($monster->GetTestType(), \MyGame\Example\Any::Monster);
119
120    $monster2 = new \MyGame\Example\Monster();
121    $assert->strictEqual($monster->GetTest($monster2) != null, true);
122    $assert->strictEqual($monster2->GetName(), 'Fred');
123
124    $assert->strictEqual($monster->GetInventoryLength(), 5);
125    $invsum = 0;
126    for ($i = 0; $i < $monster->GetInventoryLength(); $i++) {
127        $invsum += $monster->GetInventory($i);
128    }
129    $assert->strictEqual($invsum, 10);
130
131    $assert->strictEqual(bin2hex($monster->GetInventoryBytes()), "0001020304");
132
133    $test_0 = $monster->GetTest4(0);
134    $test_1 = $monster->GetTest4(1);
135    $assert->strictEqual($monster->GetTest4Length(), 2);
136    $assert->strictEqual($test_0->GetA() + $test_0->GetB() + $test_1->GetA() + $test_1->GetB(), 100);
137
138    $assert->strictEqual($monster->GetTestarrayofstringLength(), 2);
139    $assert->strictEqual($monster->GetTestarrayofstring(0), 'test1');
140    $assert->strictEqual($monster->GetTestarrayofstring(1), 'test2');
141
142    $fred = $monster->getEnemy();
143    $assert->Equal('Fred', $fred->getName());
144
145    $assert->strictEqual($monster->GetTestbool(), true);
146}
147
148//function testUnicode(Assert $assert) {
149//    // missing unicode_test.mon, implemented later
150//    $correct = file_get_contents('unicode_test.mon');
151//    $json = json_decode(file_get_contents('unicode_test.json'));
152//
153//    // Test reading
154//    $bb = flatbuffers\ByteBuffer::Wrap($correct);
155//    $monster = \MyGame\Example\Monster::GetRootAsMonster($bb);
156//    $assert->strictEqual($monster->GetName(), $json["name"]);
157//
158//    //$assert->deepEqual(new Buffer(monster.name(flatbuffers.Encoding.UTF8_BYTES)), new Buffer(json.name));
159//    //assert.strictEqual(monster.testarrayoftablesLength(), json.testarrayoftables.length);
160//    foreach ($json["testarrayoftables"]as $i => $table) {
161//        $value = $monster->GetTestArrayOfTables($i);
162//        $assert->strictEqual($value->GetName(), $table["name"]);
163//        //assert.deepEqual(new Buffer(value.name(flatbuffers.Encoding.UTF8_BYTES)), new Buffer(table.name));
164//    }
165//    $assert->strictEqual($monster->GetTestarrayofstringLength(), $json["testarrayofstring"]["length"]);
166//    foreach ($json["testarrayofstring"] as $i => $string) {
167//        $assert->strictEqual($monster->GetTestarrayofstring($i), $string);
168//        //assert.deepEqual(new Buffer(monster.testarrayofstring(i, flatbuffers.Encoding.UTF8_BYTES)), new Buffer(string));
169//    }
170//
171//    // Test writing
172//    $fbb = new FlatBuffers\FlatBufferBuilder(1);
173//    $name = $fbb->CreateString($json["name"]);
174//    $testarrayoftablesOffsets = array_map(function($table) use($fbb) {
175//        $name = $fbb->CreateString($table["name"]);
176//        \MyGame\Example\Monster::StartMonster($fbb);
177//        \MyGame\Example\Monster::AddName($fbb, $name);
178//        return \MyGame\Example\Monster::EndMonster($fbb);
179//    }, $json["testarrayoftables"]);
180//    $testarrayoftablesOffset = \MyGame\Example\Monster::CreateTestarrayoftablesVector($fbb,
181//            $testarrayoftablesOffsets);
182////    $testarrayofstringOffset = \MyGame\Example\Monster::CreateTestarrayofstringVector($fbb,
183////            $json["testarrayofstring"].map(function(string) { return fbb.createString(string); }));
184//
185//    \MyGame\Example\Monster::startMonster($fbb);
186//    \MyGame\Example\Monster::addTestarrayofstring($fbb, $testarrayoftablesOffset);
187//    \MyGame\Example\Monster::addTestarrayoftables($fbb, $testarrayoftablesOffset);
188//    \MyGame\Example\Monster::addName($fbb, $name);
189//    \MyGame\Example\Monster::finishMonsterBuffer($fbb, \MyGame\Example\Monster::endMonster($fbb));
190//    //;assert.deepEqual(new Buffer(fbb.asUint8Array()), correct);
191//}
192
193// Low level stress/fuzz test: serialize/deserialize a variety of
194// different kinds of data in different combinations
195function fuzzTest1(Assert $assert)
196{
197
198    // Values we're testing against: chosen to ensure no bits get chopped
199    // off anywhere, and also be different from eachother.
200    $bool_val = true;
201    $char_val = -127; // 0x81
202    $uchar_val = 0xFF;
203    $short_val = -32222; // 0x8222;
204    $ushort_val = 0xFEEE;
205    $int_val = 0x7fffffff | 0;
206    // for now
207    $uint_val = 1;
208    $long_val = 2;
209    $ulong_val = 3;
210
211//    var uint_val   = 0xFDDDDDDD;
212//    var long_val   = new flatbuffers.Long(0x44444444, 0x84444444);
213//    var ulong_val  = new flatbuffers.Long(0xCCCCCCCC, 0xFCCCCCCC);
214
215    $float_val = 3.14159;
216    $double_val = 3.14159265359;
217
218    $test_values_max = 11;
219    $fields_per_object = 4;
220    // current implementation is not good at encoding.
221    $num_fuzz_objects = 1000;
222    $builder = new Google\FlatBuffers\FlatBufferBuilder(1);
223
224    // can't use same implementation due to PHP_INTMAX overflow issue.
225    // we use mt_rand function to reproduce fuzzy test.
226    mt_srand(48271);
227    $objects = array();
228    // Generate num_fuzz_objects random objects each consisting of
229    // fields_per_object fields, each of a random type.
230    for ($i = 0; $i < $num_fuzz_objects; $i++) {
231        $builder->startObject($fields_per_object);
232        for ($f = 0; $f < $fields_per_object; $f++) {
233            $choice = mt_rand() % $test_values_max;
234            switch ($choice) {
235                case 0:
236                    $builder->addBoolX($f, $bool_val, 0);
237                    break;
238                case 1:
239                    $builder->addByteX($f, $char_val, 0);
240                    break;
241                case 2:
242                    $builder->addSbyteX($f, $uchar_val, 0);
243                    break;
244                case 3:
245                    $builder->addShortX($f, $short_val, 0);
246                    break;
247                case 4:
248                    $builder->addUshortX($f, $ushort_val, 0);
249                    break;
250                case 5:
251                    $builder->addIntX($f, $int_val, 0);
252                    break;
253                case 6:
254                    $builder->addUintX($f, $uint_val, 0);
255                    break;
256                case 7:
257                    $builder->addLongX($f, $long_val, 0);
258                    break;
259                case 8:
260                    $builder->addUlongX($f, $ulong_val, 0);
261                    break;
262                case 9:
263                    $builder->addFloatX($f, $float_val, 0);
264                    break;
265                case 10:
266                    $builder->addDoubleX($f, $double_val, 0);
267                    break;
268            }
269        }
270        $objects[] = $builder->endObject();
271    }
272    $builder->prep(8, 0); // Align whole buffer.
273
274    mt_srand(48271); // Reset
275    $builder->finish($objects[count($objects) - 1]);
276
277    $view = Google\FlatBuffers\ByteBuffer::wrap($builder->sizedByteArray());
278    for ($i = 0; $i < $num_fuzz_objects; $i++) {
279        $offset = $view->capacity() - $objects[$i];
280        for ($f = 0; $f < $fields_per_object; $f++) {
281            $choice = mt_rand() % $test_values_max;
282            $vtable_offset = fieldIndexToOffset($f);
283            $vtable = $offset - $view->getInt($offset);
284            $assert->ok($vtable_offset < $view->getShort($vtable));
285            $field_offset = $offset + $view->getShort($vtable + $vtable_offset);
286            switch ($choice) {
287                case 0:
288                    $assert->strictEqual(!!$view->getBool($field_offset), $bool_val);
289                    break;
290                case 1:
291                    $assert->strictEqual($view->getSbyte($field_offset), $char_val);
292                    break;
293                case 2:
294                    $assert->strictEqual($view->getByte($field_offset), $uchar_val);
295                    break;
296                case 3:
297                    $assert->strictEqual($view->getShort($field_offset), $short_val);
298                    break;
299                case 4:
300                    $assert->strictEqual($view->getUShort($field_offset), $ushort_val);
301                    break;
302                case 5:
303                    $assert->strictEqual($view->getInt($field_offset), $int_val);
304                    break;
305                case 6:
306                    $assert->strictEqual($view->getUint($field_offset), $uint_val);
307                    break;
308                case 7:
309                    if (PHP_INT_SIZE <= 4) break;
310                    $assert->strictEqual($view->getLong($field_offset), $long_val);
311                    break;
312                case 8:
313                    if (PHP_INT_SIZE <= 4) break;
314                    $assert->strictEqual($view->getUlong($field_offset), $ulong_val);
315                    break;
316                case 9:
317                    $assert->strictEqual(floor($view->getFloat($field_offset)), floor($float_val));
318                    break;
319                case 10:
320                    $assert->strictEqual($view->getDouble($field_offset), $double_val);
321                    break;
322            }
323        }
324    }
325}
326
327function fieldIndexToOffset($field_id) {
328    // Should correspond to what EndTable() below builds up.
329    $fixed_fields = 2;  // Vtable size and Object Size.
330    return ($field_id + $fixed_fields) * 2;
331}
332
333function testByteBuffer(Assert $assert) {
334
335    //Test: ByteBuffer_Length_MatchesBufferLength
336    $buffer = str_repeat("\0", 100);
337    $uut  = Google\FlatBuffers\ByteBuffer::wrap($buffer);
338    $assert->Equal($uut->capacity(), strlen($buffer));
339
340    //Test: ByteBuffer_PutBytePopulatesBufferAtZeroOffset
341    $buffer = "\0";
342    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
343    $uut->putByte(0, "\x63"); // 99
344    $assert->Equal("\x63", $uut->_buffer[0]); // don't share buffer as php user might confuse reference.
345
346    //Test: ByteBuffer_PutByteCannotPutAtOffsetPastLength
347    $buffer = "\0";
348    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
349    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
350        $uut->putByte(1, "\x63"); // 99
351    });
352
353    //Test: ByteBuffer_PutShortPopulatesBufferCorrectly
354    $buffer = str_repeat("\0", 2);
355    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
356    $uut->putShort(0, 1);
357
358    // Ensure Endiannes was written correctly
359    $assert->Equal(chr(0x01), $uut->_buffer[0]);
360    $assert->Equal(chr(0x00), $uut->_buffer[1]);
361
362    $buffer = str_repeat("\0", 2);
363    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
364    $uut->putShort(0, -32768);
365
366    // Ensure Endiannes was written correctly
367    $assert->Equal(chr(0x00), $uut->_buffer[0]);
368    $assert->Equal(chr(0x80), $uut->_buffer[1]);
369
370    //Test: ByteBuffer_PutShortCannotPutAtOffsetPastLength
371    $buffer = "\0";
372    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
373    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
374        $uut->putShort(2, "\x63"); // 99
375    });
376
377    //Test: ByteBuffer_PutShortChecksLength
378    $buffer = "\0";
379    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
380    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
381        $uut->putShort(0, "\x63"); // 99
382    });
383
384    //Test: ByteBuffer_PutShortChecksLengthAndOffset
385    $buffer = str_repeat("\0", 2);
386    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
387    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
388        $uut->putShort(1, "\x63"); // 99
389    });
390
391    //Test: ByteBuffer_PutIntPopulatesBufferCorrectly
392    $buffer = str_repeat("\0", 4);
393    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
394    $uut->putInt(0, 0x0A0B0C0D);
395    $assert->Equal(chr(0x0D), $uut->_buffer[0]);
396    $assert->Equal(chr(0x0C), $uut->_buffer[1]);
397    $assert->Equal(chr(0x0B), $uut->_buffer[2]);
398    $assert->Equal(chr(0x0A), $uut->_buffer[3]);
399
400    $buffer = str_repeat("\0", 4);
401    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
402    $uut->putInt(0, -2147483648);
403    $assert->Equal(chr(0x00), $uut->_buffer[0]);
404    $assert->Equal(chr(0x00), $uut->_buffer[1]);
405    $assert->Equal(chr(0x00), $uut->_buffer[2]);
406    $assert->Equal(chr(0x80), $uut->_buffer[3]);
407
408    //Test: ByteBuffer_PutIntCannotPutAtOffsetPastLength
409    $buffer = str_repeat("\0", 4);
410    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
411    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
412        $uut->putInt(2, 0x0A0B0C0D);
413    });
414
415    //Test: ByteBuffer_PutIntChecksLength
416    $buffer = str_repeat("\0", 1);
417    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
418    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
419        $uut->putInt(0, 0x0A0B0C0D);
420    });
421
422    //Test: ByteBuffer_PutIntChecksLengthAndOffset
423    $buffer = str_repeat("\0", 4);
424    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
425    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
426        $uut->putInt(2, 0x0A0B0C0D);
427    });
428
429    if (PHP_INT_SIZE > 4) {
430        //Test: ByteBuffer_PutLongPopulatesBufferCorrectly
431        $buffer = str_repeat("\0", 8);
432        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
433        $uut->putLong(0, 0x010203040A0B0C0D);
434        $assert->Equal(chr(0x0D), $uut->_buffer[0]);
435        $assert->Equal(chr(0x0C), $uut->_buffer[1]);
436        $assert->Equal(chr(0x0B), $uut->_buffer[2]);
437        $assert->Equal(chr(0x0A), $uut->_buffer[3]);
438        $assert->Equal(chr(0x04), $uut->_buffer[4]);
439        $assert->Equal(chr(0x03), $uut->_buffer[5]);
440        $assert->Equal(chr(0x02), $uut->_buffer[6]);
441        $assert->Equal(chr(0x01), $uut->_buffer[7]);
442
443        //Test: ByteBuffer_PutLongCannotPutAtOffsetPastLength
444        $buffer = str_repeat("\0", 8);
445        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
446        $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
447            $uut->putLong(2, 0x010203040A0B0C0D);
448        });
449
450        //Test: ByteBuffer_PutLongCannotPutAtOffsetPastLength
451        $buffer = str_repeat("\0", 1);
452        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
453        $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
454            $uut->putLong(0, 0x010203040A0B0C0D);
455        });
456
457
458        //Test: ByteBuffer_PutLongChecksLengthAndOffset
459        $buffer = str_repeat("\0", 8);
460        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
461        $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
462            $uut->putLong(2, 0x010203040A0B0C0D);
463        });
464    }
465
466    //Test: ByteBuffer_GetByteReturnsCorrectData
467    $buffer = str_repeat("\0", 1);
468    $buffer[0] = "\x63";
469    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
470    $assert->Equal("\x63", $uut->get(0));
471
472    //Test: ByteBuffer_GetByteChecksOffset
473    $buffer = str_repeat("\0", 1);
474    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
475    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
476        $uut->get(1);
477    });
478
479    //Test: ByteBuffer_GetShortReturnsCorrectData
480    $buffer = str_repeat("\0", 2);
481    $buffer[0] = chr(0x01);
482    $buffer[1] = chr(0x00);
483    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
484    $assert->Equal(1, $uut->getShort(0));
485
486    //Test: ByteBuffer_GetShortReturnsCorrectData (signed value)
487    $buffer = str_repeat("\0", 2);
488    $buffer[0] = chr(0x00);
489    $buffer[1] = chr(0x80);
490    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
491    $assert->Equal(-32768, $uut->getShort(0));
492
493    //Test: ByteBuffer_GetShortChecksOffset
494    $buffer = str_repeat("\0", 2);
495    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
496    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
497        $uut->getShort(2);
498    });
499
500    //Test: ByteBuffer_GetShortChecksLength
501    $buffer = str_repeat("\0", 2);
502    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
503    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
504        $uut->getShort(1);
505    });
506
507    //Test: ByteBuffer_GetIntReturnsCorrectData
508    $buffer = str_repeat("\0", 4);
509    $buffer[0] = chr(0x0D);
510    $buffer[1] = chr(0x0C);
511    $buffer[2] = chr(0x0B);
512    $buffer[3] = chr(0x0A);
513    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
514    $assert->Equal(0x0A0B0C0D, $uut->getInt(0));
515
516    $buffer = str_repeat("\0", 4);
517    $buffer[0] = chr(0x00);
518    $buffer[1] = chr(0x00);
519    $buffer[2] = chr(0x00);
520    $buffer[3] = chr(0x80);
521    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
522    $assert->Equal(-2147483648, $uut->getInt(0));
523
524    //Test: ByteBuffer_GetIntChecksOffset
525    $buffer = str_repeat("\0", 4);
526
527    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
528    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
529        $uut->getInt(4);
530    });
531
532    //Test: ByteBuffer_GetIntChecksLength
533    $buffer = str_repeat("\0", 2);
534    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
535    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
536        $uut->getInt(0);
537    });
538
539    if (PHP_INT_SIZE > 4) {
540        //Test: ByteBuffer_GetLongReturnsCorrectData
541        $buffer = str_repeat("\0", 8);
542        $buffer[0] = chr(0x0D);
543        $buffer[1] = chr(0x0C);
544        $buffer[2] = chr(0x0B);
545        $buffer[3] = chr(0x0A);
546        $buffer[4] = chr(0x04);
547        $buffer[5] = chr(0x03);
548        $buffer[6] = chr(0x02);
549        $buffer[7] = chr(0x01);
550        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
551        $assert->Equal(0x010203040A0B0C0D, $uut->getLong(0));
552
553        //Test: Signed Long
554        $buffer = str_repeat("\0", 8);
555        $buffer[0] = chr(0x00);
556        $buffer[1] = chr(0x00);
557        $buffer[2] = chr(0x00);
558        $buffer[3] = chr(0x00);
559        $buffer[4] = chr(0x00);
560        $buffer[5] = chr(0x00);
561        $buffer[6] = chr(0x00);
562        $buffer[7] = chr(0x80);
563        $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
564        $assert->Equal(-1 << 63, $uut->getLong(0));
565    }
566
567    //Test: ByteBuffer_GetLongChecksOffset
568    $buffer = str_repeat("\0", 8);
569    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
570    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
571        $uut->getLong(8);
572    });
573
574    //Test: ByteBuffer_GetLongChecksLength
575    $buffer = str_repeat("\0", 7);
576    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
577    $assert->Throws(new OutOfRangeException(), function()  use ($uut) {
578        $uut->getLong(0);
579    });
580
581    //Test: big endian
582    $buffer = str_repeat("\0", 2);
583    // 0xFF 0x00
584    // Little Endian: 255
585    // Big Endian: 65280
586    $buffer[0] = chr(0xff);
587    $buffer[1] = chr(0x00);
588    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
589    $assert->Equal(65280, $uut->readLittleEndian(0, 2, true));
590
591    $buffer = str_repeat("\0", 4);
592    $buffer[0] = chr(0x0D);
593    $buffer[1] = chr(0x0C);
594    $buffer[2] = chr(0x0B);
595    $buffer[3] = chr(0x0A);
596    $uut = Google\FlatBuffers\ByteBuffer::wrap($buffer);
597    $assert->Equal(0x0D0C0B0A, $uut->readLittleEndian(0, 4, true));
598
599}
600
601class Assert {
602    public function ok($result, $message = "") {
603        if (!$result){
604            throw new Exception(!empty($message) ? $message : "{$result} is not true.");
605        }
606    }
607
608    public function Equal($result, $expected, $message = "") {
609        if ($result != $expected) {
610            throw new Exception(!empty($message) ? $message : "given the result {$result} is not equals as {$expected}");
611        }
612    }
613
614
615    public function strictEqual($result, $expected, $message = "") {
616        if ($result !== $expected) {
617            throw new Exception(!empty($message) ? $message : "given the result {$result} is not strict equals as {$expected}");
618        }
619    }
620
621    public function Throws($class, Callable $callback) {
622        try {
623            $callback();
624
625            throw new \Exception("passed statement don't throw an exception.");
626        } catch (\Exception $e) {
627            if (get_class($e) != get_class($class)) {
628                throw new Exception("passed statement doesn't throw " . get_class($class) . ". throwws " . get_class($e));
629            }
630        }
631    }
632}
633