blob: f75e9c6626fa5be6a7e90a3fcca823379119ffb3 [file] [log] [blame]
avm9996399bb77c2020-01-27 03:15:08 +01001<?php
2
3// Protocol Buffers - Google's data interchange format
4// Copyright 2008 Google Inc. All rights reserved.
5// https://developers.google.com/protocol-buffers/
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met:
10//
11// * Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13// * Redistributions in binary form must reproduce the above
14// copyright notice, this list of conditions and the following disclaimer
15// in the documentation and/or other materials provided with the
16// distribution.
17// * Neither the name of Google Inc. nor the names of its
18// contributors may be used to endorse or promote products derived from
19// this software without specific prior written permission.
20//
21// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33namespace Google\Protobuf\Internal;
34
35class CodedOutputStream
36{
37
38 private $buffer;
39 private $buffer_size;
40 private $current;
41
42 const MAX_VARINT64_BYTES = 10;
43
44 public function __construct($size)
45 {
46 $this->current = 0;
47 $this->buffer_size = $size;
48 $this->buffer = str_repeat(chr(0), $this->buffer_size);
49 }
50
51 public function getData()
52 {
53 return $this->buffer;
54 }
55
56 public function writeVarint32($value, $trim)
57 {
58 $bytes = str_repeat(chr(0), self::MAX_VARINT64_BYTES);
59 $size = self::writeVarintToArray($value, $bytes, $trim);
60 return $this->writeRaw($bytes, $size);
61 }
62
63 public function writeVarint64($value)
64 {
65 $bytes = str_repeat(chr(0), self::MAX_VARINT64_BYTES);
66 $size = self::writeVarintToArray($value, $bytes);
67 return $this->writeRaw($bytes, $size);
68 }
69
70 public function writeLittleEndian32($value)
71 {
72 $bytes = str_repeat(chr(0), 4);
73 $size = self::writeLittleEndian32ToArray($value, $bytes);
74 return $this->writeRaw($bytes, $size);
75 }
76
77 public function writeLittleEndian64($value)
78 {
79 $bytes = str_repeat(chr(0), 8);
80 $size = self::writeLittleEndian64ToArray($value, $bytes);
81 return $this->writeRaw($bytes, $size);
82 }
83
84 public function writeTag($tag)
85 {
86 return $this->writeVarint32($tag, true);
87 }
88
89 public function writeRaw($data, $size)
90 {
91 if ($this->buffer_size < $size) {
92 trigger_error("Output stream doesn't have enough buffer.");
93 return false;
94 }
95
96 for ($i = 0; $i < $size; $i++) {
97 $this->buffer[$this->current] = $data[$i];
98 $this->current++;
99 $this->buffer_size--;
100 }
101 return true;
102 }
103
104 public static function writeVarintToArray($value, &$buffer, $trim = false)
105 {
106 $current = 0;
107
108 $high = 0;
109 $low = 0;
110 if (PHP_INT_SIZE == 4) {
111 GPBUtil::divideInt64ToInt32($value, $high, $low, $trim);
112 } else {
113 $low = $value;
114 }
115
116 while (($low >= 0x80 || $low < 0) || $high != 0) {
117 $buffer[$current] = chr($low | 0x80);
118 $value = ($value >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7));
119 $carry = ($high & 0x7F) << ((PHP_INT_SIZE << 3) - 7);
120 $high = ($high >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7));
121 $low = (($low >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7)) | $carry);
122 $current++;
123 }
124 $buffer[$current] = chr($low);
125 return $current + 1;
126 }
127
128 private static function writeLittleEndian32ToArray($value, &$buffer)
129 {
130 $buffer[0] = chr($value & 0x000000FF);
131 $buffer[1] = chr(($value >> 8) & 0x000000FF);
132 $buffer[2] = chr(($value >> 16) & 0x000000FF);
133 $buffer[3] = chr(($value >> 24) & 0x000000FF);
134 return 4;
135 }
136
137 private static function writeLittleEndian64ToArray($value, &$buffer)
138 {
139 $high = 0;
140 $low = 0;
141 if (PHP_INT_SIZE == 4) {
142 GPBUtil::divideInt64ToInt32($value, $high, $low);
143 } else {
144 $low = $value & 0xFFFFFFFF;
145 $high = ($value >> 32) & 0xFFFFFFFF;
146 }
147
148 $buffer[0] = chr($low & 0x000000FF);
149 $buffer[1] = chr(($low >> 8) & 0x000000FF);
150 $buffer[2] = chr(($low >> 16) & 0x000000FF);
151 $buffer[3] = chr(($low >> 24) & 0x000000FF);
152 $buffer[4] = chr($high & 0x000000FF);
153 $buffer[5] = chr(($high >> 8) & 0x000000FF);
154 $buffer[6] = chr(($high >> 16) & 0x000000FF);
155 $buffer[7] = chr(($high >> 24) & 0x000000FF);
156 return 8;
157 }
158
159}