676. File Comparison Report

Produced on Mon May 12 13:06:46 2008 UTC. This report uses XHTML and CSS2, and is best viewed with a reasonably standards compliant browser such as the latest version of Firefox or Internet Explorer. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.

676.1 Files compared

# Location File Last Modified
1 Mon May 12 13:06:46 2008 UTC
2 Dolphin-v.6.1.0\plugins Services_JSON.php Thu Mar 27 04:18:04 2008 UTC

676.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 0 0
Changed 0 0
Inserted 1 806
Removed 0 0

676.3 Comparison options

Whitespace
Character case Differences in character case are significant
Line endings Differences in line endings (CR and LF characters) are ignored
CR/LF characters Not shown in the comparison detail

676.4 Active regular expressions

No regular expressions were active.

676.5 Comparison detail

    1   <?php
    2   /* vim: se t expandta b tabstop= 4 shiftwid th=4 softt abstop=4:  */
    3  
    4   /**
    5   * Converts  to and fr om JSON fo rmat.
    6   *
    7   * JSON (Ja vaScript O bject Nota tion) is a  lightweig ht data-in terchange
    8   * format.  It is easy  for human s to read  and write.  It is eas y for mach ines
    9   * to parse  and gener ate. It is  based on  a subset o f the Java Script
    10   * Programm ing Langua ge, Standa rd ECMA-26 2 3rd Edit ion - Dece mber 1999.
    11   * This fea ture can a lso be fou nd in  Pyt hon. JSON  is a text  format tha t is
    12   * complete ly languag e independ ent but us es convent ions that  are famili ar
    13   * to progr ammers of  the C-fami ly of lang uages, inc luding C,  C++, C#, J ava,
    14   * JavaScri pt, Perl,  TCL, and m any others . These pr operties m ake JSON a n
    15   * ideal da ta-interch ange langu age.
    16   *
    17   * This pac kage provi des a simp le encoder  and decod er for JSO N notation . It
    18   * is inten ded for us e with cli ent-side J avascript  applicatio ns that ma ke
    19   * use of H TTPRequest  to perfor m server c ommunicati on functio ns - data  can
    20   * be encod ed into JS ON notatio n for use  in a clien t-side jav ascript, o r
    21   * decoded  from incom ing Javasc ript reque sts. JSON  format is  native to
    22   * Javascri pt, and ca n be direc tly eval() 'ed with n o further  parsing
    23   * overhead
    24   *
    25   * All stri ngs should  be in ASC II or UTF- 8 format!
    26   *
    27   * LICENSE:  Redistrib ution and  use in sou rce and bi nary forms , with or
    28   * without  modificati on, are pe rmitted pr ovided tha t the foll owing
    29   * conditio ns are met : Redistri butions of  source co de must re tain the
    30   * above co pyright no tice, this  list of c onditions  and the fo llowing
    31   * disclaim er. Redist ributions  in binary  form must  reproduce  the above
    32   * copyrigh t notice,  this list  of conditi ons and th e followin g disclaim er
    33   * in the d ocumentati on and/or  other mate rials prov ided with  the
    34   * distribu tion.
    35   *
    36   * THIS SOF TWARE IS P ROVIDED `` AS IS'' AN D ANY EXPR ESS OR IMP LIED
    37   * WARRANTI ES, INCLUD ING, BUT N OT LIMITED  TO, THE I MPLIED WAR RANTIES OF
    38   * MERCHANT ABILITY AN D FITNESS  FOR A PART ICULAR PUR POSE ARE D ISCLAIMED.  IN
    39   * NO EVENT  SHALL CON TRIBUTORS  BE LIABLE  FOR ANY DI RECT, INDI RECT,
    40   * INCIDENT AL, SPECIA L, EXEMPLA RY, OR CON SEQUENTIAL  DAMAGES ( INCLUDING,
    41   * BUT NOT  LIMITED TO , PROCUREM ENT OF SUB STITUTE GO ODS OR SER VICES; LOS S
    42   * OF USE,  DATA, OR P ROFITS; OR  BUSINESS  INTERRUPTI ON) HOWEVE R CAUSED A ND
    43   * ON ANY T HEORY OF L IABILITY,  WHETHER IN  CONTRACT,  STRICT LI ABILITY, O R
    44   * TORT (IN CLUDING NE GLIGENCE O R OTHERWIS E) ARISING  IN ANY WA Y OUT OF T HE
    45   * USE OF T HIS SOFTWA RE, EVEN I F ADVISED  OF THE POS SIBILITY O F SUCH
    46   * DAMAGE.
    47   *
    48   * @categor y
    49   * @package      Servi ces_JSON
    50   * @author       Micha l Migurski  <mike-jso n@teczno.c om>
    51   * @author       Matt  Knapp <mdk napp[at]gm ail[dot]co m>
    52   * @author       Brett  Stimmerma n <brettst immerman[a t]gmail[do t]com>
    53   * @copyrig ht   2005  Michal Mig urski
    54   * @version      CVS:  $Id: JSON. php,v 1.31  2006/06/2 8 05:54:17  migurski  Exp $
    55   * @license      http: //www.open source.org /licenses/ bsd-licens e.php
    56   * @link         http: //pear.php .net/pepr/ pepr-propo sal-show.p hp?id=198
    57   */
    58  
    59   /**
    60   * Marker c onstant fo r Services _JSON::dec ode(), use d to flag  stack stat e
    61   */
    62   define('SE RVICES_JSO N_SLICE',    1);
    63  
    64   /**
    65   * Marker c onstant fo r Services _JSON::dec ode(), use d to flag  stack stat e
    66   */
    67   define('SE RVICES_JSO N_IN_STR',   2);
    68  
    69   /**
    70   * Marker c onstant fo r Services _JSON::dec ode(), use d to flag  stack stat e
    71   */
    72   define('SE RVICES_JSO N_IN_ARR',   3);
    73  
    74   /**
    75   * Marker c onstant fo r Services _JSON::dec ode(), use d to flag  stack stat e
    76   */
    77   define('SE RVICES_JSO N_IN_OBJ',   4);
    78  
    79   /**
    80   * Marker c onstant fo r Services _JSON::dec ode(), use d to flag  stack stat e
    81   */
    82   define('SE RVICES_JSO N_IN_CMT',  5);
    83  
    84   /**
    85   * Behavior  switch fo r Services _JSON::dec ode()
    86   */
    87   define('SE RVICES_JSO N_LOOSE_TY PE', 16);
    88  
    89   /**
    90   * Behavior  switch fo r Services _JSON::dec ode()
    91   */
    92   define('SE RVICES_JSO N_SUPPRESS _ERRORS',  32);
    93  
    94   /**
    95   * Converts  to and fr om JSON fo rmat.
    96   *
    97   * Brief ex ample of u se:
    98   *
    99   * <code>
    100   * // creat e a new in stance of  Services_J SON
    101   * $json =  new Servic es_JSON();
    102   *
    103   * // conve rt a compl exe value  to JSON no tation, an d send it  to the bro wser
    104   * $value =  array('fo o', 'bar',  array(1,  2, 'baz'),  array(3,  array(4))) ;
    105   * $output  = $json->e ncode($val ue);
    106   *
    107   * print($o utput);
    108   * // print s: ["foo", "bar",[1,2 ,"baz"],[3 ,[4]]]
    109   *
    110   * // accep t incoming  POST data , assumed  to be in J SON notati on
    111   * $input =  file_get_ contents(' php://inpu t', 100000 0);
    112   * $value =  $json->de code($inpu t);
    113   * </code>
    114   */
    115   class Serv ices_JSON
    116   {
    117      /**
    118       * cons tructs a n ew JSON in stance
    119       *
    120       * @par am    int      $use     object b ehavior fl ags; combi ne with bo olean-OR
    121       *
    122       *                              possible  values:
    123       *                              - SERVIC ES_JSON_LO OSE_TYPE:   loose typ ing.
    124       *                                       "{...}" sy ntax creat es associa tive array s
    125       *                                       instead of  objects i n decode() .
    126       *                              - SERVIC ES_JSON_SU PPRESS_ERR ORS:  erro r suppress ion.
    127       *                                       Values whi ch can't b e encoded  (e.g. reso urces)
    128       *                                       appear as  NULL inste ad of thro wing error s.
    129       *                                       By default , a deeply -nested re source wil l
    130       *                                       bubble up  with an er ror, so al l return v alues
    131       *                                       from encod e() should  be checke d with isE rror()
    132       */
    133       functi on Service s_JSON($us e = 0)
    134       {
    135           $t his->use =  $use;
    136       }
    137  
    138      /**
    139       * conv ert a stri ng from on e UTF-16 c har to one  UTF-8 cha r
    140       *
    141       * Norm ally shoul d be handl ed by mb_c onvert_enc oding, but
    142       * prov ides a slo wer PHP-on ly method  for instal lations
    143       * that  lack the  multibye s tring exte nsion.
    144       *
    145       * @par am    stri ng  $utf16   UTF-16 c haracter
    146       * @ret urn   stri ng  UTF-8  character
    147       * @acc ess   priv ate
    148       */
    149       functi on utf162u tf8($utf16 )
    150       {
    151           //  oh please  oh please  oh please  oh please  oh please
    152           if (function_ exists('mb _convert_e ncoding'))  {
    153                return m b_convert_ encoding($ utf16, 'UT F-8', 'UTF -16');
    154           }
    155  
    156           $b ytes = (or d($utf16{0 }) << 8) |  ord($utf1 6{1});
    157  
    158           sw itch(true)  {
    159                case ((0 x7F & $byt es) == $by tes):
    160                    // t his case s hould neve r be reach ed, becaus e we are i n ASCII ra nge
    161                    // s ee: http:/ /www.cl.ca m.ac.uk/~m gk25/unico de.html#ut f-8
    162                    retu rn chr(0x7 F & $bytes );
    163  
    164                case (0x 07FF & $by tes) == $b ytes:
    165                    // r eturn a 2- byte UTF-8  character
    166                    // s ee: http:/ /www.cl.ca m.ac.uk/~m gk25/unico de.html#ut f-8
    167                    retu rn chr(0xC 0 | (($byt es >> 6) &  0x1F))
    168                          . chr(0x8 0 | ($byte s & 0x3F)) ;
    169  
    170                case (0x FFFF & $by tes) == $b ytes:
    171                    // r eturn a 3- byte UTF-8  character
    172                    // s ee: http:/ /www.cl.ca m.ac.uk/~m gk25/unico de.html#ut f-8
    173                    retu rn chr(0xE 0 | (($byt es >> 12)  & 0x0F))
    174                          . chr(0x8 0 | (($byt es >> 6) &  0x3F))
    175                          . chr(0x8 0 | ($byte s & 0x3F)) ;
    176           }
    177  
    178           //  ignoring  UTF-32 for  now, sorr y
    179           re turn '';
    180       }
    181  
    182      /**
    183       * conv ert a stri ng from on e UTF-8 ch ar to one  UTF-16 cha r
    184       *
    185       * Norm ally shoul d be handl ed by mb_c onvert_enc oding, but
    186       * prov ides a slo wer PHP-on ly method  for instal lations
    187       * that  lack the  multibye s tring exte nsion.
    188       *
    189       * @par am    stri ng  $utf8    UTF-8 ch aracter
    190       * @ret urn   stri ng  UTF-16  character
    191       * @acc ess   priv ate
    192       */
    193       functi on utf82ut f16($utf8)
    194       {
    195           //  oh please  oh please  oh please  oh please  oh please
    196           if (function_ exists('mb _convert_e ncoding'))  {
    197                return m b_convert_ encoding($ utf8, 'UTF -16', 'UTF -8');
    198           }
    199  
    200           sw itch(strle n($utf8))  {
    201                case 1:
    202                    // t his case s hould neve r be reach ed, becaus e we are i n ASCII ra nge
    203                    // s ee: http:/ /www.cl.ca m.ac.uk/~m gk25/unico de.html#ut f-8
    204                    retu rn $utf8;
    205  
    206                case 2:
    207                    // r eturn a UT F-16 chara cter from  a 2-byte U TF-8 char
    208                    // s ee: http:/ /www.cl.ca m.ac.uk/~m gk25/unico de.html#ut f-8
    209                    retu rn chr(0x0 7 & (ord($ utf8{0}) > > 2))
    210                          . chr((0x C0 & (ord( $utf8{0})  << 6))
    211                              | (0x 3F & ord($ utf8{1}))) ;
    212  
    213                case 3:
    214                    // r eturn a UT F-16 chara cter from  a 3-byte U TF-8 char
    215                    // s ee: http:/ /www.cl.ca m.ac.uk/~m gk25/unico de.html#ut f-8
    216                    retu rn chr((0x F0 & (ord( $utf8{0})  << 4))
    217                              | (0x 0F & (ord( $utf8{1})  >> 2)))
    218                          . chr((0x C0 & (ord( $utf8{1})  << 6))
    219                              | (0x 7F & ord($ utf8{2}))) ;
    220           }
    221  
    222           //  ignoring  UTF-32 for  now, sorr y
    223           re turn '';
    224       }
    225  
    226      /**
    227       * enco des an arb itrary var iable into  JSON form at
    228       *
    229       * @par am    mixe d   $var     any numb er, boolea n, string,  array, or  object to  be encode d.
    230       *                              see argu ment 1 to  Services_J SON() abov e for arra y-parsing  behavior.
    231       *                              if var i s a strng,  note that  encode()  always exp ects it
    232       *                              to be in  ASCII or  UTF-8 form at!
    233       *
    234       * @ret urn   mixe d   JSON s tring repr esentation  of input  var or an  error if a  problem o ccurs
    235       * @acc ess   publ ic
    236       */
    237       functi on encode( $var)
    238       {
    239           sw itch (gett ype($var))  {
    240                case 'bo olean':
    241                    retu rn $var ?  'true' : ' false';
    242  
    243                case 'NU LL':
    244                    retu rn 'null';
    245  
    246                case 'in teger':
    247                    retu rn (int) $ var;
    248  
    249                case 'do uble':
    250                case 'fl oat':
    251                    retu rn (float)  $var;
    252  
    253                case 'st ring':
    254                    // S TRINGS ARE  EXPECTED  TO BE IN A SCII OR UT F-8 FORMAT
    255                    $asc ii = '';
    256                    $str len_var =  strlen($va r);
    257  
    258                   /*
    259                    * It erate over  every cha racter in  the string ,
    260                    * es caping wit h a slash  or encodin g to UTF-8  where nec essary
    261                    */
    262                    for  ($c = 0; $ c < $strle n_var; ++$ c) {
    263  
    264                         $ord_var_c  = ord($va r{$c});
    265  
    266                         switch (tr ue) {
    267                             case $ ord_var_c  == 0x08:
    268                                 $a scii .= '\ b';
    269                                 br eak;
    270                             case $ ord_var_c  == 0x09:
    271                                 $a scii .= '\ t';
    272                                 br eak;
    273                             case $ ord_var_c  == 0x0A:
    274                                 $a scii .= '\ n';
    275                                 br eak;
    276                             case $ ord_var_c  == 0x0C:
    277                                 $a scii .= '\ f';
    278                                 br eak;
    279                             case $ ord_var_c  == 0x0D:
    280                                 $a scii .= '\ r';
    281                                 br eak;
    282  
    283                             case $ ord_var_c  == 0x22:
    284                             case $ ord_var_c  == 0x2F:
    285                             case $ ord_var_c  == 0x5C:
    286                                 //  double qu ote, slash , slosh
    287                                 $a scii .= '\ \'.$var{$c };
    288                                 br eak;
    289  
    290                             case ( ($ord_var_ c >= 0x20)  && ($ord_ var_c <= 0 x7F)):
    291                                 //  character s U-000000 00 - U-000 0007F (sam e as ASCII )
    292                                 $a scii .= $v ar{$c};
    293                                 br eak;
    294  
    295                             case ( ($ord_var_ c & 0xE0)  == 0xC0):
    296                                 //  character s U-000000 80 - U-000 007FF, mas k 110XXXXX
    297                                 //  see http: //www.cl.c am.ac.uk/~ mgk25/unic ode.html#u tf-8
    298                                 $c har = pack ('C*', $or d_var_c, o rd($var{$c  + 1}));
    299                                 $c  += 1;
    300                                 $u tf16 = $th is->utf82u tf16($char );
    301                                 $a scii .= sp rintf('\u% 04s', bin2 hex($utf16 ));
    302                                 br eak;
    303  
    304                             case ( ($ord_var_ c & 0xF0)  == 0xE0):
    305                                 //  character s U-000008 00 - U-000 0FFFF, mas k 1110XXXX
    306                                 //  see http: //www.cl.c am.ac.uk/~ mgk25/unic ode.html#u tf-8
    307                                 $c har = pack ('C*', $or d_var_c,
    308                                                ord($var{ $c + 1}),
    309                                                ord($var{ $c + 2}));
    310                                 $c  += 2;
    311                                 $u tf16 = $th is->utf82u tf16($char );
    312                                 $a scii .= sp rintf('\u% 04s', bin2 hex($utf16 ));
    313                                 br eak;
    314  
    315                             case ( ($ord_var_ c & 0xF8)  == 0xF0):
    316                                 //  character s U-000100 00 - U-001 FFFFF, mas k 11110XXX
    317                                 //  see http: //www.cl.c am.ac.uk/~ mgk25/unic ode.html#u tf-8
    318                                 $c har = pack ('C*', $or d_var_c,
    319                                                ord($var{ $c + 1}),
    320                                                ord($var{ $c + 2}),
    321                                                ord($var{ $c + 3}));
    322                                 $c  += 3;
    323                                 $u tf16 = $th is->utf82u tf16($char );
    324                                 $a scii .= sp rintf('\u% 04s', bin2 hex($utf16 ));
    325                                 br eak;
    326  
    327                             case ( ($ord_var_ c & 0xFC)  == 0xF8):
    328                                 //  character s U-002000 00 - U-03F FFFFF, mas k 111110XX
    329                                 //  see http: //www.cl.c am.ac.uk/~ mgk25/unic ode.html#u tf-8
    330                                 $c har = pack ('C*', $or d_var_c,
    331                                                ord($var{ $c + 1}),
    332                                                ord($var{ $c + 2}),
    333                                                ord($var{ $c + 3}),
    334                                                ord($var{ $c + 4}));
    335                                 $c  += 4;
    336                                 $u tf16 = $th is->utf82u tf16($char );
    337                                 $a scii .= sp rintf('\u% 04s', bin2 hex($utf16 ));
    338                                 br eak;
    339  
    340                             case ( ($ord_var_ c & 0xFE)  == 0xFC):
    341                                 //  character s U-040000 00 - U-7FF FFFFF, mas k 1111110X
    342                                 //  see http: //www.cl.c am.ac.uk/~ mgk25/unic ode.html#u tf-8
    343                                 $c har = pack ('C*', $or d_var_c,
    344                                                ord($var{ $c + 1}),
    345                                                ord($var{ $c + 2}),
    346                                                ord($var{ $c + 3}),
    347                                                ord($var{ $c + 4}),
    348                                                ord($var{ $c + 5}));
    349                                 $c  += 5;
    350                                 $u tf16 = $th is->utf82u tf16($char );
    351                                 $a scii .= sp rintf('\u% 04s', bin2 hex($utf16 ));
    352                                 br eak;
    353                         }
    354                    }
    355  
    356                    retu rn '"'.$as cii.'"';
    357  
    358                case 'ar ray':
    359                   /*
    360                    * As  per JSON  spec if an y array ke y is not a n integer
    361                    * we  must trea t the the  whole arra y as an ob ject. We
    362                    * al so try to  catch a sp arsely pop ulated ass ociative
    363                    * ar ray with n umeric key s here bec ause some  JS engines
    364                    * wi ll create  an array w ith empty  indexes up  to
    365                    * ma x_index wh ich can ca use memory  issues an d because
    366                    * th e keys, wh ich may be  relevant,  will be r emapped
    367                    * ot herwise.
    368                    *
    369                    * As  per the E CMA and JS ON specifi cation an  object may
    370                    * ha ve any str ing as a p roperty. U nfortunate ly due to
    371                    * a  hole in th e ECMA spe cification  if the ke y is a
    372                    * EC MA reserve d word or  starts wit h a digit  the
    373                    * pa rameter is  only acce ssible usi ng ECMAScr ipt's
    374                    * br acket nota tion.
    375                    */
    376  
    377                    // t reat as a  JSON objec t
    378                    if ( is_array($ var) && co unt($var)  && (array_ keys($var)  !== range (0, sizeof ($var) - 1 ))) {
    379                         $propertie s = array_ map(array( $this, 'na me_value') ,
    380                                                   array_ keys($var) ,
    381                                                   array_ values($va r));
    382  
    383                         foreach($p roperties  as $proper ty) {
    384                             if(Ser vices_JSON ::isError( $property) ) {
    385                                 re turn $prop erty;
    386                             }
    387                         }
    388  
    389                         return '{'  . join(', ', $proper ties) . '} ';
    390                    }
    391  
    392                    // t reat it li ke a regul ar array
    393                    $ele ments = ar ray_map(ar ray($this,  'encode') , $var);
    394  
    395                    fore ach($eleme nts as $el ement) {
    396                         if(Service s_JSON::is Error($ele ment)) {
    397                             return  $element;
    398                         }
    399                    }
    400  
    401                    retu rn '[' . j oin(',', $ elements)  . ']';
    402  
    403                case 'ob ject':
    404                    $var s = get_ob ject_vars( $var);
    405  
    406                    $pro perties =  array_map( array($thi s, 'name_v alue'),
    407                                               array_keys ($vars),
    408                                               array_valu es($vars)) ;
    409  
    410                    fore ach($prope rties as $ property)  {
    411                         if(Service s_JSON::is Error($pro perty)) {
    412                             return  $property ;
    413                         }
    414                    }
    415  
    416                    retu rn '{' . j oin(',', $ properties ) . '}';
    417  
    418                default:
    419                    retu rn ($this- >use & SER VICES_JSON _SUPPRESS_ ERRORS)
    420                         ? 'null'
    421                         : new Serv ices_JSON_ Error(gett ype($var). " can not  be encoded  as JSON s tring");
    422           }
    423       }
    424  
    425      /**
    426       * arra y-walking  function f or use in  generating  JSON-form atted name -value pai rs
    427       *
    428       * @par am    stri ng  $name    name of  key to use
    429       * @par am    mixe d   $value   referenc e to an ar ray elemen t to be en coded
    430       *
    431       * @ret urn   stri ng  JSON-f ormatted n ame-value  pair, like  '"name":v alue'
    432       * @acc ess   priv ate
    433       */
    434       functi on name_va lue($name,  $value)
    435       {
    436           $e ncoded_val ue = $this ->encode($ value);
    437  
    438           if (Services_ JSON::isEr ror($encod ed_value))  {
    439                return $ encoded_va lue;
    440           }
    441  
    442           re turn $this ->encode(s trval($nam e)) . ':'  . $encoded _value;
    443       }
    444  
    445      /**
    446       * redu ce a strin g by remov ing leadin g and trai ling comme nts and wh itespace
    447       *
    448       * @par am    $str     string       stri ng value t o strip of  comments  and whites pace
    449       *
    450       * @ret urn   stri ng  string  value str ipped of c omments an d whitespa ce
    451       * @acc ess   priv ate
    452       */
    453       functi on reduce_ string($st r)
    454       {
    455           $s tr = preg_ replace(ar ray(
    456  
    457                    // e liminate s ingle line  comments  in '// ... ' form
    458                    '#^\ s*//(.+)$# m',
    459  
    460                    // e liminate m ulti-line  comments i n '/* ...  */' form,  at start o f string
    461                    '#^\ s*/\*(.+)\ */#Us',
    462  
    463                    // e liminate m ulti-line  comments i n '/* ...  */' form,  at end of  string
    464                    '#/\ *(.+)\*/\s *$#Us'
    465  
    466                ), '', $ str);
    467  
    468           //  eliminate  extraneou s space
    469           re turn trim( $str);
    470       }
    471  
    472      /**
    473       * deco des a JSON  string in to appropr iate varia ble
    474       *
    475       * @par am    stri ng  $str     JSON-for matted str ing
    476       *
    477       * @ret urn   mixe d   number , boolean,  string, a rray, or o bject
    478       *                     corres ponding to  given JSO N input st ring.
    479       *                     See ar gument 1 t o Services _JSON() ab ove for ob ject-outpu t behavior .
    480       *                     Note t hat decode () always  returns st rings
    481       *                     in ASC II or UTF- 8 format!
    482       * @acc ess   publ ic
    483       */
    484       functi on decode( $str)
    485       {
    486           $s tr = $this ->reduce_s tring($str );
    487  
    488           sw itch (strt olower($st r)) {
    489                case 'tr ue':
    490                    retu rn true;
    491  
    492                case 'fa lse':
    493                    retu rn false;
    494  
    495                case 'nu ll':
    496                    retu rn null;
    497  
    498                default:
    499                    $m =  array();
    500  
    501                    if ( is_numeric ($str)) {
    502                         // Lookie- loo, it's  a number
    503  
    504                         // This wo uld work o n its own,  but I'm t rying to b e
    505                         // good ab out return ing intege rs where a ppropriate :
    506                         // return  (float)$st r;
    507  
    508                         // Return  float or i nt, as app ropriate
    509                         return ((f loat)$str  == (intege r)$str)
    510                             ? (int eger)$str
    511                             : (flo at)$str;
    512  
    513                    } el seif (preg _match('/^ ("|\').*(\ 1)$/s', $s tr, $m) &&  $m[1] ==  $m[2]) {
    514                         // STRINGS  RETURNED  IN UTF-8 F ORMAT
    515                         $delim = s ubstr($str , 0, 1);
    516                         $chrs = su bstr($str,  1, -1);
    517                         $utf8 = '' ;
    518                         $strlen_ch rs = strle n($chrs);
    519  
    520                         for ($c =  0; $c < $s trlen_chrs ; ++$c) {
    521  
    522                             $subst r_chrs_c_2  = substr( $chrs, $c,  2);
    523                             $ord_c hrs_c = or d($chrs{$c });
    524  
    525                             switch  (true) {
    526                                 ca se $substr _chrs_c_2  == '\b':
    527                                      $utf8 .=  chr(0x08) ;
    528                                      ++$c;
    529                                      break;
    530                                 ca se $substr _chrs_c_2  == '\t':
    531                                      $utf8 .=  chr(0x09) ;
    532                                      ++$c;
    533                                      break;
    534                                 ca se $substr _chrs_c_2  == '\n':
    535                                      $utf8 .=  chr(0x0A) ;
    536                                      ++$c;
    537                                      break;
    538                                 ca se $substr _chrs_c_2  == '\f':
    539                                      $utf8 .=  chr(0x0C) ;
    540                                      ++$c;
    541                                      break;
    542                                 ca se $substr _chrs_c_2  == '\r':
    543                                      $utf8 .=  chr(0x0D) ;
    544                                      ++$c;
    545                                      break;
    546  
    547                                 ca se $substr _chrs_c_2  == '\\"':
    548                                 ca se $substr _chrs_c_2  == '\\\'':
    549                                 ca se $substr _chrs_c_2  == '\\\\':
    550                                 ca se $substr _chrs_c_2  == '\\/':
    551                                      if (($de lim == '"'  && $subst r_chrs_c_2  != '\\\'' ) ||
    552                                         ($del im == "'"  && $substr _chrs_c_2  != '\\"'))  {
    553                                          $utf 8 .= $chrs {++$c};
    554                                      }
    555                                      break;
    556  
    557                                 ca se preg_ma tch('/\\\u [0-9A-F]{4 }/i', subs tr($chrs,  $c, 6)):
    558                                      // singl e, escaped  unicode c haracter
    559                                      $utf16 =  chr(hexde c(substr($ chrs, ($c  + 2), 2)))
    560                                             .  chr(hexde c(substr($ chrs, ($c  + 4), 2))) ;
    561                                      $utf8 .=  $this->ut f162utf8($ utf16);
    562                                      $c += 5;
    563                                      break;
    564  
    565                                 ca se ($ord_c hrs_c >= 0 x20) && ($ ord_chrs_c  <= 0x7F):
    566                                      $utf8 .=  $chrs{$c} ;
    567                                      break;
    568  
    569                                 ca se ($ord_c hrs_c & 0x E0) == 0xC 0:
    570                                      // chara cters U-00 000080 - U -000007FF,  mask 110X XXXX
    571                                      //see ht tp://www.c l.cam.ac.u k/~mgk25/u nicode.htm l#utf-8
    572                                      $utf8 .=  substr($c hrs, $c, 2 );
    573                                      ++$c;
    574                                      break;
    575  
    576                                 ca se ($ord_c hrs_c & 0x F0) == 0xE 0:
    577                                      // chara cters U-00 000800 - U -0000FFFF,  mask 1110 XXXX
    578                                      // see h ttp://www. cl.cam.ac. uk/~mgk25/ unicode.ht ml#utf-8
    579                                      $utf8 .=  substr($c hrs, $c, 3 );
    580                                      $c += 2;
    581                                      break;
    582  
    583                                 ca se ($ord_c hrs_c & 0x F8) == 0xF 0:
    584                                      // chara cters U-00 010000 - U -001FFFFF,  mask 1111 0XXX
    585                                      // see h ttp://www. cl.cam.ac. uk/~mgk25/ unicode.ht ml#utf-8
    586                                      $utf8 .=  substr($c hrs, $c, 4 );
    587                                      $c += 3;
    588                                      break;
    589  
    590                                 ca se ($ord_c hrs_c & 0x FC) == 0xF 8:
    591                                      // chara cters U-00 200000 - U -03FFFFFF,  mask 1111 10XX
    592                                      // see h ttp://www. cl.cam.ac. uk/~mgk25/ unicode.ht ml#utf-8
    593                                      $utf8 .=  substr($c hrs, $c, 5 );
    594                                      $c += 4;
    595                                      break;
    596  
    597                                 ca se ($ord_c hrs_c & 0x FE) == 0xF C:
    598                                      // chara cters U-04 000000 - U -7FFFFFFF,  mask 1111 110X
    599                                      // see h ttp://www. cl.cam.ac. uk/~mgk25/ unicode.ht ml#utf-8
    600                                      $utf8 .=  substr($c hrs, $c, 6 );
    601                                      $c += 5;
    602                                      break;
    603  
    604                             }
    605  
    606                         }
    607  
    608                         return $ut f8;
    609  
    610                    } el seif (preg _match('/^ \[.*\]$/s' , $str) ||  preg_matc h('/^\{.*\ }$/s', $st r)) {
    611                         // array,  or object  notation
    612  
    613                         if ($str{0 } == '[')  {
    614                             $stk =  array(SER VICES_JSON _IN_ARR);
    615                             $arr =  array();
    616                         } else {
    617                             if ($t his->use &  SERVICES_ JSON_LOOSE _TYPE) {
    618                                 $s tk = array (SERVICES_ JSON_IN_OB J);
    619                                 $o bj = array ();
    620                             } else  {
    621                                 $s tk = array (SERVICES_ JSON_IN_OB J);
    622                                 $o bj = new s tdClass();
    623                             }
    624                         }
    625  
    626                         array_push ($stk, arr ay('what'   => SERVIC ES_JSON_SL ICE,
    627                                                  'where'  => 0,
    628                                                  'delim'  => false) );
    629  
    630                         $chrs = su bstr($str,  1, -1);
    631                         $chrs = $t his->reduc e_string($ chrs);
    632  
    633                         if ($chrs  == '') {
    634                             if (re set($stk)  == SERVICE S_JSON_IN_ ARR) {
    635                                 re turn $arr;
    636  
    637                             } else  {
    638                                 re turn $obj;
    639  
    640                             }
    641                         }
    642  
    643                         //print("\ nparsing { $chrs}\n") ;
    644  
    645                         $strlen_ch rs = strle n($chrs);
    646  
    647                         for ($c =  0; $c <= $ strlen_chr s; ++$c) {
    648  
    649                             $top =  end($stk) ;
    650                             $subst r_chrs_c_2  = substr( $chrs, $c,  2);
    651  
    652                             if (($ c == $strl en_chrs) | | (($chrs{ $c} == ',' ) && ($top ['what'] = = SERVICES _JSON_SLIC E))) {
    653                                 //  found a c omma that  is not ins ide a stri ng, array,  etc.,
    654                                 //  OR we've  reached th e end of t he charact er list
    655                                 $s lice = sub str($chrs,  $top['whe re'], ($c  - $top['wh ere']));
    656                                 ar ray_push($ stk, array ('what' =>  SERVICES_ JSON_SLICE , 'where'  => ($c + 1 ), 'delim'  => false) );
    657                                 // print("Fou nd split a t {$c}: ". substr($ch rs, $top[' where'], ( 1 + $c - $ top['where ']))."\n") ;
    658  
    659                                 if  (reset($s tk) == SER VICES_JSON _IN_ARR) {
    660                                      // we ar e in an ar ray, so ju st push an  element o nto the st ack
    661                                      array_pu sh($arr, $ this->deco de($slice) );
    662  
    663                                 }  elseif (re set($stk)  == SERVICE S_JSON_IN_ OBJ) {
    664                                      // we ar e in an ob ject, so f igure
    665                                      // out t he propert y name and  set an
    666                                      // eleme nt in an a ssociative  array,
    667                                      // for n ow
    668                                      $parts =  array();
    669                                      
    670                                      if (preg _match('/^ \s*(["\']. *[^\\\]["\ '])\s*:\s* (\S.*),?$/ Uis', $sli ce, $parts )) {
    671                                          // " name":valu e pair
    672                                          $key  = $this-> decode($pa rts[1]);
    673                                          $val  = $this-> decode($pa rts[2]);
    674  
    675                                          if ( $this->use  & SERVICE S_JSON_LOO SE_TYPE) {
    676                                               $obj[$key]  = $val;
    677                                          } el se {
    678                                               $obj->$key  = $val;
    679                                          }
    680                                      } elseif  (preg_mat ch('/^\s*( \w+)\s*:\s *(\S.*),?$ /Uis', $sl ice, $part s)) {
    681                                          // n ame:value  pair, wher e name is  unquoted
    682                                          $key  = $parts[ 1];
    683                                          $val  = $this-> decode($pa rts[2]);
    684  
    685                                          if ( $this->use  & SERVICE S_JSON_LOO SE_TYPE) {
    686                                               $obj[$key]  = $val;
    687                                          } el se {
    688                                               $obj->$key  = $val;
    689                                          }
    690                                      }
    691  
    692                                 }
    693  
    694                             } else if ((($chr s{$c} == ' "') || ($c hrs{$c} ==  "'")) &&  ($top['wha t'] != SER VICES_JSON _IN_STR))  {
    695                                 //  found a q uote, and  we are not  inside a  string
    696                                 ar ray_push($ stk, array ('what' =>  SERVICES_ JSON_IN_ST R, 'where'  => $c, 'd elim' => $ chrs{$c})) ;
    697                                 // print("Fou nd start o f string a t {$c}\n") ;
    698  
    699                             } else if (($chrs {$c} == $t op['delim' ]) &&
    700                                       ($top[' what'] ==  SERVICES_J SON_IN_STR ) &&
    701                                       ((strle n(substr($ chrs, 0, $ c)) - strl en(rtrim(s ubstr($chr s, 0, $c),  '\\'))) %  2 != 1))  {
    702                                 //  found a q uote, we'r e in a str ing, and i t's not es caped
    703                                 //  we know t hat it's n ot escaped  becase th ere is _no t_ an
    704                                 //  odd numbe r of backs lashes at  the end of  the strin g so far
    705                                 ar ray_pop($s tk);
    706                                 // print("Fou nd end of  string at  {$c}: ".su bstr($chrs , $top['wh ere'], (1  + 1 + $c -  $top['whe re']))."\n ");
    707  
    708                             } else if (($chrs {$c} == '[ ') &&
    709                                       in_arra y($top['wh at'], arra y(SERVICES _JSON_SLIC E, SERVICE S_JSON_IN_ ARR, SERVI CES_JSON_I N_OBJ))) {
    710                                 //  found a l eft-bracke t, and we  are in an  array, obj ect, or sl ice
    711                                 ar ray_push($ stk, array ('what' =>  SERVICES_ JSON_IN_AR R, 'where'  => $c, 'd elim' => f alse));
    712                                 // print("Fou nd start o f array at  {$c}\n");
    713  
    714                             } else if (($chrs {$c} == '] ') && ($to p['what']  == SERVICE S_JSON_IN_ ARR)) {
    715                                 //  found a r ight-brack et, and we 're in an  array
    716                                 ar ray_pop($s tk);
    717                                 // print("Fou nd end of  array at { $c}: ".sub str($chrs,  $top['whe re'], (1 +  $c - $top ['where']) )."\n");
    718  
    719                             } else if (($chrs {$c} == '{ ') &&
    720                                       in_arra y($top['wh at'], arra y(SERVICES _JSON_SLIC E, SERVICE S_JSON_IN_ ARR, SERVI CES_JSON_I N_OBJ))) {
    721                                 //  found a l eft-brace,  and we ar e in an ar ray, objec t, or slic e
    722                                 ar ray_push($ stk, array ('what' =>  SERVICES_ JSON_IN_OB J, 'where'  => $c, 'd elim' => f alse));
    723                                 // print("Fou nd start o f object a t {$c}\n") ;
    724  
    725                             } else if (($chrs {$c} == '} ') && ($to p['what']  == SERVICE S_JSON_IN_ OBJ)) {
    726                                 //  found a r ight-brace , and we'r e in an ob ject
    727                                 ar ray_pop($s tk);
    728                                 // print("Fou nd end of  object at  {$c}: ".su bstr($chrs , $top['wh ere'], (1  + $c - $to p['where'] ))."\n");
    729  
    730                             } else if (($subs tr_chrs_c_ 2 == '/*')  &&
    731                                       in_arra y($top['wh at'], arra y(SERVICES _JSON_SLIC E, SERVICE S_JSON_IN_ ARR, SERVI CES_JSON_I N_OBJ))) {
    732                                 //  found a c omment sta rt, and we  are in an  array, ob ject, or s lice
    733                                 ar ray_push($ stk, array ('what' =>  SERVICES_ JSON_IN_CM T, 'where'  => $c, 'd elim' => f alse));
    734                                 $c ++;
    735                                 // print("Fou nd start o f comment  at {$c}\n" );
    736  
    737                             } else if (($subs tr_chrs_c_ 2 == '*/')  && ($top[ 'what'] ==  SERVICES_ JSON_IN_CM T)) {
    738                                 //  found a c omment end , and we'r e in one n ow
    739                                 ar ray_pop($s tk);
    740                                 $c ++;
    741  
    742                                 fo r ($i = $t op['where' ]; $i <= $ c; ++$i)
    743                                      $chrs =  substr_rep lace($chrs , ' ', $i,  1);
    744  
    745                                 // print("Fou nd end of  comment at  {$c}: ".s ubstr($chr s, $top['w here'], (1  + $c - $t op['where' ]))."\n");
    746  
    747                             }
    748  
    749                         }
    750  
    751                         if (reset( $stk) == S ERVICES_JS ON_IN_ARR)  {
    752                             return  $arr;
    753  
    754                         } elseif ( reset($stk ) == SERVI CES_JSON_I N_OBJ) {
    755                             return  $obj;
    756  
    757                         }
    758  
    759                    }
    760           }
    761       }
    762  
    763       /**
    764        * @to do Ultimat ely, this  should jus t call PEA R::isError ()
    765        */
    766       functi on isError ($data, $c ode = null )
    767       {
    768           if  (class_ex ists('pear ')) {
    769                return P EAR::isErr or($data,  $code);
    770           }  elseif (is _object($d ata) && (g et_class($ data) == ' services_j son_error'  ||
    771                                       is_subc lass_of($d ata, 'serv ices_json_ error')))  {
    772                return t rue;
    773           }
    774  
    775           re turn false ;
    776       }
    777   }
    778  
    779   if (class_ exists('PE AR_Error') ) {
    780  
    781       class  Services_J SON_Error  extends PE AR_Error
    782       {
    783           fu nction Ser vices_JSON _Error($me ssage = 'u nknown err or', $code  = null,
    784                                           $mo de = null,  $options  = null, $u serinfo =  null)
    785           {
    786                parent:: PEAR_Error ($message,  $code, $m ode, $opti ons, $user info);
    787           }
    788       }
    789  
    790   } else {
    791  
    792       /**
    793        * @to do Ultimat ely, this  class shal l be desce nded from  PEAR_Error
    794        */
    795       class  Services_J SON_Error
    796       {
    797           fu nction Ser vices_JSON _Error($me ssage = 'u nknown err or', $code  = null,
    798                                           $mo de = null,  $options  = null, $u serinfo =  null)
    799           {
    800  
    801           }
    802       }
    803  
    804   }
    805       
    806   ?>