• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List

E:/E/GEAMP/www/openbiz/openbiz/others/Zend/Json/Encoder.php

00001 <?php
00030 class Zend_Json_Encoder
00031 {
00037     protected $_cycleCheck;
00038 
00044     protected $_options = array();
00045 
00051     protected $_visited = array();
00052 
00060     protected function __construct($cycleCheck = false, $options = array())
00061     {
00062         $this->_cycleCheck = $cycleCheck;
00063         $this->_options = $options;
00064     }
00065 
00074     public static function encode($value, $cycleCheck = false, $options = array())
00075     {
00076         $encoder = new self(($cycleCheck) ? true : false, $options);
00077 
00078         return $encoder->_encodeValue($value);
00079     }
00080 
00091     protected function _encodeValue(&$value)
00092     {
00093         if (is_object($value)) {
00094             return $this->_encodeObject($value);
00095         } else if (is_array($value)) {
00096             return $this->_encodeArray($value);
00097         }
00098 
00099         return $this->_encodeDatum($value);
00100     }
00101 
00102 
00103 
00115     protected function _encodeObject(&$value)
00116     {
00117         if ($this->_cycleCheck) {
00118             if ($this->_wasVisited($value)) {
00119 
00120                 if (isset($this->_options['silenceCyclicalExceptions'])
00121                     && $this->_options['silenceCyclicalExceptions']===true) {
00122 
00123                     return '"* RECURSION (' . get_class($value) . ') *"';
00124 
00125                 } else {
00126                     require_once 'Zend/Json/Exception.php';
00127                     throw new Zend_Json_Exception(
00128                         'Cycles not supported in JSON encoding, cycle introduced by '
00129                         . 'class "' . get_class($value) . '"'
00130                     );
00131                 }
00132             }
00133 
00134             $this->_visited[] = $value;
00135         }
00136 
00137         $props = '';
00138 
00139         if ($value instanceof Iterator) {
00140             $propCollection = $value;
00141         } else {
00142             $propCollection = get_object_vars($value);
00143         }
00144 
00145         foreach ($propCollection as $name => $propValue) {
00146             if (isset($propValue)) {
00147                 $props .= ','
00148                         . $this->_encodeValue($name)
00149                         . ':'
00150                         . $this->_encodeValue($propValue);
00151             }
00152         }
00153 
00154         return '{"__className":"' . get_class($value) . '"'
00155                 . $props . '}';
00156     }
00157 
00158 
00165     protected function _wasVisited(&$value)
00166     {
00167         if (in_array($value, $this->_visited, true)) {
00168             return true;
00169         }
00170 
00171         return false;
00172     }
00173 
00174 
00188     protected function _encodeArray(&$array)
00189     {
00190         $tmpArray = array();
00191 
00192         // Check for associative array
00193         if (!empty($array) && (array_keys($array) !== range(0, count($array) - 1))) {
00194             // Associative array
00195             $result = '{';
00196             foreach ($array as $key => $value) {
00197                 $key = (string) $key;
00198                 $tmpArray[] = $this->_encodeString($key)
00199                             . ':'
00200                             . $this->_encodeValue($value);
00201             }
00202             $result .= implode(',', $tmpArray);
00203             $result .= '}';
00204         } else {
00205             // Indexed array
00206             $result = '[';
00207             $length = count($array);
00208             for ($i = 0; $i < $length; $i++) {
00209                 $tmpArray[] = $this->_encodeValue($array[$i]);
00210             }
00211             $result .= implode(',', $tmpArray);
00212             $result .= ']';
00213         }
00214 
00215         return $result;
00216     }
00217 
00218 
00228     protected function _encodeDatum(&$value)
00229     {
00230         $result = 'null';
00231 
00232         if (is_int($value) || is_float($value)) {
00233             $result = (string) $value;
00234             $result = str_replace(",", ".", $result);
00235         } elseif (is_string($value)) {
00236             $result = $this->_encodeString($value);
00237         } elseif (is_bool($value)) {
00238             $result = $value ? 'true' : 'false';
00239         }
00240 
00241         return $result;
00242     }
00243 
00244 
00251     protected function _encodeString(&$string)
00252     {
00253         // Escape these characters with a backslash:
00254         // " \ / \n \r \t \b \f
00255         $search  = array('\\', "\n", "\t", "\r", "\b", "\f", '"');
00256         $replace = array('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\"');
00257         $string  = str_replace($search, $replace, $string);
00258 
00259         // Escape certain ASCII characters:
00260         // 0x08 => \b
00261         // 0x0c => \f
00262         $string = str_replace(array(chr(0x08), chr(0x0C)), array('\b', '\f'), $string);
00263         $string = self::encodeUnicodeString($string);
00264 
00265         return '"' . $string . '"';
00266     }
00267 
00268 
00276     private static function _encodeConstants(ReflectionClass $cls)
00277     {
00278         $result    = "constants : {";
00279         $constants = $cls->getConstants();
00280 
00281         $tmpArray = array();
00282         if (!empty($constants)) {
00283             foreach ($constants as $key => $value) {
00284                 $tmpArray[] = "$key: " . self::encode($value);
00285             }
00286 
00287             $result .= implode(', ', $tmpArray);
00288         }
00289 
00290         return $result . "}";
00291     }
00292 
00293 
00302     private static function _encodeMethods(ReflectionClass $cls)
00303     {
00304         $methods = $cls->getMethods();
00305         $result = 'methods:{';
00306 
00307         $started = false;
00308         foreach ($methods as $method) {
00309             if (! $method->isPublic() || !$method->isUserDefined()) {
00310                 continue;
00311             }
00312 
00313             if ($started) {
00314                 $result .= ',';
00315             }
00316             $started = true;
00317 
00318             $result .= '' . $method->getName(). ':function(';
00319 
00320             if ('__construct' != $method->getName()) {
00321                 $parameters  = $method->getParameters();
00322                 $paramCount  = count($parameters);
00323                 $argsStarted = false;
00324 
00325                 $argNames = "var argNames=[";
00326                 foreach ($parameters as $param) {
00327                     if ($argsStarted) {
00328                         $result .= ',';
00329                     }
00330 
00331                     $result .= $param->getName();
00332 
00333                     if ($argsStarted) {
00334                         $argNames .= ',';
00335                     }
00336 
00337                     $argNames .= '"' . $param->getName() . '"';
00338 
00339                     $argsStarted = true;
00340                 }
00341                 $argNames .= "];";
00342 
00343                 $result .= "){"
00344                          . $argNames
00345                          . 'var result = ZAjaxEngine.invokeRemoteMethod('
00346                          . "this, '" . $method->getName()
00347                          . "',argNames,arguments);"
00348                          . 'return(result);}';
00349             } else {
00350                 $result .= "){}";
00351             }
00352         }
00353 
00354         return $result . "}";
00355     }
00356 
00357 
00366     private static function _encodeVariables(ReflectionClass $cls)
00367     {
00368         $properties = $cls->getProperties();
00369         $propValues = get_class_vars($cls->getName());
00370         $result = "variables:{";
00371         $cnt = 0;
00372 
00373         $tmpArray = array();
00374         foreach ($properties as $prop) {
00375             if (! $prop->isPublic()) {
00376                 continue;
00377             }
00378 
00379             $tmpArray[] = $prop->getName()
00380                         . ':'
00381                         . self::encode($propValues[$prop->getName()]);
00382         }
00383         $result .= implode(',', $tmpArray);
00384 
00385         return $result . "}";
00386     }
00387 
00401     public static function encodeClass($className, $package = '')
00402     {
00403         $cls = new ReflectionClass($className);
00404         if (! $cls->isInstantiable()) {
00405             require_once 'Zend/Json/Exception.php';
00406             throw new Zend_Json_Exception("$className must be instantiable");
00407         }
00408 
00409         return "Class.create('$package$className',{"
00410                 . self::_encodeConstants($cls)    .","
00411                 . self::_encodeMethods($cls)      .","
00412                 . self::_encodeVariables($cls)    .'});';
00413     }
00414 
00415 
00425     public static function encodeClasses(array $classNames, $package = '')
00426     {
00427         $result = '';
00428         foreach ($classNames as $className) {
00429             $result .= self::encodeClass($className, $package);
00430         }
00431 
00432         return $result;
00433     }
00434 
00446     public static function encodeUnicodeString($value)
00447     {
00448         $strlen_var = strlen($value);
00449         $ascii = "";
00450 
00455         for($i = 0; $i < $strlen_var; $i++) {
00456             $ord_var_c = ord($value[$i]);
00457 
00458             switch (true) {
00459                 case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
00460                     // characters U-00000000 - U-0000007F (same as ASCII)
00461                     $ascii .= $value[$i];
00462                     break;
00463 
00464                 case (($ord_var_c & 0xE0) == 0xC0):
00465                     // characters U-00000080 - U-000007FF, mask 110XXXXX
00466                     // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
00467                     $char = pack('C*', $ord_var_c, ord($value[$i + 1]));
00468                     $i += 1;
00469                     $utf16 = self::_utf82utf16($char);
00470                     $ascii .= sprintf('\u%04s', bin2hex($utf16));
00471                     break;
00472 
00473                 case (($ord_var_c & 0xF0) == 0xE0):
00474                     // characters U-00000800 - U-0000FFFF, mask 1110XXXX
00475                     // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
00476                     $char = pack('C*', $ord_var_c,
00477                                  ord($value[$i + 1]),
00478                                  ord($value[$i + 2]));
00479                     $i += 2;
00480                     $utf16 = self::_utf82utf16($char);
00481                     $ascii .= sprintf('\u%04s', bin2hex($utf16));
00482                     break;
00483 
00484                 case (($ord_var_c & 0xF8) == 0xF0):
00485                     // characters U-00010000 - U-001FFFFF, mask 11110XXX
00486                     // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
00487                     $char = pack('C*', $ord_var_c,
00488                                  ord($value[$i + 1]),
00489                                  ord($value[$i + 2]),
00490                                  ord($value[$i + 3]));
00491                     $i += 3;
00492                     $utf16 = self::_utf82utf16($char);
00493                     $ascii .= sprintf('\u%04s', bin2hex($utf16));
00494                     break;
00495 
00496                 case (($ord_var_c & 0xFC) == 0xF8):
00497                     // characters U-00200000 - U-03FFFFFF, mask 111110XX
00498                     // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
00499                     $char = pack('C*', $ord_var_c,
00500                                  ord($value[$i + 1]),
00501                                  ord($value[$i + 2]),
00502                                  ord($value[$i + 3]),
00503                                  ord($value[$i + 4]));
00504                     $i += 4;
00505                     $utf16 = self::_utf82utf16($char);
00506                     $ascii .= sprintf('\u%04s', bin2hex($utf16));
00507                     break;
00508 
00509                 case (($ord_var_c & 0xFE) == 0xFC):
00510                     // characters U-04000000 - U-7FFFFFFF, mask 1111110X
00511                     // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
00512                     $char = pack('C*', $ord_var_c,
00513                                  ord($value[$i + 1]),
00514                                  ord($value[$i + 2]),
00515                                  ord($value[$i + 3]),
00516                                  ord($value[$i + 4]),
00517                                  ord($value[$i + 5]));
00518                     $i += 5;
00519                     $utf16 = self::_utf82utf16($char);
00520                     $ascii .= sprintf('\u%04s', bin2hex($utf16));
00521                     break;
00522             }
00523         }
00524 
00525         return $ascii;
00526      }
00527 
00541     protected static function _utf82utf16($utf8)
00542     {
00543         // Check for mb extension otherwise do by hand.
00544         if( function_exists('mb_convert_encoding') ) {
00545             return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
00546         }
00547 
00548         switch (strlen($utf8)) {
00549             case 1:
00550                 // this case should never be reached, because we are in ASCII range
00551                 // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
00552                 return $utf8;
00553 
00554             case 2:
00555                 // return a UTF-16 character from a 2-byte UTF-8 char
00556                 // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
00557                 return chr(0x07 & (ord($utf8{0}) >> 2))
00558                      . chr((0xC0 & (ord($utf8{0}) << 6))
00559                          | (0x3F & ord($utf8{1})));
00560 
00561             case 3:
00562                 // return a UTF-16 character from a 3-byte UTF-8 char
00563                 // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
00564                 return chr((0xF0 & (ord($utf8{0}) << 4))
00565                          | (0x0F & (ord($utf8{1}) >> 2)))
00566                      . chr((0xC0 & (ord($utf8{1}) << 6))
00567                          | (0x7F & ord($utf8{2})));
00568         }
00569 
00570         // ignoring UTF-32 for now, sorry
00571         return '';
00572     }
00573 }
00574 

Generated on Thu Apr 19 2012 17:01:17 for openbiz by  doxygen 1.7.2