62 define(
'SERVICES_JSON_SLICE', 1);
67 define(
'SERVICES_JSON_IN_STR', 2);
72 define(
'SERVICES_JSON_IN_ARR', 3);
77 define(
'SERVICES_JSON_IN_OBJ', 4);
82 define(
'SERVICES_JSON_IN_CMT', 5);
87 define(
'SERVICES_JSON_LOOSE_TYPE', 16);
92 define(
'SERVICES_JSON_SUPPRESS_ERRORS', 32);
152 if(function_exists(
'mb_convert_encoding')) {
153 return mb_convert_encoding($utf16,
'UTF-8',
'UTF-16');
156 $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
159 case ((0x7F & $bytes) == $bytes):
162 return chr(0x7F & $bytes);
164 case (0x07FF & $bytes) == $bytes:
167 return chr(0xC0 | (($bytes >> 6) & 0x1F))
168 . chr(0x80 | ($bytes & 0x3F));
170 case (0xFFFF & $bytes) == $bytes:
173 return chr(0xE0 | (($bytes >> 12) & 0x0F))
174 . chr(0x80 | (($bytes >> 6) & 0x3F))
175 . chr(0x80 | ($bytes & 0x3F));
196 if(function_exists(
'mb_convert_encoding')) {
197 return mb_convert_encoding($utf8,
'UTF-16',
'UTF-8');
200 switch(strlen($utf8)) {
209 return chr(0x07 & (ord($utf8{0}) >> 2))
210 . chr((0xC0 & (ord($utf8{0}) << 6))
211 | (0x3F & ord($utf8{1})));
216 return chr((0xF0 & (ord($utf8{0}) << 4))
217 | (0x0F & (ord($utf8{1}) >> 2)))
218 . chr((0xC0 & (ord($utf8{1}) << 6))
219 | (0x7F & ord($utf8{2})));
239 switch (gettype($var)) {
241 return $var ?
'true' :
'false';
256 $strlen_var = strlen($var);
262 for ($c = 0; $c < $strlen_var; ++$c) {
264 $ord_var_c = ord($var{$c});
267 case $ord_var_c == 0x08:
270 case $ord_var_c == 0x09:
273 case $ord_var_c == 0x0A:
276 case $ord_var_c == 0x0C:
279 case $ord_var_c == 0x0D:
283 case $ord_var_c == 0x22:
284 case $ord_var_c == 0x2F:
285 case $ord_var_c == 0x5C:
287 $ascii .=
'\\'.$var{$c};
290 case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
295 case (($ord_var_c & 0xE0) == 0xC0):
298 $char = pack(
'C*', $ord_var_c, ord($var{$c + 1}));
301 $ascii .= sprintf(
'\u%04s', bin2hex($utf16));
304 case (($ord_var_c & 0xF0) == 0xE0):
307 $char = pack(
'C*', $ord_var_c,
312 $ascii .= sprintf(
'\u%04s', bin2hex($utf16));
315 case (($ord_var_c & 0xF8) == 0xF0):
318 $char = pack(
'C*', $ord_var_c,
324 $ascii .= sprintf(
'\u%04s', bin2hex($utf16));
327 case (($ord_var_c & 0xFC) == 0xF8):
330 $char = pack(
'C*', $ord_var_c,
337 $ascii .= sprintf(
'\u%04s', bin2hex($utf16));
340 case (($ord_var_c & 0xFE) == 0xFC):
343 $char = pack(
'C*', $ord_var_c,
351 $ascii .= sprintf(
'\u%04s', bin2hex($utf16));
356 return '"'.$ascii.
'"';
378 if (is_array($var) && count($var) && (array_keys($var) !== range(0,
sizeof($var) - 1))) {
379 $properties = array_map(array($this,
'name_value'),
383 foreach($properties as $property) {
389 return '{' . join(
',', $properties) .
'}';
393 $elements = array_map(array($this,
'encode'), $var);
395 foreach($elements as $element) {
401 return '[' . join(
',', $elements) .
']';
404 $vars = get_object_vars($var);
406 $properties = array_map(array($this,
'name_value'),
408 array_values($vars));
410 foreach($properties as $property) {
416 return '{' . join(
',', $properties) .
'}';
421 :
new Services_JSON_Error(gettype($var).
" can not be encoded as JSON string");
436 $encoded_value = $this->
encode($value);
439 return $encoded_value;
442 return $this->
encode(strval($name)) .
':' . $encoded_value;
455 $str = preg_replace(array(
461 '#^\s*/\*(.+)\*/#Us',
488 switch (strtolower($str)) {
501 if (is_numeric($str)) {
509 return ((
float)$str == (integer)$str)
513 } elseif (preg_match(
'/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
515 $delim = substr($str, 0, 1);
516 $chrs = substr($str, 1, -1);
518 $strlen_chrs = strlen($chrs);
520 for ($c = 0; $c < $strlen_chrs; ++$c) {
522 $substr_chrs_c_2 = substr($chrs, $c, 2);
523 $ord_chrs_c = ord($chrs{$c});
526 case $substr_chrs_c_2 ==
'\b':
530 case $substr_chrs_c_2 ==
'\t':
534 case $substr_chrs_c_2 ==
'\n':
538 case $substr_chrs_c_2 ==
'\f':
542 case $substr_chrs_c_2 ==
'\r':
547 case $substr_chrs_c_2 ==
'\\"':
548 case $substr_chrs_c_2 ==
'\\\'':
549 case $substr_chrs_c_2 ==
'\\\\':
550 case $substr_chrs_c_2 ==
'\\/':
551 if (($delim ==
'"' && $substr_chrs_c_2 !=
'\\\'') ||
552 ($delim ==
"'" && $substr_chrs_c_2 !=
'\\"')) {
553 $utf8 .= $chrs{++$c};
557 case preg_match(
'/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
559 $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
560 . chr(hexdec(substr($chrs, ($c + 4), 2)));
565 case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
569 case ($ord_chrs_c & 0xE0) == 0xC0:
572 $utf8 .= substr($chrs, $c, 2);
576 case ($ord_chrs_c & 0xF0) == 0xE0:
579 $utf8 .= substr($chrs, $c, 3);
583 case ($ord_chrs_c & 0xF8) == 0xF0:
586 $utf8 .= substr($chrs, $c, 4);
590 case ($ord_chrs_c & 0xFC) == 0xF8:
593 $utf8 .= substr($chrs, $c, 5);
597 case ($ord_chrs_c & 0xFE) == 0xFC:
600 $utf8 .= substr($chrs, $c, 6);
610 } elseif (preg_match(
'/^\[.*\]$/s', $str) || preg_match(
'/^\{.*\}$/s', $str)) {
613 if ($str{0} ==
'[') {
622 $obj =
new stdClass();
630 $chrs = substr($str, 1, -1);
645 $strlen_chrs = strlen($chrs);
647 for ($c = 0; $c <= $strlen_chrs; ++$c) {
650 $substr_chrs_c_2 = substr($chrs, $c, 2);
652 if (($c == $strlen_chrs) || (($chrs{$c} ==
',') && ($top[
'what'] ==
SERVICES_JSON_SLICE))) {
655 $slice = substr($chrs, $top[
'where'], ($c - $top[
'where']));
656 array_push($stk, array(
'what' =>
SERVICES_JSON_SLICE,
'where' => ($c + 1),
'delim' =>
false));
661 array_push($arr, $this->
decode($slice));
670 if (preg_match(
'/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
672 $key = $this->
decode($parts[1]);
673 $val = $this->
decode($parts[2]);
680 } elseif (preg_match(
'/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
683 $val = $this->
decode($parts[2]);
694 } elseif ((($chrs{$c} ==
'"') || ($chrs{$c} ==
"'")) && ($top[
'what'] !=
SERVICES_JSON_IN_STR)) {
699 } elseif (($chrs{$c} == $top[
'delim']) &&
701 ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c),
'\\'))) % 2 != 1)) {
708 } elseif (($chrs{$c} ==
'[') &&
719 } elseif (($chrs{$c} ==
'{') &&
730 } elseif (($substr_chrs_c_2 ==
'/*') &&
742 for ($i = $top[
'where']; $i <= $c; ++$i)
743 $chrs = substr_replace($chrs,
' ', $i, 1);
768 if (class_exists(
'pear')) {
770 } elseif (is_object($data) && (get_class($data) ==
'services_json_error' ||
771 is_subclass_of($data,
'services_json_error'))) {
779 if (class_exists(
'PEAR_Error')) {
783 function Services_JSON_Error($message =
'unknown error', $code = null,
784 $mode = null,
$options = null, $userinfo = null)
786 parent::PEAR_Error($message, $code, $mode,
$options, $userinfo);
795 class Services_JSON_Error
797 function Services_JSON_Error($message =
'unknown error', $code = null,
798 $mode = null,
$options = null, $userinfo = null)