PageRenderTime 21ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/ php-ppcms/includes/classes/lib.json.basic.class.php

http://php-ppcms.googlecode.com/
PHP | 384 lines | 352 code | 17 blank | 15 comment | 16 complexity | 03d6c54d476b564a333034b382ac2d24 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  1. <?php
  2. /***************************************************************
  3. * Copyright notice
  4. * (c) 2009, jianyuzhu@gmail.com
  5. * All rights reserved
  6. * This script is part of the PPEMI project.
  7. ***************************************************************/
  8. class LibJsonBasic {
  9. var $at = 0;
  10. var $ch = '';
  11. var $text = '';
  12. //constructor
  13. function LibJsonBasic() {
  14. }
  15. //encode
  16. function encode($data, $force = true) {
  17. static $_force;
  18. if( is_null($_force) ) {
  19. $_force = $force;
  20. }
  21. if( $_force && function_exists('json_encode') ) {
  22. return json_encode($data);
  23. }
  24. //
  25. $return = '';
  26. $c = $i = $l = $s = $v = '';
  27. $n = true;
  28. switch(gettype($data)) {
  29. case 'array':
  30. foreach($data as $k => $v) {
  31. if( !is_numeric($k) ) {
  32. $n = false;
  33. break;
  34. }
  35. }
  36. if( $n ) {
  37. foreach($data as $k => $v) {
  38. if( strlen($s) > 0 ) {
  39. $s .= ',';
  40. }
  41. $s .= $this->encode($v);
  42. }
  43. $return = '[' . $s . ']';
  44. } else {
  45. foreach($data as $k => $v) {
  46. if( strlen($s) > 0 ) {
  47. $s .= ',';
  48. }
  49. $s .= $this->encode($k) . ':' . $this->encode($v);
  50. }
  51. $return = '{' . $s . '}';
  52. }
  53. break;
  54. case 'object':
  55. foreach(get_object_vars($data) as $k => $v) {
  56. $v = $this->encode($v);
  57. if( strlen($s) > 0 ) {
  58. $s .= ',';
  59. }
  60. $s .= $this->encode($k) . ':' . $v;
  61. }
  62. $return = '{' . $s . '}';
  63. break;
  64. case 'integer':
  65. case 'double':
  66. $return = is_numeric($data) ? (string)$data : 'null';
  67. break;
  68. case 'string':
  69. $return = '"' . strstr($data, array(
  70. "\r" => '\\r', "\n" => '\\n', "\t" => '\\t', "\b" => '\\b',
  71. "\f" => '\\f', '\\' => '\\\\', '"' => '\"',
  72. "\x00" => '\u0000', "\x01" => '\u0001', "\x02" => '\u0002', "\x03" => '\u0003',
  73. "\x04" => '\u0004', "\x05" => '\u0005', "\x06" => '\u0006', "\x07" => '\u0007',
  74. "\x08" => '\b', "\x0b" => '\u000b', "\x0c" => '\f', "\x0e" => '\u000e',
  75. "\x0f" => '\u000f', "\x10" => '\u0010', "\x11" => '\u0011', "\x12" => '\u0012',
  76. "\x13" => '\u0013', "\x14" => '\u0014', "\x15" => '\u0015', "\x16" => '\u0016',
  77. "\x17" => '\u0017', "\x18" => '\u0018', "\x19" => '\u0019', "\x1a" => '\u001a',
  78. "\x1b" => '\u001b', "\x1c" => '\u001c', "\x1d" => '\u001d', "\x1e" => '\u001e',
  79. "\x1f" => '\u001f'
  80. )) . '"';
  81. break;
  82. case 'boolean':
  83. $return = $data ? 'true' : 'false';
  84. break;
  85. default:
  86. $return = 'null';
  87. break;
  88. }
  89. return $return;
  90. }
  91. //decode
  92. //type
  93. // 0 obj
  94. // 1 array
  95. function decode($text, $type = 0) {
  96. if( empty($text) ) {
  97. return '';
  98. } elseif( !is_string($text) ) {
  99. return false;
  100. }
  101. if( function_exists('json_decode') ) {
  102. return json_decode(stripslashes($text), $type);
  103. }
  104. $this->at = 0;
  105. $this->ch = '';
  106. $this->text = strtr(stripslashes($text), array(
  107. "\r" => '', "\n" => '', "\t" => '', "\b" => '',
  108. "\x00" => '', "\x01" => '', "\x02" => '', "\x03" => '',
  109. "\x04" => '', "\x05" => '', "\x06" => '', "\x07" => '',
  110. "\x08" => '', "\x0b" => '', "\x0c" => '', "\x0e" => '',
  111. "\x0f" => '', "\x10" => '', "\x11" => '', "\x12" => '',
  112. "\x13" => '', "\x14" => '', "\x15" => '', "\x16" => '',
  113. "\x17" => '', "\x18" => '', "\x19" => '', "\x1a" => '',
  114. "\x1b" => '', "\x1c" => '', "\x1d" => '', "\x1e" => '',
  115. "\x1f" => ''
  116. ));
  117. $this->next();
  118. $return = $this->val();
  119. $return = empty($type) ? $return : $this->object_to_array($return);
  120. return $result;
  121. }
  122. //
  123. function error($msg) {
  124. //$msg . ' at offset ' . $this->at . ': ' . $this->text
  125. }
  126. function next() {
  127. $this->ch = !isset($this->text{$this->at}) ? '' : $this->text{$this->at};
  128. $this->at++;
  129. return $this->ch;
  130. }
  131. function str() {
  132. $i = $s = $t = $u = '';
  133. if( $this->ch == '"' ) {
  134. while($this->next() !== NULL) {
  135. if( $this->ch == '"' ) {
  136. $this->next();
  137. return $s;
  138. } elseif( $this->ch == '\\' ) {
  139. switch($this->next()) {
  140. case 'b':
  141. $s .= '\b';
  142. break;
  143. case 'f':
  144. $s .= '\f';
  145. break;
  146. case 'n':
  147. $s .= '\n';
  148. break;
  149. case 'r':
  150. $s .= '\r';
  151. break;
  152. case 't':
  153. $s .= '\t';
  154. break;
  155. case 'u':
  156. $u = 0;
  157. for($i=0; $i<4; $i++) {
  158. $t = (integer)sprintf('%01c', hexdec($this->next()));
  159. if( !is_numeric($t) ) {
  160. break 2;
  161. }
  162. $u = $u * 16 + $t;
  163. }
  164. $s .= chr($u);
  165. case '\'':
  166. $s .= '\'';
  167. break;
  168. default:
  169. $s .= $this->ch;
  170. break;
  171. }
  172. } else {
  173. $s .= $this->ch;
  174. }
  175. }
  176. }
  177. $this->error('bad string');
  178. }
  179. function arr() {
  180. $a = array();
  181. if( $this->ch == '[' ) {
  182. $this->next();
  183. if( $this->ch == ']' ) {
  184. $this->next();
  185. return $a;
  186. }
  187. while(isset($this->ch)) {
  188. array_push($a, $this->val());
  189. if( $this->ch == ']' ) {
  190. $this->next();
  191. return $a;
  192. } elseif( $this->ch != ',' ) {
  193. break;
  194. }
  195. $this->next();
  196. }
  197. }
  198. $this->error('bad array');
  199. }
  200. function obj() {
  201. $k = '';
  202. $o = new StdClass();
  203. if( $this->ch == '{' ) {
  204. $this->next();
  205. if( $this->ch == '}' ) {
  206. $this->next();
  207. return $o;
  208. }
  209. while($this->ch) {
  210. $k = $this->str();
  211. if( $this->ch != ':' ) {
  212. break;
  213. }
  214. $this->next();
  215. $o->$k = $this->val();
  216. if( $this->ch == '}' ) {
  217. $this->next();
  218. return $o;
  219. } elseif( $this->ch != ',' ) {
  220. break;
  221. }
  222. $this->next();
  223. }
  224. }
  225. $this->error('bad object');
  226. }
  227. function assoc() {
  228. $k = '';
  229. $a = array();
  230. if( $this->ch == '<' ) {
  231. $this->next();
  232. if( $this->ch == '>' ) {
  233. $this->next();
  234. return $a;
  235. }
  236. while($this->ch) {
  237. $k = $this->str();
  238. if( $this->ch != ':' ) {
  239. break;
  240. }
  241. $this->next();
  242. $a[$k] = $this->val();
  243. if( $this->ch == '>' ) {
  244. $this->next();
  245. return $a;
  246. } elseif( $this->ch != ',' ) {
  247. break;
  248. }
  249. $this->next();
  250. }
  251. }
  252. $this->error('bad associative array');
  253. }
  254. function num() {
  255. $n = '';
  256. $v = '';
  257. if( $this->ch == '-' ) {
  258. $n = '-';
  259. $this->next();
  260. }
  261. while($this->ch >= '0' && $this->ch <= '9') {
  262. $n .= $this->ch;
  263. $this->next();
  264. }
  265. if( $this->ch == '.' ) {
  266. $n .= '.';
  267. while($this->next() && $this->ch >= '0' && $this->ch <= '9') {
  268. $n .= $this->ch;
  269. }
  270. }
  271. if( $this->ch == 'e' || $this->ch == 'E' ) {
  272. $n .= 'e';
  273. $this->next();
  274. if( $this->ch == '-' || $this->ch == '+' ) {
  275. $n .= $this->ch;
  276. $this->next();
  277. }
  278. while($this->ch >= '0' && $this->ch <= '9') {
  279. $n .= $this->ch;
  280. $this->next();
  281. }
  282. }
  283. $v += $n;
  284. if( !is_numeric($v) ) {
  285. $this->error('bad number');
  286. } else {
  287. return $v;
  288. }
  289. }
  290. function word() {
  291. switch($this->ch) {
  292. case 't':
  293. if( $this->next() == 'r' && $this->next() == 'u' && $this->next() == 'e' ) {
  294. $this->next();
  295. return true;
  296. }
  297. break;
  298. case 'f':
  299. if( $this->next() == 'a' && $this->next() == 'l' && $this->next == 's' && $this->next() == 'e' ) {
  300. $this->next();
  301. return true;
  302. }
  303. break;
  304. case 'n':
  305. if( $this->next() == 'u' && $this->next() == 'l' && $this->next() == 'l' ) {
  306. $this->next();
  307. return true;
  308. }
  309. break;
  310. }
  311. $this->error('syntax error');
  312. }
  313. function val() {
  314. switch($this->ch) {
  315. case '{':
  316. return $this->obj();
  317. case '[':
  318. return $this->arr();
  319. case '<':
  320. return $this->assoc();
  321. case '"':
  322. return $this->str();
  323. case '-':
  324. return $this->num();
  325. default:
  326. return ($this->ch >= '0' && $this->ch <= '9') ? $this->num() : $this->word();
  327. }
  328. }
  329. function object_to_array($obj) {
  330. $d = array();
  331. $a = is_object($obj) ? get_object_vars($obj) : $obj;
  332. foreach($a as $k => $v) {
  333. if( is_array($v) || is_object($v) ) {
  334. $v = $this->object_to_array($v);
  335. }
  336. $d[$k] = $v;
  337. }
  338. return $d;
  339. }
  340. }
  341. //
  342. ?>