1ffe3c632Sopenharmony_ci<?php
2ffe3c632Sopenharmony_ci
3ffe3c632Sopenharmony_ci// Protocol Buffers - Google's data interchange format
4ffe3c632Sopenharmony_ci// Copyright 2008 Google Inc.  All rights reserved.
5ffe3c632Sopenharmony_ci// https://developers.google.com/protocol-buffers/
6ffe3c632Sopenharmony_ci//
7ffe3c632Sopenharmony_ci// Redistribution and use in source and binary forms, with or without
8ffe3c632Sopenharmony_ci// modification, are permitted provided that the following conditions are
9ffe3c632Sopenharmony_ci// met:
10ffe3c632Sopenharmony_ci//
11ffe3c632Sopenharmony_ci//     * Redistributions of source code must retain the above copyright
12ffe3c632Sopenharmony_ci// notice, this list of conditions and the following disclaimer.
13ffe3c632Sopenharmony_ci//     * Redistributions in binary form must reproduce the above
14ffe3c632Sopenharmony_ci// copyright notice, this list of conditions and the following disclaimer
15ffe3c632Sopenharmony_ci// in the documentation and/or other materials provided with the
16ffe3c632Sopenharmony_ci// distribution.
17ffe3c632Sopenharmony_ci//     * Neither the name of Google Inc. nor the names of its
18ffe3c632Sopenharmony_ci// contributors may be used to endorse or promote products derived from
19ffe3c632Sopenharmony_ci// this software without specific prior written permission.
20ffe3c632Sopenharmony_ci//
21ffe3c632Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22ffe3c632Sopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23ffe3c632Sopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24ffe3c632Sopenharmony_ci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25ffe3c632Sopenharmony_ci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26ffe3c632Sopenharmony_ci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27ffe3c632Sopenharmony_ci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28ffe3c632Sopenharmony_ci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29ffe3c632Sopenharmony_ci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30ffe3c632Sopenharmony_ci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31ffe3c632Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32ffe3c632Sopenharmony_ci
33ffe3c632Sopenharmony_cinamespace Google\Protobuf\Internal;
34ffe3c632Sopenharmony_ci
35ffe3c632Sopenharmony_ciclass GPBWire
36ffe3c632Sopenharmony_ci{
37ffe3c632Sopenharmony_ci
38ffe3c632Sopenharmony_ci    const TAG_TYPE_BITS = 3;
39ffe3c632Sopenharmony_ci
40ffe3c632Sopenharmony_ci    const WIRETYPE_VARINT  = 0;
41ffe3c632Sopenharmony_ci    const WIRETYPE_FIXED64 = 1;
42ffe3c632Sopenharmony_ci    const WIRETYPE_LENGTH_DELIMITED = 2;
43ffe3c632Sopenharmony_ci    const WIRETYPE_START_GROUP = 3;
44ffe3c632Sopenharmony_ci    const WIRETYPE_END_GROUP = 4;
45ffe3c632Sopenharmony_ci    const WIRETYPE_FIXED32 = 5;
46ffe3c632Sopenharmony_ci
47ffe3c632Sopenharmony_ci    const UNKNOWN = 0;
48ffe3c632Sopenharmony_ci    const NORMAL_FORMAT = 1;
49ffe3c632Sopenharmony_ci    const PACKED_FORMAT = 2;
50ffe3c632Sopenharmony_ci
51ffe3c632Sopenharmony_ci    public static function getTagFieldNumber($tag)
52ffe3c632Sopenharmony_ci    {
53ffe3c632Sopenharmony_ci        return ($tag >> self::TAG_TYPE_BITS) &
54ffe3c632Sopenharmony_ci            (1 << ((PHP_INT_SIZE * 8) - self::TAG_TYPE_BITS)) - 1;
55ffe3c632Sopenharmony_ci    }
56ffe3c632Sopenharmony_ci
57ffe3c632Sopenharmony_ci    public static function getTagWireType($tag)
58ffe3c632Sopenharmony_ci    {
59ffe3c632Sopenharmony_ci        return $tag & 0x7;
60ffe3c632Sopenharmony_ci    }
61ffe3c632Sopenharmony_ci
62ffe3c632Sopenharmony_ci    public static function getWireType($type)
63ffe3c632Sopenharmony_ci    {
64ffe3c632Sopenharmony_ci        switch ($type) {
65ffe3c632Sopenharmony_ci            case GPBType::FLOAT:
66ffe3c632Sopenharmony_ci            case GPBType::FIXED32:
67ffe3c632Sopenharmony_ci            case GPBType::SFIXED32:
68ffe3c632Sopenharmony_ci                return self::WIRETYPE_FIXED32;
69ffe3c632Sopenharmony_ci            case GPBType::DOUBLE:
70ffe3c632Sopenharmony_ci            case GPBType::FIXED64:
71ffe3c632Sopenharmony_ci            case GPBType::SFIXED64:
72ffe3c632Sopenharmony_ci                return self::WIRETYPE_FIXED64;
73ffe3c632Sopenharmony_ci            case GPBType::UINT32:
74ffe3c632Sopenharmony_ci            case GPBType::UINT64:
75ffe3c632Sopenharmony_ci            case GPBType::INT32:
76ffe3c632Sopenharmony_ci            case GPBType::INT64:
77ffe3c632Sopenharmony_ci            case GPBType::SINT32:
78ffe3c632Sopenharmony_ci            case GPBType::SINT64:
79ffe3c632Sopenharmony_ci            case GPBType::ENUM:
80ffe3c632Sopenharmony_ci            case GPBType::BOOL:
81ffe3c632Sopenharmony_ci                return self::WIRETYPE_VARINT;
82ffe3c632Sopenharmony_ci            case GPBType::STRING:
83ffe3c632Sopenharmony_ci            case GPBType::BYTES:
84ffe3c632Sopenharmony_ci            case GPBType::MESSAGE:
85ffe3c632Sopenharmony_ci                return self::WIRETYPE_LENGTH_DELIMITED;
86ffe3c632Sopenharmony_ci            case GPBType::GROUP:
87ffe3c632Sopenharmony_ci                user_error("Unsupported type.");
88ffe3c632Sopenharmony_ci                return 0;
89ffe3c632Sopenharmony_ci            default:
90ffe3c632Sopenharmony_ci                user_error("Unsupported type.");
91ffe3c632Sopenharmony_ci                return 0;
92ffe3c632Sopenharmony_ci        }
93ffe3c632Sopenharmony_ci    }
94ffe3c632Sopenharmony_ci
95ffe3c632Sopenharmony_ci  // ZigZag Transform:  Encodes signed integers so that they can be effectively
96ffe3c632Sopenharmony_ci  // used with varint encoding.
97ffe3c632Sopenharmony_ci  //
98ffe3c632Sopenharmony_ci  // varint operates on unsigned integers, encoding smaller numbers into fewer
99ffe3c632Sopenharmony_ci  // bytes.  If you try to use it on a signed integer, it will treat this
100ffe3c632Sopenharmony_ci  // number as a very large unsigned integer, which means that even small
101ffe3c632Sopenharmony_ci  // signed numbers like -1 will take the maximum number of bytes (10) to
102ffe3c632Sopenharmony_ci  // encode.  zigZagEncode() maps signed integers to unsigned in such a way
103ffe3c632Sopenharmony_ci  // that those with a small absolute value will have smaller encoded values,
104ffe3c632Sopenharmony_ci  // making them appropriate for encoding using varint.
105ffe3c632Sopenharmony_ci  //
106ffe3c632Sopenharmony_ci  // int32 ->     uint32
107ffe3c632Sopenharmony_ci  // -------------------------
108ffe3c632Sopenharmony_ci  //           0 ->          0
109ffe3c632Sopenharmony_ci  //          -1 ->          1
110ffe3c632Sopenharmony_ci  //           1 ->          2
111ffe3c632Sopenharmony_ci  //          -2 ->          3
112ffe3c632Sopenharmony_ci  //         ... ->        ...
113ffe3c632Sopenharmony_ci  //  2147483647 -> 4294967294
114ffe3c632Sopenharmony_ci  // -2147483648 -> 4294967295
115ffe3c632Sopenharmony_ci  //
116ffe3c632Sopenharmony_ci  //        >> encode >>
117ffe3c632Sopenharmony_ci  //        << decode <<
118ffe3c632Sopenharmony_ci  public static function zigZagEncode32($int32)
119ffe3c632Sopenharmony_ci  {
120ffe3c632Sopenharmony_ci      if (PHP_INT_SIZE == 8) {
121ffe3c632Sopenharmony_ci          $trim_int32 = $int32 & 0xFFFFFFFF;
122ffe3c632Sopenharmony_ci          return (($trim_int32 << 1) ^ ($int32 << 32 >> 63)) & 0xFFFFFFFF;
123ffe3c632Sopenharmony_ci      } else {
124ffe3c632Sopenharmony_ci          return ($int32 << 1) ^ ($int32 >> 31);
125ffe3c632Sopenharmony_ci      }
126ffe3c632Sopenharmony_ci  }
127ffe3c632Sopenharmony_ci
128ffe3c632Sopenharmony_ci    public static function zigZagDecode32($uint32)
129ffe3c632Sopenharmony_ci    {
130ffe3c632Sopenharmony_ci        // Fill high 32 bits.
131ffe3c632Sopenharmony_ci        if (PHP_INT_SIZE === 8) {
132ffe3c632Sopenharmony_ci            $uint32 |= ($uint32 & 0xFFFFFFFF);
133ffe3c632Sopenharmony_ci        }
134ffe3c632Sopenharmony_ci
135ffe3c632Sopenharmony_ci        $int32 = (($uint32 >> 1) & 0x7FFFFFFF) ^ (-($uint32 & 1));
136ffe3c632Sopenharmony_ci
137ffe3c632Sopenharmony_ci        return $int32;
138ffe3c632Sopenharmony_ci    }
139ffe3c632Sopenharmony_ci
140ffe3c632Sopenharmony_ci    public static function zigZagEncode64($int64)
141ffe3c632Sopenharmony_ci    {
142ffe3c632Sopenharmony_ci        if (PHP_INT_SIZE == 4) {
143ffe3c632Sopenharmony_ci            if (bccomp($int64, 0) >= 0) {
144ffe3c632Sopenharmony_ci                return bcmul($int64, 2);
145ffe3c632Sopenharmony_ci            } else {
146ffe3c632Sopenharmony_ci                return bcsub(bcmul(bcsub(0, $int64), 2), 1);
147ffe3c632Sopenharmony_ci            }
148ffe3c632Sopenharmony_ci        } else {
149ffe3c632Sopenharmony_ci            return ($int64 << 1) ^ ($int64 >> 63);
150ffe3c632Sopenharmony_ci        }
151ffe3c632Sopenharmony_ci    }
152ffe3c632Sopenharmony_ci
153ffe3c632Sopenharmony_ci    public static function zigZagDecode64($uint64)
154ffe3c632Sopenharmony_ci    {
155ffe3c632Sopenharmony_ci        if (PHP_INT_SIZE == 4) {
156ffe3c632Sopenharmony_ci            if (bcmod($uint64, 2) == 0) {
157ffe3c632Sopenharmony_ci                return bcdiv($uint64, 2, 0);
158ffe3c632Sopenharmony_ci            } else {
159ffe3c632Sopenharmony_ci                return bcsub(0, bcdiv(bcadd($uint64, 1), 2, 0));
160ffe3c632Sopenharmony_ci            }
161ffe3c632Sopenharmony_ci        } else {
162ffe3c632Sopenharmony_ci            return (($uint64 >> 1) & 0x7FFFFFFFFFFFFFFF) ^ (-($uint64 & 1));
163ffe3c632Sopenharmony_ci        }
164ffe3c632Sopenharmony_ci    }
165ffe3c632Sopenharmony_ci
166ffe3c632Sopenharmony_ci    public static function readInt32(&$input, &$value)
167ffe3c632Sopenharmony_ci    {
168ffe3c632Sopenharmony_ci        return $input->readVarint32($value);
169ffe3c632Sopenharmony_ci    }
170ffe3c632Sopenharmony_ci
171ffe3c632Sopenharmony_ci    public static function readInt64(&$input, &$value)
172ffe3c632Sopenharmony_ci    {
173ffe3c632Sopenharmony_ci        $success = $input->readVarint64($value);
174ffe3c632Sopenharmony_ci        if (PHP_INT_SIZE == 4 && bccomp($value, "9223372036854775807") > 0) {
175ffe3c632Sopenharmony_ci            $value = bcsub($value, "18446744073709551616");
176ffe3c632Sopenharmony_ci        }
177ffe3c632Sopenharmony_ci        return $success;
178ffe3c632Sopenharmony_ci    }
179ffe3c632Sopenharmony_ci
180ffe3c632Sopenharmony_ci    public static function readUint32(&$input, &$value)
181ffe3c632Sopenharmony_ci    {
182ffe3c632Sopenharmony_ci        return self::readInt32($input, $value);
183ffe3c632Sopenharmony_ci    }
184ffe3c632Sopenharmony_ci
185ffe3c632Sopenharmony_ci    public static function readUint64(&$input, &$value)
186ffe3c632Sopenharmony_ci    {
187ffe3c632Sopenharmony_ci        return self::readInt64($input, $value);
188ffe3c632Sopenharmony_ci    }
189ffe3c632Sopenharmony_ci
190ffe3c632Sopenharmony_ci    public static function readSint32(&$input, &$value)
191ffe3c632Sopenharmony_ci    {
192ffe3c632Sopenharmony_ci        if (!$input->readVarint32($value)) {
193ffe3c632Sopenharmony_ci            return false;
194ffe3c632Sopenharmony_ci        }
195ffe3c632Sopenharmony_ci        $value = GPBWire::zigZagDecode32($value);
196ffe3c632Sopenharmony_ci        return true;
197ffe3c632Sopenharmony_ci    }
198ffe3c632Sopenharmony_ci
199ffe3c632Sopenharmony_ci    public static function readSint64(&$input, &$value)
200ffe3c632Sopenharmony_ci    {
201ffe3c632Sopenharmony_ci        if (!$input->readVarint64($value)) {
202ffe3c632Sopenharmony_ci            return false;
203ffe3c632Sopenharmony_ci        }
204ffe3c632Sopenharmony_ci        $value = GPBWire::zigZagDecode64($value);
205ffe3c632Sopenharmony_ci        return true;
206ffe3c632Sopenharmony_ci    }
207ffe3c632Sopenharmony_ci
208ffe3c632Sopenharmony_ci    public static function readFixed32(&$input, &$value)
209ffe3c632Sopenharmony_ci    {
210ffe3c632Sopenharmony_ci        return $input->readLittleEndian32($value);
211ffe3c632Sopenharmony_ci    }
212ffe3c632Sopenharmony_ci
213ffe3c632Sopenharmony_ci    public static function readFixed64(&$input, &$value)
214ffe3c632Sopenharmony_ci    {
215ffe3c632Sopenharmony_ci        return $input->readLittleEndian64($value);
216ffe3c632Sopenharmony_ci    }
217ffe3c632Sopenharmony_ci
218ffe3c632Sopenharmony_ci    public static function readSfixed32(&$input, &$value)
219ffe3c632Sopenharmony_ci    {
220ffe3c632Sopenharmony_ci        if (!self::readFixed32($input, $value)) {
221ffe3c632Sopenharmony_ci            return false;
222ffe3c632Sopenharmony_ci        }
223ffe3c632Sopenharmony_ci        if (PHP_INT_SIZE === 8) {
224ffe3c632Sopenharmony_ci            $value |= (-($value >> 31) << 32);
225ffe3c632Sopenharmony_ci        }
226ffe3c632Sopenharmony_ci        return true;
227ffe3c632Sopenharmony_ci    }
228ffe3c632Sopenharmony_ci
229ffe3c632Sopenharmony_ci    public static function readSfixed64(&$input, &$value)
230ffe3c632Sopenharmony_ci    {
231ffe3c632Sopenharmony_ci        $success = $input->readLittleEndian64($value);
232ffe3c632Sopenharmony_ci        if (PHP_INT_SIZE == 4 && bccomp($value, "9223372036854775807") > 0) {
233ffe3c632Sopenharmony_ci            $value = bcsub($value, "18446744073709551616");
234ffe3c632Sopenharmony_ci        }
235ffe3c632Sopenharmony_ci        return $success;
236ffe3c632Sopenharmony_ci    }
237ffe3c632Sopenharmony_ci
238ffe3c632Sopenharmony_ci    public static function readFloat(&$input, &$value)
239ffe3c632Sopenharmony_ci    {
240ffe3c632Sopenharmony_ci        $data = null;
241ffe3c632Sopenharmony_ci        if (!$input->readRaw(4, $data)) {
242ffe3c632Sopenharmony_ci            return false;
243ffe3c632Sopenharmony_ci        }
244ffe3c632Sopenharmony_ci        $value = unpack('f', $data)[1];
245ffe3c632Sopenharmony_ci        return true;
246ffe3c632Sopenharmony_ci    }
247ffe3c632Sopenharmony_ci
248ffe3c632Sopenharmony_ci    public static function readDouble(&$input, &$value)
249ffe3c632Sopenharmony_ci    {
250ffe3c632Sopenharmony_ci        $data = null;
251ffe3c632Sopenharmony_ci        if (!$input->readRaw(8, $data)) {
252ffe3c632Sopenharmony_ci            return false;
253ffe3c632Sopenharmony_ci        }
254ffe3c632Sopenharmony_ci        $value = unpack('d', $data)[1];
255ffe3c632Sopenharmony_ci        return true;
256ffe3c632Sopenharmony_ci    }
257ffe3c632Sopenharmony_ci
258ffe3c632Sopenharmony_ci    public static function readBool(&$input, &$value)
259ffe3c632Sopenharmony_ci    {
260ffe3c632Sopenharmony_ci        if (!$input->readVarint64($value)) {
261ffe3c632Sopenharmony_ci            return false;
262ffe3c632Sopenharmony_ci        }
263ffe3c632Sopenharmony_ci        if ($value == 0) {
264ffe3c632Sopenharmony_ci            $value = false;
265ffe3c632Sopenharmony_ci        } else {
266ffe3c632Sopenharmony_ci            $value = true;
267ffe3c632Sopenharmony_ci        }
268ffe3c632Sopenharmony_ci        return true;
269ffe3c632Sopenharmony_ci    }
270ffe3c632Sopenharmony_ci
271ffe3c632Sopenharmony_ci    public static function readString(&$input, &$value)
272ffe3c632Sopenharmony_ci    {
273ffe3c632Sopenharmony_ci        $length = 0;
274ffe3c632Sopenharmony_ci        return $input->readVarintSizeAsInt($length) && $input->readRaw($length, $value);
275ffe3c632Sopenharmony_ci    }
276ffe3c632Sopenharmony_ci
277ffe3c632Sopenharmony_ci    public static function readMessage(&$input, &$message)
278ffe3c632Sopenharmony_ci    {
279ffe3c632Sopenharmony_ci        $length = 0;
280ffe3c632Sopenharmony_ci        if (!$input->readVarintSizeAsInt($length)) {
281ffe3c632Sopenharmony_ci            return false;
282ffe3c632Sopenharmony_ci        }
283ffe3c632Sopenharmony_ci        $old_limit = 0;
284ffe3c632Sopenharmony_ci        $recursion_limit = 0;
285ffe3c632Sopenharmony_ci        $input->incrementRecursionDepthAndPushLimit(
286ffe3c632Sopenharmony_ci            $length,
287ffe3c632Sopenharmony_ci            $old_limit,
288ffe3c632Sopenharmony_ci            $recursion_limit);
289ffe3c632Sopenharmony_ci        if ($recursion_limit < 0 || !$message->parseFromStream($input)) {
290ffe3c632Sopenharmony_ci            return false;
291ffe3c632Sopenharmony_ci        }
292ffe3c632Sopenharmony_ci        return $input->decrementRecursionDepthAndPopLimit($old_limit);
293ffe3c632Sopenharmony_ci    }
294ffe3c632Sopenharmony_ci
295ffe3c632Sopenharmony_ci    public static function writeTag(&$output, $tag)
296ffe3c632Sopenharmony_ci    {
297ffe3c632Sopenharmony_ci        return $output->writeTag($tag);
298ffe3c632Sopenharmony_ci    }
299ffe3c632Sopenharmony_ci
300ffe3c632Sopenharmony_ci    public static function writeInt32(&$output, $value)
301ffe3c632Sopenharmony_ci    {
302ffe3c632Sopenharmony_ci        return $output->writeVarint32($value, false);
303ffe3c632Sopenharmony_ci    }
304ffe3c632Sopenharmony_ci
305ffe3c632Sopenharmony_ci    public static function writeInt64(&$output, $value)
306ffe3c632Sopenharmony_ci    {
307ffe3c632Sopenharmony_ci        return $output->writeVarint64($value);
308ffe3c632Sopenharmony_ci    }
309ffe3c632Sopenharmony_ci
310ffe3c632Sopenharmony_ci    public static function writeUint32(&$output, $value)
311ffe3c632Sopenharmony_ci    {
312ffe3c632Sopenharmony_ci        return $output->writeVarint32($value, true);
313ffe3c632Sopenharmony_ci    }
314ffe3c632Sopenharmony_ci
315ffe3c632Sopenharmony_ci    public static function writeUint64(&$output, $value)
316ffe3c632Sopenharmony_ci    {
317ffe3c632Sopenharmony_ci        return $output->writeVarint64($value);
318ffe3c632Sopenharmony_ci    }
319ffe3c632Sopenharmony_ci
320ffe3c632Sopenharmony_ci    public static function writeSint32(&$output, $value)
321ffe3c632Sopenharmony_ci    {
322ffe3c632Sopenharmony_ci        $value = GPBWire::zigZagEncode32($value);
323ffe3c632Sopenharmony_ci        return $output->writeVarint32($value, true);
324ffe3c632Sopenharmony_ci    }
325ffe3c632Sopenharmony_ci
326ffe3c632Sopenharmony_ci    public static function writeSint64(&$output, $value)
327ffe3c632Sopenharmony_ci    {
328ffe3c632Sopenharmony_ci        $value = GPBWire::zigZagEncode64($value);
329ffe3c632Sopenharmony_ci        return $output->writeVarint64($value);
330ffe3c632Sopenharmony_ci    }
331ffe3c632Sopenharmony_ci
332ffe3c632Sopenharmony_ci    public static function writeFixed32(&$output, $value)
333ffe3c632Sopenharmony_ci    {
334ffe3c632Sopenharmony_ci        return $output->writeLittleEndian32($value);
335ffe3c632Sopenharmony_ci    }
336ffe3c632Sopenharmony_ci
337ffe3c632Sopenharmony_ci    public static function writeFixed64(&$output, $value)
338ffe3c632Sopenharmony_ci    {
339ffe3c632Sopenharmony_ci        return $output->writeLittleEndian64($value);
340ffe3c632Sopenharmony_ci    }
341ffe3c632Sopenharmony_ci
342ffe3c632Sopenharmony_ci    public static function writeSfixed32(&$output, $value)
343ffe3c632Sopenharmony_ci    {
344ffe3c632Sopenharmony_ci        return $output->writeLittleEndian32($value);
345ffe3c632Sopenharmony_ci    }
346ffe3c632Sopenharmony_ci
347ffe3c632Sopenharmony_ci    public static function writeSfixed64(&$output, $value)
348ffe3c632Sopenharmony_ci    {
349ffe3c632Sopenharmony_ci        return $output->writeLittleEndian64($value);
350ffe3c632Sopenharmony_ci    }
351ffe3c632Sopenharmony_ci
352ffe3c632Sopenharmony_ci    public static function writeBool(&$output, $value)
353ffe3c632Sopenharmony_ci    {
354ffe3c632Sopenharmony_ci        if ($value) {
355ffe3c632Sopenharmony_ci            return $output->writeVarint32(1, true);
356ffe3c632Sopenharmony_ci        } else {
357ffe3c632Sopenharmony_ci            return $output->writeVarint32(0, true);
358ffe3c632Sopenharmony_ci        }
359ffe3c632Sopenharmony_ci    }
360ffe3c632Sopenharmony_ci
361ffe3c632Sopenharmony_ci    public static function writeFloat(&$output, $value)
362ffe3c632Sopenharmony_ci    {
363ffe3c632Sopenharmony_ci        $data = pack("f", $value);
364ffe3c632Sopenharmony_ci        return $output->writeRaw($data, 4);
365ffe3c632Sopenharmony_ci    }
366ffe3c632Sopenharmony_ci
367ffe3c632Sopenharmony_ci    public static function writeDouble(&$output, $value)
368ffe3c632Sopenharmony_ci    {
369ffe3c632Sopenharmony_ci        $data = pack("d", $value);
370ffe3c632Sopenharmony_ci        return $output->writeRaw($data, 8);
371ffe3c632Sopenharmony_ci    }
372ffe3c632Sopenharmony_ci
373ffe3c632Sopenharmony_ci    public static function writeString(&$output, $value)
374ffe3c632Sopenharmony_ci    {
375ffe3c632Sopenharmony_ci        return self::writeBytes($output, $value);
376ffe3c632Sopenharmony_ci    }
377ffe3c632Sopenharmony_ci
378ffe3c632Sopenharmony_ci    public static function writeBytes(&$output, $value)
379ffe3c632Sopenharmony_ci    {
380ffe3c632Sopenharmony_ci        $size = strlen($value);
381ffe3c632Sopenharmony_ci        if (!$output->writeVarint32($size, true)) {
382ffe3c632Sopenharmony_ci            return false;
383ffe3c632Sopenharmony_ci        }
384ffe3c632Sopenharmony_ci        return $output->writeRaw($value, $size);
385ffe3c632Sopenharmony_ci    }
386ffe3c632Sopenharmony_ci
387ffe3c632Sopenharmony_ci    public static function writeMessage(&$output, $value)
388ffe3c632Sopenharmony_ci    {
389ffe3c632Sopenharmony_ci        $size = $value->byteSize();
390ffe3c632Sopenharmony_ci        if (!$output->writeVarint32($size, true)) {
391ffe3c632Sopenharmony_ci            return false;
392ffe3c632Sopenharmony_ci        }
393ffe3c632Sopenharmony_ci        return $value->serializeToStream($output);
394ffe3c632Sopenharmony_ci    }
395ffe3c632Sopenharmony_ci
396ffe3c632Sopenharmony_ci    public static function makeTag($number, $type)
397ffe3c632Sopenharmony_ci    {
398ffe3c632Sopenharmony_ci        return ($number << 3) | self::getWireType($type);
399ffe3c632Sopenharmony_ci    }
400ffe3c632Sopenharmony_ci
401ffe3c632Sopenharmony_ci    public static function tagSize($field)
402ffe3c632Sopenharmony_ci    {
403ffe3c632Sopenharmony_ci        $tag = self::makeTag($field->getNumber(), $field->getType());
404ffe3c632Sopenharmony_ci        return self::varint32Size($tag);
405ffe3c632Sopenharmony_ci    }
406ffe3c632Sopenharmony_ci
407ffe3c632Sopenharmony_ci    public static function varint32Size($value, $sign_extended = false)
408ffe3c632Sopenharmony_ci    {
409ffe3c632Sopenharmony_ci        if ($value < 0) {
410ffe3c632Sopenharmony_ci            if ($sign_extended) {
411ffe3c632Sopenharmony_ci                return 10;
412ffe3c632Sopenharmony_ci            } else {
413ffe3c632Sopenharmony_ci                return 5;
414ffe3c632Sopenharmony_ci            }
415ffe3c632Sopenharmony_ci        }
416ffe3c632Sopenharmony_ci        if ($value < (1 <<  7)) {
417ffe3c632Sopenharmony_ci            return 1;
418ffe3c632Sopenharmony_ci        }
419ffe3c632Sopenharmony_ci        if ($value < (1 << 14)) {
420ffe3c632Sopenharmony_ci            return 2;
421ffe3c632Sopenharmony_ci        }
422ffe3c632Sopenharmony_ci        if ($value < (1 << 21)) {
423ffe3c632Sopenharmony_ci            return 3;
424ffe3c632Sopenharmony_ci        }
425ffe3c632Sopenharmony_ci        if ($value < (1 << 28)) {
426ffe3c632Sopenharmony_ci            return 4;
427ffe3c632Sopenharmony_ci        }
428ffe3c632Sopenharmony_ci        return 5;
429ffe3c632Sopenharmony_ci    }
430ffe3c632Sopenharmony_ci
431ffe3c632Sopenharmony_ci    public static function sint32Size($value)
432ffe3c632Sopenharmony_ci    {
433ffe3c632Sopenharmony_ci        $value = self::zigZagEncode32($value);
434ffe3c632Sopenharmony_ci        return self::varint32Size($value);
435ffe3c632Sopenharmony_ci    }
436ffe3c632Sopenharmony_ci
437ffe3c632Sopenharmony_ci    public static function sint64Size($value)
438ffe3c632Sopenharmony_ci    {
439ffe3c632Sopenharmony_ci        $value = self::zigZagEncode64($value);
440ffe3c632Sopenharmony_ci        return self::varint64Size($value);
441ffe3c632Sopenharmony_ci    }
442ffe3c632Sopenharmony_ci
443ffe3c632Sopenharmony_ci    public static function varint64Size($value)
444ffe3c632Sopenharmony_ci    {
445ffe3c632Sopenharmony_ci        if (PHP_INT_SIZE == 4) {
446ffe3c632Sopenharmony_ci            if (bccomp($value, 0) < 0 ||
447ffe3c632Sopenharmony_ci                bccomp($value, "9223372036854775807") > 0) {
448ffe3c632Sopenharmony_ci                return 10;
449ffe3c632Sopenharmony_ci            }
450ffe3c632Sopenharmony_ci            if (bccomp($value, 1 << 7) < 0) {
451ffe3c632Sopenharmony_ci                return 1;
452ffe3c632Sopenharmony_ci            }
453ffe3c632Sopenharmony_ci            if (bccomp($value, 1 << 14) < 0) {
454ffe3c632Sopenharmony_ci                return 2;
455ffe3c632Sopenharmony_ci            }
456ffe3c632Sopenharmony_ci            if (bccomp($value, 1 << 21) < 0) {
457ffe3c632Sopenharmony_ci                return 3;
458ffe3c632Sopenharmony_ci            }
459ffe3c632Sopenharmony_ci            if (bccomp($value, 1 << 28) < 0) {
460ffe3c632Sopenharmony_ci                return 4;
461ffe3c632Sopenharmony_ci            }
462ffe3c632Sopenharmony_ci            if (bccomp($value, '34359738368') < 0) {
463ffe3c632Sopenharmony_ci                return 5;
464ffe3c632Sopenharmony_ci            }
465ffe3c632Sopenharmony_ci            if (bccomp($value, '4398046511104') < 0) {
466ffe3c632Sopenharmony_ci                return 6;
467ffe3c632Sopenharmony_ci            }
468ffe3c632Sopenharmony_ci            if (bccomp($value, '562949953421312') < 0) {
469ffe3c632Sopenharmony_ci                return 7;
470ffe3c632Sopenharmony_ci            }
471ffe3c632Sopenharmony_ci            if (bccomp($value, '72057594037927936') < 0) {
472ffe3c632Sopenharmony_ci                return 8;
473ffe3c632Sopenharmony_ci            }
474ffe3c632Sopenharmony_ci            return 9;
475ffe3c632Sopenharmony_ci        } else {
476ffe3c632Sopenharmony_ci            if ($value < 0) {
477ffe3c632Sopenharmony_ci                return 10;
478ffe3c632Sopenharmony_ci            }
479ffe3c632Sopenharmony_ci            if ($value < (1 <<  7)) {
480ffe3c632Sopenharmony_ci                return 1;
481ffe3c632Sopenharmony_ci            }
482ffe3c632Sopenharmony_ci            if ($value < (1 << 14)) {
483ffe3c632Sopenharmony_ci                return 2;
484ffe3c632Sopenharmony_ci            }
485ffe3c632Sopenharmony_ci            if ($value < (1 << 21)) {
486ffe3c632Sopenharmony_ci                return 3;
487ffe3c632Sopenharmony_ci            }
488ffe3c632Sopenharmony_ci            if ($value < (1 << 28)) {
489ffe3c632Sopenharmony_ci                return 4;
490ffe3c632Sopenharmony_ci            }
491ffe3c632Sopenharmony_ci            if ($value < (1 << 35)) {
492ffe3c632Sopenharmony_ci                return 5;
493ffe3c632Sopenharmony_ci            }
494ffe3c632Sopenharmony_ci            if ($value < (1 << 42)) {
495ffe3c632Sopenharmony_ci                return 6;
496ffe3c632Sopenharmony_ci            }
497ffe3c632Sopenharmony_ci            if ($value < (1 << 49)) {
498ffe3c632Sopenharmony_ci                return 7;
499ffe3c632Sopenharmony_ci            }
500ffe3c632Sopenharmony_ci            if ($value < (1 << 56)) {
501ffe3c632Sopenharmony_ci                return 8;
502ffe3c632Sopenharmony_ci            }
503ffe3c632Sopenharmony_ci            return 9;
504ffe3c632Sopenharmony_ci        }
505ffe3c632Sopenharmony_ci    }
506ffe3c632Sopenharmony_ci
507ffe3c632Sopenharmony_ci    public static function serializeFieldToStream(
508ffe3c632Sopenharmony_ci        $value,
509ffe3c632Sopenharmony_ci        $field,
510ffe3c632Sopenharmony_ci        $need_tag,
511ffe3c632Sopenharmony_ci        &$output)
512ffe3c632Sopenharmony_ci    {
513ffe3c632Sopenharmony_ci        if ($need_tag) {
514ffe3c632Sopenharmony_ci            if (!GPBWire::writeTag(
515ffe3c632Sopenharmony_ci                $output,
516ffe3c632Sopenharmony_ci                self::makeTag(
517ffe3c632Sopenharmony_ci                    $field->getNumber(),
518ffe3c632Sopenharmony_ci                    $field->getType()))) {
519ffe3c632Sopenharmony_ci                return false;
520ffe3c632Sopenharmony_ci            }
521ffe3c632Sopenharmony_ci        }
522ffe3c632Sopenharmony_ci        switch ($field->getType()) {
523ffe3c632Sopenharmony_ci            case GPBType::DOUBLE:
524ffe3c632Sopenharmony_ci                if (!GPBWire::writeDouble($output, $value)) {
525ffe3c632Sopenharmony_ci                    return false;
526ffe3c632Sopenharmony_ci                }
527ffe3c632Sopenharmony_ci                break;
528ffe3c632Sopenharmony_ci            case GPBType::FLOAT:
529ffe3c632Sopenharmony_ci                if (!GPBWire::writeFloat($output, $value)) {
530ffe3c632Sopenharmony_ci                    return false;
531ffe3c632Sopenharmony_ci                }
532ffe3c632Sopenharmony_ci                break;
533ffe3c632Sopenharmony_ci            case GPBType::INT64:
534ffe3c632Sopenharmony_ci                if (!GPBWire::writeInt64($output, $value)) {
535ffe3c632Sopenharmony_ci                    return false;
536ffe3c632Sopenharmony_ci                }
537ffe3c632Sopenharmony_ci                break;
538ffe3c632Sopenharmony_ci            case GPBType::UINT64:
539ffe3c632Sopenharmony_ci                if (!GPBWire::writeUint64($output, $value)) {
540ffe3c632Sopenharmony_ci                    return false;
541ffe3c632Sopenharmony_ci                }
542ffe3c632Sopenharmony_ci                break;
543ffe3c632Sopenharmony_ci            case GPBType::INT32:
544ffe3c632Sopenharmony_ci                if (!GPBWire::writeInt32($output, $value)) {
545ffe3c632Sopenharmony_ci                    return false;
546ffe3c632Sopenharmony_ci                }
547ffe3c632Sopenharmony_ci                break;
548ffe3c632Sopenharmony_ci            case GPBType::FIXED32:
549ffe3c632Sopenharmony_ci                if (!GPBWire::writeFixed32($output, $value)) {
550ffe3c632Sopenharmony_ci                    return false;
551ffe3c632Sopenharmony_ci                }
552ffe3c632Sopenharmony_ci                break;
553ffe3c632Sopenharmony_ci            case GPBType::FIXED64:
554ffe3c632Sopenharmony_ci                if (!GPBWire::writeFixed64($output, $value)) {
555ffe3c632Sopenharmony_ci                    return false;
556ffe3c632Sopenharmony_ci                }
557ffe3c632Sopenharmony_ci                break;
558ffe3c632Sopenharmony_ci            case GPBType::BOOL:
559ffe3c632Sopenharmony_ci                if (!GPBWire::writeBool($output, $value)) {
560ffe3c632Sopenharmony_ci                    return false;
561ffe3c632Sopenharmony_ci                }
562ffe3c632Sopenharmony_ci                break;
563ffe3c632Sopenharmony_ci            case GPBType::STRING:
564ffe3c632Sopenharmony_ci                if (!GPBWire::writeString($output, $value)) {
565ffe3c632Sopenharmony_ci                    return false;
566ffe3c632Sopenharmony_ci                }
567ffe3c632Sopenharmony_ci                break;
568ffe3c632Sopenharmony_ci            //    case GPBType::GROUP:
569ffe3c632Sopenharmony_ci            //      echo "GROUP\xA";
570ffe3c632Sopenharmony_ci            //      trigger_error("Not implemented.", E_ERROR);
571ffe3c632Sopenharmony_ci            //      break;
572ffe3c632Sopenharmony_ci            case GPBType::MESSAGE:
573ffe3c632Sopenharmony_ci                if (!GPBWire::writeMessage($output, $value)) {
574ffe3c632Sopenharmony_ci                    return false;
575ffe3c632Sopenharmony_ci                }
576ffe3c632Sopenharmony_ci                break;
577ffe3c632Sopenharmony_ci            case GPBType::BYTES:
578ffe3c632Sopenharmony_ci                if (!GPBWire::writeBytes($output, $value)) {
579ffe3c632Sopenharmony_ci                    return false;
580ffe3c632Sopenharmony_ci                }
581ffe3c632Sopenharmony_ci                break;
582ffe3c632Sopenharmony_ci            case GPBType::UINT32:
583ffe3c632Sopenharmony_ci                if (PHP_INT_SIZE === 8 && $value < 0) {
584ffe3c632Sopenharmony_ci                    $value += 4294967296;
585ffe3c632Sopenharmony_ci                }
586ffe3c632Sopenharmony_ci                if (!GPBWire::writeUint32($output, $value)) {
587ffe3c632Sopenharmony_ci                    return false;
588ffe3c632Sopenharmony_ci                }
589ffe3c632Sopenharmony_ci                break;
590ffe3c632Sopenharmony_ci            case GPBType::ENUM:
591ffe3c632Sopenharmony_ci                if (!GPBWire::writeInt32($output, $value)) {
592ffe3c632Sopenharmony_ci                    return false;
593ffe3c632Sopenharmony_ci                }
594ffe3c632Sopenharmony_ci                break;
595ffe3c632Sopenharmony_ci            case GPBType::SFIXED32:
596ffe3c632Sopenharmony_ci                if (!GPBWire::writeSfixed32($output, $value)) {
597ffe3c632Sopenharmony_ci                    return false;
598ffe3c632Sopenharmony_ci                }
599ffe3c632Sopenharmony_ci                break;
600ffe3c632Sopenharmony_ci            case GPBType::SFIXED64:
601ffe3c632Sopenharmony_ci                if (!GPBWire::writeSfixed64($output, $value)) {
602ffe3c632Sopenharmony_ci                    return false;
603ffe3c632Sopenharmony_ci                }
604ffe3c632Sopenharmony_ci                break;
605ffe3c632Sopenharmony_ci            case GPBType::SINT32:
606ffe3c632Sopenharmony_ci                if (!GPBWire::writeSint32($output, $value)) {
607ffe3c632Sopenharmony_ci                    return false;
608ffe3c632Sopenharmony_ci                }
609ffe3c632Sopenharmony_ci                break;
610ffe3c632Sopenharmony_ci            case GPBType::SINT64:
611ffe3c632Sopenharmony_ci                if (!GPBWire::writeSint64($output, $value)) {
612ffe3c632Sopenharmony_ci                    return false;
613ffe3c632Sopenharmony_ci                }
614ffe3c632Sopenharmony_ci                break;
615ffe3c632Sopenharmony_ci            default:
616ffe3c632Sopenharmony_ci                user_error("Unsupported type.");
617ffe3c632Sopenharmony_ci                return false;
618ffe3c632Sopenharmony_ci        }
619ffe3c632Sopenharmony_ci
620ffe3c632Sopenharmony_ci        return true;
621ffe3c632Sopenharmony_ci    }
622ffe3c632Sopenharmony_ci}
623