PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/amfphp/core/shared/util/JSON.php

https://github.com/christoff/as3-youtube-data-api
PHP | 645 lines | 411 code | 100 blank | 134 comment | 94 complexity | 0217e0ea99c4814029c6b9cb7d6ddf26 MD5 | raw file
  1. <?php
  2. /**
  3. * LICENSE: Redistribution and use in source and binary forms, with or
  4. * without modification, are permitted provided that the following
  5. * conditions are met: Redistributions of source code must retain the
  6. * above copyright notice, this list of conditions and the following
  7. * disclaimer. Redistributions in binary form must reproduce the above
  8. * copyright notice, this list of conditions and the following disclaimer
  9. * in the documentation and/or other materials provided with the
  10. * distribution.
  11. *
  12. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  13. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  14. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
  15. * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  17. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  18. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  19. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  20. * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  21. * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  22. * DAMAGE.
  23. *
  24. * @category
  25. * @package Services_JSON
  26. * @author Michal Migurski <mike-json@teczno.com>
  27. * @author Matt Knapp <mdknapp[at]gmail[dot]com>
  28. * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
  29. * @copyright 2005 Michal Migurski
  30. * @license http://www.opensource.org/licenses/bsd-license.php
  31. * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
  32. *
  33. * Note: this is a stripped version of JSON.php to remove pear dependencies and
  34. * encoding capability
  35. */
  36. /**
  37. * Marker constant for Services_JSON::decode(), used to flag stack state
  38. */
  39. define('SERVICES_JSON_SLICE', 1);
  40. /**
  41. * Marker constant for Services_JSON::decode(), used to flag stack state
  42. */
  43. define('SERVICES_JSON_IN_STR', 2);
  44. /**
  45. * Marker constant for Services_JSON::decode(), used to flag stack state
  46. */
  47. define('SERVICES_JSON_IN_ARR', 3);
  48. /**
  49. * Marker constant for Services_JSON::decode(), used to flag stack state
  50. */
  51. define('SERVICES_JSON_IN_OBJ', 4);
  52. /**
  53. * Marker constant for Services_JSON::decode(), used to flag stack state
  54. */
  55. define('SERVICES_JSON_IN_CMT', 5);
  56. /**
  57. * Behavior switch for Services_JSON::decode()
  58. */
  59. define('SERVICES_JSON_LOOSE_TYPE', 16);
  60. /**
  61. * Behavior switch for Services_JSON::decode()
  62. */
  63. define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
  64. class Services_JSON
  65. {
  66. function Services_JSON($use = 0)
  67. {
  68. $this->use = $use;
  69. }
  70. function utf162utf8($utf16)
  71. {
  72. // oh please oh please oh please oh please oh please
  73. if(function_exists('mb_convert_encoding'))
  74. return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
  75. $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
  76. switch(true) {
  77. case ((0x7F & $bytes) == $bytes):
  78. // this case should never be reached, because we are in ASCII range
  79. // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  80. return chr(0x7F & $bytes);
  81. case (0x07FF & $bytes) == $bytes:
  82. // return a 2-byte UTF-8 character
  83. // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  84. return chr(0xC0 | (($bytes >> 6) & 0x1F))
  85. . chr(0x80 | ($bytes & 0x3F));
  86. case (0xFFFF & $bytes) == $bytes:
  87. // return a 3-byte UTF-8 character
  88. // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  89. return chr(0xE0 | (($bytes >> 12) & 0x0F))
  90. . chr(0x80 | (($bytes >> 6) & 0x3F))
  91. . chr(0x80 | ($bytes & 0x3F));
  92. }
  93. // ignoring UTF-32 for now, sorry
  94. return '';
  95. }
  96. function utf82utf16($utf8)
  97. {
  98. // oh please oh please oh please oh please oh please
  99. if(function_exists('mb_convert_encoding'))
  100. return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
  101. switch(strlen($utf8)) {
  102. case 1:
  103. // this case should never be reached, because we are in ASCII range
  104. // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  105. return $ut8;
  106. case 2:
  107. // return a UTF-16 character from a 2-byte UTF-8 char
  108. // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  109. return chr(0x07 & (ord($utf8{0}) >> 2))
  110. . chr((0xC0 & (ord($utf8{0}) << 6))
  111. | (0x3F & ord($utf8{1})));
  112. case 3:
  113. // return a UTF-16 character from a 3-byte UTF-8 char
  114. // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  115. return chr((0xF0 & (ord($utf8{0}) << 4))
  116. | (0x0F & (ord($utf8{1}) >> 2)))
  117. . chr((0xC0 & (ord($utf8{1}) << 6))
  118. | (0x7F & ord($utf8{2})));
  119. }
  120. // ignoring UTF-32 for now, sorry
  121. return '';
  122. }
  123. function name_value($name, $value)
  124. {
  125. $encoded_value = $this->encode($value);
  126. return $this->encode(strval($name)) . ':' . $encoded_value;
  127. }
  128. function reduce_string($str)
  129. {
  130. $str = preg_replace(array(
  131. // eliminate single line comments in '// ...' form
  132. '#^\s*//(.+)$#m',
  133. // eliminate multi-line comments in '/* ... */' form, at start of string
  134. '#^\s*/\*(.+)\*/#Us',
  135. // eliminate multi-line comments in '/* ... */' form, at end of string
  136. '#/\*(.+)\*/\s*$#Us'
  137. ), '', $str);
  138. // eliminate extraneous space
  139. return trim($str);
  140. }
  141. /**
  142. * encodes an arbitrary variable into JSON format
  143. *
  144. * @param mixed $var any number, boolean, string, array, or object to be encoded.
  145. * see argument 1 to Services_JSON() above for array-parsing behavior.
  146. * if var is a strng, note that encode() always expects it
  147. * to be in ASCII or UTF-8 format!
  148. *
  149. * @return mixed JSON string representation of input var or an error if a problem occurs
  150. * @access public
  151. */
  152. function encode($var)
  153. {
  154. switch (gettype($var)) {
  155. case 'boolean':
  156. return $var ? 'true' : 'false';
  157. case 'NULL':
  158. return 'null';
  159. case 'integer':
  160. return (int) $var;
  161. case 'double':
  162. case 'float':
  163. return (float) $var;
  164. case 'string':
  165. // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
  166. $ascii = '';
  167. $strlen_var = strlen($var);
  168. /*
  169. * Iterate over every character in the string,
  170. * escaping with a slash or encoding to UTF-8 where necessary
  171. */
  172. for ($c = 0; $c < $strlen_var; ++$c) {
  173. $ord_var_c = ord($var{$c});
  174. switch (true) {
  175. case $ord_var_c == 0x08:
  176. $ascii .= '\b';
  177. break;
  178. case $ord_var_c == 0x09:
  179. $ascii .= '\t';
  180. break;
  181. case $ord_var_c == 0x0A:
  182. $ascii .= '\n';
  183. break;
  184. case $ord_var_c == 0x0C:
  185. $ascii .= '\f';
  186. break;
  187. case $ord_var_c == 0x0D:
  188. $ascii .= '\r';
  189. break;
  190. case $ord_var_c == 0x22:
  191. case $ord_var_c == 0x2F:
  192. case $ord_var_c == 0x5C:
  193. // double quote, slash, slosh
  194. $ascii .= '\\'.$var{$c};
  195. break;
  196. case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
  197. // characters U-00000000 - U-0000007F (same as ASCII)
  198. $ascii .= $var{$c};
  199. break;
  200. case (($ord_var_c & 0xE0) == 0xC0):
  201. // characters U-00000080 - U-000007FF, mask 110XXXXX
  202. // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  203. $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
  204. $c += 1;
  205. $utf16 = $this->utf82utf16($char);
  206. $ascii .= sprintf('\u%04s', bin2hex($utf16));
  207. break;
  208. case (($ord_var_c & 0xF0) == 0xE0):
  209. // characters U-00000800 - U-0000FFFF, mask 1110XXXX
  210. // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  211. $char = pack('C*', $ord_var_c,
  212. ord($var{$c + 1}),
  213. ord($var{$c + 2}));
  214. $c += 2;
  215. $utf16 = $this->utf82utf16($char);
  216. $ascii .= sprintf('\u%04s', bin2hex($utf16));
  217. break;
  218. case (($ord_var_c & 0xF8) == 0xF0):
  219. // characters U-00010000 - U-001FFFFF, mask 11110XXX
  220. // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  221. $char = pack('C*', $ord_var_c,
  222. ord($var{$c + 1}),
  223. ord($var{$c + 2}),
  224. ord($var{$c + 3}));
  225. $c += 3;
  226. $utf16 = $this->utf82utf16($char);
  227. $ascii .= sprintf('\u%04s', bin2hex($utf16));
  228. break;
  229. case (($ord_var_c & 0xFC) == 0xF8):
  230. // characters U-00200000 - U-03FFFFFF, mask 111110XX
  231. // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  232. $char = pack('C*', $ord_var_c,
  233. ord($var{$c + 1}),
  234. ord($var{$c + 2}),
  235. ord($var{$c + 3}),
  236. ord($var{$c + 4}));
  237. $c += 4;
  238. $utf16 = $this->utf82utf16($char);
  239. $ascii .= sprintf('\u%04s', bin2hex($utf16));
  240. break;
  241. case (($ord_var_c & 0xFE) == 0xFC):
  242. // characters U-04000000 - U-7FFFFFFF, mask 1111110X
  243. // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  244. $char = pack('C*', $ord_var_c,
  245. ord($var{$c + 1}),
  246. ord($var{$c + 2}),
  247. ord($var{$c + 3}),
  248. ord($var{$c + 4}),
  249. ord($var{$c + 5}));
  250. $c += 5;
  251. $utf16 = $this->utf82utf16($char);
  252. $ascii .= sprintf('\u%04s', bin2hex($utf16));
  253. break;
  254. }
  255. }
  256. return '"'.$ascii.'"';
  257. case 'array':
  258. /*
  259. * As per JSON spec if any array key is not an integer
  260. * we must treat the the whole array as an object. We
  261. * also try to catch a sparsely populated associative
  262. * array with numeric keys here because some JS engines
  263. * will create an array with empty indexes up to
  264. * max_index which can cause memory issues and because
  265. * the keys, which may be relevant, will be remapped
  266. * otherwise.
  267. *
  268. * As per the ECMA and JSON specification an object may
  269. * have any string as a property. Unfortunately due to
  270. * a hole in the ECMA specification if the key is a
  271. * ECMA reserved word or starts with a digit the
  272. * parameter is only accessible using ECMAScript's
  273. * bracket notation.
  274. */
  275. // treat as a JSON object
  276. if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
  277. $properties = array_map(array($this, 'name_value'),
  278. array_keys($var),
  279. array_values($var));
  280. return '{' . join(',', $properties) . '}';
  281. }
  282. // treat it like a regular array
  283. $elements = array_map(array($this, 'encode'), $var);
  284. return '[' . join(',', $elements) . ']';
  285. case 'object':
  286. $vars = get_object_vars($var);
  287. $properties = array_map(array($this, 'name_value'),
  288. array_keys($vars),
  289. array_values($vars));
  290. return '{' . join(',', $properties) . '}';
  291. case 'resource':
  292. return null;
  293. default:
  294. return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
  295. ? 'null'
  296. : trigger_error(gettype($var)." can not be encoded as JSON string", E_USER_ERROR);
  297. }
  298. }
  299. function sanitizeType($type)
  300. {
  301. $subtype = -1;
  302. $type = strtolower($type);
  303. if($type == NULL || trim($type) == "")
  304. {
  305. $type = -1;
  306. }
  307. if(strpos($type, ' ') !== false)
  308. {
  309. $str = explode(' ', $type);
  310. if(in_array($str[1], array("result", 'resultset', "recordset", "statement")))
  311. {
  312. $type = "__RECORDSET__";
  313. $subtype = $str[0];
  314. }
  315. }
  316. return array($type, $subtype);
  317. }
  318. function decode($str)
  319. {
  320. $str = $this->reduce_string($str);
  321. switch (strtolower($str)) {
  322. case 'true':
  323. return true;
  324. case 'false':
  325. return false;
  326. case 'null':
  327. return null;
  328. default:
  329. if (is_numeric($str)) {
  330. // Lookie-loo, it's a number
  331. // Return float or int, as appropriate
  332. return ((float)$str == (integer)$str)
  333. ? (integer)$str
  334. : (float)$str;
  335. }
  336. elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
  337. // STRINGS RETURNED IN UTF-8 FORMAT
  338. $delim = substr($str, 0, 1);
  339. $chrs = substr($str, 1, -1);
  340. $utf8 = '';
  341. $strlen_chrs = strlen($chrs);
  342. for ($c = 0; $c < $strlen_chrs; ++$c) {
  343. $substr_chrs_c_2 = substr($chrs, $c, 2);
  344. $ord_chrs_c = ord($chrs{$c});
  345. switch (true) {
  346. case $substr_chrs_c_2 == '\b':
  347. $utf8 .= chr(0x08);
  348. ++$c;
  349. break;
  350. case $substr_chrs_c_2 == '\t':
  351. $utf8 .= chr(0x09);
  352. ++$c;
  353. break;
  354. case $substr_chrs_c_2 == '\n':
  355. $utf8 .= chr(0x0A);
  356. ++$c;
  357. break;
  358. case $substr_chrs_c_2 == '\f':
  359. $utf8 .= chr(0x0C);
  360. ++$c;
  361. break;
  362. case $substr_chrs_c_2 == '\r':
  363. $utf8 .= chr(0x0D);
  364. ++$c;
  365. break;
  366. case $substr_chrs_c_2 == '\\"':
  367. case $substr_chrs_c_2 == '\\\'':
  368. case $substr_chrs_c_2 == '\\\\':
  369. case $substr_chrs_c_2 == '\\/':
  370. if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
  371. ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
  372. $utf8 .= $chrs{++$c};
  373. }
  374. break;
  375. case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
  376. // single, escaped unicode character
  377. $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
  378. . chr(hexdec(substr($chrs, ($c + 4), 2)));
  379. $utf8 .= $this->utf162utf8($utf16);
  380. $c += 5;
  381. break;
  382. case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
  383. $utf8 .= $chrs{$c};
  384. break;
  385. case ($ord_chrs_c & 0xE0) == 0xC0:
  386. // characters U-00000080 - U-000007FF, mask 110XXXXX
  387. //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  388. $utf8 .= substr($chrs, $c, 2);
  389. ++$c;
  390. break;
  391. case ($ord_chrs_c & 0xF0) == 0xE0:
  392. // characters U-00000800 - U-0000FFFF, mask 1110XXXX
  393. // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  394. $utf8 .= substr($chrs, $c, 3);
  395. $c += 2;
  396. break;
  397. case ($ord_chrs_c & 0xF8) == 0xF0:
  398. // characters U-00010000 - U-001FFFFF, mask 11110XXX
  399. // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  400. $utf8 .= substr($chrs, $c, 4);
  401. $c += 3;
  402. break;
  403. case ($ord_chrs_c & 0xFC) == 0xF8:
  404. // characters U-00200000 - U-03FFFFFF, mask 111110XX
  405. // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  406. $utf8 .= substr($chrs, $c, 5);
  407. $c += 4;
  408. break;
  409. case ($ord_chrs_c & 0xFE) == 0xFC:
  410. // characters U-04000000 - U-7FFFFFFF, mask 1111110X
  411. // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  412. $utf8 .= substr($chrs, $c, 6);
  413. $c += 5;
  414. break;
  415. }
  416. }
  417. return $utf8;
  418. } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
  419. // array, or object notation
  420. if ($str{0} == '[') {
  421. $stk = array(SERVICES_JSON_IN_ARR);
  422. $arr = array();
  423. } else {
  424. if ($this->use & SERVICES_JSON_LOOSE_TYPE ) {
  425. $stk = array(SERVICES_JSON_IN_OBJ);
  426. $obj = array();
  427. } else {
  428. $stk = array(SERVICES_JSON_IN_OBJ);
  429. $obj = new stdClass();
  430. }
  431. }
  432. array_push($stk, array('what' => SERVICES_JSON_SLICE,
  433. 'where' => 0,
  434. 'delim' => false));
  435. $chrs = substr($str, 1, -1);
  436. $chrs = $this->reduce_string($chrs);
  437. if ($chrs == '') {
  438. if (reset($stk) == SERVICES_JSON_IN_ARR) {
  439. return $arr;
  440. } else {
  441. return $obj;
  442. }
  443. }
  444. //print("\nparsing {$chrs}\n");
  445. $strlen_chrs = strlen($chrs);
  446. for ($c = 0; $c <= $strlen_chrs; ++$c) {
  447. $top = end($stk);
  448. $substr_chrs_c_2 = substr($chrs, $c, 2);
  449. if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
  450. // found a comma that is not inside a string, array, etc.,
  451. // OR we've reached the end of the character list
  452. $slice = substr($chrs, $top['where'], ($c - $top['where']));
  453. array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
  454. //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
  455. if (reset($stk) == SERVICES_JSON_IN_ARR) {
  456. // we are in an array, so just push an element onto the stack
  457. array_push($arr, $this->decode($slice));
  458. } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
  459. // we are in an object, so figure
  460. // out the property name and set an
  461. // element in an associative array,
  462. // for now
  463. if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
  464. // "name":value pair
  465. $key = $this->decode($parts[1]);
  466. $val = $this->decode($parts[2]);
  467. if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
  468. $obj[$key] = $val;
  469. } else {
  470. $obj->$key = $val;
  471. }
  472. } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
  473. // name:value pair, where name is unquoted
  474. $key = $parts[1];
  475. $val = $this->decode($parts[2]);
  476. if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
  477. $obj[$key] = $val;
  478. } else {
  479. $obj->$key = $val;
  480. }
  481. }
  482. }
  483. } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
  484. // found a quote, and we are not inside a string
  485. array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
  486. //print("Found start of string at {$c}\n");
  487. } elseif (($chrs{$c} == $top['delim']) &&
  488. ($top['what'] == SERVICES_JSON_IN_STR) &&
  489. (($chrs{$c - 1} != '\\') ||
  490. ($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
  491. // found a quote, we're in a string, and it's not escaped
  492. array_pop($stk);
  493. //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
  494. } elseif (($chrs{$c} == '[') &&
  495. in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
  496. // found a left-bracket, and we are in an array, object, or slice
  497. array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
  498. //print("Found start of array at {$c}\n");
  499. } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
  500. // found a right-bracket, and we're in an array
  501. array_pop($stk);
  502. //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
  503. } elseif (($chrs{$c} == '{') &&
  504. in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
  505. // found a left-brace, and we are in an array, object, or slice
  506. array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
  507. //print("Found start of object at {$c}\n");
  508. } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
  509. // found a right-brace, and we're in an object
  510. array_pop($stk);
  511. //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
  512. } elseif (($substr_chrs_c_2 == '/*') &&
  513. in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
  514. // found a comment start, and we are in an array, object, or slice
  515. array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
  516. $c++;
  517. //print("Found start of comment at {$c}\n");
  518. } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
  519. // found a comment end, and we're in one now
  520. array_pop($stk);
  521. $c++;
  522. for ($i = $top['where']; $i <= $c; ++$i)
  523. $chrs = substr_replace($chrs, ' ', $i, 1);
  524. //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
  525. }
  526. }
  527. if (reset($stk) == SERVICES_JSON_IN_ARR) {
  528. return $arr;
  529. } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
  530. return $obj;
  531. }
  532. }
  533. }
  534. }
  535. }
  536. ?>