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 CodedOutputStream
36ffe3c632Sopenharmony_ci{
37ffe3c632Sopenharmony_ci
38ffe3c632Sopenharmony_ci    private $buffer;
39ffe3c632Sopenharmony_ci    private $buffer_size;
40ffe3c632Sopenharmony_ci    private $current;
41ffe3c632Sopenharmony_ci
42ffe3c632Sopenharmony_ci    const MAX_VARINT64_BYTES = 10;
43ffe3c632Sopenharmony_ci
44ffe3c632Sopenharmony_ci    public function __construct($size)
45ffe3c632Sopenharmony_ci    {
46ffe3c632Sopenharmony_ci        $this->current = 0;
47ffe3c632Sopenharmony_ci        $this->buffer_size = $size;
48ffe3c632Sopenharmony_ci        $this->buffer = str_repeat(chr(0), $this->buffer_size);
49ffe3c632Sopenharmony_ci    }
50ffe3c632Sopenharmony_ci
51ffe3c632Sopenharmony_ci    public function getData()
52ffe3c632Sopenharmony_ci    {
53ffe3c632Sopenharmony_ci        return $this->buffer;
54ffe3c632Sopenharmony_ci    }
55ffe3c632Sopenharmony_ci
56ffe3c632Sopenharmony_ci    public function writeVarint32($value, $trim)
57ffe3c632Sopenharmony_ci    {
58ffe3c632Sopenharmony_ci        $bytes = str_repeat(chr(0), self::MAX_VARINT64_BYTES);
59ffe3c632Sopenharmony_ci        $size = self::writeVarintToArray($value, $bytes, $trim);
60ffe3c632Sopenharmony_ci        return $this->writeRaw($bytes, $size);
61ffe3c632Sopenharmony_ci    }
62ffe3c632Sopenharmony_ci
63ffe3c632Sopenharmony_ci    public function writeVarint64($value)
64ffe3c632Sopenharmony_ci    {
65ffe3c632Sopenharmony_ci        $bytes = str_repeat(chr(0), self::MAX_VARINT64_BYTES);
66ffe3c632Sopenharmony_ci        $size = self::writeVarintToArray($value, $bytes);
67ffe3c632Sopenharmony_ci        return $this->writeRaw($bytes, $size);
68ffe3c632Sopenharmony_ci    }
69ffe3c632Sopenharmony_ci
70ffe3c632Sopenharmony_ci    public function writeLittleEndian32($value)
71ffe3c632Sopenharmony_ci    {
72ffe3c632Sopenharmony_ci        $bytes = str_repeat(chr(0), 4);
73ffe3c632Sopenharmony_ci        $size = self::writeLittleEndian32ToArray($value, $bytes);
74ffe3c632Sopenharmony_ci        return $this->writeRaw($bytes, $size);
75ffe3c632Sopenharmony_ci    }
76ffe3c632Sopenharmony_ci
77ffe3c632Sopenharmony_ci    public function writeLittleEndian64($value)
78ffe3c632Sopenharmony_ci    {
79ffe3c632Sopenharmony_ci        $bytes = str_repeat(chr(0), 8);
80ffe3c632Sopenharmony_ci        $size = self::writeLittleEndian64ToArray($value, $bytes);
81ffe3c632Sopenharmony_ci        return $this->writeRaw($bytes, $size);
82ffe3c632Sopenharmony_ci    }
83ffe3c632Sopenharmony_ci
84ffe3c632Sopenharmony_ci    public function writeTag($tag)
85ffe3c632Sopenharmony_ci    {
86ffe3c632Sopenharmony_ci        return $this->writeVarint32($tag, true);
87ffe3c632Sopenharmony_ci    }
88ffe3c632Sopenharmony_ci
89ffe3c632Sopenharmony_ci    public function writeRaw($data, $size)
90ffe3c632Sopenharmony_ci    {
91ffe3c632Sopenharmony_ci        if ($this->buffer_size < $size) {
92ffe3c632Sopenharmony_ci            trigger_error("Output stream doesn't have enough buffer.");
93ffe3c632Sopenharmony_ci            return false;
94ffe3c632Sopenharmony_ci        }
95ffe3c632Sopenharmony_ci
96ffe3c632Sopenharmony_ci        for ($i = 0; $i < $size; $i++) {
97ffe3c632Sopenharmony_ci            $this->buffer[$this->current] = $data[$i];
98ffe3c632Sopenharmony_ci            $this->current++;
99ffe3c632Sopenharmony_ci            $this->buffer_size--;
100ffe3c632Sopenharmony_ci        }
101ffe3c632Sopenharmony_ci        return true;
102ffe3c632Sopenharmony_ci    }
103ffe3c632Sopenharmony_ci
104ffe3c632Sopenharmony_ci    public static function writeVarintToArray($value, &$buffer, $trim = false)
105ffe3c632Sopenharmony_ci    {
106ffe3c632Sopenharmony_ci        $current = 0;
107ffe3c632Sopenharmony_ci
108ffe3c632Sopenharmony_ci        $high = 0;
109ffe3c632Sopenharmony_ci        $low = 0;
110ffe3c632Sopenharmony_ci        if (PHP_INT_SIZE == 4) {
111ffe3c632Sopenharmony_ci            GPBUtil::divideInt64ToInt32($value, $high, $low, $trim);
112ffe3c632Sopenharmony_ci        } else {
113ffe3c632Sopenharmony_ci            $low = $value;
114ffe3c632Sopenharmony_ci        }
115ffe3c632Sopenharmony_ci
116ffe3c632Sopenharmony_ci        while (($low >= 0x80 || $low < 0) || $high != 0) {
117ffe3c632Sopenharmony_ci            $buffer[$current] = chr($low | 0x80);
118ffe3c632Sopenharmony_ci            $value = ($value >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7));
119ffe3c632Sopenharmony_ci            $carry = ($high & 0x7F) << ((PHP_INT_SIZE << 3) - 7);
120ffe3c632Sopenharmony_ci            $high = ($high >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7));
121ffe3c632Sopenharmony_ci            $low = (($low >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7)) | $carry);
122ffe3c632Sopenharmony_ci            $current++;
123ffe3c632Sopenharmony_ci        }
124ffe3c632Sopenharmony_ci        $buffer[$current] = chr($low);
125ffe3c632Sopenharmony_ci        return $current + 1;
126ffe3c632Sopenharmony_ci    }
127ffe3c632Sopenharmony_ci
128ffe3c632Sopenharmony_ci    private static function writeLittleEndian32ToArray($value, &$buffer)
129ffe3c632Sopenharmony_ci    {
130ffe3c632Sopenharmony_ci        $buffer[0] = chr($value & 0x000000FF);
131ffe3c632Sopenharmony_ci        $buffer[1] = chr(($value >> 8) & 0x000000FF);
132ffe3c632Sopenharmony_ci        $buffer[2] = chr(($value >> 16) & 0x000000FF);
133ffe3c632Sopenharmony_ci        $buffer[3] = chr(($value >> 24) & 0x000000FF);
134ffe3c632Sopenharmony_ci        return 4;
135ffe3c632Sopenharmony_ci    }
136ffe3c632Sopenharmony_ci
137ffe3c632Sopenharmony_ci    private static function writeLittleEndian64ToArray($value, &$buffer)
138ffe3c632Sopenharmony_ci    {
139ffe3c632Sopenharmony_ci        $high = 0;
140ffe3c632Sopenharmony_ci        $low = 0;
141ffe3c632Sopenharmony_ci        if (PHP_INT_SIZE == 4) {
142ffe3c632Sopenharmony_ci            GPBUtil::divideInt64ToInt32($value, $high, $low);
143ffe3c632Sopenharmony_ci        } else {
144ffe3c632Sopenharmony_ci            $low = $value & 0xFFFFFFFF;
145ffe3c632Sopenharmony_ci            $high = ($value >> 32) & 0xFFFFFFFF;
146ffe3c632Sopenharmony_ci        }
147ffe3c632Sopenharmony_ci
148ffe3c632Sopenharmony_ci        $buffer[0] = chr($low & 0x000000FF);
149ffe3c632Sopenharmony_ci        $buffer[1] = chr(($low >> 8) & 0x000000FF);
150ffe3c632Sopenharmony_ci        $buffer[2] = chr(($low >> 16) & 0x000000FF);
151ffe3c632Sopenharmony_ci        $buffer[3] = chr(($low >> 24) & 0x000000FF);
152ffe3c632Sopenharmony_ci        $buffer[4] = chr($high & 0x000000FF);
153ffe3c632Sopenharmony_ci        $buffer[5] = chr(($high >> 8) & 0x000000FF);
154ffe3c632Sopenharmony_ci        $buffer[6] = chr(($high >> 16) & 0x000000FF);
155ffe3c632Sopenharmony_ci        $buffer[7] = chr(($high >> 24) & 0x000000FF);
156ffe3c632Sopenharmony_ci        return 8;
157ffe3c632Sopenharmony_ci    }
158ffe3c632Sopenharmony_ci
159ffe3c632Sopenharmony_ci}
160