WordPress.org

Make WordPress Core

Ticket #16918: 16918.3.patch

File 16918.3.patch, 35.2 KB (added by hakre, 3 years ago)

_http_build_query() vs http_build_query()

  • wp-includes/class-http.php

    ### Eclipse Workspace Patch 1.0
    #P wordpress-trunk bare
     
    293293                        $transports = WP_Http::_getTransport( $r ); 
    294294                } else { 
    295295                        if ( is_array( $r['body'] ) || is_object( $r['body'] ) ) { 
    296                                 if ( ! version_compare(phpversion(), '5.1.2', '>=') ) 
    297                                         $r['body'] = _http_build_query( $r['body'], null, '&' ); 
    298                                 else 
    299                                         $r['body'] = http_build_query( $r['body'], null, '&' ); 
     296                                $r['body'] = http_build_query( $r['body'], null, '&' ); 
    300297                                $r['headers']['Content-Type'] = 'application/x-www-form-urlencoded; charset=' . get_option( 'blog_charset' ); 
    301298                                $r['headers']['Content-Length'] = strlen( $r['body'] ); 
    302299                        } 
  • wp-includes/functions.php

     
    13551355 * Build URL query based on an associative and, or indexed array. 
    13561356 * 
    13571357 * This is a convenient function for easily building url queries. It sets the 
    1358  * separator to '&' and uses _http_build_query() function. 
     1358 * separator to '&' and uses http_build_query() function. 
    13591359 * 
    1360  * @see _http_build_query() Used to build the query 
     1360 * @see http_build_query() Used to build the query 
    13611361 * @link http://us2.php.net/manual/en/function.http-build-query.php more on what 
    13621362 *              http_build_query() does. 
    13631363 * 
     
    13671367 * @return string URL encoded string 
    13681368 */ 
    13691369function build_query( $data ) { 
    1370         return _http_build_query( $data, null, '&', '', false ); 
     1370        return http_build_query( $data, '', '&' ); 
    13711371} 
    13721372 
    13731373/** 
  • wp-admin/setup-config.php

     
    4040/**#@-*/ 
    4141 
    4242require_once(ABSPATH . WPINC . '/load.php'); 
    43 require_once(ABSPATH . WPINC . '/compat.php'); 
    4443require_once(ABSPATH . WPINC . '/functions.php'); 
    4544require_once(ABSPATH . WPINC . '/class-wp-error.php'); 
    4645require_once(ABSPATH . WPINC . '/version.php'); 
  • wp-includes/compat.php

     
    1 <?php 
    2 /** 
    3  * WordPress implementation for PHP functions missing from older PHP versions. 
    4  * 
    5  * @package PHP 
    6  * @access private 
    7  */ 
    8  
    9 // Added in PHP 5.0 
    10  
    11 if (!function_exists('http_build_query')) { 
    12         function http_build_query($data, $prefix=null, $sep=null) { 
    13                 return _http_build_query($data, $prefix, $sep); 
    14         } 
    15 } 
    16  
    17 // from php.net (modified by Mark Jaquith to behave like the native PHP5 function) 
    18 function _http_build_query($data, $prefix=null, $sep=null, $key='', $urlencode=true) { 
    19         $ret = array(); 
    20  
    21         foreach ( (array) $data as $k => $v ) { 
    22                 if ( $urlencode) 
    23                         $k = urlencode($k); 
    24                 if ( is_int($k) && $prefix != null ) 
    25                         $k = $prefix.$k; 
    26                 if ( !empty($key) ) 
    27                         $k = $key . '%5B' . $k . '%5D'; 
    28                 if ( $v === NULL ) 
    29                         continue; 
    30                 elseif ( $v === FALSE ) 
    31                         $v = '0'; 
    32  
    33                 if ( is_array($v) || is_object($v) ) 
    34                         array_push($ret,_http_build_query($v, '', $sep, $k, $urlencode)); 
    35                 elseif ( $urlencode ) 
    36                         array_push($ret, $k.'='.urlencode($v)); 
    37                 else 
    38                         array_push($ret, $k.'='.$v); 
    39         } 
    40  
    41         if ( NULL === $sep ) 
    42                 $sep = ini_get('arg_separator.output'); 
    43  
    44         return implode($sep, $ret); 
    45 } 
    46  
    47 if ( !function_exists('_') ) { 
    48         function _($string) { 
    49                 return $string; 
    50         } 
    51 } 
    52  
    53 if (!function_exists('stripos')) { 
    54         function stripos($haystack, $needle, $offset = 0) { 
    55                 return strpos(strtolower($haystack), strtolower($needle), $offset); 
    56         } 
    57 } 
    58  
    59 if ( !function_exists('hash_hmac') ): 
    60 function hash_hmac($algo, $data, $key, $raw_output = false) { 
    61         return _hash_hmac($algo, $data, $key, $raw_output); 
    62 } 
    63 endif; 
    64  
    65 function _hash_hmac($algo, $data, $key, $raw_output = false) { 
    66         $packs = array('md5' => 'H32', 'sha1' => 'H40'); 
    67  
    68         if ( !isset($packs[$algo]) ) 
    69                 return false; 
    70  
    71         $pack = $packs[$algo]; 
    72  
    73         if (strlen($key) > 64) 
    74                 $key = pack($pack, $algo($key)); 
    75  
    76         $key = str_pad($key, 64, chr(0)); 
    77  
    78         $ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64)); 
    79         $opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64)); 
    80  
    81         $hmac = $algo($opad . pack($pack, $algo($ipad . $data))); 
    82  
    83         if ( $raw_output ) 
    84                 return pack( $pack, $hmac ); 
    85         return $hmac; 
    86 } 
    87  
    88 if ( !function_exists('mb_substr') ): 
    89         function mb_substr( $str, $start, $length=null, $encoding=null ) { 
    90                 return _mb_substr($str, $start, $length, $encoding); 
    91         } 
    92 endif; 
    93  
    94 function _mb_substr( $str, $start, $length=null, $encoding=null ) { 
    95         // the solution below, works only for utf-8, so in case of a different 
    96         // charset, just use built-in substr 
    97         $charset = get_option( 'blog_charset' ); 
    98         if ( !in_array( $charset, array('utf8', 'utf-8', 'UTF8', 'UTF-8') ) ) { 
    99                 return is_null( $length )? substr( $str, $start ) : substr( $str, $start, $length); 
    100         } 
    101         // use the regex unicode support to separate the UTF-8 characters into an array 
    102         preg_match_all( '/./us', $str, $match ); 
    103         $chars = is_null( $length )? array_slice( $match[0], $start ) : array_slice( $match[0], $start, $length ); 
    104         return implode( '', $chars ); 
    105 } 
    106  
    107 if ( !function_exists( 'htmlspecialchars_decode' ) ) { 
    108         // Added in PHP 5.1.0 
    109         // Error checks from PEAR::PHP_Compat 
    110         function htmlspecialchars_decode( $string, $quote_style = ENT_COMPAT ) 
    111         { 
    112                 if ( !is_scalar( $string ) ) { 
    113                         trigger_error( 'htmlspecialchars_decode() expects parameter 1 to be string, ' . gettype( $string ) . ' given', E_USER_WARNING ); 
    114                         return; 
    115                 } 
    116  
    117                 if ( !is_int( $quote_style ) && $quote_style !== null ) { 
    118                         trigger_error( 'htmlspecialchars_decode() expects parameter 2 to be integer, ' . gettype( $quote_style ) . ' given', E_USER_WARNING ); 
    119                         return; 
    120                 } 
    121  
    122                 return wp_specialchars_decode( $string, $quote_style ); 
    123         } 
    124 } 
    125  
    126 // For PHP < 5.2.0 
    127 if ( !function_exists('json_encode') ) { 
    128         function json_encode( $string ) { 
    129                 global $wp_json; 
    130  
    131                 if ( !is_a($wp_json, 'Services_JSON') ) { 
    132                         require_once( ABSPATH . WPINC . '/class-json.php' ); 
    133                         $wp_json = new Services_JSON(); 
    134                 } 
    135  
    136                 return $wp_json->encodeUnsafe( $string ); 
    137         } 
    138 } 
    139  
    140 if ( !function_exists('json_decode') ) { 
    141         function json_decode( $string, $assoc_array = false ) { 
    142                 global $wp_json; 
    143  
    144                 if ( !is_a($wp_json, 'Services_JSON') ) { 
    145                         require_once( ABSPATH . WPINC . '/class-json.php' ); 
    146                         $wp_json = new Services_JSON(); 
    147                 } 
    148  
    149                 $res = $wp_json->decode( $string ); 
    150                 if ( $assoc_array ) 
    151                         $res = _json_decode_object_helper( $res ); 
    152                 return $res; 
    153         } 
    154         function _json_decode_object_helper($data) { 
    155                 if ( is_object($data) ) 
    156                         $data = get_object_vars($data); 
    157                 return is_array($data) ? array_map(__FUNCTION__, $data) : $data; 
    158         } 
    159 } 
    160  
    161 // pathinfo that fills 'filename' without extension like in PHP 5.2+ 
    162 function pathinfo52($path) { 
    163         $parts = pathinfo($path); 
    164         if ( !isset($parts['filename']) ) { 
    165                 $parts['filename'] = substr( $parts['basename'], 0, strrpos($parts['basename'], '.') ); 
    166                 if ( empty($parts['filename']) ) // there's no extension 
    167                         $parts['filename'] = $parts['basename']; 
    168         } 
    169         return $parts; 
    170 } 
  • wp-settings.php

     
    6363wp_set_lang_dir(); 
    6464 
    6565// Load early WordPress files. 
    66 require( ABSPATH . WPINC . '/compat.php' ); 
    6766require( ABSPATH . WPINC . '/functions.php' ); 
    6867require( ABSPATH . WPINC . '/class-wp.php' ); 
    6968require( ABSPATH . WPINC . '/class-wp-error.php' ); 
  • wp-admin/includes/image-edit.php

     
    551551 
    552552        // generate new filename 
    553553        $path = get_attached_file($post_id); 
    554         $path_parts = pathinfo52( $path ); 
     554        $path_parts = pathinfo( $path ); 
    555555        $filename = $path_parts['filename']; 
    556556        $suffix = time() . rand(100, 999); 
    557557 
  • wp-includes/class-json.php

     
    1 <?php 
    2 if ( !class_exists( 'Services_JSON' ) ) : 
    3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 
    4 /** 
    5  * Converts to and from JSON format. 
    6  * 
    7  * JSON (JavaScript Object Notation) is a lightweight data-interchange 
    8  * format. It is easy for humans to read and write. It is easy for machines 
    9  * to parse and generate. It is based on a subset of the JavaScript 
    10  * Programming Language, Standard ECMA-262 3rd Edition - December 1999. 
    11  * This feature can also be found in  Python. JSON is a text format that is 
    12  * completely language independent but uses conventions that are familiar 
    13  * to programmers of the C-family of languages, including C, C++, C#, Java, 
    14  * JavaScript, Perl, TCL, and many others. These properties make JSON an 
    15  * ideal data-interchange language. 
    16  * 
    17  * This package provides a simple encoder and decoder for JSON notation. It 
    18  * is intended for use with client-side Javascript applications that make 
    19  * use of HTTPRequest to perform server communication functions - data can 
    20  * be encoded into JSON notation for use in a client-side javascript, or 
    21  * decoded from incoming Javascript requests. JSON format is native to 
    22  * Javascript, and can be directly eval()'ed with no further parsing 
    23  * overhead 
    24  * 
    25  * All strings should be in ASCII or UTF-8 format! 
    26  * 
    27  * LICENSE: Redistribution and use in source and binary forms, with or 
    28  * without modification, are permitted provided that the following 
    29  * conditions are met: Redistributions of source code must retain the 
    30  * above copyright notice, this list of conditions and the following 
    31  * disclaimer. Redistributions in binary form must reproduce the above 
    32  * copyright notice, this list of conditions and the following disclaimer 
    33  * in the documentation and/or other materials provided with the 
    34  * distribution. 
    35  * 
    36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
    37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
    38  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
    39  * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
    40  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
    41  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
    42  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
    43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
    44  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
    45  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 
    46  * DAMAGE. 
    47  * 
    48  * @category 
    49  * @package             Services_JSON 
    50  * @author              Michal Migurski <mike-json@teczno.com> 
    51  * @author              Matt Knapp <mdknapp[at]gmail[dot]com> 
    52  * @author              Brett Stimmerman <brettstimmerman[at]gmail[dot]com> 
    53  * @copyright   2005 Michal Migurski 
    54  * @version     CVS: $Id: JSON.php 288200 2009-09-09 15:41:29Z alan_k $ 
    55  * @license             http://www.opensource.org/licenses/bsd-license.php 
    56  * @link                http://pear.php.net/pepr/pepr-proposal-show.php?id=198 
    57  */ 
    58  
    59 /** 
    60  * Marker constant for Services_JSON::decode(), used to flag stack state 
    61  */ 
    62 define('SERVICES_JSON_SLICE', 1); 
    63  
    64 /** 
    65  * Marker constant for Services_JSON::decode(), used to flag stack state 
    66  */ 
    67 define('SERVICES_JSON_IN_STR',  2); 
    68  
    69 /** 
    70  * Marker constant for Services_JSON::decode(), used to flag stack state 
    71  */ 
    72 define('SERVICES_JSON_IN_ARR',  3); 
    73  
    74 /** 
    75  * Marker constant for Services_JSON::decode(), used to flag stack state 
    76  */ 
    77 define('SERVICES_JSON_IN_OBJ',  4); 
    78  
    79 /** 
    80  * Marker constant for Services_JSON::decode(), used to flag stack state 
    81  */ 
    82 define('SERVICES_JSON_IN_CMT', 5); 
    83  
    84 /** 
    85  * Behavior switch for Services_JSON::decode() 
    86  */ 
    87 define('SERVICES_JSON_LOOSE_TYPE', 16); 
    88  
    89 /** 
    90  * Behavior switch for Services_JSON::decode() 
    91  */ 
    92 define('SERVICES_JSON_SUPPRESS_ERRORS', 32); 
    93  
    94 /** 
    95  * Converts to and from JSON format. 
    96  * 
    97  * Brief example of use: 
    98  * 
    99  * <code> 
    100  * // create a new instance of Services_JSON 
    101  * $json = new Services_JSON(); 
    102  * 
    103  * // convert a complexe value to JSON notation, and send it to the browser 
    104  * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); 
    105  * $output = $json->encode($value); 
    106  * 
    107  * print($output); 
    108  * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] 
    109  * 
    110  * // accept incoming POST data, assumed to be in JSON notation 
    111  * $input = file_get_contents('php://input', 1000000); 
    112  * $value = $json->decode($input); 
    113  * </code> 
    114  */ 
    115 class Services_JSON 
    116 { 
    117  /** 
    118         * constructs a new JSON instance 
    119         * 
    120         * @param int $use object behavior flags; combine with boolean-OR 
    121         * 
    122         *                                               possible values: 
    123         *                                               - SERVICES_JSON_LOOSE_TYPE:  loose typing. 
    124         *                                                               "{...}" syntax creates associative arrays 
    125         *                                                               instead of objects in decode(). 
    126         *                                               - SERVICES_JSON_SUPPRESS_ERRORS:  error suppression. 
    127         *                                                               Values which can't be encoded (e.g. resources) 
    128         *                                                               appear as NULL instead of throwing errors. 
    129         *                                                               By default, a deeply-nested resource will 
    130         *                                                               bubble up with an error, so all return values 
    131         *                                                               from encode() should be checked with isError() 
    132         */ 
    133         function Services_JSON($use = 0) 
    134         { 
    135                 $this->use = $use; 
    136         } 
    137  
    138  /** 
    139         * convert a string from one UTF-16 char to one UTF-8 char 
    140         * 
    141         * Normally should be handled by mb_convert_encoding, but 
    142         * provides a slower PHP-only method for installations 
    143         * that lack the multibye string extension. 
    144         * 
    145         * @param        string  $utf16  UTF-16 character 
    146         * @return string  UTF-8 character 
    147         * @access private 
    148         */ 
    149         function utf162utf8($utf16) 
    150         { 
    151                 // oh please oh please oh please oh please oh please 
    152                 if(function_exists('mb_convert_encoding')) { 
    153                         return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); 
    154                 } 
    155  
    156                 $bytes = (ord($utf16[0]) << 8) | ord($utf16[1]); 
    157  
    158                 switch(true) { 
    159                         case ((0x7F & $bytes) == $bytes): 
    160                                 // this case should never be reached, because we are in ASCII range 
    161                                 // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    162                                 return chr(0x7F & $bytes); 
    163  
    164                         case (0x07FF & $bytes) == $bytes: 
    165                                 // return a 2-byte UTF-8 character 
    166                                 // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    167                                 return chr(0xC0 | (($bytes >> 6) & 0x1F)) 
    168                                         . chr(0x80 | ($bytes & 0x3F)); 
    169  
    170                         case (0xFFFF & $bytes) == $bytes: 
    171                                 // return a 3-byte UTF-8 character 
    172                                 // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    173                                 return chr(0xE0 | (($bytes >> 12) & 0x0F)) 
    174                                         . chr(0x80 | (($bytes >> 6) & 0x3F)) 
    175                                         . chr(0x80 | ($bytes & 0x3F)); 
    176                 } 
    177  
    178                 // ignoring UTF-32 for now, sorry 
    179                 return ''; 
    180         } 
    181  
    182  /** 
    183         * convert a string from one UTF-8 char to one UTF-16 char 
    184         * 
    185         * Normally should be handled by mb_convert_encoding, but 
    186         * provides a slower PHP-only method for installations 
    187         * that lack the multibye string extension. 
    188         * 
    189         * @param        string  $utf8 UTF-8 character 
    190         * @return string  UTF-16 character 
    191         * @access private 
    192         */ 
    193         function utf82utf16($utf8) 
    194         { 
    195                 // oh please oh please oh please oh please oh please 
    196                 if(function_exists('mb_convert_encoding')) { 
    197                         return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); 
    198                 } 
    199  
    200                 switch(strlen($utf8)) { 
    201                         case 1: 
    202                                 // this case should never be reached, because we are in ASCII range 
    203                                 // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    204                                 return $utf8; 
    205  
    206                         case 2: 
    207                                 // return a UTF-16 character from a 2-byte UTF-8 char 
    208                                 // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    209                                 return chr(0x07 & (ord($utf8[0]) >> 2)) 
    210                                         . chr((0xC0 & (ord($utf8[0]) << 6)) 
    211                                                 | (0x3F & ord($utf8[1]))); 
    212  
    213                         case 3: 
    214                                 // return a UTF-16 character from a 3-byte UTF-8 char 
    215                                 // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    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]))); 
    220                 } 
    221  
    222                 // ignoring UTF-32 for now, sorry 
    223                 return ''; 
    224         } 
    225  
    226  /** 
    227         * encodes an arbitrary variable into JSON format (and sends JSON Header) 
    228         * 
    229         * @param        mixed $var      any number, boolean, string, array, or object to be encoded. 
    230         *                                               see argument 1 to Services_JSON() above for array-parsing behavior. 
    231         *                                               if var is a strng, note that encode() always expects it 
    232         *                                               to be in ASCII or UTF-8 format! 
    233         * 
    234         * @return mixed JSON string representation of input var or an error if a problem occurs 
    235         * @access public 
    236         */ 
    237         function encode($var) 
    238         { 
    239                 header('Content-type: application/json'); 
    240                 return $this->_encode($var); 
    241         } 
    242         /** 
    243         * encodes an arbitrary variable into JSON format without JSON Header - warning - may allow CSS!!!!) 
    244         * 
    245         * @param        mixed $var      any number, boolean, string, array, or object to be encoded. 
    246         *                                               see argument 1 to Services_JSON() above for array-parsing behavior. 
    247         *                                               if var is a strng, note that encode() always expects it 
    248         *                                               to be in ASCII or UTF-8 format! 
    249         * 
    250         * @return mixed JSON string representation of input var or an error if a problem occurs 
    251         * @access public 
    252         */ 
    253         function encodeUnsafe($var) 
    254         { 
    255                 return $this->_encode($var); 
    256         } 
    257         /** 
    258         * PRIVATE CODE that does the work of encodes an arbitrary variable into JSON format 
    259         * 
    260         * @param        mixed $var      any number, boolean, string, array, or object to be encoded. 
    261         *                                               see argument 1 to Services_JSON() above for array-parsing behavior. 
    262         *                                               if var is a strng, note that encode() always expects it 
    263         *                                               to be in ASCII or UTF-8 format! 
    264         * 
    265         * @return mixed JSON string representation of input var or an error if a problem occurs 
    266         * @access public 
    267         */ 
    268         function _encode($var) 
    269         { 
    270  
    271                 switch (gettype($var)) { 
    272                         case 'boolean': 
    273                                 return $var ? 'true' : 'false'; 
    274  
    275                         case 'NULL': 
    276                                 return 'null'; 
    277  
    278                         case 'integer': 
    279                                 return (int) $var; 
    280  
    281                         case 'double': 
    282                         case 'float': 
    283                                 return (float) $var; 
    284  
    285                         case 'string': 
    286                                 // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT 
    287                                 $ascii = ''; 
    288                                 $strlen_var = strlen($var); 
    289  
    290                         /* 
    291                                 * Iterate over every character in the string, 
    292                                 * escaping with a slash or encoding to UTF-8 where necessary 
    293                                 */ 
    294                                 for ($c = 0; $c < $strlen_var; ++$c) { 
    295  
    296                                         $ord_var_c = ord($var[$c]); 
    297  
    298                                         switch (true) { 
    299                                                 case $ord_var_c == 0x08: 
    300                                                         $ascii .= '\b'; 
    301                                                         break; 
    302                                                 case $ord_var_c == 0x09: 
    303                                                         $ascii .= '\t'; 
    304                                                         break; 
    305                                                 case $ord_var_c == 0x0A: 
    306                                                         $ascii .= '\n'; 
    307                                                         break; 
    308                                                 case $ord_var_c == 0x0C: 
    309                                                         $ascii .= '\f'; 
    310                                                         break; 
    311                                                 case $ord_var_c == 0x0D: 
    312                                                         $ascii .= '\r'; 
    313                                                         break; 
    314  
    315                                                 case $ord_var_c == 0x22: 
    316                                                 case $ord_var_c == 0x2F: 
    317                                                 case $ord_var_c == 0x5C: 
    318                                                         // double quote, slash, slosh 
    319                                                         $ascii .= '\\'.$var[$c]; 
    320                                                         break; 
    321  
    322                                                 case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): 
    323                                                         // characters U-00000000 - U-0000007F (same as ASCII) 
    324                                                         $ascii .= $var[$c]; 
    325                                                         break; 
    326  
    327                                                 case (($ord_var_c & 0xE0) == 0xC0): 
    328                                                         // characters U-00000080 - U-000007FF, mask 110XXXXX 
    329                                                         // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    330                                                         if ($c+1 >= $strlen_var) { 
    331                                                                 $c += 1; 
    332                                                                 $ascii .= '?'; 
    333                                                                 break; 
    334                                                         } 
    335  
    336                                                         $char = pack('C*', $ord_var_c, ord($var[$c + 1])); 
    337                                                         $c += 1; 
    338                                                         $utf16 = $this->utf82utf16($char); 
    339                                                         $ascii .= sprintf('\u%04s', bin2hex($utf16)); 
    340                                                         break; 
    341  
    342                                                 case (($ord_var_c & 0xF0) == 0xE0): 
    343                                                         if ($c+2 >= $strlen_var) { 
    344                                                                 $c += 2; 
    345                                                                 $ascii .= '?'; 
    346                                                                 break; 
    347                                                         } 
    348                                                         // characters U-00000800 - U-0000FFFF, mask 1110XXXX 
    349                                                         // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    350                                                         $char = pack('C*', $ord_var_c, 
    351                                                                                 @ord($var[$c + 1]), 
    352                                                                                 @ord($var[$c + 2])); 
    353                                                         $c += 2; 
    354                                                         $utf16 = $this->utf82utf16($char); 
    355                                                         $ascii .= sprintf('\u%04s', bin2hex($utf16)); 
    356                                                         break; 
    357  
    358                                                 case (($ord_var_c & 0xF8) == 0xF0): 
    359                                                         if ($c+3 >= $strlen_var) { 
    360                                                                 $c += 3; 
    361                                                                 $ascii .= '?'; 
    362                                                                 break; 
    363                                                         } 
    364                                                         // characters U-00010000 - U-001FFFFF, mask 11110XXX 
    365                                                         // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    366                                                         $char = pack('C*', $ord_var_c, 
    367                                                                                 ord($var[$c + 1]), 
    368                                                                                 ord($var[$c + 2]), 
    369                                                                                 ord($var[$c + 3])); 
    370                                                         $c += 3; 
    371                                                         $utf16 = $this->utf82utf16($char); 
    372                                                         $ascii .= sprintf('\u%04s', bin2hex($utf16)); 
    373                                                         break; 
    374  
    375                                                 case (($ord_var_c & 0xFC) == 0xF8): 
    376                                                         // characters U-00200000 - U-03FFFFFF, mask 111110XX 
    377                                                         // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    378                                                         if ($c+4 >= $strlen_var) { 
    379                                                                 $c += 4; 
    380                                                                 $ascii .= '?'; 
    381                                                                 break; 
    382                                                         } 
    383                                                         $char = pack('C*', $ord_var_c, 
    384                                                                                 ord($var[$c + 1]), 
    385                                                                                 ord($var[$c + 2]), 
    386                                                                                 ord($var[$c + 3]), 
    387                                                                                 ord($var[$c + 4])); 
    388                                                         $c += 4; 
    389                                                         $utf16 = $this->utf82utf16($char); 
    390                                                         $ascii .= sprintf('\u%04s', bin2hex($utf16)); 
    391                                                         break; 
    392  
    393                                                 case (($ord_var_c & 0xFE) == 0xFC): 
    394                                                 if ($c+5 >= $strlen_var) { 
    395                                                                 $c += 5; 
    396                                                                 $ascii .= '?'; 
    397                                                                 break; 
    398                                                         } 
    399                                                         // characters U-04000000 - U-7FFFFFFF, mask 1111110X 
    400                                                         // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    401                                                         $char = pack('C*', $ord_var_c, 
    402                                                                                 ord($var[$c + 1]), 
    403                                                                                 ord($var[$c + 2]), 
    404                                                                                 ord($var[$c + 3]), 
    405                                                                                 ord($var[$c + 4]), 
    406                                                                                 ord($var[$c + 5])); 
    407                                                         $c += 5; 
    408                                                         $utf16 = $this->utf82utf16($char); 
    409                                                         $ascii .= sprintf('\u%04s', bin2hex($utf16)); 
    410                                                         break; 
    411                                         } 
    412                                 } 
    413                                 return  '"'.$ascii.'"'; 
    414  
    415                         case 'array': 
    416                         /* 
    417                                 * As per JSON spec if any array key is not an integer 
    418                                 * we must treat the the whole array as an object. We 
    419                                 * also try to catch a sparsely populated associative 
    420                                 * array with numeric keys here because some JS engines 
    421                                 * will create an array with empty indexes up to 
    422                                 * max_index which can cause memory issues and because 
    423                                 * the keys, which may be relevant, will be remapped 
    424                                 * otherwise. 
    425                                 * 
    426                                 * As per the ECMA and JSON specification an object may 
    427                                 * have any string as a property. Unfortunately due to 
    428                                 * a hole in the ECMA specification if the key is a 
    429                                 * ECMA reserved word or starts with a digit the 
    430                                 * parameter is only accessible using ECMAScript's 
    431                                 * bracket notation. 
    432                                 */ 
    433  
    434                                 // treat as a JSON object 
    435                                 if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { 
    436                                         $properties = array_map(array($this, 'name_value'), 
    437                                                                                         array_keys($var), 
    438                                                                                         array_values($var)); 
    439  
    440                                         foreach($properties as $property) { 
    441                                                 if(Services_JSON::isError($property)) { 
    442                                                         return $property; 
    443                                                 } 
    444                                         } 
    445  
    446                                         return '{' . join(',', $properties) . '}'; 
    447                                 } 
    448  
    449                                 // treat it like a regular array 
    450                                 $elements = array_map(array($this, '_encode'), $var); 
    451  
    452                                 foreach($elements as $element) { 
    453                                         if(Services_JSON::isError($element)) { 
    454                                                 return $element; 
    455                                         } 
    456                                 } 
    457  
    458                                 return '[' . join(',', $elements) . ']'; 
    459  
    460                         case 'object': 
    461                                 $vars = get_object_vars($var); 
    462  
    463                                 $properties = array_map(array($this, 'name_value'), 
    464                                                                                 array_keys($vars), 
    465                                                                                 array_values($vars)); 
    466  
    467                                 foreach($properties as $property) { 
    468                                         if(Services_JSON::isError($property)) { 
    469                                                 return $property; 
    470                                         } 
    471                                 } 
    472  
    473                                 return '{' . join(',', $properties) . '}'; 
    474  
    475                         default: 
    476                                 return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) 
    477                                         ? 'null' 
    478                                         : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); 
    479                 } 
    480         } 
    481  
    482  /** 
    483         * array-walking function for use in generating JSON-formatted name-value pairs 
    484         * 
    485         * @param        string  $name name of key to use 
    486         * @param        mixed $value  reference to an array element to be encoded 
    487         * 
    488         * @return string  JSON-formatted name-value pair, like '"name":value' 
    489         * @access private 
    490         */ 
    491         function name_value($name, $value) 
    492         { 
    493                 $encoded_value = $this->_encode($value); 
    494  
    495                 if(Services_JSON::isError($encoded_value)) { 
    496                         return $encoded_value; 
    497                 } 
    498  
    499                 return $this->_encode(strval($name)) . ':' . $encoded_value; 
    500         } 
    501  
    502  /** 
    503         * reduce a string by removing leading and trailing comments and whitespace 
    504         * 
    505         * @param        $str    string  string value to strip of comments and whitespace 
    506         * 
    507         * @return string  string value stripped of comments and whitespace 
    508         * @access private 
    509         */ 
    510         function reduce_string($str) 
    511         { 
    512                 $str = preg_replace(array( 
    513  
    514                                 // eliminate single line comments in '// ...' form 
    515                                 '#^\s*//(.+)$#m', 
    516  
    517                                 // eliminate multi-line comments in '/* ... */' form, at start of string 
    518                                 '#^\s*/\*(.+)\*/#Us', 
    519  
    520                                 // eliminate multi-line comments in '/* ... */' form, at end of string 
    521                                 '#/\*(.+)\*/\s*$#Us' 
    522  
    523                         ), '', $str); 
    524  
    525                 // eliminate extraneous space 
    526                 return trim($str); 
    527         } 
    528  
    529  /** 
    530         * decodes a JSON string into appropriate variable 
    531         * 
    532         * @param        string  $str    JSON-formatted string 
    533         * 
    534         * @return mixed number, boolean, string, array, or object 
    535         *                               corresponding to given JSON input string. 
    536         *                               See argument 1 to Services_JSON() above for object-output behavior. 
    537         *                               Note that decode() always returns strings 
    538         *                               in ASCII or UTF-8 format! 
    539         * @access public 
    540         */ 
    541         function decode($str) 
    542         { 
    543                 $str = $this->reduce_string($str); 
    544  
    545                 switch (strtolower($str)) { 
    546                         case 'true': 
    547                                 return true; 
    548  
    549                         case 'false': 
    550                                 return false; 
    551  
    552                         case 'null': 
    553                                 return null; 
    554  
    555                         default: 
    556                                 $m = array(); 
    557  
    558                                 if (is_numeric($str)) { 
    559                                         // Lookie-loo, it's a number 
    560  
    561                                         // This would work on its own, but I'm trying to be 
    562                                         // good about returning integers where appropriate: 
    563                                         // return (float)$str; 
    564  
    565                                         // Return float or int, as appropriate 
    566                                         return ((float)$str == (integer)$str) 
    567                                                 ? (integer)$str 
    568                                                 : (float)$str; 
    569  
    570                                 } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { 
    571                                         // STRINGS RETURNED IN UTF-8 FORMAT 
    572                                         $delim = substr($str, 0, 1); 
    573                                         $chrs = substr($str, 1, -1); 
    574                                         $utf8 = ''; 
    575                                         $strlen_chrs = strlen($chrs); 
    576  
    577                                         for ($c = 0; $c < $strlen_chrs; ++$c) { 
    578  
    579                                                 $substr_chrs_c_2 = substr($chrs, $c, 2); 
    580                                                 $ord_chrs_c = ord($chrs[$c]); 
    581  
    582                                                 switch (true) { 
    583                                                         case $substr_chrs_c_2 == '\b': 
    584                                                                 $utf8 .= chr(0x08); 
    585                                                                 ++$c; 
    586                                                                 break; 
    587                                                         case $substr_chrs_c_2 == '\t': 
    588                                                                 $utf8 .= chr(0x09); 
    589                                                                 ++$c; 
    590                                                                 break; 
    591                                                         case $substr_chrs_c_2 == '\n': 
    592                                                                 $utf8 .= chr(0x0A); 
    593                                                                 ++$c; 
    594                                                                 break; 
    595                                                         case $substr_chrs_c_2 == '\f': 
    596                                                                 $utf8 .= chr(0x0C); 
    597                                                                 ++$c; 
    598                                                                 break; 
    599                                                         case $substr_chrs_c_2 == '\r': 
    600                                                                 $utf8 .= chr(0x0D); 
    601                                                                 ++$c; 
    602                                                                 break; 
    603  
    604                                                         case $substr_chrs_c_2 == '\\"': 
    605                                                         case $substr_chrs_c_2 == '\\\'': 
    606                                                         case $substr_chrs_c_2 == '\\\\': 
    607                                                         case $substr_chrs_c_2 == '\\/': 
    608                                                                 if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || 
    609                                                                 ($delim == "'" && $substr_chrs_c_2 != '\\"')) { 
    610                                                                         $utf8 .= $chrs[++$c]; 
    611                                                                 } 
    612                                                                 break; 
    613  
    614                                                         case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): 
    615                                                                 // single, escaped unicode character 
    616                                                                 $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) 
    617                                                                         . chr(hexdec(substr($chrs, ($c + 4), 2))); 
    618                                                                 $utf8 .= $this->utf162utf8($utf16); 
    619                                                                 $c += 5; 
    620                                                                 break; 
    621  
    622                                                         case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): 
    623                                                                 $utf8 .= $chrs[$c]; 
    624                                                                 break; 
    625  
    626                                                         case ($ord_chrs_c & 0xE0) == 0xC0: 
    627                                                                 // characters U-00000080 - U-000007FF, mask 110XXXXX 
    628                                                                 //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    629                                                                 $utf8 .= substr($chrs, $c, 2); 
    630                                                                 ++$c; 
    631                                                                 break; 
    632  
    633                                                         case ($ord_chrs_c & 0xF0) == 0xE0: 
    634                                                                 // characters U-00000800 - U-0000FFFF, mask 1110XXXX 
    635                                                                 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    636                                                                 $utf8 .= substr($chrs, $c, 3); 
    637                                                                 $c += 2; 
    638                                                                 break; 
    639  
    640                                                         case ($ord_chrs_c & 0xF8) == 0xF0: 
    641                                                                 // characters U-00010000 - U-001FFFFF, mask 11110XXX 
    642                                                                 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    643                                                                 $utf8 .= substr($chrs, $c, 4); 
    644                                                                 $c += 3; 
    645                                                                 break; 
    646  
    647                                                         case ($ord_chrs_c & 0xFC) == 0xF8: 
    648                                                                 // characters U-00200000 - U-03FFFFFF, mask 111110XX 
    649                                                                 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    650                                                                 $utf8 .= substr($chrs, $c, 5); 
    651                                                                 $c += 4; 
    652                                                                 break; 
    653  
    654                                                         case ($ord_chrs_c & 0xFE) == 0xFC: 
    655                                                                 // characters U-04000000 - U-7FFFFFFF, mask 1111110X 
    656                                                                 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    657                                                                 $utf8 .= substr($chrs, $c, 6); 
    658                                                                 $c += 5; 
    659                                                                 break; 
    660  
    661                                                 } 
    662  
    663                                         } 
    664  
    665                                         return $utf8; 
    666  
    667                                 } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { 
    668                                         // array, or object notation 
    669  
    670                                         if ($str[0] == '[') { 
    671                                                 $stk = array(SERVICES_JSON_IN_ARR); 
    672                                                 $arr = array(); 
    673                                         } else { 
    674                                                 if ($this->use & SERVICES_JSON_LOOSE_TYPE) { 
    675                                                         $stk = array(SERVICES_JSON_IN_OBJ); 
    676                                                         $obj = array(); 
    677                                                 } else { 
    678                                                         $stk = array(SERVICES_JSON_IN_OBJ); 
    679                                                         $obj = new stdClass(); 
    680                                                 } 
    681                                         } 
    682  
    683                                         array_push($stk, array('what'  => SERVICES_JSON_SLICE, 
    684                                                                                 'where' => 0, 
    685                                                                                 'delim' => false)); 
    686  
    687                                         $chrs = substr($str, 1, -1); 
    688                                         $chrs = $this->reduce_string($chrs); 
    689  
    690                                         if ($chrs == '') { 
    691                                                 if (reset($stk) == SERVICES_JSON_IN_ARR) { 
    692                                                         return $arr; 
    693  
    694                                                 } else { 
    695                                                         return $obj; 
    696  
    697                                                 } 
    698                                         } 
    699  
    700                                         //print("\nparsing {$chrs}\n"); 
    701  
    702                                         $strlen_chrs = strlen($chrs); 
    703  
    704                                         for ($c = 0; $c <= $strlen_chrs; ++$c) { 
    705  
    706                                                 $top = end($stk); 
    707                                                 $substr_chrs_c_2 = substr($chrs, $c, 2); 
    708  
    709                                                 if (($c == $strlen_chrs) || (($chrs[$c] == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { 
    710                                                         // found a comma that is not inside a string, array, etc., 
    711                                                         // OR we've reached the end of the character list 
    712                                                         $slice = substr($chrs, $top['where'], ($c - $top['where'])); 
    713                                                         array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); 
    714                                                         //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); 
    715  
    716                                                         if (reset($stk) == SERVICES_JSON_IN_ARR) { 
    717                                                                 // we are in an array, so just push an element onto the stack 
    718                                                                 array_push($arr, $this->decode($slice)); 
    719  
    720                                                         } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { 
    721                                                                 // we are in an object, so figure 
    722                                                                 // out the property name and set an 
    723                                                                 // element in an associative array, 
    724                                                                 // for now 
    725                                                                 $parts = array(); 
    726  
    727                                                                 if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { 
    728                                                                         // "name":value pair 
    729                                                                         $key = $this->decode($parts[1]); 
    730                                                                         $val = $this->decode($parts[2]); 
    731  
    732                                                                         if ($this->use & SERVICES_JSON_LOOSE_TYPE) { 
    733                                                                                 $obj[$key] = $val; 
    734                                                                         } else { 
    735                                                                                 $obj->$key = $val; 
    736                                                                         } 
    737                                                                 } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { 
    738                                                                         // name:value pair, where name is unquoted 
    739                                                                         $key = $parts[1]; 
    740                                                                         $val = $this->decode($parts[2]); 
    741  
    742                                                                         if ($this->use & SERVICES_JSON_LOOSE_TYPE) { 
    743                                                                                 $obj[$key] = $val; 
    744                                                                         } else { 
    745                                                                                 $obj->$key = $val; 
    746                                                                         } 
    747                                                                 } 
    748  
    749                                                         } 
    750  
    751                                                 } elseif ((($chrs[$c] == '"') || ($chrs[$c] == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { 
    752                                                         // found a quote, and we are not inside a string 
    753                                                         array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs[$c])); 
    754                                                         //print("Found start of string at {$c}\n"); 
    755  
    756                                                 } elseif (($chrs[$c] == $top['delim']) && 
    757                                                                 ($top['what'] == SERVICES_JSON_IN_STR) && 
    758                                                                 ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { 
    759                                                         // found a quote, we're in a string, and it's not escaped 
    760                                                         // we know that it's not escaped becase there is _not_ an 
    761                                                         // odd number of backslashes at the end of the string so far 
    762                                                         array_pop($stk); 
    763                                                         //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); 
    764  
    765                                                 } elseif (($chrs[$c] == '[') && 
    766                                                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { 
    767                                                         // found a left-bracket, and we are in an array, object, or slice 
    768                                                         array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); 
    769                                                         //print("Found start of array at {$c}\n"); 
    770  
    771                                                 } elseif (($chrs[$c] == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { 
    772                                                         // found a right-bracket, and we're in an array 
    773                                                         array_pop($stk); 
    774                                                         //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); 
    775  
    776                                                 } elseif (($chrs[$c] == '{') && 
    777                                                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { 
    778                                                         // found a left-brace, and we are in an array, object, or slice 
    779                                                         array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); 
    780                                                         //print("Found start of object at {$c}\n"); 
    781  
    782                                                 } elseif (($chrs[$c] == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { 
    783                                                         // found a right-brace, and we're in an object 
    784                                                         array_pop($stk); 
    785                                                         //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); 
    786  
    787                                                 } elseif (($substr_chrs_c_2 == '/*') && 
    788                                                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { 
    789                                                         // found a comment start, and we are in an array, object, or slice 
    790                                                         array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); 
    791                                                         $c++; 
    792                                                         //print("Found start of comment at {$c}\n"); 
    793  
    794                                                 } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { 
    795                                                         // found a comment end, and we're in one now 
    796                                                         array_pop($stk); 
    797                                                         $c++; 
    798  
    799                                                         for ($i = $top['where']; $i <= $c; ++$i) 
    800                                                                 $chrs = substr_replace($chrs, ' ', $i, 1); 
    801  
    802                                                         //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); 
    803  
    804                                                 } 
    805  
    806                                         } 
    807  
    808                                         if (reset($stk) == SERVICES_JSON_IN_ARR) { 
    809                                                 return $arr; 
    810  
    811                                         } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { 
    812                                                 return $obj; 
    813  
    814                                         } 
    815  
    816                                 } 
    817                 } 
    818         } 
    819  
    820         /** 
    821         * @todo Ultimately, this should just call PEAR::isError() 
    822         */ 
    823         function isError($data, $code = null) 
    824         { 
    825                 if (class_exists('pear')) { 
    826                         return PEAR::isError($data, $code); 
    827                 } elseif (is_object($data) && (get_class($data) == 'services_json_error' || 
    828                                                                 is_subclass_of($data, 'services_json_error'))) { 
    829                         return true; 
    830                 } 
    831  
    832                 return false; 
    833         } 
    834 } 
    835  
    836 if (class_exists('PEAR_Error')) { 
    837  
    838         class Services_JSON_Error extends PEAR_Error 
    839         { 
    840                 function Services_JSON_Error($message = 'unknown error', $code = null, 
    841                                                                         $mode = null, $options = null, $userinfo = null) 
    842                 { 
    843                         parent::PEAR_Error($message, $code, $mode, $options, $userinfo); 
    844                 } 
    845         } 
    846  
    847 } else { 
    848  
    849         /** 
    850         * @todo Ultimately, this class shall be descended from PEAR_Error 
    851         */ 
    852         class Services_JSON_Error 
    853         { 
    854                 function Services_JSON_Error($message = 'unknown error', $code = null, 
    855                                                                         $mode = null, $options = null, $userinfo = null) 
    856                 { 
    857  
    858                 } 
    859         } 
    860  
    861 } 
    862 endif; 
    863 ?>