Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/editor/tinymce/tiny_mce/3.4.6/plugins/spellchecker/classes/utils/JSON.php
Go to the documentation of this file.
00001 <?php
00010 define('JSON_BOOL', 1);
00011 define('JSON_INT', 2);
00012 define('JSON_STR', 3);
00013 define('JSON_FLOAT', 4);
00014 define('JSON_NULL', 5);
00015 define('JSON_START_OBJ', 6);
00016 define('JSON_END_OBJ', 7);
00017 define('JSON_START_ARRAY', 8);
00018 define('JSON_END_ARRAY', 9);
00019 define('JSON_KEY', 10);
00020 define('JSON_SKIP', 11);
00021 
00022 define('JSON_IN_ARRAY', 30);
00023 define('JSON_IN_OBJECT', 40);
00024 define('JSON_IN_BETWEEN', 50);
00025 
00026 class Moxiecode_JSONReader {
00027         var $_data, $_len, $_pos;
00028         var $_value, $_token;
00029         var $_location, $_lastLocations;
00030         var $_needProp;
00031 
00032         function Moxiecode_JSONReader($data) {
00033                 $this->_data = $data;
00034                 $this->_len = strlen($data);
00035                 $this->_pos = -1;
00036                 $this->_location = JSON_IN_BETWEEN;
00037                 $this->_lastLocations = array();
00038                 $this->_needProp = false;
00039         }
00040 
00041         function getToken() {
00042                 return $this->_token;
00043         }
00044 
00045         function getLocation() {
00046                 return $this->_location;
00047         }
00048 
00049         function getTokenName() {
00050                 switch ($this->_token) {
00051                         case JSON_BOOL:
00052                                 return 'JSON_BOOL';
00053 
00054                         case JSON_INT:
00055                                 return 'JSON_INT';
00056 
00057                         case JSON_STR:
00058                                 return 'JSON_STR';
00059 
00060                         case JSON_FLOAT:
00061                                 return 'JSON_FLOAT';
00062 
00063                         case JSON_NULL:
00064                                 return 'JSON_NULL';
00065 
00066                         case JSON_START_OBJ:
00067                                 return 'JSON_START_OBJ';
00068 
00069                         case JSON_END_OBJ:
00070                                 return 'JSON_END_OBJ';
00071 
00072                         case JSON_START_ARRAY:
00073                                 return 'JSON_START_ARRAY';
00074 
00075                         case JSON_END_ARRAY:
00076                                 return 'JSON_END_ARRAY';
00077 
00078                         case JSON_KEY:
00079                                 return 'JSON_KEY';
00080                 }
00081 
00082                 return 'UNKNOWN';
00083         }
00084 
00085         function getValue() {
00086                 return $this->_value;
00087         }
00088 
00089         function readToken() {
00090                 $chr = $this->read();
00091 
00092                 if ($chr != null) {
00093                         switch ($chr) {
00094                                 case '[':
00095                                         $this->_lastLocation[] = $this->_location;
00096                                         $this->_location = JSON_IN_ARRAY;
00097                                         $this->_token = JSON_START_ARRAY;
00098                                         $this->_value = null;
00099                                         $this->readAway();
00100                                         return true;
00101 
00102                                 case ']':
00103                                         $this->_location = array_pop($this->_lastLocation);
00104                                         $this->_token = JSON_END_ARRAY;
00105                                         $this->_value = null;
00106                                         $this->readAway();
00107 
00108                                         if ($this->_location == JSON_IN_OBJECT)
00109                                                 $this->_needProp = true;
00110 
00111                                         return true;
00112 
00113                                 case '{':
00114                                         $this->_lastLocation[] = $this->_location;
00115                                         $this->_location = JSON_IN_OBJECT;
00116                                         $this->_needProp = true;
00117                                         $this->_token = JSON_START_OBJ;
00118                                         $this->_value = null;
00119                                         $this->readAway();
00120                                         return true;
00121 
00122                                 case '}':
00123                                         $this->_location = array_pop($this->_lastLocation);
00124                                         $this->_token = JSON_END_OBJ;
00125                                         $this->_value = null;
00126                                         $this->readAway();
00127 
00128                                         if ($this->_location == JSON_IN_OBJECT)
00129                                                 $this->_needProp = true;
00130 
00131                                         return true;
00132 
00133                                 // String
00134                                 case '"':
00135                                 case '\'':
00136                                         return $this->_readString($chr);
00137 
00138                                 // Null
00139                                 case 'n':
00140                                         return $this->_readNull();
00141 
00142                                 // Bool
00143                                 case 't':
00144                                 case 'f':
00145                                         return $this->_readBool($chr);
00146 
00147                                 default:
00148                                         // Is number
00149                                         if (is_numeric($chr) || $chr == '-' || $chr == '.')
00150                                                 return $this->_readNumber($chr);
00151 
00152                                         return true;
00153                         }
00154                 }
00155 
00156                 return false;
00157         }
00158 
00159         function _readBool($chr) {
00160                 $this->_token = JSON_BOOL;
00161                 $this->_value = $chr == 't';
00162 
00163                 if ($chr == 't')
00164                         $this->skip(3); // rue
00165                 else
00166                         $this->skip(4); // alse
00167 
00168                 $this->readAway();
00169 
00170                 if ($this->_location == JSON_IN_OBJECT && !$this->_needProp)
00171                         $this->_needProp = true;
00172 
00173                 return true;
00174         }
00175 
00176         function _readNull() {
00177                 $this->_token = JSON_NULL;
00178                 $this->_value = null;
00179 
00180                 $this->skip(3); // ull
00181                 $this->readAway();
00182 
00183                 if ($this->_location == JSON_IN_OBJECT && !$this->_needProp)
00184                         $this->_needProp = true;
00185 
00186                 return true;
00187         }
00188 
00189         function _readString($quote) {
00190                 $output = "";
00191                 $this->_token = JSON_STR;
00192                 $endString = false;
00193 
00194                 while (($chr = $this->peek()) != -1) {
00195                         switch ($chr) {
00196                                 case '\\':
00197                                         // Read away slash
00198                                         $this->read();
00199 
00200                                         // Read escape code
00201                                         $chr = $this->read();
00202                                         switch ($chr) {
00203                                                         case 't':
00204                                                                 $output .= "\t";
00205                                                                 break;
00206 
00207                                                         case 'b':
00208                                                                 $output .= "\b";
00209                                                                 break;
00210 
00211                                                         case 'f':
00212                                                                 $output .= "\f";
00213                                                                 break;
00214 
00215                                                         case 'r':
00216                                                                 $output .= "\r";
00217                                                                 break;
00218 
00219                                                         case 'n':
00220                                                                 $output .= "\n";
00221                                                                 break;
00222 
00223                                                         case 'u':
00224                                                                 $output .= $this->_int2utf8(hexdec($this->read(4)));
00225                                                                 break;
00226 
00227                                                         default:
00228                                                                 $output .= $chr;
00229                                                                 break;
00230                                         }
00231 
00232                                         break;
00233 
00234                                         case '\'':
00235                                         case '"':
00236                                                 if ($chr == $quote)
00237                                                         $endString = true;
00238 
00239                                                 $chr = $this->read();
00240                                                 if ($chr != -1 && $chr != $quote)
00241                                                         $output .= $chr;
00242 
00243                                                 break;
00244 
00245                                         default:
00246                                                 $output .= $this->read();
00247                         }
00248 
00249                         // String terminated
00250                         if ($endString)
00251                                 break;
00252                 }
00253 
00254                 $this->readAway();
00255                 $this->_value = $output;
00256 
00257                 // Needed a property
00258                 if ($this->_needProp) {
00259                         $this->_token = JSON_KEY;
00260                         $this->_needProp = false;
00261                         return true;
00262                 }
00263 
00264                 if ($this->_location == JSON_IN_OBJECT && !$this->_needProp)
00265                         $this->_needProp = true;
00266 
00267                 return true;
00268         }
00269 
00270         function _int2utf8($int) {
00271                 $int = intval($int);
00272 
00273                 switch ($int) {
00274                         case 0:
00275                                 return chr(0);
00276 
00277                         case ($int & 0x7F):
00278                                 return chr($int);
00279 
00280                         case ($int & 0x7FF):
00281                                 return chr(0xC0 | (($int >> 6) & 0x1F)) . chr(0x80 | ($int & 0x3F));
00282 
00283                         case ($int & 0xFFFF):
00284                                 return chr(0xE0 | (($int >> 12) & 0x0F)) . chr(0x80 | (($int >> 6) & 0x3F)) . chr (0x80 | ($int & 0x3F));
00285 
00286                         case ($int & 0x1FFFFF):
00287                                 return chr(0xF0 | ($int >> 18)) . chr(0x80 | (($int >> 12) & 0x3F)) . chr(0x80 | (($int >> 6) & 0x3F)) . chr(0x80 | ($int & 0x3F));
00288                 }
00289         }
00290 
00291         function _readNumber($start) {
00292                 $value = "";
00293                 $isFloat = false;
00294 
00295                 $this->_token = JSON_INT;
00296                 $value .= $start;
00297 
00298                 while (($chr = $this->peek()) != -1) {
00299                         if (is_numeric($chr) || $chr == '-' || $chr == '.') {
00300                                 if ($chr == '.')
00301                                         $isFloat = true;
00302 
00303                                 $value .= $this->read();
00304                         } else
00305                                 break;
00306                 }
00307 
00308                 $this->readAway();
00309 
00310                 if ($isFloat) {
00311                         $this->_token = JSON_FLOAT;
00312                         $this->_value = floatval($value);
00313                 } else
00314                         $this->_value = intval($value);
00315 
00316                 if ($this->_location == JSON_IN_OBJECT && !$this->_needProp)
00317                         $this->_needProp = true;
00318 
00319                 return true;
00320         }
00321 
00322         function readAway() {
00323                 while (($chr = $this->peek()) != null) {
00324                         if ($chr != ':' && $chr != ',' && $chr != ' ')
00325                                 return;
00326 
00327                         $this->read();
00328                 }
00329         }
00330 
00331         function read($len = 1) {
00332                 if ($this->_pos < $this->_len) {
00333                         if ($len > 1) {
00334                                 $str = substr($this->_data, $this->_pos + 1, $len);
00335                                 $this->_pos += $len;
00336 
00337                                 return $str;
00338                         } else
00339                                 return $this->_data[++$this->_pos];
00340                 }
00341 
00342                 return null;
00343         }
00344 
00345         function skip($len) {
00346                 $this->_pos += $len;
00347         }
00348 
00349         function peek() {
00350                 if ($this->_pos < $this->_len)
00351                         return $this->_data[$this->_pos + 1];
00352 
00353                 return null;
00354         }
00355 }
00356 
00362 class Moxiecode_JSON {
00363         function Moxiecode_JSON() {
00364         }
00365 
00366         function decode($input) {
00367                 $reader = new Moxiecode_JSONReader($input);
00368 
00369                 return $this->readValue($reader);
00370         }
00371 
00372         function readValue(&$reader) {
00373                 $this->data = array();
00374                 $this->parents = array();
00375                 $this->cur =& $this->data;
00376                 $key = null;
00377                 $loc = JSON_IN_ARRAY;
00378 
00379                 while ($reader->readToken()) {
00380                         switch ($reader->getToken()) {
00381                                 case JSON_STR:
00382                                 case JSON_INT:
00383                                 case JSON_BOOL:
00384                                 case JSON_FLOAT:
00385                                 case JSON_NULL:
00386                                         switch ($reader->getLocation()) {
00387                                                 case JSON_IN_OBJECT:
00388                                                         $this->cur[$key] = $reader->getValue();
00389                                                         break;
00390 
00391                                                 case JSON_IN_ARRAY:
00392                                                         $this->cur[] = $reader->getValue();
00393                                                         break;
00394 
00395                                                 default:
00396                                                         return $reader->getValue();
00397                                         }
00398                                         break;
00399 
00400                                 case JSON_KEY:
00401                                         $key = $reader->getValue();
00402                                         break;
00403 
00404                                 case JSON_START_OBJ:
00405                                 case JSON_START_ARRAY:
00406                                         if ($loc == JSON_IN_OBJECT)
00407                                                 $this->addArray($key);
00408                                         else
00409                                                 $this->addArray(null);
00410 
00411                                         $cur =& $obj;
00412 
00413                                         $loc = $reader->getLocation();
00414                                         break;
00415 
00416                                 case JSON_END_OBJ:
00417                                 case JSON_END_ARRAY:
00418                                         $loc = $reader->getLocation();
00419 
00420                                         if (count($this->parents) > 0) {
00421                                                 $this->cur =& $this->parents[count($this->parents) - 1];
00422                                                 array_pop($this->parents);
00423                                         }
00424                                         break;
00425                         }
00426                 }
00427 
00428                 return $this->data[0];
00429         }
00430 
00431         // This method was needed since PHP is crapy and doesn't have pointers/references
00432         function addArray($key) {
00433                 $this->parents[] =& $this->cur;
00434                 $ar = array();
00435 
00436                 if ($key)
00437                         $this->cur[$key] =& $ar;
00438                 else
00439                         $this->cur[] =& $ar;
00440 
00441                 $this->cur =& $ar;
00442         }
00443 
00444         function getDelim($index, &$reader) {
00445                 switch ($reader->getLocation()) {
00446                         case JSON_IN_ARRAY:
00447                         case JSON_IN_OBJECT:
00448                                 if ($index > 0)
00449                                         return ",";
00450                                 break;
00451                 }
00452 
00453                 return "";
00454         }
00455 
00456         function encode($input) {
00457                 switch (gettype($input)) {
00458                         case 'boolean':
00459                                 return $input ? 'true' : 'false';
00460 
00461                         case 'integer':
00462                                 return (int) $input;
00463 
00464                         case 'float':
00465                         case 'double':
00466                                 return (float) $input;
00467 
00468                         case 'NULL':
00469                                 return 'null';
00470 
00471                         case 'string':
00472                                 return $this->encodeString($input);
00473 
00474                         case 'array':
00475                                 return $this->_encodeArray($input);
00476 
00477                         case 'object':
00478                                 return $this->_encodeArray(get_object_vars($input));
00479                 }
00480 
00481                 return '';
00482         }
00483 
00484         function encodeString($input) {
00485                 // Needs to be escaped
00486                 if (preg_match('/[^a-zA-Z0-9]/', $input)) {
00487                         $output = '';
00488 
00489                         for ($i=0; $i<strlen($input); $i++) {
00490                                 switch ($input[$i]) {
00491                                         case "\b":
00492                                                 $output .= "\\b";
00493                                                 break;
00494 
00495                                         case "\t":
00496                                                 $output .= "\\t";
00497                                                 break;
00498 
00499                                         case "\f":
00500                                                 $output .= "\\f";
00501                                                 break;
00502 
00503                                         case "\r":
00504                                                 $output .= "\\r";
00505                                                 break;
00506 
00507                                         case "\n":
00508                                                 $output .= "\\n";
00509                                                 break;
00510 
00511                                         case '\\':
00512                                                 $output .= "\\\\";
00513                                                 break;
00514 
00515                                         case '\'':
00516                                                 $output .= "\\'";
00517                                                 break;
00518 
00519                                         case '"':
00520                                                 $output .= '\"';
00521                                                 break;
00522 
00523                                         default:
00524                                                 $byte = ord($input[$i]);
00525 
00526                                                 if (($byte & 0xE0) == 0xC0) {
00527                                                         $char = pack('C*', $byte, ord($input[$i + 1]));
00528                                                         $i += 1;
00529                                                         $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
00530                                                 } if (($byte & 0xF0) == 0xE0) {
00531                                                         $char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]));
00532                                                         $i += 2;
00533                                                         $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
00534                                                 } if (($byte & 0xF8) == 0xF0) {
00535                                                         $char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]), ord($input[$i + 3]));
00536                                                         $i += 3;
00537                                                         $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
00538                                                 } if (($byte & 0xFC) == 0xF8) {
00539                                                         $char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]), ord($input[$i + 3]), ord($input[$i + 4]));
00540                                                         $i += 4;
00541                                                         $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
00542                                                 } if (($byte & 0xFE) == 0xFC) {
00543                                                         $char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]), ord($input[$i + 3]), ord($input[$i + 4]), ord($input[$i + 5]));
00544                                                         $i += 5;
00545                                                         $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
00546                                                 } else if ($byte < 128)
00547                                                         $output .= $input[$i];
00548                                 }
00549                         }
00550 
00551                         return '"' . $output . '"';
00552                 }
00553 
00554                 return '"' . $input . '"';
00555         }
00556 
00557         function _utf82utf16($utf8) {
00558                 if (function_exists('mb_convert_encoding'))
00559                         return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
00560 
00561                 switch (strlen($utf8)) {
00562                         case 1:
00563                                 return $utf8;
00564 
00565                         case 2:
00566                                 return chr(0x07 & (ord($utf8[0]) >> 2)) . chr((0xC0 & (ord($utf8[0]) << 6)) | (0x3F & ord($utf8[1])));
00567 
00568                         case 3:
00569                                 return chr((0xF0 & (ord($utf8[0]) << 4)) | (0x0F & (ord($utf8[1]) >> 2))) . chr((0xC0 & (ord($utf8[1]) << 6)) | (0x7F & ord($utf8[2])));
00570                 }
00571 
00572                 return '';
00573         }
00574 
00575         function _encodeArray($input) {
00576                 $output = '';
00577                 $isIndexed = true;
00578 
00579                 $keys = array_keys($input);
00580                 for ($i=0; $i<count($keys); $i++) {
00581                         if (!is_int($keys[$i])) {
00582                                 $output .= $this->encodeString($keys[$i]) . ':' . $this->encode($input[$keys[$i]]);
00583                                 $isIndexed = false;
00584                         } else
00585                                 $output .= $this->encode($input[$keys[$i]]);
00586 
00587                         if ($i != count($keys) - 1)
00588                                 $output .= ',';
00589                 }
00590 
00591                 return $isIndexed ? '[' . $output . ']' : '{' . $output . '}';
00592         }
00593 }
00594 
00595 ?>
 All Data Structures Namespaces Files Functions Variables Enumerations