123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- <?php
- /**********************************************************\
- | |
- | hprose |
- | |
- | Official WebSite: http://www.hprose.com/ |
- | http://www.hprose.net/ |
- | http://www.hprose.org/ |
- | |
- \**********************************************************/
- /**********************************************************\
- * *
- * HproseWriter.php *
- * *
- * hprose writer library for php5. *
- * *
- * LastModified: Nov 13, 2013 *
- * Author: Ma Bingyao <andot@hprfc.com> *
- * *
- \**********************************************************/
- require_once('HproseCommon.php');
- require_once('HproseTags.php');
- require_once('HproseClassManager.php');
- class HproseSimpleWriter {
- public $stream;
- private $classref;
- private $fieldsref;
- function __construct(&$stream) {
- $this->stream = &$stream;
- $this->classref = array();
- $this->fieldsref = array();
- }
- public function serialize(&$var) {
- if ((!isset($var)) || ($var === NULL)) {
- $this->writeNull();
- }
- elseif (is_scalar($var)) {
- if (is_int($var)) {
- $this->writeInteger($var);
- }
- elseif (is_bool($var)) {
- $this->writeBoolean($var);
- }
- elseif (is_float($var)) {
- $this->writeDouble($var);
- }
- elseif (is_string($var)) {
- if ($var === '') {
- $this->writeEmpty();
- }
- elseif ((strlen($var) < 4) && is_utf8($var) && (ustrlen($var) == 1)) {
- $this->writeUTF8Char($var);
- }
- elseif (is_utf8($var)) {
- $this->writeString($var, true);
- }
- else {
- $this->writeBytes($var, true);
- }
- }
- }
- elseif (is_array($var)) {
- if (is_list($var)) {
- $this->writeList($var, true);
- }
- else {
- $this->writeMap($var, true);
- }
- }
- elseif (is_object($var)) {
- if ($var instanceof stdClass) {
- $this->writeStdObject($var, true);
- }
- elseif (($var instanceof HproseDate) || ($var instanceof HproseDateTime)) {
- $this->writeDate($var, true);
- }
- elseif ($var instanceof HproseTime) {
- $this->writeTime($var, true);
- }
- else {
- $this->writeObject($var, true);
- }
- }
- else {
- throw new HproseException('Not support to serialize this data');
- }
- }
- public function writeInteger($integer) {
- if ($integer >= 0 && $integer <= 9) {
- $this->stream->write((string)$integer);
- }
- else {
- $this->stream->write(HproseTags::TagInteger . $integer . HproseTags::TagSemicolon);
- }
- }
- public function writeLong($long) {
- if ($long >= '0' && $long <= '9') {
- $this->stream->write($long);
- }
- else {
- $this->stream->write(HproseTags::TagLong . $long . HproseTags::TagSemicolon);
- }
- }
- public function writeDouble($double) {
- if (is_nan($double)) {
- $this->writeNaN();
- }
- elseif (is_infinite($double)) {
- $this->writeInfinity($double > 0);
- }
- else {
- $this->stream->write(HproseTags::TagDouble . $double . HproseTags::TagSemicolon);
- }
- }
- public function writeNaN() {
- $this->stream->write(HproseTags::TagNaN);
- }
- public function writeInfinity($positive = true) {
- $this->stream->write(HproseTags::TagInfinity . ($positive ? HproseTags::TagPos : HproseTags::TagNeg));
- }
- public function writeNull() {
- $this->stream->write(HproseTags::TagNull);
- }
- public function writeEmpty() {
- $this->stream->write(HproseTags::TagEmpty);
- }
- public function writeBoolean($bool) {
- $this->stream->write($bool ? HproseTags::TagTrue : HproseTags::TagFalse);
- }
- public function writeDate($date, $checkRef = false) {
- if ($date->utc) {
- $this->stream->write(HproseTags::TagDate . $date->toString(false));
- }
- else {
- $this->stream->write(HproseTags::TagDate . $date->toString(false) . HproseTags::TagSemicolon);
- }
- }
- public function writeTime($time, $checkRef = false) {
- if ($time->utc) {
- $this->stream->write(HproseTags::TagTime . $time->toString(false));
- }
- else {
- $this->stream->write(HproseTags::TagTime . $time->toString(false) . HproseTags::TagSemicolon);
- }
- }
- public function writeBytes($bytes, $checkRef = false) {
- $len = strlen($bytes);
- $this->stream->write(HproseTags::TagBytes);
- if ($len > 0) $this->stream->write((string)$len);
- $this->stream->write(HproseTags::TagQuote . $bytes . HproseTags::TagQuote);
- }
- public function writeUTF8Char($char) {
- $this->stream->write(HproseTags::TagUTF8Char . $char);
- }
- public function writeString($str, $checkRef = false) {
- $len = ustrlen($str);
- $this->stream->write(HproseTags::TagString);
- if ($len > 0) $this->stream->write((string)$len);
- $this->stream->write(HproseTags::TagQuote . $str . HproseTags::TagQuote);
- }
- public function writeList(&$list, $checkRef = false) {
- $count = count($list);
- $this->stream->write(HproseTags::TagList);
- if ($count > 0) $this->stream->write((string)$count);
- $this->stream->write(HproseTags::TagOpenbrace);
- for ($i = 0; $i < $count; ++$i) {
- $this->serialize($list[$i]);
- }
- $this->stream->write(HproseTags::TagClosebrace);
- }
- public function writeMap(&$map, $checkRef = false) {
- $count = count($map);
- $this->stream->write(HproseTags::TagMap);
- if ($count > 0) $this->stream->write((string)$count);
- $this->stream->write(HproseTags::TagOpenbrace);
- foreach ($map as $key => &$value) {
- $this->serialize($key);
- $this->serialize($value);
- }
- $this->stream->write(HproseTags::TagClosebrace);
- }
- public function writeStdObject($obj, $checkRef = false) {
- $map = (array)$obj;
- self::writeMap($map);
- }
- protected function writeObjectBegin($obj) {
- $class = get_class($obj);
- $alias = HproseClassManager::getClassAlias($class);
- $fields = array_keys((array)$obj);
- if (array_key_exists($alias, $this->classref)) {
- $index = $this->classref[$alias];
- }
- else {
- $index = $this->writeClass($alias, $fields);
- }
- return $index;
- }
- protected function writeObjectEnd($obj, $index) {
- $fields = $this->fieldsref[$index];
- $count = count($fields);
- $this->stream->write(HproseTags::TagObject . $index . HproseTags::TagOpenbrace);
- $array = (array)$obj;
- for ($i = 0; $i < $count; ++$i) {
- $this->serialize($array[$fields[$i]]);
- }
- $this->stream->write(HproseTags::TagClosebrace);
- }
- public function writeObject($obj, $checkRef = false) {
- $this->writeObjectEnd($obj, $this->writeObjectBegin($obj));
- }
- protected function writeClass($alias, $fields) {
- $len = ustrlen($alias);
- $this->stream->write(HproseTags::TagClass . $len .
- HproseTags::TagQuote . $alias . HproseTags::TagQuote);
- $count = count($fields);
- if ($count > 0) $this->stream->write((string)$count);
- $this->stream->write(HproseTags::TagOpenbrace);
- for ($i = 0; $i < $count; ++$i) {
- $field = $fields[$i];
- if ($field{0} === "\0") {
- $field = substr($field, strpos($field, "\0", 1) + 1);
- }
- $this->writeString($field);
- }
- $this->stream->write(HproseTags::TagClosebrace);
- $index = count($this->fieldsref);
- $this->classref[$alias] = $index;
- $this->fieldsref[$index] = $fields;
- return $index;
- }
- public function reset() {
- $this->classref = array();
- $this->fieldsref = array();
- }
- }
- class HproseWriter extends HproseSimpleWriter {
- private $ref;
- private $arrayref;
- function __construct(&$stream) {
- parent::__construct($stream);
- $this->ref = array();
- $this->arrayref = array();
- }
- private function writeRef(&$obj, $checkRef, $writeBegin, $writeEnd) {
- if (is_string($obj)) {
- $key = 's_' . $obj;
- }
- elseif (is_array($obj)) {
- if (($i = array_ref_search($obj, $this->arrayref)) === false) {
- $i = count($this->arrayref);
- $this->arrayref[$i] = &$obj;
- }
- $key = 'a_' . $i;
- }
- else {
- $key = 'o_' . spl_object_hash($obj);
- }
- if ($checkRef && array_key_exists($key, $this->ref)) {
- $this->stream->write(HproseTags::TagRef . $this->ref[$key] . HproseTags::TagSemicolon);
- }
- else {
- $result = $writeBegin ? call_user_func_array($writeBegin, array(&$obj)) : false;
- $index = count($this->ref);
- $this->ref[$key] = $index;
- call_user_func_array($writeEnd, array(&$obj, $result));
- }
- }
- public function writeDate($date, $checkRef = false) {
- $this->writeRef($date, $checkRef, NULL, array(&$this, 'parent::writeDate'));
- }
- public function writeTime($time, $checkRef = false) {
- $this->writeRef($time, $checkRef, NULL, array(&$this, 'parent::writeTime'));
- }
- public function writeBytes($bytes, $checkRef = false) {
- $this->writeRef($bytes, $checkRef, NULL, array(&$this, 'parent::writeBytes'));
- }
- public function writeString($str, $checkRef = false) {
- $this->writeRef($str, $checkRef, NULL, array(&$this, 'parent::writeString'));
- }
- public function writeList(&$list, $checkRef = false) {
- $this->writeRef($list, $checkRef, NULL, array(&$this, 'parent::writeList'));
- }
- public function writeMap(&$map, $checkRef = false) {
- $this->writeRef($map, $checkRef, NULL, array(&$this, 'parent::writeMap'));
- }
- public function writeStdObject($obj, $checkRef = false) {
- $this->writeRef($obj, $checkRef, NULL, array(&$this, 'parent::writeStdObject'));
- }
- public function writeObject($obj, $checkRef = false) {
- $this->writeRef($obj, $checkRef, array(&$this, 'writeObjectBegin'), array(&$this, 'writeObjectEnd'));
- }
- public function reset() {
- parent::reset();
- $this->ref = array();
- $this->arrayref = array();
- }
- }
- ?>
|