Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: third_party/protobuf/php/src/Google/Protobuf/Internal/GPBWire.php

Issue 2599263002: third_party/protobuf: Update to HEAD (f52e188fe4) (Closed)
Patch Set: Address comments Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <?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
33 namespace Google\Protobuf\Internal;
34
35 class GPBWire
36 {
37
38 const TAG_TYPE_BITS = 3;
39
40 const WIRETYPE_VARINT = 0;
41 const WIRETYPE_FIXED64 = 1;
42 const WIRETYPE_LENGTH_DELIMITED = 2;
43 const WIRETYPE_START_GROUP = 3;
44 const WIRETYPE_END_GROUP = 4;
45 const WIRETYPE_FIXED32 = 5;
46
47 const UNKNOWN = 0;
48 const NORMAL_FORMAT = 1;
49 const PACKED_FORMAT = 2;
50
51 public static function getTagFieldNumber($tag)
52 {
53 return ($tag >> self::TAG_TYPE_BITS) &
54 (1 << ((PHP_INT_SIZE * 8) - self::TAG_TYPE_BITS)) - 1;
55 }
56
57 public static function getTagWireType($tag)
58 {
59 return $tag & 0x7;
60 }
61
62 public static function getWireType($type)
63 {
64 switch ($type) {
65 case GPBType::FLOAT:
66 case GPBType::FIXED32:
67 case GPBType::SFIXED32:
68 return self::WIRETYPE_FIXED32;
69 case GPBType::DOUBLE:
70 case GPBType::FIXED64:
71 case GPBType::SFIXED64:
72 return self::WIRETYPE_FIXED64;
73 case GPBType::UINT32:
74 case GPBType::UINT64:
75 case GPBType::INT32:
76 case GPBType::INT64:
77 case GPBType::SINT32:
78 case GPBType::SINT64:
79 case GPBType::ENUM:
80 case GPBType::BOOL:
81 return self::WIRETYPE_VARINT;
82 case GPBType::STRING:
83 case GPBType::BYTES:
84 case GPBType::MESSAGE:
85 return self::WIRETYPE_LENGTH_DELIMITED;
86 case GPBType::GROUP:
87 user_error("Unsupported type.");
88 return 0;
89 default:
90 user_error("Unsupported type.");
91 return 0;
92 }
93 }
94
95 // ZigZag Transform: Encodes signed integers so that they can be effectively
96 // used with varint encoding.
97 //
98 // varint operates on unsigned integers, encoding smaller numbers into fewer
99 // bytes. If you try to use it on a signed integer, it will treat this
100 // number as a very large unsigned integer, which means that even small
101 // signed numbers like -1 will take the maximum number of bytes (10) to
102 // encode. zigZagEncode() maps signed integers to unsigned in such a way
103 // that those with a small absolute value will have smaller encoded values,
104 // making them appropriate for encoding using varint.
105 //
106 // int32 -> uint32
107 // -------------------------
108 // 0 -> 0
109 // -1 -> 1
110 // 1 -> 2
111 // -2 -> 3
112 // ... -> ...
113 // 2147483647 -> 4294967294
114 // -2147483648 -> 4294967295
115 //
116 // >> encode >>
117 // << decode <<
118 public static function zigZagEncode32($int32)
119 {
120 // Fill high 32 bits.
121 if (PHP_INT_SIZE === 8) {
122 $int32 |= ((($int32 << 32) >> 31) & (0xFFFFFFFF << 32));
123 }
124
125 $uint32 = ($int32 << 1) ^ ($int32 >> 31);
126
127 // Fill high 32 bits.
128 if (PHP_INT_SIZE === 8) {
129 $uint32 |= ((($uint32 << 32) >> 31) & (0xFFFFFFFF << 32));
130 }
131
132 return $uint32;
133 }
134
135 public static function zigZagDecode32($uint32)
136 {
137 // Fill high 32 bits.
138 if (PHP_INT_SIZE === 8) {
139 $uint32 |= ($uint32 & 0xFFFFFFFF);
140 }
141
142 $int32 = (($uint32 >> 1) & 0x7FFFFFFF) ^ (-($uint32 & 1));
143
144 return $int32;
145 }
146
147 public static function zigZagEncode64($int64)
148 {
149 if (PHP_INT_SIZE == 4) {
150 if (bccomp($int64, 0) >= 0) {
151 return bcmul($int64, 2);
152 } else {
153 return bcsub(bcmul(bcsub(0, $int64), 2), 1);
154 }
155 } else {
156 return ($int64 << 1) ^ ($int64 >> 63);
157 }
158 }
159
160 public static function zigZagDecode64($uint64)
161 {
162 if (PHP_INT_SIZE == 4) {
163 if (bcmod($uint64, 2) == 0) {
164 return bcdiv($uint64, 2, 0);
165 } else {
166 return bcsub(0, bcdiv(bcadd($uint64, 1), 2, 0));
167 }
168 } else {
169 return (($uint64 >> 1) & 0x7FFFFFFFFFFFFFFF) ^ (-($uint64 & 1));
170 }
171 }
172
173 public static function readInt32(&$input, &$value)
174 {
175 return $input->readVarint32($value);
176 }
177
178 public static function readInt64(&$input, &$value)
179 {
180 return $input->readVarint64($value);
181 }
182
183 public static function readUint32(&$input, &$value)
184 {
185 return self::readInt32($input, $value);
186 }
187
188 public static function readUint64(&$input, &$value)
189 {
190 return self::readInt64($input, $value);
191 }
192
193 public static function readSint32(&$input, &$value)
194 {
195 if (!$input->readVarint32($value)) {
196 return false;
197 }
198 $value = GPBWire::zigZagDecode32($value);
199 return true;
200 }
201
202 public static function readSint64(&$input, &$value)
203 {
204 if (!$input->readVarint64($value)) {
205 return false;
206 }
207 $value = GPBWire::zigZagDecode64($value);
208 return true;
209 }
210
211 public static function readFixed32(&$input, &$value)
212 {
213 return $input->readLittleEndian32($value);
214 }
215
216 public static function readFixed64(&$input, &$value)
217 {
218 return $input->readLittleEndian64($value);
219 }
220
221 public static function readSfixed32(&$input, &$value)
222 {
223 if (!self::readFixed32($input, $value)) {
224 return false;
225 }
226 if (PHP_INT_SIZE === 8) {
227 $value |= (-($value >> 31) << 32);
228 }
229 return true;
230 }
231
232 public static function readSfixed64(&$input, &$value)
233 {
234 return $input->readLittleEndian64($value);
235 }
236
237 public static function readFloat(&$input, &$value)
238 {
239 $data = null;
240 if (!$input->readRaw(4, $data)) {
241 return false;
242 }
243 $value = unpack('f', $data)[1];
244 return true;
245 }
246
247 public static function readDouble(&$input, &$value)
248 {
249 $data = null;
250 if (!$input->readRaw(8, $data)) {
251 return false;
252 }
253 $value = unpack('d', $data)[1];
254 return true;
255 }
256
257 public static function readBool(&$input, &$value)
258 {
259 if (!$input->readVarint64($value)) {
260 return false;
261 }
262 if ($value == 0) {
263 $value = false;
264 } else {
265 $value = true;
266 }
267 return true;
268 }
269
270 public static function readString(&$input, &$value)
271 {
272 $length = 0;
273 return $input->readVarintSizeAsInt($length) && $input->readRaw($length, $value);
274 }
275
276 public static function readMessage(&$input, &$message)
277 {
278 $length = 0;
279 if (!$input->readVarintSizeAsInt($length)) {
280 return false;
281 }
282 $old_limit = 0;
283 $recursion_limit = 0;
284 $input->incrementRecursionDepthAndPushLimit(
285 $length,
286 $old_limit,
287 $recursion_limit);
288 if ($recursion_limit < 0 || !$message->parseFromStream($input)) {
289 return false;
290 }
291 return $input->decrementRecursionDepthAndPopLimit($old_limit);
292 }
293
294 public static function writeTag(&$output, $tag)
295 {
296 return $output->writeTag($tag);
297 }
298
299 public static function writeInt32(&$output, $value)
300 {
301 return $output->writeVarint32($value);
302 }
303
304 public static function writeInt64(&$output, $value)
305 {
306 return $output->writeVarint64($value);
307 }
308
309 public static function writeUint32(&$output, $value)
310 {
311 return $output->writeVarint32($value);
312 }
313
314 public static function writeUint64(&$output, $value)
315 {
316 return $output->writeVarint64($value);
317 }
318
319 public static function writeSint32(&$output, $value)
320 {
321 $value = GPBWire::zigZagEncode32($value);
322 return $output->writeVarint64($value);
323 }
324
325 public static function writeSint64(&$output, $value)
326 {
327 $value = GPBWire::zigZagEncode64($value);
328 return $output->writeVarint64($value);
329 }
330
331 public static function writeFixed32(&$output, $value)
332 {
333 return $output->writeLittleEndian32($value);
334 }
335
336 public static function writeFixed64(&$output, $value)
337 {
338 return $output->writeLittleEndian64($value);
339 }
340
341 public static function writeSfixed32(&$output, $value)
342 {
343 return $output->writeLittleEndian32($value);
344 }
345
346 public static function writeSfixed64(&$output, $value)
347 {
348 return $output->writeLittleEndian64($value);
349 }
350
351 public static function writeBool(&$output, $value)
352 {
353 if ($value) {
354 return $output->writeVarint32(1);
355 } else {
356 return $output->writeVarint32(0);
357 }
358 }
359
360 public static function writeFloat(&$output, $value)
361 {
362 $data = pack("f", $value);
363 return $output->writeRaw($data, 4);
364 }
365
366 public static function writeDouble(&$output, $value)
367 {
368 $data = pack("d", $value);
369 return $output->writeRaw($data, 8);
370 }
371
372 public static function writeString(&$output, $value)
373 {
374 return self::writeBytes($output, $value);
375 }
376
377 public static function writeBytes(&$output, $value)
378 {
379 $size = strlen($value);
380 if (!$output->writeVarint32($size)) {
381 return false;
382 }
383 return $output->writeRaw($value, $size);
384 }
385
386 public static function writeMessage(&$output, $value)
387 {
388 $size = $value->byteSize();
389 if (!$output->writeVarint32($size)) {
390 return false;
391 }
392 return $value->serializeToStream($output);
393 }
394
395 public static function makeTag($number, $type)
396 {
397 return ($number << 3) | self::getWireType($type);
398 }
399
400 public static function tagSize($field)
401 {
402 $tag = self::makeTag($field->getNumber(), $field->getType());
403 return self::varint32Size($tag);
404 }
405
406 public static function varint32Size($value)
407 {
408 if ($value < 0) {
409 return 5;
410 }
411 if ($value < (1 << 7)) {
412 return 1;
413 }
414 if ($value < (1 << 14)) {
415 return 2;
416 }
417 if ($value < (1 << 21)) {
418 return 3;
419 }
420 if ($value < (1 << 28)) {
421 return 4;
422 }
423 return 5;
424 }
425
426 public static function sint32Size($value)
427 {
428 $value = self::zigZagEncode32($value);
429 return self::varint32Size($value);
430 }
431
432 public static function sint64Size($value)
433 {
434 $value = self::zigZagEncode64($value);
435 return self::varint64Size($value);
436 }
437
438 public static function varint64Size($value)
439 {
440 if ($value < 0) {
441 return 10;
442 }
443 if ($value < (1 << 7)) {
444 return 1;
445 }
446 if ($value < (1 << 14)) {
447 return 2;
448 }
449 if ($value < (1 << 21)) {
450 return 3;
451 }
452 if ($value < (1 << 28)) {
453 return 4;
454 }
455 if ($value < (1 << 35)) {
456 return 5;
457 }
458 if ($value < (1 << 42)) {
459 return 6;
460 }
461 if ($value < (1 << 49)) {
462 return 7;
463 }
464 if ($value < (1 << 56)) {
465 return 8;
466 }
467 return 9;
468 }
469
470 public static function serializeFieldToStream(
471 $value,
472 $field,
473 $need_tag,
474 &$output)
475 {
476 if ($need_tag) {
477 if (!GPBWire::writeTag(
478 $output,
479 self::makeTag(
480 $field->getNumber(),
481 $field->getType()))) {
482 return false;
483 }
484 }
485 switch ($field->getType()) {
486 case GPBType::DOUBLE:
487 if (!GPBWire::writeDouble($output, $value)) {
488 return false;
489 }
490 break;
491 case GPBType::FLOAT:
492 if (!GPBWire::writeFloat($output, $value)) {
493 return false;
494 }
495 break;
496 case GPBType::INT64:
497 if (!GPBWire::writeInt64($output, $value)) {
498 return false;
499 }
500 break;
501 case GPBType::UINT64:
502 if (!GPBWire::writeUint64($output, $value)) {
503 return false;
504 }
505 break;
506 case GPBType::INT32:
507 if (!GPBWire::writeInt32($output, $value)) {
508 return false;
509 }
510 break;
511 case GPBType::FIXED32:
512 if (!GPBWire::writeFixed32($output, $value)) {
513 return false;
514 }
515 break;
516 case GPBType::FIXED64:
517 if (!GPBWire::writeFixed64($output, $value)) {
518 return false;
519 }
520 break;
521 case GPBType::BOOL:
522 if (!GPBWire::writeBool($output, $value)) {
523 return false;
524 }
525 break;
526 case GPBType::STRING:
527 if (!GPBWire::writeString($output, $value)) {
528 return false;
529 }
530 break;
531 // case GPBType::GROUP:
532 // echo "GROUP\xA";
533 // trigger_error("Not implemented.", E_ERROR);
534 // break;
535 case GPBType::MESSAGE:
536 if (!GPBWire::writeMessage($output, $value)) {
537 return false;
538 }
539 break;
540 case GPBType::BYTES:
541 if (!GPBWire::writeBytes($output, $value)) {
542 return false;
543 }
544 break;
545 case GPBType::UINT32:
546 if (!GPBWire::writeUint32($output, $value)) {
547 return false;
548 }
549 break;
550 case GPBType::ENUM:
551 if (!GPBWire::writeInt32($output, $value)) {
552 return false;
553 }
554 break;
555 case GPBType::SFIXED32:
556 if (!GPBWire::writeSfixed32($output, $value)) {
557 return false;
558 }
559 break;
560 case GPBType::SFIXED64:
561 if (!GPBWire::writeSfixed64($output, $value)) {
562 return false;
563 }
564 break;
565 case GPBType::SINT32:
566 if (!GPBWire::writeSint32($output, $value)) {
567 return false;
568 }
569 break;
570 case GPBType::SINT64:
571 if (!GPBWire::writeSint64($output, $value)) {
572 return false;
573 }
574 break;
575 default:
576 user_error("Unsupported type.");
577 return false;
578 }
579
580 return true;
581 }
582 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698