Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F8198660
Decoder.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
Decoder.php
View Options
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Json
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Decoder.php 10020 2009-08-18 14:34:09Z j.fischer@metaways.de $
*/
/**
* @see Zend_Json
*/
require_once
'Zend/Json.php'
;
/**
* Decode JSON encoded string to PHP variable constructs
*
* @category Zend
* @package Zend_Json
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class
Zend_Json_Decoder
{
/**
* Parse tokens used to decode the JSON object. These are not
* for public consumption, they are just used internally to the
* class.
*/
const
EOF
=
0
;
const
DATUM
=
1
;
const
LBRACE
=
2
;
const
LBRACKET
=
3
;
const
RBRACE
=
4
;
const
RBRACKET
=
5
;
const
COMMA
=
6
;
const
COLON
=
7
;
/**
* Use to maintain a "pointer" to the source being decoded
*
* @var string
*/
protected
$_source
;
/**
* Caches the source length
*
* @var int
*/
protected
$_sourceLength
;
/**
* The offset within the souce being decoded
*
* @var int
*
*/
protected
$_offset
;
/**
* The current token being considered in the parser cycle
*
* @var int
*/
protected
$_token
;
/**
* Flag indicating how objects should be decoded
*
* @var int
* @access protected
*/
protected
$_decodeType
;
/**
* Constructor
*
* @param string $source String source to decode
* @param int $decodeType How objects should be decoded -- see
* {@link Zend_Json::TYPE_ARRAY} and {@link Zend_Json::TYPE_OBJECT} for
* valid values
* @return void
*/
protected
function
__construct
(
$source
,
$decodeType
)
{
// Set defaults
$this
->
_source
=
self
::
decodeUnicodeString
(
$source
);
$this
->
_sourceLength
=
strlen
(
$this
->
_source
);
$this
->
_token
=
self
::
EOF
;
$this
->
_offset
=
0
;
// Normalize and set $decodeType
if
(!
in_array
(
$decodeType
,
array
(
Zend_Json
::
TYPE_ARRAY
,
Zend_Json
::
TYPE_OBJECT
)))
{
$decodeType
=
Zend_Json
::
TYPE_ARRAY
;
}
$this
->
_decodeType
=
$decodeType
;
// Set pointer at first token
$this
->
_getNextToken
();
}
/**
* Decode a JSON source string
*
* Decodes a JSON encoded string. The value returned will be one of the
* following:
* - integer
* - float
* - boolean
* - null
* - StdClass
* - array
* - array of one or more of the above types
*
* By default, decoded objects will be returned as associative arrays; to
* return a StdClass object instead, pass {@link Zend_Json::TYPE_OBJECT} to
* the $objectDecodeType parameter.
*
* Throws a Zend_Json_Exception if the source string is null.
*
* @static
* @access public
* @param string $source String to be decoded
* @param int $objectDecodeType How objects should be decoded; should be
* either or {@link Zend_Json::TYPE_ARRAY} or
* {@link Zend_Json::TYPE_OBJECT}; defaults to TYPE_ARRAY
* @return mixed
* @throws Zend_Json_Exception
*/
public
static
function
decode
(
$source
=
null
,
$objectDecodeType
=
Zend_Json
::
TYPE_ARRAY
)
{
if
(
null
===
$source
)
{
require_once
'Zend/Json/Exception.php'
;
throw
new
Zend_Json_Exception
(
'Must specify JSON encoded source for decoding'
);
}
elseif
(!
is_string
(
$source
))
{
require_once
'Zend/Json/Exception.php'
;
throw
new
Zend_Json_Exception
(
'Can only decode JSON encoded strings'
);
}
$decoder
=
new
self
(
$source
,
$objectDecodeType
);
return
$decoder
->
_decodeValue
();
}
/**
* Recursive driving rountine for supported toplevel tops
*
* @return mixed
*/
protected
function
_decodeValue
()
{
switch
(
$this
->
_token
)
{
case
self
::
DATUM
:
$result
=
$this
->
_tokenValue
;
$this
->
_getNextToken
();
return
(
$result
);
break
;
case
self
::
LBRACE
:
return
(
$this
->
_decodeObject
());
break
;
case
self
::
LBRACKET
:
return
(
$this
->
_decodeArray
());
break
;
default
:
return
null
;
break
;
}
}
/**
* Decodes an object of the form:
* { "attribute: value, "attribute2" : value,...}
*
* If Zend_Json_Encoder was used to encode the original object then
* a special attribute called __className which specifies a class
* name that should wrap the data contained within the encoded source.
*
* Decodes to either an array or StdClass object, based on the value of
* {@link $_decodeType}. If invalid $_decodeType present, returns as an
* array.
*
* @return array|StdClass
*/
protected
function
_decodeObject
()
{
$members
=
array
();
$tok
=
$this
->
_getNextToken
();
while
(
$tok
&&
$tok
!=
self
::
RBRACE
)
{
if
(
$tok
!=
self
::
DATUM
||
!
is_string
(
$this
->
_tokenValue
))
{
require_once
'Zend/Json/Exception.php'
;
throw
new
Zend_Json_Exception
(
'Missing key in object encoding: '
.
$this
->
_source
);
}
$key
=
$this
->
_tokenValue
;
$tok
=
$this
->
_getNextToken
();
if
(
$tok
!=
self
::
COLON
)
{
require_once
'Zend/Json/Exception.php'
;
throw
new
Zend_Json_Exception
(
'Missing ":" in object encoding: '
.
$this
->
_source
);
}
$tok
=
$this
->
_getNextToken
();
$members
[
$key
]
=
$this
->
_decodeValue
();
$tok
=
$this
->
_token
;
if
(
$tok
==
self
::
RBRACE
)
{
break
;
}
if
(
$tok
!=
self
::
COMMA
)
{
require_once
'Zend/Json/Exception.php'
;
throw
new
Zend_Json_Exception
(
'Missing "," in object encoding: '
.
$this
->
_source
);
}
$tok
=
$this
->
_getNextToken
();
}
switch
(
$this
->
_decodeType
)
{
case
Zend_Json
::
TYPE_OBJECT
:
// Create new StdClass and populate with $members
$result
=
new
StdClass
();
foreach
(
$members
as
$key
=>
$value
)
{
$result
->
$key
=
$value
;
}
break
;
case
Zend_Json
::
TYPE_ARRAY
:
default
:
$result
=
$members
;
break
;
}
$this
->
_getNextToken
();
return
$result
;
}
/**
* Decodes a JSON array format:
* [element, element2,...,elementN]
*
* @return array
*/
protected
function
_decodeArray
()
{
$result
=
array
();
$starttok
=
$tok
=
$this
->
_getNextToken
();
// Move past the '['
$index
=
0
;
while
(
$tok
&&
$tok
!=
self
::
RBRACKET
)
{
$result
[
$index
++]
=
$this
->
_decodeValue
();
$tok
=
$this
->
_token
;
if
(
$tok
==
self
::
RBRACKET
||
!
$tok
)
{
break
;
}
if
(
$tok
!=
self
::
COMMA
)
{
require_once
'Zend/Json/Exception.php'
;
throw
new
Zend_Json_Exception
(
'Missing "," in array encoding: '
.
$this
->
_source
);
}
$tok
=
$this
->
_getNextToken
();
}
$this
->
_getNextToken
();
return
(
$result
);
}
/**
* Removes whitepsace characters from the source input
*/
protected
function
_eatWhitespace
()
{
if
(
preg_match
(
'/([
\t\b\f\n\r
])*/s'
,
$this
->
_source
,
$matches
,
PREG_OFFSET_CAPTURE
,
$this
->
_offset
)
&&
$matches
[
0
][
1
]
==
$this
->
_offset
)
{
$this
->
_offset
+=
strlen
(
$matches
[
0
][
0
]);
}
}
/**
* Retrieves the next token from the source stream
*
* @return int Token constant value specified in class definition
*/
protected
function
_getNextToken
()
{
$this
->
_token
=
self
::
EOF
;
$this
->
_tokenValue
=
null
;
$this
->
_eatWhitespace
();
if
(
$this
->
_offset
>=
$this
->
_sourceLength
)
{
return
(
self
::
EOF
);
}
$str
=
$this
->
_source
;
$str_length
=
$this
->
_sourceLength
;
$i
=
$this
->
_offset
;
$start
=
$i
;
switch
(
$str
{
$i
})
{
case
'{'
:
$this
->
_token
=
self
::
LBRACE
;
break
;
case
'}'
:
$this
->
_token
=
self
::
RBRACE
;
break
;
case
'['
:
$this
->
_token
=
self
::
LBRACKET
;
break
;
case
']'
:
$this
->
_token
=
self
::
RBRACKET
;
break
;
case
','
:
$this
->
_token
=
self
::
COMMA
;
break
;
case
':'
:
$this
->
_token
=
self
::
COLON
;
break
;
case
'"'
:
$result
=
''
;
do
{
$i
++;
if
(
$i
>=
$str_length
)
{
break
;
}
$chr
=
$str
{
$i
};
if
(
$chr
==
'
\\
'
)
{
$i
++;
if
(
$i
>=
$str_length
)
{
break
;
}
$chr
=
$str
{
$i
};
switch
(
$chr
)
{
case
'"'
:
$result
.=
'"'
;
break
;
case
'
\\
'
:
$result
.=
'
\\
'
;
break
;
case
'/'
:
$result
.=
'/'
;
break
;
case
'b'
:
$result
.=
chr
(
8
);
break
;
case
'f'
:
$result
.=
chr
(
12
);
break
;
case
'n'
:
$result
.=
chr
(
10
);
break
;
case
'r'
:
$result
.=
chr
(
13
);
break
;
case
't'
:
$result
.=
chr
(
9
);
break
;
case
'
\'
'
:
$result
.=
'
\'
'
;
break
;
default
:
require_once
'Zend/Json/Exception.php'
;
throw
new
Zend_Json_Exception
(
"Illegal escape "
.
"sequence '"
.
$chr
.
"'"
);
}
}
elseif
(
$chr
==
'"'
)
{
break
;
}
else
{
$result
.=
$chr
;
}
}
while
(
$i
<
$str_length
);
$this
->
_token
=
self
::
DATUM
;
//$this->_tokenValue = substr($str, $start + 1, $i - $start - 1);
$this
->
_tokenValue
=
$result
;
break
;
case
't'
:
if
((
$i
+
3
)
<
$str_length
&&
substr
(
$str
,
$start
,
4
)
==
"true"
)
{
$this
->
_token
=
self
::
DATUM
;
}
$this
->
_tokenValue
=
true
;
$i
+=
3
;
break
;
case
'f'
:
if
((
$i
+
4
)
<
$str_length
&&
substr
(
$str
,
$start
,
5
)
==
"false"
)
{
$this
->
_token
=
self
::
DATUM
;
}
$this
->
_tokenValue
=
false
;
$i
+=
4
;
break
;
case
'n'
:
if
((
$i
+
3
)
<
$str_length
&&
substr
(
$str
,
$start
,
4
)
==
"null"
)
{
$this
->
_token
=
self
::
DATUM
;
}
$this
->
_tokenValue
=
NULL
;
$i
+=
3
;
break
;
}
if
(
$this
->
_token
!=
self
::
EOF
)
{
$this
->
_offset
=
$i
+
1
;
// Consume the last token character
return
(
$this
->
_token
);
}
$chr
=
$str
{
$i
};
if
(
$chr
==
'-'
||
$chr
==
'.'
||
(
$chr
>=
'0'
&&
$chr
<=
'9'
))
{
if
(
preg_match
(
'/-?([0-9])*(
\.
[0-9]*)?((e|E)((-|
\+
)?)[0-9]+)?/s'
,
$str
,
$matches
,
PREG_OFFSET_CAPTURE
,
$start
)
&&
$matches
[
0
][
1
]
==
$start
)
{
$datum
=
$matches
[
0
][
0
];
if
(
is_numeric
(
$datum
))
{
if
(
preg_match
(
'/^0
\d
+$/'
,
$datum
))
{
require_once
'Zend/Json/Exception.php'
;
throw
new
Zend_Json_Exception
(
"Octal notation not supported by JSON (value: $datum)"
);
}
else
{
$val
=
intval
(
$datum
);
$fVal
=
floatval
(
$datum
);
$this
->
_tokenValue
=
(
$val
==
$fVal
?
$val
:
$fVal
);
}
}
else
{
require_once
'Zend/Json/Exception.php'
;
throw
new
Zend_Json_Exception
(
"Illegal number format: $datum"
);
}
$this
->
_token
=
self
::
DATUM
;
$this
->
_offset
=
$start
+
strlen
(
$datum
);
}
}
else
{
require_once
'Zend/Json/Exception.php'
;
throw
new
Zend_Json_Exception
(
'Illegal Token'
);
}
return
(
$this
->
_token
);
}
/**
* Decode Unicode Characters from \u0000 ASCII syntax.
*
* This algorithm was originally developed for the
* Solar Framework by Paul M. Jones
*
* @link http://solarphp.com/
* @link http://svn.solarphp.com/core/trunk/Solar/Json.php
* @param string $value
* @return string
*/
public
static
function
decodeUnicodeString
(
$chrs
)
{
$delim
=
substr
(
$chrs
,
0
,
1
);
$utf8
=
''
;
$strlen_chrs
=
strlen
(
$chrs
);
for
(
$i
=
0
;
$i
<
$strlen_chrs
;
$i
++)
{
$substr_chrs_c_2
=
substr
(
$chrs
,
$i
,
2
);
$ord_chrs_c
=
ord
(
$chrs
[
$i
]);
switch
(
true
)
{
case
preg_match
(
'/
\\\u
[0-9A-F]{4}/i'
,
substr
(
$chrs
,
$i
,
6
)):
// single, escaped unicode character
$utf16
=
chr
(
hexdec
(
substr
(
$chrs
,
(
$i
+
2
),
2
)))
.
chr
(
hexdec
(
substr
(
$chrs
,
(
$i
+
4
),
2
)));
$utf8
.=
self
::
_utf162utf8
(
$utf16
);
$i
+=
5
;
break
;
case
(
$ord_chrs_c
>=
0x20
)
&&
(
$ord_chrs_c
<=
0x7F
):
$utf8
.=
$chrs
{
$i
};
break
;
case
(
$ord_chrs_c
&
0xE0
)
==
0xC0
:
// characters U-00000080 - U-000007FF, mask 110XXXXX
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8
.=
substr
(
$chrs
,
$i
,
2
);
++
$i
;
break
;
case
(
$ord_chrs_c
&
0xF0
)
==
0xE0
:
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8
.=
substr
(
$chrs
,
$i
,
3
);
$i
+=
2
;
break
;
case
(
$ord_chrs_c
&
0xF8
)
==
0xF0
:
// characters U-00010000 - U-001FFFFF, mask 11110XXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8
.=
substr
(
$chrs
,
$i
,
4
);
$i
+=
3
;
break
;
case
(
$ord_chrs_c
&
0xFC
)
==
0xF8
:
// characters U-00200000 - U-03FFFFFF, mask 111110XX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8
.=
substr
(
$chrs
,
$i
,
5
);
$i
+=
4
;
break
;
case
(
$ord_chrs_c
&
0xFE
)
==
0xFC
:
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8
.=
substr
(
$chrs
,
$i
,
6
);
$i
+=
5
;
break
;
}
}
return
$utf8
;
}
/**
* Convert a string from one UTF-16 char to one UTF-8 char.
*
* Normally should be handled by mb_convert_encoding, but
* provides a slower PHP-only method for installations
* that lack the multibye string extension.
*
* This method is from the Solar Framework by Paul M. Jones
*
* @link http://solarphp.com
* @param string $utf16 UTF-16 character
* @return string UTF-8 character
*/
protected
static
function
_utf162utf8
(
$utf16
)
{
// Check for mb extension otherwise do by hand.
if
(
function_exists
(
'mb_convert_encoding'
)
)
{
return
mb_convert_encoding
(
$utf16
,
'UTF-8'
,
'UTF-16'
);
}
$bytes
=
(
ord
(
$utf16
{
0
})
<<
8
)
|
ord
(
$utf16
{
1
});
switch
(
true
)
{
case
((
0x7F
&
$bytes
)
==
$bytes
):
// this case should never be reached, because we are in ASCII range
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return
chr
(
0x7F
&
$bytes
);
case
(
0x07FF
&
$bytes
)
==
$bytes
:
// return a 2-byte UTF-8 character
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return
chr
(
0xC0
|
((
$bytes
>>
6
)
&
0x1F
))
.
chr
(
0x80
|
(
$bytes
&
0x3F
));
case
(
0xFFFF
&
$bytes
)
==
$bytes
:
// return a 3-byte UTF-8 character
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return
chr
(
0xE0
|
((
$bytes
>>
12
)
&
0x0F
))
.
chr
(
0x80
|
((
$bytes
>>
6
)
&
0x3F
))
.
chr
(
0x80
|
(
$bytes
&
0x3F
));
}
// ignoring UTF-32 for now, sorry
return
''
;
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Wed, Jul 8, 8:30 PM (1 d, 22 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1051735
Default Alt Text
Decoder.php (18 KB)
Attached To
Mode
R4 syncroton
Attached
Detach File
Event Timeline
Log In to Comment