[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/editor/tinymce/plugins/spellchecker/classes/utils/ -> JSON.php (source)

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


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1