<?php
// $Id: rpc_decoder.php,v 1.1 2004/07/11 10:28:46 Farsus Exp $
// -------------------------------------------------------------------------//
//			                 RUNCMS                                         //
//                                                                          //
//	 reliable - Unique - Nocost &  Simplicity & ease off use                //
//                       < http://www.runcms.org >                          //
// -------------------------------------------------------------------------//
// Original Author: i-Tech (Half-Dead)
// Author Website : http://www.i-Technology.NET
// License Type   : LGPL: See /manual/LICENSES/LGPL.txt
// ------------------------------------------------------------------------- //

//------------------------------------------------------------------------------------------//
/**
* Converts xml data into readable php arrays.
* @author Half-Dead
* @copyright ©2002 {@link http://www.e-xoops.com www.e-xoops.com} :: {@link http://www.topsite-toplist.com www.topsite-toplist.com}
* @version 1.2b
* @package phpRPC
*/
class rpc_Decoder  {

	var $parser;

/**
* Contains the name of the recieved method <methodName>
*
* Normaly used internaly,
* but may be accessed with $rpc_decoder->methodName
* @var string
*/
	var $methodName;
	var $mode;

/**
* Contains the accumulated decoder code.
*
* Used internaly but can be dumped with $rpc_decoder->code
* @var string
*/
	var $code;
	var $m_name;

/**
* Encoding used by the decoder.
*
* Is set in the config file,
* but can also be set with i.e: $rpc_decoder->encoding = "UTF-8";
* May be: ISO-8859-1, UTF-8, or US-ASCII
* @var string
*/
	var $encoding;
	var $debug;
	var $logfile;


//------------------------------------------------------------------------------------------//
/**
* @access private
*/
	function rpc_Decoder() {
	global $phprpc_encoding, $phprpc_debug;

	$this->debug    = $phprpc_debug;
	$this->encoding = $phprpc_encoding;
	}


//------------------------------------------------------------------------------------------//
/**
* Tells the decoder to process the xml data
*
* Normaly used internaly, but may also be used to send xml data
* to the decoder: $rpc_decoder->decode($data);
* @param string $data Transforms $data into a php readable array
* @return array Returns an array containing the extracted data
*/
function decode($data) {

$this->parser = xml_parser_create($this->encoding);

	xml_set_object($this->parser, $this);
	xml_set_element_handler($this->parser, "tag_open", "tag_close");
	xml_set_character_data_handler($this->parser, "cdata");
	xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE, 1);
	xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 1);
	xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->encoding);
	xml_parse($this->parser, $data);
	xml_parser_free($this->parser);

if ( $this->debug == 1 ) {
	dump_data($this->code, $this->methodName.'_rpcDecoder.txt');
	}

	eval($this->code);
	return $params;
}


//------------------------------------------------------------------------------------------//
/**
* @access private
*/
function tag_open($parser, $tag, $attributes) {

switch($tag) {

case 'STRING':
	if($this->m_name == '') {
		$this->code .= "'";
	} else {
		$this->code .= "'" . (string)$this->m_name . "'" . '=>' . "'";
	}
	$this->mode = 'STRING';
break;

case 'TIME':
case 'DATE':
case 'DATETIME':
case 'DATETIME.ISO8601':
	if($this->m_name != '') {
		$this->code .=  "'" . (string)$this->m_name . "'" . '=>';
	}
	$this->mode = 'DATETIME';
break;

case 'I4':
case 'INT':
case 'LONG':
case 'INTEGER':
	if ($this->m_name != '') {
		$this->code .=  "'" . (string)$this->m_name . "'" . '=>';
	}
	$this->mode = 'INT';
break;

case 'BOOL':
case 'BOOLEAN':
	if($this->m_name != '') {
		$this->code .= "'" . (string)$this->m_name . "'" . '=>';
	}
	$this->mode = 'BOOL';
break;

case 'REAL':
case 'FLOAT':
case 'DOUBLE':
	if ($this->m_name != '') {
		$this->code .=  "'" . (string)$this->m_name . "'" . '=>';
	}
	$this->mode = 'FLOAT';
break;

case 'B64':
case 'BASE64':
	if ($this->m_name == '') {
		$this->code .= "base64_decode('";
	} else {
		$this->code .=  "'" . (string)$this->m_name . "'" . '=>' . "base64_decode('";
	}
	$this->mode = 'BASE64';
break;

case 'ARRAY':
case 'STRUCT':
case 'OBJECT':
	if ($this->m_name != '') {
		$this->code .= "'" . (string)$this->m_name . "'" . '=>' . "array(";
		unset($this->m_name);
	} else {
		$this->code .= "array(";
	}
	$this->mode  = 'ARRAY';
break;

case 'NAME':
	$this->mode = 'NAME';
break;

case 'METHODNAME':
	$this->code .= '$params=array(';
	$this->mode  = 'METHODNAME';
break;

case 'METHODRESPONSE':
	$this->code .= '$params=array(';
	$this->mode  = 'METHODRESPONSE';
break;
} // End switch
}


//------------------------------------------------------------------------------------------//
/**
* @access private
*/
function tag_close($parser, $tag) {

switch($tag) {

case 'STRING':
	$this->code .= "',";
	$this->mode  = 'none';
break;

case 'I4':
case 'INT':
case 'LONG':
case 'INTEGER':

case 'BOOL':
case 'BOOLEAN':

case 'REAL':
case 'FLOAT':
case 'DOUBLE':

case 'TIME':
case 'DATE':
case 'DATETIME':
case 'DATETIME.ISO8601':
	$this->code .= ",";
	$this->mode  = 'none';
break;

case 'NAME':
case 'VALUE':
	$this->mode  = 'none';
break;

case 'B64':
case 'BASE64':
	$this->code .= "'),";
	$this->mode  = 'none';
break;

case 'ARRAY':
case 'STRUCT':
case 'OBJECT':
	if (substr($this->code, -1) == ',') {
		$this->code = substr($this->code, 0, (strlen($this->code) -1));
	}
	$this->code .= "),";
	$this->mode  = 'none';
break;

case 'MEMBER':
	unset($this->m_name);
	$this->mode  = 'none';
break;

case 'METHODNAME':
	$this->mode = 'none';
break;

case 'METHODCALL':
case 'METHODRESPONSE':
	if (substr($this->code, -1) == ',') {
		$this->code = substr($this->code, 0, (strlen($this->code) -1));
	}
	$this->code .= ");";
	$this->mode  = 'none';
break;
} // End switch
}


//------------------------------------------------------------------------------------------//
/**
* @access private
*/
function cdata($parser, $cdata) {

switch($this->mode) {

case 'STRING':
	$this->code .= (string)htmlentities($cdata, ENT_QUOTES);
break;

case 'INT':
	$this->code .=  (int)$cdata;
break;

case 'BOOL':
	if($cdata == '1' || $cdata == 'true') {
		$this->code .= (boolean)true;
	} else {
		$this->code .= (boolean)false;
	}
break;

case 'FLOAT':
	$this->code .= (float)$cdata;
break;

case 'BASE64':
	$this->code .= (string)$cdata;
break;

case 'DATETIME':
	$this->code .= (int)iso8601_decode($cdata);
break;

case 'NAME':
	$this->m_name = (string)$cdata;
break;

case 'METHODNAME':
	$this->methodName = (string)$cdata;
break;

case 'METHODRESPONSE':
	$this->methodName = (string)'MethodResponse';
break;
} // End switch
}
//------------------------------------------------------------------------------------------//
}
//------------------------------------------------------------------------------------------//
$rpc_decoder = new rpc_Decoder();
?>
