<?php
/**
* dom_xmlrpc_utilities are a set of static utilities for handling XML-RPC
* @package dom-xmlrpc
* @copyright (C) 2004 John Heinstein. All rights reserved
* @license http://www.gnu.org/copyleft/lesser.html LGPL License
* @author John Heinstein <johnkarl@nbnet.nb.ca>
* @link http://www.engageinteractive.com/dom_xmlrpc/ DOM XML-RPC Home Page
* DOM XML-RPC is Free Software
**/

if (!defined('DOM_XMLRPC_INCLUDE_PATH')) {
	define('DOM_XMLRPC_INCLUDE_PATH', (dirname(__FILE__) . "/"));
}

/**
* A set of static utilities for handling XML-RPC
*
* @package dom-xmlrpc
* @author John Heinstein <johnkarl@nbnet.nb.ca>
*/
class dom_xmlrpc_utilities {

	/**
	* Strips the HTTP headers from the method response
	* @param string The method response, including headers
	* @return string The method response with headers stripped
	*/
	function stripHeader($myResponse) {
		$body = '';
		$total = strlen($myResponse);
		
		for ($i = 0; $i < $total; $i++) {
			if ($myResponse{$i} == '<') {
				$body = substr($myResponse, $i);
				break;
			}
		}

		return $body;
	} //stripHeader
	
	/**
	* Determines the type of a scalar value
	* @param mixed The scalar value
	* @return string The type of the scalar value
	*/
	function getScalarTypeFromValue(&$value) {
		require_once(DOM_XMLRPC_INCLUDE_PATH . 'dom_xmlrpc_constants.php');
		
		if (is_string($value)) {
			return DOM_XMLRPC_TYPE_STRING;
		}
		else if (is_int($value)) {
			return DOM_XMLRPC_TYPE_INT;
		}
		else if (is_float($value)) {
			return DOM_XMLRPC_TYPE_DOUBLE;
		}
		else if (is_bool($value)) {
			return DOM_XMLRPC_TYPE_BOOLEAN;
		}
		else if (is_object($value)) {
			require_once(DOM_XMLRPC_INCLUDE_PATH . 'dom_xmlrpc_datetime_iso8601.php');
			require_once(DOM_XMLRPC_INCLUDE_PATH . 'dom_xmlrpc_base64.php');
				
			if (get_class($value) == 'dom_xmlrpc_datetime_iso8601') {
				return DOM_XMLRPC_TYPE_DATETIME;
			}
			else if (get_class($value) == 'dom_xmlrpc_base64') {
				return DOM_XMLRPC_TYPE_BASE64;
			}
		}
		
		return '';
	} //getScalarTypeFromValue
	
	/**
	* Determines the type of any XML-RPC value
	* @param mixed The XML-RPC value
	* @return string The type of the XML-RPC value
	*/
	function getTypeFromValue(&$value) {
		require_once(DOM_XMLRPC_INCLUDE_PATH . 'dom_xmlrpc_constants.php');
		$scalarType = dom_xmlrpc_utilities::getScalarTypeFromValue($value);

		if ($scalarType == '') {
			require_once(DOM_XMLRPC_INCLUDE_PATH . 'dom_xmlrpc_struct.php');
			
			if (is_array($value)) {
				if (dom_xmlrpc_utilities::isAssociativeArray($value)) {
					return DOM_XMLRPC_TYPE_STRUCT;
				}
				else {
					return DOM_XMLRPC_TYPE_ARRAY;
				}
			}
			else if (get_class($value) == 'dom_xmlrpc_struct') {
				return DOM_XMLRPC_TYPE_STRUCT;
			}
			else if(is_object($value)) {
				return DOM_XMLRPC_TYPE_STRUCT;
			}
		}
		else {
			return $scalarType;
		}
	} //getTypeFromValue
	
	/**
	* Converts the given scalar value to its XML-RPC equivalent
	* @param mixed The scalar value
	* @param string The type of the scalar value
	* @return string The XML-RPC equivalent of the scalar value
	*/
	function getScalarValue(&$value, $type) {
		require_once(DOM_XMLRPC_INCLUDE_PATH . 'dom_xmlrpc_constants.php');
	
		switch($type) {
			case DOM_XMLRPC_TYPE_BOOLEAN:
				return (($value == true) ? '1' : '0');
				break;
				
			case DOM_XMLRPC_TYPE_DATETIME:
				require_once(DOM_XMLRPC_INCLUDE_PATH . 'dom_xmlrpc_datetime_iso8601.php');

				if (is_object($value) && (get_class($value) == 'dom_xmlrpc_datetime_iso8601')) { 
					return ($value->getDateTime_iso());
				}
				break;
				
			case DOM_XMLRPC_TYPE_BASE64:
				require_once(DOM_XMLRPC_INCLUDE_PATH . 'dom_xmlrpc_base64.php');

				if (is_object($value) && (get_class($value) == 'dom_xmlrpc_base64')) { 					
					return ($value->getEncoded());
				}
				break;
				
			default:
				return ('' . $value);		
		}
		
		return ('' . $value);	
	} //getScalarValue
	
	/**
	* Determines whether an array is associative or not
	*
	* Note: PHP converts string keys that look like integers
	* to actual integer keys. This function will thus NOT trap 
	* $myArray = array('1'=>'blah');
	* DON'T use integer string keys,
	* UNLESS you wrap them in a dom_xmlrpc_struct object
	* The following IS considered associative, however:
	* $myArray = array('1.2'=>'blah');
	* @param array The array to be tested
	* @return boolean True if the array is associative
	*/
	function isAssociativeArray(&$myArray) { 
		reset($myArray);
		$myKey = key($myArray);
		
		if (is_string($myKey)) {			
			return true;
		}
		
		return false;
	} //isAssociativeArray
	
	/**
	* Flips the html translation table
	*
	* @return array The flipped html translation table
	*/
	function getInverseTranslationTable() {
		$trans = get_html_translation_table(HTML_ENTITIES, ENT_QUOTES);
		$trans = array_flip($trans);
		$trans['&amp;'] = "'";
		return $trans;
	} //getInverseTranslationTable
} //dom_xmlrpc_utilities

?>