1<?php 2 3/** 4 * This file contains the BinaryReader class. 5 * For more information see the class description below. 6 * 7 * @author Peter Bathory <peter.bathory@cartographia.hu> 8 * @since 2016-02-18 9 * 10 * This code is open-source and licenced under the Modified BSD License. 11 * For the full copyright and license information, please view the LICENSE 12 * file that was distributed with this source code. 13 */ 14 15namespace geoPHP\Adapter; 16 17/** 18 * Helper class BinaryWriter 19 * 20 * A simple binary writer supporting both byte orders 21 */ 22class BinaryWriter 23{ 24 25 const BIG_ENDIAN = 0; 26 const LITTLE_ENDIAN = 1; 27 28 private $endianness = 0; 29 30 public function __construct($endianness = 0) 31 { 32 $this->endianness = $endianness; 33 } 34 35 /** 36 * @return bool Returns true if Writer is in BigEndian mode 37 */ 38 public function isBigEndian() 39 { 40 return $this->endianness === self::BIG_ENDIAN; 41 } 42 43 /** 44 * @return bool Returns true if Writer is in LittleEndian mode 45 */ 46 public function isLittleEndian() 47 { 48 return $this->endianness === self::LITTLE_ENDIAN; 49 } 50 51 /** 52 * Writes a signed 8-bit integer 53 * @param int $value 54 * @return string The integer as a binary string 55 */ 56 public function writeSInt8($value) 57 { 58 return pack('c', $value); 59 } 60 61 /** 62 * Writes an unsigned 8-bit integer 63 * @param int $value 64 * @return string The integer as a binary string 65 */ 66 public function writeUInt8($value) 67 { 68 return pack('C', $value); 69 } 70 71 /** 72 * Writes an unsigned 32-bit integer 73 * @param int $value 74 * @return string The integer as a binary string 75 */ 76 public function writeUInt32($value) 77 { 78 return pack($this->isLittleEndian() ? 'V' : 'N', $value); 79 } 80 81 /** 82 * Writes a double 83 * @param float $value 84 * @return string The floating point number as a binary string 85 */ 86 public function writeDouble($value) 87 { 88 return $this->isLittleEndian() ? pack('d', $value) : strrev(pack('d', $value)); 89 } 90 91 /** 92 * Writes a positive integer as an unsigned base-128 varint 93 * 94 * Ported from https://github.com/cschwarz/wkx/blob/master/lib/binaryreader.js 95 * 96 * @param int $value 97 * @return string The integer as a binary string 98 */ 99 public function writeUVarInt($value) 100 { 101 $out = ''; 102 103 while (($value & 0xFFFFFF80) !== 0) { 104 $out .= $this->writeUInt8(($value & 0x7F) | 0x80); 105 // Zero fill by 7 zero 106 if ($value >= 0) { 107 $value >>= 7; 108 } else { 109 $value = ((~$value) >> 7) ^ (0x7fffffff >> (7 - 1)); 110 } 111 } 112 113 $out .= $this->writeUInt8($value & 0x7F); 114 115 return $out; 116 } 117 118 /** 119 * Writes an integer as a signed base-128 varint 120 * @param int $value 121 * @return string The integer as a binary string 122 */ 123 public function writeSVarInt($value) 124 { 125 return $this->writeUVarInt(self::zigZagEncode($value)); 126 } 127 128 /** 129 * ZigZag encoding maps signed integers to unsigned integers 130 * 131 * @param int $value Signed integer 132 * @return int Encoded positive integer value 133 */ 134 public static function zigZagEncode($value) 135 { 136 return ($value << 1) ^ ($value >> 31); 137 } 138} 139