PageRenderTime 56ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/proto/protocolbuffers.inc.php

https://github.com/dgnakouri/android-market-api-php
PHP | 316 lines | 220 code | 40 blank | 56 comment | 41 complexity | 52855cab6e6398869cb082217a0f0a72 MD5 | raw file
  1. <?php
  2. class ProtobufEnum {
  3. public static function toString($value) {
  4. if (is_null($value))
  5. return null;
  6. if (array_key_exists($value, self::$_values))
  7. return self::$_values[$value];
  8. return 'UNKNOWN';
  9. }
  10. }
  11. class ProtobufMessage {
  12. function __construct($fp = NULL, &$limit = PHP_INT_MAX) {
  13. if($fp !== NULL) {
  14. if (is_string($fp)) {
  15. // If the input is a string, turn it into a stream and decode it
  16. $str = $fp;
  17. $fp = fopen('php://memory', 'r+b');
  18. fwrite($fp, $str);
  19. rewind($fp);
  20. }
  21. $this->read($fp, $limit);
  22. if (isset($str))
  23. fclose($fp);
  24. }
  25. }
  26. }
  27. /**
  28. * Class to aid in the parsing and creating of Protocol Buffer Messages
  29. * This class should be included by the developer before they use a
  30. * generated protobuf class.
  31. *
  32. * @author Andrew Brampton
  33. *
  34. */
  35. class Protobuf {
  36. const TYPE_DOUBLE = 1; // double, exactly eight bytes on the wire.
  37. const TYPE_FLOAT = 2; // float, exactly four bytes on the wire.
  38. const TYPE_INT64 = 3; // int64, varint on the wire. Negative numbers
  39. // take 10 bytes. Use TYPE_SINT64 if negative
  40. // values are likely.
  41. const TYPE_UINT64 = 4; // uint64, varint on the wire.
  42. const TYPE_INT32 = 5; // int32, varint on the wire. Negative numbers
  43. // take 10 bytes. Use TYPE_SINT32 if negative
  44. // values are likely.
  45. const TYPE_FIXED64 = 6; // uint64, exactly eight bytes on the wire.
  46. const TYPE_FIXED32 = 7; // uint32, exactly four bytes on the wire.
  47. const TYPE_BOOL = 8; // bool, varint on the wire.
  48. const TYPE_STRING = 9; // UTF-8 text.
  49. const TYPE_GROUP = 10; // Tag-delimited message. Deprecated.
  50. const TYPE_MESSAGE = 11; // Length-delimited message.
  51. const TYPE_BYTES = 12; // Arbitrary byte array.
  52. const TYPE_UINT32 = 13; // uint32, varint on the wire
  53. const TYPE_ENUM = 14; // Enum, varint on the wire
  54. const TYPE_SFIXED32 = 15; // int32, exactly four bytes on the wire
  55. const TYPE_SFIXED64 = 16; // int64, exactly eight bytes on the wire
  56. const TYPE_SINT32 = 17; // int32, ZigZag-encoded varint on the wire
  57. const TYPE_SINT64 = 18; // int64, ZigZag-encoded varint on the wire
  58. /**
  59. * Returns a string representing this wiretype
  60. */
  61. public static function get_wiretype($wire_type) {
  62. switch ($wire_type) {
  63. case 0: return 'varint';
  64. case 1: return '64-bit';
  65. case 2: return 'length-delimited';
  66. case 3: return 'group start';
  67. case 4: return 'group end';
  68. case 5: return '32-bit';
  69. default: return 'unknown';
  70. }
  71. }
  72. /**
  73. * Returns how big (in bytes) this number would be as a varint
  74. */
  75. public static function size_varint($i) {
  76. /* $len = 0;
  77. do {
  78. $i = $i >> 7;
  79. $len++;
  80. } while ($i != 0);
  81. return $len;
  82. */
  83. // TODO Change to a binary search
  84. if ($i < 0x80)
  85. return 1;
  86. if ($i < 0x4000)
  87. return 2;
  88. if ($i < 0x200000)
  89. return 3;
  90. if ($i < 0x10000000)
  91. return 4;
  92. if ($i < 0x800000000)
  93. return 5;
  94. if ($i < 0x40000000000)
  95. return 6;
  96. if ($i < 0x2000000000000)
  97. return 7;
  98. if ($i < 0x100000000000000)
  99. return 8;
  100. if ($i < 0x8000000000000000)
  101. return 9;
  102. }
  103. /**
  104. * Tries to read a varint from $fp.
  105. * @returns the Varint from the stream, or false if the stream has reached eof.
  106. */
  107. public static function read_varint($fp, &$limit = null) {
  108. $value = '';
  109. $len = 0;
  110. do { // Keep reading until we find the last byte
  111. $b = fread($fp, 1);
  112. if ($b === false)
  113. throw new Exception("read_varint(): Error reading byte");
  114. if (strlen($b) < 1)
  115. break;
  116. $value .= $b;
  117. $len++;
  118. } while ($b >= "\x80");
  119. if ($len == 0) {
  120. if (feof($fp))
  121. return false;
  122. throw new Exception("read_varint(): Error reading byte");
  123. }
  124. if ($limit !== null)
  125. $limit -= $len;
  126. $i = 0;
  127. $shift = 0;
  128. for ($j = 0; $j < $len; $j++) {
  129. $i |= ((ord($value[$j]) & 0x7F) << $shift);
  130. $shift += 7;
  131. }
  132. return $i;
  133. }
  134. public static function read_double($fp){throw "I've not coded it yet Exception";}
  135. public static function read_float ($fp){throw "I've not coded it yet Exception";}
  136. public static function read_uint64($fp){throw "I've not coded it yet Exception";}
  137. public static function read_int64 ($fp){throw "I've not coded it yet Exception";}
  138. public static function read_uint32($fp){throw "I've not coded it yet Exception";}
  139. public static function read_int32 ($fp){throw "I've not coded it yet Exception";}
  140. public static function read_zint32($fp){throw "I've not coded it yet Exception";}
  141. public static function read_zint64($fp){throw "I've not coded it yet Exception";}
  142. /**
  143. * Writes a varint to $fp
  144. * returns the number of bytes written
  145. * @param $fp
  146. * @param $i The int to encode
  147. * @return The number of bytes written
  148. */
  149. public static function write_varint($fp, $i) {
  150. $len = 0;
  151. do {
  152. $v = $i & 0x7F;
  153. $i = $i >> 7;
  154. if ($i != 0)
  155. $v |= 0x80;
  156. if (fwrite($fp, chr($v)) !== 1)
  157. throw new Exception("write_varint(): Error writing byte");
  158. $len++;
  159. } while ($i != 0);
  160. return $len;
  161. }
  162. public static function write_double($fp, $d){throw "I've not coded it yet Exception";}
  163. public static function write_float ($fp, $f){throw "I've not coded it yet Exception";}
  164. public static function write_uint64($fp, $i){throw "I've not coded it yet Exception";}
  165. public static function write_int64 ($fp, $i){throw "I've not coded it yet Exception";}
  166. public static function write_uint32($fp, $i){throw "I've not coded it yet Exception";}
  167. public static function write_int32 ($fp, $i){throw "I've not coded it yet Exception";}
  168. public static function write_zint32($fp, $i){throw "I've not coded it yet Exception";}
  169. public static function write_zint64($fp, $i){throw "I've not coded it yet Exception";}
  170. /**
  171. * Seek past a varint
  172. */
  173. public static function skip_varint($fp) {
  174. $len = 0;
  175. do { // Keep reading until we find the last byte
  176. $b = fread($fp, 1);
  177. if ($b === false)
  178. throw new Exception("skip(varint): Error reading byte");
  179. $len++;
  180. } while ($b >= "\x80");
  181. return $len;
  182. }
  183. /**
  184. * Seek past the current field
  185. */
  186. public static function skip_field($fp, $wire_type) {
  187. switch ($wire_type) {
  188. case 0: // varint
  189. return Protobuf::skip_varint($fp);
  190. case 1: // 64bit
  191. if (fseek($fp, 8, SEEK_CUR) === -1)
  192. throw new Exception('skip(' . ProtoBuf::get_wiretype(1) . '): Error seeking');
  193. return 8;
  194. case 2: // length delimited
  195. $varlen = 0;
  196. $len = Protobuf::read_varint($fp, $varlen);
  197. if (fseek($fp, $len, SEEK_CUR) === -1)
  198. throw new Exception('skip(' . ProtoBuf::get_wiretype(2) . '): Error seeking');
  199. return $len - $varlen;
  200. //case 3: // Start group TODO we must keep looping until we find the closing end grou
  201. //case 4: // End group - We should never skip a end group!
  202. // return 0; // Do nothing
  203. case 5: // 32bit
  204. if (fseek($fp, 4, SEEK_CUR) === -1)
  205. throw new Exception('skip('. ProtoBuf::get_wiretype(5) . '): Error seeking');
  206. return 4;
  207. default:
  208. throw new Exception('skip('. ProtoBuf::get_wiretype($wire_type) . '): Unsupported wire_type');
  209. }
  210. }
  211. /**
  212. * Read a unknown field from the stream and return its raw bytes
  213. */
  214. public static function read_field($fp, $wire_type, &$limit = null) {
  215. switch ($wire_type) {
  216. case 0: // varint
  217. return Protobuf::read_varint($fp, $limit);
  218. case 1: // 64bit
  219. $limit -= 8;
  220. return fread($fp, 8);
  221. case 2: // length delimited
  222. $len = Protobuf::read_varint($fp, $limit);
  223. $limit -= $len;
  224. return fread($fp, $len);
  225. //case 3: // Start group TODO we must keep looping until we find the closing end grou
  226. case (3||4||7):
  227. return null;
  228. //case 4: // End group - We should never skip a end group!
  229. // return 0; // Do nothing
  230. case 5: // 32bit
  231. $limit -= 4;
  232. return fread($fp, 4);
  233. default:
  234. throw new Exception('read_unknown('. ProtoBuf::get_wiretype($wire_type) . '): Unsupported wire_type');
  235. }
  236. }
  237. /**
  238. * Used to aid in pretty printing of Protobuf objects
  239. */
  240. private static $print_depth = 0;
  241. private static $indent_char = "\t";
  242. private static $print_limit = 50;
  243. public static function toString($key, $value) {
  244. if (is_null($value))
  245. return;
  246. $ret = str_repeat(self::$indent_char, self::$print_depth) . "$key=>";
  247. if (is_array($value)) {
  248. $ret .= "array(\n";
  249. self::$print_depth++;
  250. foreach($value as $i => $v)
  251. $ret .= self::toString("[$i]", $v);
  252. self::$print_depth--;
  253. $ret .= str_repeat(self::$indent_char, self::$print_depth) . ")\n";
  254. } else {
  255. if (is_object($value)) {
  256. self::$print_depth++;
  257. $ret .= get_class($value) . "(\n";
  258. $ret .= $value->__toString() . "\n";
  259. self::$print_depth--;
  260. $ret .= str_repeat(self::$indent_char, self::$print_depth) . ")\n";
  261. } elseif (is_string($value)) {
  262. $safevalue = addcslashes($value, "\0..\37\177..\377");
  263. if (strlen($safevalue) > self::$print_limit) {
  264. $safevalue = substr($safevalue, 0, self::$print_limit) . '...';
  265. }
  266. $ret .= '"' . $safevalue . '" (' . strlen($value) . " bytes)\n";
  267. } elseif (is_bool($value)) {
  268. $ret .= ($value ? 'true' : 'false') . "\n";
  269. } else {
  270. $ret .= (string)$value . "\n";
  271. }
  272. }
  273. return $ret;
  274. }
  275. }
  276. ?>