You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
672 lines
24 KiB
PHTML
672 lines
24 KiB
PHTML
5 years ago
|
<?php
|
||
|
/**********************************************************\
|
||
|
| |
|
||
|
| hprose |
|
||
|
| |
|
||
|
| Official WebSite: http://www.hprose.com/ |
|
||
|
| http://www.hprose.net/ |
|
||
|
| http://www.hprose.org/ |
|
||
|
| |
|
||
|
\**********************************************************/
|
||
|
|
||
|
/**********************************************************\
|
||
|
* *
|
||
|
* HproseReader.php *
|
||
|
* *
|
||
|
* hprose reader library for php5. *
|
||
|
* *
|
||
|
* LastModified: Nov 12, 2013 *
|
||
|
* Author: Ma Bingyao <andot@hprfc.com> *
|
||
|
* *
|
||
|
\**********************************************************/
|
||
|
|
||
|
require_once('HproseCommon.php');
|
||
|
require_once('HproseTags.php');
|
||
|
require_once('HproseClassManager.php');
|
||
|
|
||
|
class HproseRawReader {
|
||
|
public $stream;
|
||
|
function __construct(&$stream) {
|
||
|
$this->stream = &$stream;
|
||
|
}
|
||
|
public function readRaw($ostream = NULL, $tag = NULL) {
|
||
|
if (is_null($ostream)) {
|
||
|
$ostream = new HproseStringStream();
|
||
|
}
|
||
|
if (is_null($tag)) {
|
||
|
$tag = $this->stream->getc();
|
||
|
}
|
||
|
switch ($tag) {
|
||
|
case '0':
|
||
|
case '1':
|
||
|
case '2':
|
||
|
case '3':
|
||
|
case '4':
|
||
|
case '5':
|
||
|
case '6':
|
||
|
case '7':
|
||
|
case '8':
|
||
|
case '9':
|
||
|
case HproseTags::TagNull:
|
||
|
case HproseTags::TagEmpty:
|
||
|
case HproseTags::TagTrue:
|
||
|
case HproseTags::TagFalse:
|
||
|
case HproseTags::TagNaN:
|
||
|
$ostream->write($tag);
|
||
|
break;
|
||
|
case HproseTags::TagInfinity:
|
||
|
$ostream->write($tag);
|
||
|
$ostream->write($this->stream->getc());
|
||
|
break;
|
||
|
case HproseTags::TagInteger:
|
||
|
case HproseTags::TagLong:
|
||
|
case HproseTags::TagDouble:
|
||
|
case HproseTags::TagRef:
|
||
|
$this->readNumberRaw($ostream, $tag);
|
||
|
break;
|
||
|
case HproseTags::TagDate:
|
||
|
case HproseTags::TagTime:
|
||
|
$this->readDateTimeRaw($ostream, $tag);
|
||
|
break;
|
||
|
case HproseTags::TagUTF8Char:
|
||
|
$this->readUTF8CharRaw($ostream, $tag);
|
||
|
break;
|
||
|
case HproseTags::TagBytes:
|
||
|
$this->readBytesRaw($ostream, $tag);
|
||
|
break;
|
||
|
case HproseTags::TagString:
|
||
|
$this->readStringRaw($ostream, $tag);
|
||
|
break;
|
||
|
case HproseTags::TagGuid:
|
||
|
$this->readGuidRaw($ostream, $tag);
|
||
|
break;
|
||
|
case HproseTags::TagList:
|
||
|
case HproseTags::TagMap:
|
||
|
case HproseTags::TagObject:
|
||
|
$this->readComplexRaw($ostream, $tag);
|
||
|
break;
|
||
|
case HproseTags::TagClass:
|
||
|
$this->readComplexRaw($ostream, $tag);
|
||
|
$this->readRaw($ostream);
|
||
|
break;
|
||
|
case HproseTags::TagError:
|
||
|
$ostream->write($tag);
|
||
|
$this->readRaw($ostream);
|
||
|
break;
|
||
|
case false:
|
||
|
throw new HproseException("No byte found in stream");
|
||
|
default:
|
||
|
throw new HproseException("Unexpected serialize tag '" + $tag + "' in stream");
|
||
|
}
|
||
|
return $ostream;
|
||
|
}
|
||
|
|
||
|
private function readNumberRaw($ostream, $tag) {
|
||
|
$s = $tag .
|
||
|
$this->stream->readuntil(HproseTags::TagSemicolon) .
|
||
|
HproseTags::TagSemicolon;
|
||
|
$ostream->write($s);
|
||
|
}
|
||
|
|
||
|
private function readDateTimeRaw($ostream, $tag) {
|
||
|
$s = $tag;
|
||
|
do {
|
||
|
$tag = $this->stream->getc();
|
||
|
$s .= $tag;
|
||
|
} while ($tag != HproseTags::TagSemicolon &&
|
||
|
$tag != HproseTags::TagUTC);
|
||
|
$ostream->write($s);
|
||
|
}
|
||
|
|
||
|
private function readUTF8CharRaw($ostream, $tag) {
|
||
|
$s = $tag;
|
||
|
$tag = $this->stream->getc();
|
||
|
$s .= $tag;
|
||
|
$a = ord($tag);
|
||
|
if (($a & 0xE0) == 0xC0) {
|
||
|
$s .= $this->stream->getc();
|
||
|
}
|
||
|
elseif (($a & 0xF0) == 0xE0) {
|
||
|
$s .= $this->stream->read(2);
|
||
|
}
|
||
|
elseif ($a > 0x7F) {
|
||
|
throw new HproseException("bad utf-8 encoding");
|
||
|
}
|
||
|
$ostream->write($s);
|
||
|
}
|
||
|
|
||
|
private function readBytesRaw($ostream, $tag) {
|
||
|
$len = $this->stream->readuntil(HproseTags::TagQuote);
|
||
|
$s = $tag . $len . HproseTags::TagQuote . $this->stream->read((int)$len) . HproseTags::TagQuote;
|
||
|
$this->stream->skip(1);
|
||
|
$ostream->write($s);
|
||
|
}
|
||
|
|
||
|
private function readStringRaw($ostream, $tag) {
|
||
|
$len = $this->stream->readuntil(HproseTags::TagQuote);
|
||
|
$s = $tag . $len . HproseTags::TagQuote;
|
||
|
$len = (int)$len;
|
||
|
$this->stream->mark();
|
||
|
$utf8len = 0;
|
||
|
for ($i = 0; $i < $len; ++$i) {
|
||
|
switch (ord($this->stream->getc()) >> 4) {
|
||
|
case 0:
|
||
|
case 1:
|
||
|
case 2:
|
||
|
case 3:
|
||
|
case 4:
|
||
|
case 5:
|
||
|
case 6:
|
||
|
case 7: {
|
||
|
// 0xxx xxxx
|
||
|
$utf8len++;
|
||
|
break;
|
||
|
}
|
||
|
case 12:
|
||
|
case 13: {
|
||
|
// 110x xxxx 10xx xxxx
|
||
|
$this->stream->skip(1);
|
||
|
$utf8len += 2;
|
||
|
break;
|
||
|
}
|
||
|
case 14: {
|
||
|
// 1110 xxxx 10xx xxxx 10xx xxxx
|
||
|
$this->stream->skip(2);
|
||
|
$utf8len += 3;
|
||
|
break;
|
||
|
}
|
||
|
case 15: {
|
||
|
// 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
|
||
|
$this->stream->skip(3);
|
||
|
$utf8len += 4;
|
||
|
++$i;
|
||
|
break;
|
||
|
}
|
||
|
default: {
|
||
|
throw new HproseException('bad utf-8 encoding');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
$this->stream->reset();
|
||
|
$this->stream->unmark();
|
||
|
$s .= $this->stream->read($utf8len) . HproseTags::TagQuote;
|
||
|
$this->stream->skip(1);
|
||
|
$ostream->write($s);
|
||
|
}
|
||
|
|
||
|
private function readGuidRaw($ostream, $tag) {
|
||
|
$s = $tag . $this->stream->read(38);
|
||
|
$ostream->write($s);
|
||
|
}
|
||
|
|
||
|
private function readComplexRaw($ostream, $tag) {
|
||
|
$s = $tag .
|
||
|
$this->stream->readuntil(HproseTags::TagOpenbrace) .
|
||
|
HproseTags::TagOpenbrace;
|
||
|
$ostream->write($s);
|
||
|
while (($tag = $this->stream->getc()) != HproseTags::TagClosebrace) {
|
||
|
$this->readRaw($ostream, $tag);
|
||
|
}
|
||
|
$ostream->write($tag);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class HproseSimpleReader extends HproseRawReader {
|
||
|
private $classref;
|
||
|
function __construct(&$stream) {
|
||
|
parent::__construct($stream);
|
||
|
$this->classref = array();
|
||
|
}
|
||
|
public function &unserialize($tag = NULL) {
|
||
|
if (is_null($tag)) {
|
||
|
$tag = $this->stream->getc();
|
||
|
}
|
||
|
$result = NULL;
|
||
|
switch ($tag) {
|
||
|
case '0':
|
||
|
case '1':
|
||
|
case '2':
|
||
|
case '3':
|
||
|
case '4':
|
||
|
case '5':
|
||
|
case '6':
|
||
|
case '7':
|
||
|
case '8':
|
||
|
case '9':
|
||
|
$result = (int)$tag; break;
|
||
|
case HproseTags::TagInteger: $result = $this->readInteger(); break;
|
||
|
case HproseTags::TagLong: $result = $this->readLong(); break;
|
||
|
case HproseTags::TagDouble: $result = $this->readDouble(); break;
|
||
|
case HproseTags::TagNull: break;
|
||
|
case HproseTags::TagEmpty: $result = ''; break;
|
||
|
case HproseTags::TagTrue: $result = true; break;
|
||
|
case HproseTags::TagFalse: $result = false; break;
|
||
|
case HproseTags::TagNaN: $result = log(-1); break;
|
||
|
case HproseTags::TagInfinity: $result = $this->readInfinity(); break;
|
||
|
case HproseTags::TagDate: $result = $this->readDate(); break;
|
||
|
case HproseTags::TagTime: $result = $this->readTime(); break;
|
||
|
case HproseTags::TagBytes: $result = $this->readBytes(); break;
|
||
|
case HproseTags::TagUTF8Char: $result = $this->readUTF8Char(); break;
|
||
|
case HproseTags::TagString: $result = $this->readString(); break;
|
||
|
case HproseTags::TagGuid: $result = $this->readGuid(); break;
|
||
|
case HproseTags::TagList: $result = &$this->readList(); break;
|
||
|
case HproseTags::TagMap: $result = &$this->readMap(); break;
|
||
|
case HproseTags::TagClass: $this->readClass(); $result = &$this->unserialize(); break;
|
||
|
case HproseTags::TagObject: $result = $this->readObject(); break;
|
||
|
case HproseTags::TagError: throw new HproseException($this->readString(true));
|
||
|
case false: throw new HproseException('No byte found in stream');
|
||
|
default: throw new HproseException("Unexpected serialize tag '$tag' in stream");
|
||
|
}
|
||
|
return $result;
|
||
|
}
|
||
|
public function checkTag($expectTag, $tag = NULL) {
|
||
|
if (is_null($tag)) $tag = $this->stream->getc();
|
||
|
if ($tag != $expectTag) {
|
||
|
throw new HproseException("Tag '$expectTag' expected, but '$tag' found in stream");
|
||
|
}
|
||
|
}
|
||
|
public function checkTags($expectTags, $tag = NULL) {
|
||
|
if (is_null($tag)) $tag = $this->stream->getc();
|
||
|
if (!in_array($tag, $expectTags)) {
|
||
|
$expectTags = implode('', $expectTags);
|
||
|
throw new HproseException("Tag '$expectTags' expected, but '$tag' found in stream");
|
||
|
}
|
||
|
return $tag;
|
||
|
}
|
||
|
public function readInteger($includeTag = false) {
|
||
|
if ($includeTag) {
|
||
|
$tag = $this->stream->getc();
|
||
|
if (($tag >= '0') && ($tag <= '9')) {
|
||
|
return (int)$tag;
|
||
|
}
|
||
|
$this->checkTag(HproseTags::TagInteger, $tag);
|
||
|
}
|
||
|
return (int)($this->stream->readuntil(HproseTags::TagSemicolon));
|
||
|
}
|
||
|
public function readLong($includeTag = false) {
|
||
|
if ($includeTag) {
|
||
|
$tag = $this->stream->getc();
|
||
|
if (($tag >= '0') && ($tag <= '9')) {
|
||
|
return $tag;
|
||
|
}
|
||
|
$this->checkTag(HproseTags::TagLong, $tag);
|
||
|
}
|
||
|
return $this->stream->readuntil(HproseTags::TagSemicolon);
|
||
|
}
|
||
|
public function readDouble($includeTag = false) {
|
||
|
if ($includeTag) {
|
||
|
$tag = $this->stream->getc();
|
||
|
if (($tag >= '0') && ($tag <= '9')) {
|
||
|
return (double)$tag;
|
||
|
}
|
||
|
$this->checkTag(HproseTags::TagDouble, $tag);
|
||
|
}
|
||
|
return (double)($this->stream->readuntil(HproseTags::TagSemicolon));
|
||
|
}
|
||
|
public function readNaN() {
|
||
|
$this->checkTag(HproseTags::TagNaN);
|
||
|
return log(-1);
|
||
|
}
|
||
|
public function readInfinity($includeTag = false) {
|
||
|
if ($includeTag) $this->checkTag(HproseTags::TagInfinity);
|
||
|
return (($this->stream->getc() == HproseTags::TagNeg) ? log(0) : -log(0));
|
||
|
}
|
||
|
public function readNull() {
|
||
|
$this->checkTag(HproseTags::TagNull);
|
||
|
return NULL;
|
||
|
}
|
||
|
public function readEmpty() {
|
||
|
$this->checkTag(HproseTags::TagEmpty);
|
||
|
return '';
|
||
|
}
|
||
|
public function readBoolean() {
|
||
|
$tag = $this->checkTags(array(HproseTags::TagTrue, HproseTags::TagFalse));
|
||
|
return ($tag == HproseTags::TagTrue);
|
||
|
}
|
||
|
public function readDate($includeTag = false) {
|
||
|
if ($includeTag) $this->checkTag(HproseTags::TagDate);
|
||
|
$year = (int)($this->stream->read(4));
|
||
|
$month = (int)($this->stream->read(2));
|
||
|
$day = (int)($this->stream->read(2));
|
||
|
$tag = $this->stream->getc();
|
||
|
if ($tag == HproseTags::TagTime) {
|
||
|
$hour = (int)($this->stream->read(2));
|
||
|
$minute = (int)($this->stream->read(2));
|
||
|
$second = (int)($this->stream->read(2));
|
||
|
$microsecond = 0;
|
||
|
$tag = $this->stream->getc();
|
||
|
if ($tag == HproseTags::TagPoint) {
|
||
|
$microsecond = (int)($this->stream->read(3)) * 1000;
|
||
|
$tag = $this->stream->getc();
|
||
|
if (($tag >= '0') && ($tag <= '9')) {
|
||
|
$microsecond += (int)($tag) * 100 + (int)($this->stream->read(2));
|
||
|
$tag = $this->stream->getc();
|
||
|
if (($tag >= '0') && ($tag <= '9')) {
|
||
|
$this->stream->skip(2);
|
||
|
$tag = $this->stream->getc();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if ($tag == HproseTags::TagUTC) {
|
||
|
$date = new HproseDateTime($year, $month, $day,
|
||
|
$hour, $minute, $second,
|
||
|
$microsecond, true);
|
||
|
}
|
||
|
else {
|
||
|
$date = new HproseDateTime($year, $month, $day,
|
||
|
$hour, $minute, $second,
|
||
|
$microsecond);
|
||
|
}
|
||
|
}
|
||
|
elseif ($tag == HproseTags::TagUTC) {
|
||
|
$date = new HproseDate($year, $month, $day, true);
|
||
|
}
|
||
|
else {
|
||
|
$date = new HproseDate($year, $month, $day);
|
||
|
}
|
||
|
return $date;
|
||
|
}
|
||
|
public function readTime($includeTag = false) {
|
||
|
if ($includeTag) $this->checkTag(HproseTags::TagTime);
|
||
|
$hour = (int)($this->stream->read(2));
|
||
|
$minute = (int)($this->stream->read(2));
|
||
|
$second = (int)($this->stream->read(2));
|
||
|
$microsecond = 0;
|
||
|
$tag = $this->stream->getc();
|
||
|
if ($tag == HproseTags::TagPoint) {
|
||
|
$microsecond = (int)($this->stream->read(3)) * 1000;
|
||
|
$tag = $this->stream->getc();
|
||
|
if (($tag >= '0') && ($tag <= '9')) {
|
||
|
$microsecond += (int)($tag) * 100 + (int)($this->stream->read(2));
|
||
|
$tag = $this->stream->getc();
|
||
|
if (($tag >= '0') && ($tag <= '9')) {
|
||
|
$this->stream->skip(2);
|
||
|
$tag = $this->stream->getc();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if ($tag == HproseTags::TagUTC) {
|
||
|
$time = new HproseTime($hour, $minute, $second, $microsecond, true);
|
||
|
}
|
||
|
else {
|
||
|
$time = new HproseTime($hour, $minute, $second, $microsecond);
|
||
|
}
|
||
|
return $time;
|
||
|
}
|
||
|
public function readBytes($includeTag = false) {
|
||
|
if ($includeTag) $this->checkTag(HproseTags::TagBytes);
|
||
|
$count = (int)($this->stream->readuntil(HproseTags::TagQuote));
|
||
|
$bytes = $this->stream->read($count);
|
||
|
$this->stream->skip(1);
|
||
|
return $bytes;
|
||
|
}
|
||
|
public function readUTF8Char($includeTag = false) {
|
||
|
if ($includeTag) $this->checkTag(HproseTags::TagUTF8Char);
|
||
|
$c = $this->stream->getc();
|
||
|
$s = $c;
|
||
|
$a = ord($c);
|
||
|
if (($a & 0xE0) == 0xC0) {
|
||
|
$s .= $this->stream->getc();
|
||
|
}
|
||
|
elseif (($a & 0xF0) == 0xE0) {
|
||
|
$s .= $this->stream->read(2);
|
||
|
}
|
||
|
elseif ($a > 0x7F) {
|
||
|
throw new HproseException("bad utf-8 encoding");
|
||
|
}
|
||
|
return $s;
|
||
|
}
|
||
|
public function readString($includeTag = false) {
|
||
|
if ($includeTag) $this->checkTag(HproseTags::TagString);
|
||
|
$len = (int)$this->stream->readuntil(HproseTags::TagQuote);
|
||
|
$this->stream->mark();
|
||
|
$utf8len = 0;
|
||
|
for ($i = 0; $i < $len; ++$i) {
|
||
|
switch (ord($this->stream->getc()) >> 4) {
|
||
|
case 0:
|
||
|
case 1:
|
||
|
case 2:
|
||
|
case 3:
|
||
|
case 4:
|
||
|
case 5:
|
||
|
case 6:
|
||
|
case 7: {
|
||
|
// 0xxx xxxx
|
||
|
$utf8len++;
|
||
|
break;
|
||
|
}
|
||
|
case 12:
|
||
|
case 13: {
|
||
|
// 110x xxxx 10xx xxxx
|
||
|
$this->stream->skip(1);
|
||
|
$utf8len += 2;
|
||
|
break;
|
||
|
}
|
||
|
case 14: {
|
||
|
// 1110 xxxx 10xx xxxx 10xx xxxx
|
||
|
$this->stream->skip(2);
|
||
|
$utf8len += 3;
|
||
|
break;
|
||
|
}
|
||
|
case 15: {
|
||
|
// 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
|
||
|
$this->stream->skip(3);
|
||
|
$utf8len += 4;
|
||
|
++$i;
|
||
|
break;
|
||
|
}
|
||
|
default: {
|
||
|
throw new HproseException('bad utf-8 encoding');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
$this->stream->reset();
|
||
|
$this->stream->unmark();
|
||
|
$s = $this->stream->read($utf8len);
|
||
|
$this->stream->skip(1);
|
||
|
return $s;
|
||
|
}
|
||
|
public function readGuid($includeTag = false) {
|
||
|
if ($includeTag) $this->checkTag(HproseTags::TagGuid);
|
||
|
$this->stream->skip(1);
|
||
|
$s = $this->stream->read(36);
|
||
|
$this->stream->skip(1);
|
||
|
return $s;
|
||
|
}
|
||
|
protected function &readListBegin() {
|
||
|
$list = array();
|
||
|
return $list;
|
||
|
}
|
||
|
protected function &readListEnd(&$list) {
|
||
|
$count = (int)$this->stream->readuntil(HproseTags::TagOpenbrace);
|
||
|
for ($i = 0; $i < $count; ++$i) {
|
||
|
$list[] = &$this->unserialize();
|
||
|
}
|
||
|
$this->stream->skip(1);
|
||
|
return $list;
|
||
|
}
|
||
|
public function &readList($includeTag = false) {
|
||
|
if ($includeTag) $this->checkTag(HproseTags::TagList);
|
||
|
$list = &$this->readListBegin();
|
||
|
return $this->readListEnd($list);
|
||
|
}
|
||
|
protected function &readMapBegin() {
|
||
|
$map = array();
|
||
|
return $map;
|
||
|
}
|
||
|
protected function &readMapEnd(&$map) {
|
||
|
$count = (int)$this->stream->readuntil(HproseTags::TagOpenbrace);
|
||
|
for ($i = 0; $i < $count; ++$i) {
|
||
|
$key = &$this->unserialize();
|
||
|
$map[$key] = &$this->unserialize();
|
||
|
}
|
||
|
$this->stream->skip(1);
|
||
|
return $map;
|
||
|
}
|
||
|
public function &readMap($includeTag = false) {
|
||
|
if ($includeTag) $this->checkTag(HproseTags::TagMap);
|
||
|
$map = &$this->readMapBegin();
|
||
|
return $this->readMapEnd($map);
|
||
|
}
|
||
|
protected function readObjectBegin() {
|
||
|
list($classname, $fields) = $this->classref[(int)$this->stream->readuntil(HproseTags::TagOpenbrace)];
|
||
|
$object = new $classname;
|
||
|
return array($object, $fields);
|
||
|
}
|
||
|
protected function readObjectEnd($object, $fields) {
|
||
|
$count = count($fields);
|
||
|
if (class_exists('ReflectionClass')) {
|
||
|
$reflector = new ReflectionClass($object);
|
||
|
for ($i = 0; $i < $count; ++$i) {
|
||
|
$field = $fields[$i];
|
||
|
if ($reflector->hasProperty($field)) {
|
||
|
$property = $reflector->getProperty($field);
|
||
|
$property->setAccessible(true);
|
||
|
$property->setValue($object, $this->unserialize());
|
||
|
}
|
||
|
else {
|
||
|
$object->$field = &$this->unserialize();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
for ($i = 0; $i < $count; ++$i) {
|
||
|
$object->$fields[$i] = &$this->unserialize();
|
||
|
}
|
||
|
}
|
||
|
$this->stream->skip(1);
|
||
|
return $object;
|
||
|
}
|
||
|
public function readObject($includeTag = false) {
|
||
|
if ($includeTag) {
|
||
|
$tag = $this->checkTags(array(HproseTags::TagClass, HproseTags::TagObject));
|
||
|
if ($tag == HproseTags::TagClass) {
|
||
|
$this->readClass();
|
||
|
return $this->readObject(true);
|
||
|
}
|
||
|
}
|
||
|
list($object, $fields) = $this->readObjectBegin();
|
||
|
return $this->readObjectEnd($object, $fields);
|
||
|
}
|
||
|
protected function readClass() {
|
||
|
$classname = HproseClassManager::getClass(self::readString());
|
||
|
$count = (int)$this->stream->readuntil(HproseTags::TagOpenbrace);
|
||
|
$fields = array();
|
||
|
for ($i = 0; $i < $count; ++$i) {
|
||
|
$fields[] = $this->readString(true);
|
||
|
}
|
||
|
$this->stream->skip(1);
|
||
|
$this->classref[] = array($classname, $fields);
|
||
|
}
|
||
|
public function reset() {
|
||
|
$this->classref = array();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class HproseReader extends HproseSimpleReader {
|
||
|
private $ref;
|
||
|
function __construct(&$stream) {
|
||
|
parent::__construct($stream);
|
||
|
$this->ref = array();
|
||
|
}
|
||
|
public function &unserialize($tag = NULL) {
|
||
|
if (is_null($tag)) {
|
||
|
$tag = $this->stream->getc();
|
||
|
}
|
||
|
if ($tag == HproseTags::TagRef) {
|
||
|
return $this->readRef();
|
||
|
}
|
||
|
return parent::unserialize($tag);
|
||
|
}
|
||
|
public function readDate($includeTag = false) {
|
||
|
if ($includeTag) {
|
||
|
$tag = $this->checkTags(array(HproseTags::TagDate, HproseTags::TagRef));
|
||
|
if ($tag == HproseTags::TagRef) return $this->readRef();
|
||
|
}
|
||
|
$date = parent::readDate();
|
||
|
$this->ref[] = $date;
|
||
|
return $date;
|
||
|
}
|
||
|
public function readTime($includeTag = false) {
|
||
|
if ($includeTag) {
|
||
|
$tag = $this->checkTags(array(HproseTags::TagTime, HproseTags::TagRef));
|
||
|
if ($tag == HproseTags::TagRef) return $this->readRef();
|
||
|
}
|
||
|
$time = parent::readTime();
|
||
|
$this->ref[] = $time;
|
||
|
return $time;
|
||
|
}
|
||
|
public function readBytes($includeTag = false) {
|
||
|
if ($includeTag) {
|
||
|
$tag = $this->checkTags(array(HproseTags::TagBytes, HproseTags::TagRef));
|
||
|
if ($tag == HproseTags::TagRef) return $this->readRef();
|
||
|
}
|
||
|
$bytes = parent::readBytes();
|
||
|
$this->ref[] = $bytes;
|
||
|
return $bytes;
|
||
|
}
|
||
|
public function readString($includeTag = false) {
|
||
|
if ($includeTag) {
|
||
|
$tag = $this->checkTags(array(HproseTags::TagString, HproseTags::TagRef));
|
||
|
if ($tag == HproseTags::TagRef) return $this->readRef();
|
||
|
}
|
||
|
$str = parent::readString();
|
||
|
$this->ref[] = $str;
|
||
|
return $str;
|
||
|
}
|
||
|
public function readGuid($includeTag = false) {
|
||
|
if ($includeTag) {
|
||
|
$tag = $this->checkTags(array(HproseTags::TagGuid, HproseTags::TagRef));
|
||
|
if ($tag == HproseTags::TagRef) return $this->readRef();
|
||
|
}
|
||
|
$guid = parent::readGuid();
|
||
|
$this->ref[] = $guid;
|
||
|
return $guid;
|
||
|
}
|
||
|
public function &readList($includeTag = false) {
|
||
|
if ($includeTag) {
|
||
|
$tag = $this->checkTags(array(HproseTags::TagList, HproseTags::TagRef));
|
||
|
if ($tag == HproseTags::TagRef) return $this->readRef();
|
||
|
}
|
||
|
$list = &$this->readListBegin();
|
||
|
$this->ref[] = &$list;
|
||
|
return $this->readListEnd($list);
|
||
|
}
|
||
|
public function &readMap($includeTag = false) {
|
||
|
if ($includeTag) {
|
||
|
$tag = $this->checkTags(array(HproseTags::TagMap, HproseTags::TagRef));
|
||
|
if ($tag == HproseTags::TagRef) return $this->readRef();
|
||
|
}
|
||
|
$map = &$this->readMapBegin();
|
||
|
$this->ref[] = &$map;
|
||
|
return $this->readMapEnd($map);
|
||
|
}
|
||
|
public function readObject($includeTag = false) {
|
||
|
if ($includeTag) {
|
||
|
$tag = $this->checkTags(array(HproseTags::TagClass, HproseTags::TagObject, HproseTags::TagRef));
|
||
|
if ($tag == HproseTags::TagRef) return $this->readRef();
|
||
|
if ($tag == HproseTags::TagClass) {
|
||
|
$this->readClass();
|
||
|
return $this->readObject(true);
|
||
|
}
|
||
|
}
|
||
|
list($object, $fields) = $this->readObjectBegin();
|
||
|
$this->ref[] = $object;
|
||
|
return $this->readObjectEnd($object, $fields);
|
||
|
}
|
||
|
private function &readRef() {
|
||
|
$ref = &$this->ref[(int)$this->stream->readuntil(HproseTags::TagSemicolon)];
|
||
|
if (gettype($ref) == 'array') {
|
||
|
$result = &$ref;
|
||
|
}
|
||
|
else {
|
||
|
$result = $ref;
|
||
|
}
|
||
|
return $result;
|
||
|
}
|
||
|
public function reset() {
|
||
|
parent::reset();
|
||
|
$this->ref = array();
|
||
|
}
|
||
|
}
|
||
|
?>
|