b2evolution PHP Cross Reference Blogging Systems

Source: /plugins/tinymce_plugin/tiny_mce/plugins/spellchecker/classes/utils/JSON.php - 595 lines - 11878 bytes - Summary - Text - Print

   1  <?php
   2  /**
   3   * $Id: JSON.php 835 2012-02-15 09:24:39Z attila $
   4   *
   5   * @package MCManager.utils
   6   * @author Moxiecode
   7   * @copyright Copyright  2007, Moxiecode Systems AB, All rights reserved.
   8   */
   9  
  10  define('JSON_BOOL', 1);
  11  define('JSON_INT', 2);
  12  define('JSON_STR', 3);
  13  define('JSON_FLOAT', 4);
  14  define('JSON_NULL', 5);
  15  define('JSON_START_OBJ', 6);
  16  define('JSON_END_OBJ', 7);
  17  define('JSON_START_ARRAY', 8);
  18  define('JSON_END_ARRAY', 9);
  19  define('JSON_KEY', 10);
  20  define('JSON_SKIP', 11);
  21  
  22  define('JSON_IN_ARRAY', 30);
  23  define('JSON_IN_OBJECT', 40);
  24  define('JSON_IN_BETWEEN', 50);
  25  
  26  class Moxiecode_JSONReader {
  27      var $_data, $_len, $_pos;
  28      var $_value, $_token;
  29      var $_location, $_lastLocations;
  30      var $_needProp;
  31  
  32  	function Moxiecode_JSONReader($data) {
  33          $this->_data = $data;
  34          $this->_len = strlen($data);
  35          $this->_pos = -1;
  36          $this->_location = JSON_IN_BETWEEN;
  37          $this->_lastLocations = array();
  38          $this->_needProp = false;
  39      }
  40  
  41  	function getToken() {
  42          return $this->_token;
  43      }
  44  
  45  	function getLocation() {
  46          return $this->_location;
  47      }
  48  
  49  	function getTokenName() {
  50          switch ($this->_token) {
  51              case JSON_BOOL:
  52                  return 'JSON_BOOL';
  53  
  54              case JSON_INT:
  55                  return 'JSON_INT';
  56  
  57              case JSON_STR:
  58                  return 'JSON_STR';
  59  
  60              case JSON_FLOAT:
  61                  return 'JSON_FLOAT';
  62  
  63              case JSON_NULL:
  64                  return 'JSON_NULL';
  65  
  66              case JSON_START_OBJ:
  67                  return 'JSON_START_OBJ';
  68  
  69              case JSON_END_OBJ:
  70                  return 'JSON_END_OBJ';
  71  
  72              case JSON_START_ARRAY:
  73                  return 'JSON_START_ARRAY';
  74  
  75              case JSON_END_ARRAY:
  76                  return 'JSON_END_ARRAY';
  77  
  78              case JSON_KEY:
  79                  return 'JSON_KEY';
  80          }
  81  
  82          return 'UNKNOWN';
  83      }
  84  
  85  	function getValue() {
  86          return $this->_value;
  87      }
  88  
  89  	function readToken() {
  90          $chr = $this->read();
  91  
  92          if ($chr != null) {
  93              switch ($chr) {
  94                  case '[':
  95                      $this->_lastLocation[] = $this->_location;
  96                      $this->_location = JSON_IN_ARRAY;
  97                      $this->_token = JSON_START_ARRAY;
  98                      $this->_value = null;
  99                      $this->readAway();
 100                      return true;
 101  
 102                  case ']':
 103                      $this->_location = array_pop($this->_lastLocation);
 104                      $this->_token = JSON_END_ARRAY;
 105                      $this->_value = null;
 106                      $this->readAway();
 107  
 108                      if ($this->_location == JSON_IN_OBJECT)
 109                          $this->_needProp = true;
 110  
 111                      return true;
 112  
 113                  case '{':
 114                      $this->_lastLocation[] = $this->_location;
 115                      $this->_location = JSON_IN_OBJECT;
 116                      $this->_needProp = true;
 117                      $this->_token = JSON_START_OBJ;
 118                      $this->_value = null;
 119                      $this->readAway();
 120                      return true;
 121  
 122                  case '}':
 123                      $this->_location = array_pop($this->_lastLocation);
 124                      $this->_token = JSON_END_OBJ;
 125                      $this->_value = null;
 126                      $this->readAway();
 127  
 128                      if ($this->_location == JSON_IN_OBJECT)
 129                          $this->_needProp = true;
 130  
 131                      return true;
 132  
 133                  // String
 134                  case '"':
 135                  case '\'':
 136                      return $this->_readString($chr);
 137  
 138                  // Null
 139                  case 'n':
 140                      return $this->_readNull();
 141  
 142                  // Bool
 143                  case 't':
 144                  case 'f':
 145                      return $this->_readBool($chr);
 146  
 147                  default:
 148                      // Is number
 149                      if (is_numeric($chr) || $chr == '-' || $chr == '.')
 150                          return $this->_readNumber($chr);
 151  
 152                      return true;
 153              }
 154          }
 155  
 156          return false;
 157      }
 158  
 159  	function _readBool($chr) {
 160          $this->_token = JSON_BOOL;
 161          $this->_value = $chr == 't';
 162  
 163          if ($chr == 't')
 164              $this->skip(3); // rue
 165          else
 166              $this->skip(4); // alse
 167  
 168          $this->readAway();
 169  
 170          if ($this->_location == JSON_IN_OBJECT && !$this->_needProp)
 171              $this->_needProp = true;
 172  
 173          return true;
 174      }
 175  
 176  	function _readNull() {
 177          $this->_token = JSON_NULL;
 178          $this->_value = null;
 179  
 180          $this->skip(3); // ull
 181          $this->readAway();
 182  
 183          if ($this->_location == JSON_IN_OBJECT && !$this->_needProp)
 184              $this->_needProp = true;
 185  
 186          return true;
 187      }
 188  
 189  	function _readString($quote) {
 190          $output = "";
 191          $this->_token = JSON_STR;
 192          $endString = false;
 193  
 194          while (($chr = $this->peek()) != -1) {
 195              switch ($chr) {
 196                  case '\\':
 197                      // Read away slash
 198                      $this->read();
 199  
 200                      // Read escape code
 201                      $chr = $this->read();
 202                      switch ($chr) {
 203                              case 't':
 204                                  $output .= "\t";
 205                                  break;
 206  
 207                              case 'b':
 208                                  $output .= "\b";
 209                                  break;
 210  
 211                              case 'f':
 212                                  $output .= "\f";
 213                                  break;
 214  
 215                              case 'r':
 216                                  $output .= "\r";
 217                                  break;
 218  
 219                              case 'n':
 220                                  $output .= "\n";
 221                                  break;
 222  
 223                              case 'u':
 224                                  $output .= $this->_int2utf8(hexdec($this->read(4)));
 225                                  break;
 226  
 227                              default:
 228                                  $output .= $chr;
 229                                  break;
 230                      }
 231  
 232                      break;
 233  
 234                      case '\'':
 235                      case '"':
 236                          if ($chr == $quote)
 237                              $endString = true;
 238  
 239                          $chr = $this->read();
 240                          if ($chr != -1 && $chr != $quote)
 241                              $output .= $chr;
 242  
 243                          break;
 244  
 245                      default:
 246                          $output .= $this->read();
 247              }
 248  
 249              // String terminated
 250              if ($endString)
 251                  break;
 252          }
 253  
 254          $this->readAway();
 255          $this->_value = $output;
 256  
 257          // Needed a property
 258          if ($this->_needProp) {
 259              $this->_token = JSON_KEY;
 260              $this->_needProp = false;
 261              return true;
 262          }
 263  
 264          if ($this->_location == JSON_IN_OBJECT && !$this->_needProp)
 265              $this->_needProp = true;
 266  
 267          return true;
 268      }
 269  
 270  	function _int2utf8($int) {
 271          $int = intval($int);
 272  
 273          switch ($int) {
 274              case 0:
 275                  return chr(0);
 276  
 277              case ($int & 0x7F):
 278                  return chr($int);
 279  
 280              case ($int & 0x7FF):
 281                  return chr(0xC0 | (($int >> 6) & 0x1F)) . chr(0x80 | ($int & 0x3F));
 282  
 283              case ($int & 0xFFFF):
 284                  return chr(0xE0 | (($int >> 12) & 0x0F)) . chr(0x80 | (($int >> 6) & 0x3F)) . chr (0x80 | ($int & 0x3F));
 285  
 286              case ($int & 0x1FFFFF):
 287                  return chr(0xF0 | ($int >> 18)) . chr(0x80 | (($int >> 12) & 0x3F)) . chr(0x80 | (($int >> 6) & 0x3F)) . chr(0x80 | ($int & 0x3F));
 288          }
 289      }
 290  
 291  	function _readNumber($start) {
 292          $value = "";
 293          $isFloat = false;
 294  
 295          $this->_token = JSON_INT;
 296          $value .= $start;
 297  
 298          while (($chr = $this->peek()) != -1) {
 299              if (is_numeric($chr) || $chr == '-' || $chr == '.') {
 300                  if ($chr == '.')
 301                      $isFloat = true;
 302  
 303                  $value .= $this->read();
 304              } else
 305                  break;
 306          }
 307  
 308          $this->readAway();
 309  
 310          if ($isFloat) {
 311              $this->_token = JSON_FLOAT;
 312              $this->_value = floatval($value);
 313          } else
 314              $this->_value = intval($value);
 315  
 316          if ($this->_location == JSON_IN_OBJECT && !$this->_needProp)
 317              $this->_needProp = true;
 318  
 319          return true;
 320      }
 321  
 322  	function readAway() {
 323          while (($chr = $this->peek()) != null) {
 324              if ($chr != ':' && $chr != ',' && $chr != ' ')
 325                  return;
 326  
 327              $this->read();
 328          }
 329      }
 330  
 331  	function read($len = 1) {
 332          if ($this->_pos < $this->_len) {
 333              if ($len > 1) {
 334                  $str = substr($this->_data, $this->_pos + 1, $len);
 335                  $this->_pos += $len;
 336  
 337                  return $str;
 338              } else
 339                  return $this->_data[++$this->_pos];
 340          }
 341  
 342          return null;
 343      }
 344  
 345  	function skip($len) {
 346          $this->_pos += $len;
 347      }
 348  
 349  	function peek() {
 350          if ($this->_pos < $this->_len)
 351              return $this->_data[$this->_pos + 1];
 352  
 353          return null;
 354      }
 355  }
 356  
 357  /**
 358   * This class handles JSON stuff.
 359   *
 360   * @package MCManager.utils
 361   */
 362  class Moxiecode_JSON {
 363  	function Moxiecode_JSON() {
 364      }
 365  
 366  	function decode($input) {
 367          $reader = new Moxiecode_JSONReader($input);
 368  
 369          return $this->readValue($reader);
 370      }
 371  
 372  	function readValue(&$reader) {
 373          $this->data = array();
 374          $this->parents = array();
 375          $this->cur =& $this->data;
 376          $key = null;
 377          $loc = JSON_IN_ARRAY;
 378  
 379          while ($reader->readToken()) {
 380              switch ($reader->getToken()) {
 381                  case JSON_STR:
 382                  case JSON_INT:
 383                  case JSON_BOOL:
 384                  case JSON_FLOAT:
 385                  case JSON_NULL:
 386                      switch ($reader->getLocation()) {
 387                          case JSON_IN_OBJECT:
 388                              $this->cur[$key] = $reader->getValue();
 389                              break;
 390  
 391                          case JSON_IN_ARRAY:
 392                              $this->cur[] = $reader->getValue();
 393                              break;
 394  
 395                          default:
 396                              return $reader->getValue();
 397                      }
 398                      break;
 399  
 400                  case JSON_KEY:
 401                      $key = $reader->getValue();
 402                      break;
 403  
 404                  case JSON_START_OBJ:
 405                  case JSON_START_ARRAY:
 406                      if ($loc == JSON_IN_OBJECT)
 407                          $this->addArray($key);
 408                      else
 409                          $this->addArray(null);
 410  
 411                      $cur =& $obj;
 412  
 413                      $loc = $reader->getLocation();
 414                      break;
 415  
 416                  case JSON_END_OBJ:
 417                  case JSON_END_ARRAY:
 418                      $loc = $reader->getLocation();
 419  
 420                      if (count($this->parents) > 0) {
 421                          $this->cur =& $this->parents[count($this->parents) - 1];
 422                          array_pop($this->parents);
 423                      }
 424                      break;
 425              }
 426          }
 427  
 428          return $this->data[0];
 429      }
 430  
 431      // This method was needed since PHP is crapy and doesn't have pointers/references
 432  	function addArray($key) {
 433          $this->parents[] =& $this->cur;
 434          $ar = array();
 435  
 436          if ($key)
 437              $this->cur[$key] =& $ar;
 438          else
 439              $this->cur[] =& $ar;
 440  
 441          $this->cur =& $ar;
 442      }
 443  
 444  	function getDelim($index, &$reader) {
 445          switch ($reader->getLocation()) {
 446              case JSON_IN_ARRAY:
 447              case JSON_IN_OBJECT:
 448                  if ($index > 0)
 449                      return ",";
 450                  break;
 451          }
 452  
 453          return "";
 454      }
 455  
 456  	function encode($input) {
 457          switch (gettype($input)) {
 458              case 'boolean':
 459                  return $input ? 'true' : 'false';
 460  
 461              case 'integer':
 462                  return (int) $input;
 463  
 464              case 'float':
 465              case 'double':
 466                  return (float) $input;
 467  
 468              case 'NULL':
 469                  return 'null';
 470  
 471              case 'string':
 472                  return $this->encodeString($input);
 473  
 474              case 'array':
 475                  return $this->_encodeArray($input);
 476  
 477              case 'object':
 478                  return $this->_encodeArray(get_object_vars($input));
 479          }
 480  
 481          return '';
 482      }
 483  
 484  	function encodeString($input) {
 485          // Needs to be escaped
 486          if (preg_match('/[^a-zA-Z0-9]/', $input)) {
 487              $output = '';
 488  
 489              for ($i=0; $i<strlen($input); $i++) {
 490                  switch ($input[$i]) {
 491                      case "\b":
 492                          $output .= "\\b";
 493                          break;
 494  
 495                      case "\t":
 496                          $output .= "\\t";
 497                          break;
 498  
 499                      case "\f":
 500                          $output .= "\\f";
 501                          break;
 502  
 503                      case "\r":
 504                          $output .= "\\r";
 505                          break;
 506  
 507                      case "\n":
 508                          $output .= "\\n";
 509                          break;
 510  
 511                      case '\\':
 512                          $output .= "\\\\";
 513                          break;
 514  
 515                      case '\'':
 516                          $output .= "\\'";
 517                          break;
 518  
 519                      case '"':
 520                          $output .= '\"';
 521                          break;
 522  
 523                      default:
 524                          $byte = ord($input[$i]);
 525  
 526                          if (($byte & 0xE0) == 0xC0) {
 527                              $char = pack('C*', $byte, ord($input[$i + 1]));
 528                              $i += 1;
 529                              $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
 530                          } if (($byte & 0xF0) == 0xE0) {
 531                              $char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]));
 532                              $i += 2;
 533                              $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
 534                          } if (($byte & 0xF8) == 0xF0) {
 535                              $char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]), ord($input[$i + 3]));
 536                              $i += 3;
 537                              $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
 538                          } if (($byte & 0xFC) == 0xF8) {
 539                              $char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]), ord($input[$i + 3]), ord($input[$i + 4]));
 540                              $i += 4;
 541                              $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
 542                          } if (($byte & 0xFE) == 0xFC) {
 543                              $char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]), ord($input[$i + 3]), ord($input[$i + 4]), ord($input[$i + 5]));
 544                              $i += 5;
 545                              $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
 546                          } else if ($byte < 128)
 547                              $output .= $input[$i];
 548                  }
 549              }
 550  
 551              return '"' . $output . '"';
 552          }
 553  
 554          return '"' . $input . '"';
 555      }
 556  
 557  	function _utf82utf16($utf8) {
 558          if (function_exists('mb_convert_encoding'))
 559              return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
 560  
 561          switch (strlen($utf8)) {
 562              case 1:
 563                  return $utf8;
 564  
 565              case 2:
 566                  return chr(0x07 & (ord($utf8[0]) >> 2)) . chr((0xC0 & (ord($utf8[0]) << 6)) | (0x3F & ord($utf8[1])));
 567  
 568              case 3:
 569                  return chr((0xF0 & (ord($utf8[0]) << 4)) | (0x0F & (ord($utf8[1]) >> 2))) . chr((0xC0 & (ord($utf8[1]) << 6)) | (0x7F & ord($utf8[2])));
 570          }
 571  
 572          return '';
 573      }
 574  
 575  	function _encodeArray($input) {
 576          $output = '';
 577          $isIndexed = true;
 578  
 579          $keys = array_keys($input);
 580          for ($i=0; $i<count($keys); $i++) {
 581              if (!is_int($keys[$i])) {
 582                  $output .= $this->encodeString($keys[$i]) . ':' . $this->encode($input[$keys[$i]]);
 583                  $isIndexed = false;
 584              } else
 585                  $output .= $this->encode($input[$keys[$i]]);
 586  
 587              if ($i != count($keys) - 1)
 588                  $output .= ',';
 589          }
 590  
 591          return $isIndexed ? '[' . $output . ']' : '{' . $output . '}';
 592      }
 593  }
 594  
 595  ?>

title

Description

title

Description

title

Description

title

title

Body