From 47bad912c6c0c2d727556c79de5b65e0c3d4de71 Mon Sep 17 00:00:00 2001 From: Edmar Moretti Date: Sat, 8 Dec 2007 02:06:24 +0000 Subject: [PATCH] movido cpaint para pacotes --- pacotes/cpaint/JSON/json.js | 377 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pacotes/cpaint/JSON/json2.php | 663 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pacotes/cpaint/JSON/testsuite.php | 351 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pacotes/cpaint/JSON/testsuite2.php | 413 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pacotes/cpaint/changelog.txt | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pacotes/cpaint/cpaint2.backend-debugger.php | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pacotes/cpaint/cpaint2.config.php | 35 +++++++++++++++++++++++++++++++++++ pacotes/cpaint/cpaint2.inc.compressed.js | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pacotes/cpaint/cpaint2.inc.js | 1429 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pacotes/cpaint/cpaint2.inc.php | 941 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pacotes/cpaint/cpaint2.proxy.php | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pacotes/cpaint/json.php | 580 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 5260 insertions(+), 0 deletions(-) create mode 100644 pacotes/cpaint/JSON/json.js create mode 100644 pacotes/cpaint/JSON/json2.php create mode 100644 pacotes/cpaint/JSON/testsuite.php create mode 100644 pacotes/cpaint/JSON/testsuite2.php create mode 100644 pacotes/cpaint/changelog.txt create mode 100644 pacotes/cpaint/cpaint2.backend-debugger.php create mode 100644 pacotes/cpaint/cpaint2.config.php create mode 100644 pacotes/cpaint/cpaint2.inc.compressed.js create mode 100644 pacotes/cpaint/cpaint2.inc.js create mode 100644 pacotes/cpaint/cpaint2.inc.php create mode 100644 pacotes/cpaint/cpaint2.proxy.php create mode 100644 pacotes/cpaint/json.php diff --git a/pacotes/cpaint/JSON/json.js b/pacotes/cpaint/JSON/json.js new file mode 100644 index 0000000..422e022 --- /dev/null +++ b/pacotes/cpaint/JSON/json.js @@ -0,0 +1,377 @@ +/* +Copyright (c) 2005 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +Array.prototype.______array = '______array'; + +var JSON = { + org: 'http://www.JSON.org', + copyright: '(c)2005 JSON.org', + license: 'http://www.crockford.com/JSON/license.html', + + stringify: function (arg) { + var c, i, l, s = '', v; + var numeric = true; + + switch (typeof arg) { + case 'object': + if (arg) { + if (arg.______array == '______array') { + // do a test whether all array keys are numeric + for (i in arg) { + if (i != '______array' + && (isNaN(i) + || !isFinite(i))) { + numeric = false; + break; + } + } + + if (numeric == true) { + for (i = 0; i < arg.length; ++i) { + if (typeof arg[i] != 'undefined') { + v = this.stringify(arg[i]); + if (s) { + s += ','; + } + s += v; + } else { + s += ',null'; + } + } + return '[' + s + ']'; + } else { + for (i in arg) { + if (i != '______array') { + v = arg[i]; + if (typeof v != 'undefined' && typeof v != 'function') { + v = this.stringify(v); + if (s) { + s += ','; + } + s += this.stringify(i) + ':' + v; + } + } + } + // return as object + return '{' + s + '}'; + } + } else if (typeof arg.toString != 'undefined') { + for (i in arg) { + v = arg[i]; + if (typeof v != 'undefined' && typeof v != 'function') { + v = this.stringify(v); + if (s) { + s += ','; + } + s += this.stringify(i) + ':' + v; + } + } + return '{' + s + '}'; + } + } + return 'null'; + case 'number': + return isFinite(arg) ? String(arg) : 'null'; + case 'string': + l = arg.length; + s = '"'; + for (i = 0; i < l; i += 1) { + c = arg.charAt(i); + if (c >= ' ') { + if (c == '\\' || c == '"') { + s += '\\'; + } + s += c; + } else { + switch (c) { + case '\b': + s += '\\b'; + break; + case '\f': + s += '\\f'; + break; + case '\n': + s += '\\n'; + break; + case '\r': + s += '\\r'; + break; + case '\t': + s += '\\t'; + break; + default: + c = c.charCodeAt(); + s += '\\u00' + Math.floor(c / 16).toString(16) + + (c % 16).toString(16); + } + } + } + return s + '"'; + case 'boolean': + return String(arg); + default: + return 'null'; + } + }, + parse: function (text) { + var at = 0; + var ch = ' '; + + function error(m) { + throw { + name: 'JSONError', + message: m, + at: at - 1, + text: text + }; + } + + function next() { + ch = text.charAt(at); + at += 1; + return ch; + } + + function white() { + while (ch != '' && ch <= ' ') { + next(); + } + } + + function str() { + var i, s = '', t, u; + + if (ch == '"') { +outer: while (next()) { + if (ch == '"') { + next(); + return s; + } else if (ch == '\\') { + switch (next()) { + case 'b': + s += '\b'; + break; + case 'f': + s += '\f'; + break; + case 'n': + s += '\n'; + break; + case 'r': + s += '\r'; + break; + case 't': + s += '\t'; + break; + case 'u': + u = 0; + for (i = 0; i < 4; i += 1) { + t = parseInt(next(), 16); + if (!isFinite(t)) { + break outer; + } + u = u * 16 + t; + } + s += String.fromCharCode(u); + break; + default: + s += ch; + } + } else { + s += ch; + } + } + } + error("Bad string"); + } + + function arr() { + var a = []; + + if (ch == '[') { + next(); + white(); + if (ch == ']') { + next(); + return a; + } + while (ch) { + a.push(val()); + white(); + if (ch == ']') { + next(); + return a; + } else if (ch != ',') { + break; + } + next(); + white(); + } + } + error("Bad array"); + } + + function obj() { + var k, o = {}; + + if (ch == '{') { + next(); + white(); + if (ch == '}') { + next(); + return o; + } + while (ch) { + k = str(); + white(); + if (ch != ':') { + break; + } + next(); + o[k] = val(); + white(); + if (ch == '}') { + next(); + return o; + } else if (ch != ',') { + break; + } + next(); + white(); + } + } + error("Bad object"); + } + + function assoc() { + var k, a = []; + + if (ch == '<') { + next(); + white(); + if (ch == '>') { + next(); + return a; + } + while (ch) { + k = str(); + white(); + if (ch != ':') { + break; + } + next(); + a[k] = val(); + white(); + if (ch == '>') { + next(); + return a; + } else if (ch != ',') { + break; + } + next(); + white(); + } + } + error("Bad associative array"); + } + + function num() { + var n = '', v; + if (ch == '-') { + n = '-'; + next(); + } + while (ch >= '0' && ch <= '9') { + n += ch; + next(); + } + if (ch == '.') { + n += '.'; + while (next() && ch >= '0' && ch <= '9') { + n += ch; + } + } + if (ch == 'e' || ch == 'E') { + n += 'e'; + next(); + if (ch == '-' || ch == '+') { + n += ch; + next(); + } + while (ch >= '0' && ch <= '9') { + n += ch; + next(); + } + } + v = +n; + if (!isFinite(v)) { + error("Bad number"); + } else { + return v; + } + } + + function word() { + switch (ch) { + case 't': + if (next() == 'r' && next() == 'u' && next() == 'e') { + next(); + return true; + } + break; + case 'f': + if (next() == 'a' && next() == 'l' && next() == 's' && + next() == 'e') { + next(); + return false; + } + break; + case 'n': + if (next() == 'u' && next() == 'l' && next() == 'l') { + next(); + return null; + } + break; + } + error("Syntax error"); + } + + function val() { + white(); + switch (ch) { + case '{': + return obj(); + case '[': + return arr(); + case '<': + return assoc(); + case '"': + return str(); + case '-': + return num(); + default: + return ch >= '0' && ch <= '9' ? num() : word(); + } + } + + return val(); + } +}; diff --git a/pacotes/cpaint/JSON/json2.php b/pacotes/cpaint/JSON/json2.php new file mode 100644 index 0000000..0fa33b6 --- /dev/null +++ b/pacotes/cpaint/JSON/json2.php @@ -0,0 +1,663 @@ + +* @author Matt Knapp +* @author Brett Stimmerman +* @copyright 2005 Michal Migurski +* @license http://www.opensource.org/licenses/bsd-license.php +* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 +*/ + +/** +* Marker constant for Services_JSON::decode(), used to flag stack state +*/ +define('SERVICES_JSON_SLICE', 1); + +/** +* Marker constant for Services_JSON::decode(), used to flag stack state +*/ +define('SERVICES_JSON_IN_STR', 2); + +/** +* Marker constant for Services_JSON::decode(), used to flag stack state +*/ +define('SERVICES_JSON_IN_ARR', 4); + +/** +* Marker constant for Services_JSON::decode(), used to flag stack state +*/ +define('SERVICES_JSON_IN_OBJ', 8); + +/** +* Marker constant for Services_JSON::decode(), used to flag stack state +*/ +define('SERVICES_JSON_IN_CMT', 16); + +/** +* Behavior switch for Services_JSON::decode() +*/ +define('SERVICES_JSON_LOOSE_TYPE', 10); + +/** +* Behavior switch for Services_JSON::decode() +*/ +define('SERVICES_JSON_STRICT_TYPE', 11); + +/** +* Converts to and from JSON format. +* +* Brief example of use: +* +* +* // create a new instance of Services_JSON +* $json = new Services_JSON(); +* +* // convert a complexe value to JSON notation, and send it to the browser +* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); +* $output = $json->encode($value); +* +* print($output); +* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] +* +* // accept incoming POST data, assumed to be in JSON notation +* $input = file_get_contents('php://input', 1000000); +* $value = $json->decode($input); +* +*/ +class Services_JSON +{ + /** + * constructs a new JSON instance + * + * @param int $use object behavior: when encoding or decoding, + * be loose or strict about object/array usage + * + * possible values: + * - SERVICES_JSON_STRICT_TYPE: strict typing, default. + * "{...}" syntax creates objects in decode(). + * - SERVICES_JSON_LOOSE_TYPE: loose typing. + * "{...}" syntax creates associative arrays in decode(). + */ + function Services_JSON($use = SERVICES_JSON_STRICT_TYPE) + { + $this->use = $use; + } + + /** + * 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. + * + * @param string $utf16 UTF-16 character + * @return string UTF-8 character + * @access private + */ + function utf162utf8($utf16) + { + // oh please oh please oh please oh please oh please + 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 ''; + } + + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + function utf82utf16($utf8) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + + switch(strlen($utf8)) { + case 1: + // 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 $utf8; //$ut8 + + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); + + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return string JSON string representation of input var + * @access public + */ + function encode($var) + { + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + + case 'NULL': + return 'null'; + + case 'integer': + return (int) $var; + + case 'double': + case 'float': + return (float) $var; + + case 'string': + $arg = $var; + $l = strlen($var); + $s = '"'; + + for ($i = 0; $i < $l; $i++) { + $c = $var{$i}; + + if (ord($c) >= ord(' ')) { + + if ($c == '\\' + || $c == '"') { + + $s .= '\\'; + } + $s .= $c; + + } else { + + switch ($c) { + + case '\b': + $s .= '\\b'; + break; + + case '\f': + $s .= '\\f'; + break; + + case '\n': + $s .= '\\n'; + break; + + case '\r': + $s .= '\\r'; + break; + + case '\t': + $s .= '\\t'; + break; + + default: + $s .= '\u00' . sprintf('%02x', ord($c)); + } + } + } + return $s . '"'; + break; + + + case 'array': + /* + * As per JSON spec if any array key is not an integer + * we must treat the the whole array as an object. We + * also try to catch a sparsely populated associative + * array with numeric keys here because some JS engines + * will create an array with empty indexes up to + * max_index which can cause memory issues and because + * the keys, which may be relevant, will be remapped + * otherwise. + * + * As per the ECMA and JSON specification an object may + * have any string as a property. Unfortunately due to + * a hole in the ECMA specification if the key is a + * ECMA reserved word or starts with a digit the + * parameter is only accessible using ECMAScript's + * bracket notation. + */ + + // treat as a JSON object + if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + return "{/*Array*/" . + join(',', array_map(array($this, 'name_value'), + array_keys($var), + array_values($var))) + . '}'; + } + + // treat it like a regular array + return '[' . join(',', array_map(array($this, 'encode'), $var)) . ']'; + + case 'object': + $vars = get_object_vars($var); + return '{' . + join(',', array_map(array($this, 'name_value'), + array_keys($vars), + array_values($vars))) + . '}'; + + default: + return ''; + } + } + + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + function name_value($name, $value) + { + return $this->encode(strval($name)) . ':' . $this->encode($value); + } + + /** + * reduce a string by removing leading and trailing comments and whitespace + * + * @param $str string string value to strip of comments and whitespace + * + * @return string string value stripped of comments and whitespace + * @access private + */ + function reduce_string($str) + { + $str = preg_replace(array( + + // eliminate single line comments in '// ...' form + '#^\s*//(.+)$#m', + + // eliminate multi-line comments in '/* ... */' form, at start of string + '#^\s*/\*(.+)\*/#Us', + + // eliminate multi-line comments in '/* ... */' form, at end of string + '#/\*(.+)\*/\s*$#Us' + + ), '', $str); + + // eliminate extraneous space + return trim($str); + } + + /** + * decodes a JSON string into appropriate variable + * + * @param string $str JSON-formatted string + * + * @return mixed number, boolean, string, array, or object + * corresponding to given JSON input string. + * See argument 1 to Services_JSON() above for object-output behavior. + * Note that decode() always returns strings + * in ASCII or UTF-8 format! + * @access public + */ + function decode($str) + { + $imarray = false; + $str = $this->reduce_string($str); + + switch (strtolower($str)) { + case 'true': + return true; + + case 'false': + return false; + + case 'null': + return null; + + default: + if (is_numeric($str)) { + // Lookie-loo, it's a number + + // This would work on its own, but I'm trying to be + // good about returning integers where appropriate: + // return (float)$str; + + // Return float or int, as appropriate + return ((float)$str == (integer)$str) + ? (integer)$str + : (float)$str; + + } elseif (preg_match('/^("|\').+(\1)$/s', $str, $m) && $m[1] == $m[2]) { + // STRINGS RETURNED IN UTF-8 FORMAT + $delim = substr($str, 0, 1); + $chrs = substr($str, 1, -1); + $utf8 = ''; + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c < $strlen_chrs; ++$c) { + + $substr_chrs_c_2 = substr($chrs, $c, 2); + $ord_chrs_c = ord($chrs{$c}); + + switch (true) { + case $substr_chrs_c_2 == '\b': + $utf8 .= chr(0x08); + ++$c; + break; + case $substr_chrs_c_2 == '\t': + $utf8 .= chr(0x09); + ++$c; + break; + case $substr_chrs_c_2 == '\n': + $utf8 .= chr(0x0A); + ++$c; + break; + case $substr_chrs_c_2 == '\f': + $utf8 .= chr(0x0C); + ++$c; + break; + case $substr_chrs_c_2 == '\r': + $utf8 .= chr(0x0D); + ++$c; + break; + + case $substr_chrs_c_2 == '\\"': + case $substr_chrs_c_2 == '\\\'': + case $substr_chrs_c_2 == '\\\\': + case $substr_chrs_c_2 == '\\/': + if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || + ($delim == "'" && $substr_chrs_c_2 != '\\"')) { + $utf8 .= $chrs{++$c}; + } + break; + + case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): + // single, escaped unicode character + $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) + . chr(hexdec(substr($chrs, ($c + 4), 2))); + $utf8 .= $this->utf162utf8($utf16); + $c += 5; + break; + + case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): + $utf8 .= $chrs{$c}; + 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, $c, 2); + ++$c; + 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, $c, 3); + $c += 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, $c, 4); + $c += 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, $c, 5); + $c += 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, $c, 6); + $c += 5; + break; + + } + + } + + return $utf8; + + } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { + // array, or object notation + + if ($str{0} == '[') { + $stk = array(SERVICES_JSON_IN_ARR); + $arr = array(); + } else { + if ($str{1} == '/' && $str{2} == '*' && $str{3} == 'A') + { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = array(); + + } + else + { + if ($this->use == SERVICES_JSON_LOOSE_TYPE) { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = array(); + + } else { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = new stdClass(); + } + } + } + + array_push($stk, array('what' => SERVICES_JSON_SLICE, + 'where' => 0, + 'delim' => false)); + + $chrs = substr($str, 1, -1); + $chrs = $this->reduce_string($chrs); + + if ($chrs == '') { + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } else { + return $obj; + + } + } + + //print("\nparsing {$chrs}\n"); + + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c <= $strlen_chrs; ++$c) { + + $top = end($stk); + $substr_chrs_c_2 = substr($chrs, $c, 2); + + if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { + // found a comma that is not inside a string, array, etc., + // OR we've reached the end of the character list + $slice = substr($chrs, $top['where'], ($c - $top['where'])); + array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); + //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + // we are in an array, so just push an element onto the stack + array_push($arr, $this->decode($slice)); + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + // we are in an object, so figure + // out the property name and set an + // element in an associative array, + // for now + if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // "name":value pair + $key = $this->decode($parts[1]); + $val = $this->decode($parts[2]); + + if ($this->use == SERVICES_JSON_LOOSE_TYPE || is_array($obj)) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // name:value pair, where name is unquoted + $key = $parts[1]; + $val = $this->decode($parts[2]); + if ($this->use == SERVICES_JSON_LOOSE_TYPE|| is_array($obj)) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } + + } + + } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { + // found a quote, and we are not inside a string + array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); + //print("Found start of string at {$c}\n"); + + } elseif (($chrs{$c} == $top['delim']) && + ($top['what'] == SERVICES_JSON_IN_STR) && + (($chrs{$c - 1} != '\\') || + ($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) { + // found a quote, we're in a string, and it's not escaped + array_pop($stk); + //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '[') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-bracket, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); + //print("Found start of array at {$c}\n"); + + } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { + // found a right-bracket, and we're in an array + array_pop($stk); + //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '{') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-brace, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); + //print("Found start of object at {$c}\n"); + + } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { + // found a right-brace, and we're in an object + array_pop($stk); + + //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } + + } + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + return $obj; + + } + + } + } + } + +} + +?> \ No newline at end of file diff --git a/pacotes/cpaint/JSON/testsuite.php b/pacotes/cpaint/JSON/testsuite.php new file mode 100644 index 0000000..dd26e55 --- /dev/null +++ b/pacotes/cpaint/JSON/testsuite.php @@ -0,0 +1,351 @@ + +*/ + +//---- includes ---------------------------------------------------------------- + /** + * @include JSON + */ + require_once('../json.php'); + +//---- class ------------------------------------------------------------------- + class MyObj { + var $id = ''; + var $name = ''; + var $attribs = array("first",'4'); + + function setId($id) { + $this->id = $id; + } + + function getId() { + return $this->id; + } + + function setName($name) { + $this->name = $name; + } + + function getName() { + return $this->name; + } + } + +//---- variables --------------------------------------------------------------- + $JSON = new JSON(); + $myObj = new MyObj(); + +//---- logic ------------------------------------------------------------------- + /* initialize object */ + $myObj->setId('Äl' . chr(18) . "ie\nn"); + $myObj->setName('objectName'); + array_push($myObj->attribs, 'øfirst'); + array_push($myObj->attribs, 'second'); + array_push($myObj->attribs, 3); + + /* create JSON representation */ + $jsonStr = $JSON->stringify($myObj); + +//---- clean-up ---------------------------------------------------------------- +//---- content ----------------------------------------------------------------- + +?> + + JSON parser test + + + + + + \n"; ?> + + + \ No newline at end of file diff --git a/pacotes/cpaint/JSON/testsuite2.php b/pacotes/cpaint/JSON/testsuite2.php new file mode 100644 index 0000000..7f92333 --- /dev/null +++ b/pacotes/cpaint/JSON/testsuite2.php @@ -0,0 +1,413 @@ +"value1", "item2"=>"value2"); + var $boolean = true; + var $integer = 5; + var $float = 1.12; + var $innerobject; + function object1() + { + $this->innerobject = new object2(); + } +} +class object2 +{ + var $firstattr = 'firstvalue'; + var $secondattr = 'secondvalue'; +} +//---- variables --------------------------------------------------------------- + $JSON = new JSON(); + $object1 = new object1(); + $JSON2 = new Services_JSON(); + $submitted = false; +//---- logic ------------------------------------------------------------------- + $origjsonstring = $JSON->stringify($object1); + $newjsonstring = $JSON2->encode($object1); + $origjson = $_REQUEST["origjson"]; + if (!empty($origjson)) + { + $origjsonprintr = $JSON->parse(stripslashes($origjson)); + $submitted = true; + } + else + { + $origjsonprintr = "Not submitted"; + } + $newjson = $_REQUEST["newjson"]; + if (!empty($newjson)) + { + $newjsonprintr = $JSON2->decode(stripslashes($newjson)); + } + else + { + $newjsonprintr = "Not submitted"; + } + +//---- content ----------------------------------------------------------------- +?> + + + JSON parser test + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
Original JSON PHP/Javascript
+ Original PHP object (print_r) + +
Result of PHP Stringify
Did it Convert to a Javascript Object origjsobj ?
+ +
+
Result of Javascript Stringify
+ +
+ Result of Conversion Back to PHP object (print_r) + +
+
+ + + + + + + + + + + + + + + + + +
New JSON PHP/Javascript
+ Original PHP object (print_r) + +
Result of PHP Stringify
Did it Convert to a Javascript Object newjsobj ?
+ +
+
Result of Javascript Stringify
+ +
+ Result of Conversion Back to PHP object (print_r) + +
+
+
+ +
+ + \ No newline at end of file diff --git a/pacotes/cpaint/changelog.txt b/pacotes/cpaint/changelog.txt new file mode 100644 index 0000000..7f249d3 --- /dev/null +++ b/pacotes/cpaint/changelog.txt @@ -0,0 +1,134 @@ +CPAINT changelog + +//---- v2.0.3 (Released Feburary 8, 2006) -------------------------- +- PHP: nixed potential security hole with invalid response types + (Thanks to James Bercegay) + +//---- v2.0.2 (Released January 20, 2006) -------------------------- +- JS: check HTTP response code and throw an error if request was + not accepted by server. (thanks gloomyandy) +- JS: allowing the underscore in node names. +- JS: added support for the passing of arrays and objects to the + backend. +- JS: added X-Powered-By request header. +- JS: node names, attribute names and -values from backend are now + expected to be valid ISO-8859-1. +- JS: fixed wrong initialization of the data property to int zero in + class cpaint_result_object. +- JS: removed unneccessary setter() methods from internal classes + to reduce size. +- JS: added debugging level cp.set_debug(-1) to suppress errors. +- JS: fixed type conversion issue where non-empty, pure whitespace + strings where interpreted as numbers. +- JS: fixed problem with callback being called twice. + (thanks to Lance Rushing) +- JS: fixed problem with URLs with existing GET parameters. + (thanks to Nelson Antunes) +- JS / PHP: added support for JSON as response type. +- JS / PHP: added support for E4X as response type. +- PHP: added cpaint::unregister() +- PHP: added cpaint::get_response_type(); +- PHP: removed a bug in JSON library that prevented the generation of valid JSON + when including a leading zero character. +- PHP: Removed unneccessary unescaping of parameters in proxy script. +- PHP: added support for array and object parameters from JavaScript (JSON!). +- PHP: added X-Powered-By response header. +- PHP: removed encoding of node names, attribute names and attribute + values to UTF-8 if possible. those values must now be valid + ISO-8859-1. +- PHP: removed output buffer to make it possible to include backend + and frontend in the same file. +- PHP: fixed error output (a function was called...) when no + parameters where sent to CPAINT indicating a function call, thus + making it possible to include backend and frontend in the same file + (thanks S. Alexandre M. Lemaire) +- PHP: added backend debugger code to main source tree & documentation. +- PHP: secured proxy utility (see documentation). +- PHP: added backend configuration file (for proxy security and future use) +- ASP: removed from distribution to focus on PHP and other ports. + +//---- v2.0.1 (Released September 5, 2005) -------------------------- +- JS: added the returning of plain-text response when using XML|OBJECT + response type as second parameter to user-defined callback function + (thanks Gunther) +- JS: added cpaint.capable property to determine AJAX-compatible + browsers +- JS: cleaned up CPAINT parameters when not using CPAINT API w/ proxy +- PHP: fixed callability of object methods (thanks Markus Wolf) +- PHP: fixed HTTP authentication in proxy file +- ASP: improved security regarding incoming function arguments + +//---- v2.0 (Released August 20, 2005) ------------------------------ +- completely rewrote the JavaScript frontend. + - 100% OOP approach. + - completely configurable through setter methods. + - support for syncronized calls (SJAX?) ;-). + - automatic XML parsing into JavaScript document structure if + response_type='object'. + - support for arbitrary character sets, including non-printable + characters. + - automatic detection and conversion of numeric data into + integers / floats. + - unified use of call() for local and remote targets. + - can now use frontend to retrieve static files or backend + functions not implemented with CPAINT + - use of a single (persistent) connection for multiple calls. + - XML to JavaScript parser is able to parse any XML structure now. + - support for XML attributes. + - added find_item_by_type() to cpaint_result_object. + - added get_attribute(), set_attribute() to cpaint_result_object. + - improved debugging, added debuglevels 1, 2. see set_debug() + +- completely rewrote the PHP and ASP backends. + - 100% OOP approach. + - protection against remote code-execution. + - support for object methods as callable functions. + - nested XML support through composite pattern. + - arbitrary XML structure creation support. + - support for arbitrary character sets. + - replaced remote code-execution blacklisting approach of v1.3-SP + with whitelisting through cpaint.register(). + - changed XML name convention. Attributes and tagnames are send + as-is, not in uppercase. + +- improved readability of the ASP and PHP proxy utilities. + - fixed GET requests. + - proxy now uses attributenames identical to the CPAINT backend + itself whenever possible. + - added support for target ports other than 80. + - added support for Basic Authentication. + - completely redesigned and rewritten documentation! + +//---- v1.3-SP2 (Released August 16, 2005) -------------------------- +- improved the remote-code execution fix. + +//---- v1.3-SP (Released August 15, 2005) --------------------------- +- fixed a remote code-execution vulnerability on the backend by + adding a blacklist test on the function name passed by the + frontend. + +//---- v1.3 (Released July 10, 2005) -------------------------------- +- rewrote cpaint_parse_ajax_xml() to be able to parse arbitrary XML. +- added bugfix from v1.01 to cpaint_get_remote_file() as well. + +//---- v1.2 (Released June 20, 2005) -------------------------------- +- added method cpaint_parse_ajax_xml() to the JavaScript frontend for + primitive XML to JavaScript transformation of response data. + +//---- v1.01 (Released June 16, 2005) ------------------------------- +- bugfix regarding Unicode character encoding in cpaint_call(). + +//---- v1.0 (Released June 13, 2005) -------------------------------- +- added support for XML/DOM document object returns. +- added support for XML on the backend. +- added proxy files for accessing remote functions & data. +- greatly improved documentation & examples. +- code stablized +- development effort moved to SourceForge.Net + +//---- Pre-1.0 Releases and Dates ----------------------------------- +- v0.7 - released June 8, 2005 +- v0.5 & 0.6 - released June 6, 2005 +- v0.4 - released June 3, 2005 +- v0.2 & 0.3 - released June 2, 2005 +- v0.1 - released May 31, 2005 (first release) diff --git a/pacotes/cpaint/cpaint2.backend-debugger.php b/pacotes/cpaint/cpaint2.backend-debugger.php new file mode 100644 index 0000000..77c9a9b --- /dev/null +++ b/pacotes/cpaint/cpaint2.backend-debugger.php @@ -0,0 +1,104 @@ + + @author Stephan Tijink + @copyright Copyright (c) 2005-2006 Paul Sullivan - http://sf.net/projects/cpaint + @version 2.0.3 +*/ + +if (!(isset($_REQUEST["cpaint_function"]))) { + $debug_html_start = ' + + CPAINT Debug Interface + + + + + + + + + +
CPAINT Debug Interface
backend filename: '.$_SERVER["SCRIPT_NAME"].'
'; + $debug_html_end = "

"; + + // get function names and function variables/values + $functionArray = getCallableCode(); + + $debug_body = ""; + if (count($functionArray) > 0) { + foreach ($functionArray as $func_name=>$func_variables) { + $debug_body = $debug_body . "
" . $func_name . "
"; + + $debug_body = $debug_body . ''; + if ( count($func_variables) > 0) { + foreach ($func_variables as $var_name=>$var_preset) { + $debug_body = $debug_body . ''; + if (strlen($var_preset) > 0) { $debug_body = $debug_body . ""; } + $debug_body = $debug_body . ''; + } + } + $debug_body = $debug_body . ""; + $debug_body = $debug_body . "
Parameter ($'.$var_name.'):   default value is ".$var_preset."  
Response Type:
"; + } + } + + print($debug_html_start . $debug_body . $debug_html_end); + die(); +} + +function getCallableCode() { + $scriptName = $_SERVER['SCRIPT_FILENAME']; + $fileLines = file($scriptName); + for ($i=0; $i < sizeof($fileLines); $i++) { + $line = trim($fileLines[$i]); + if (substr($line, 0, 9) == "FUNCTION " || substr($line,0,9) == "function ") { + $match[] = $line; + } + } + for ($i = 0; $i < sizeof($match); $i++) { + $line = str_replace("function ", "", $match[$i]); + $line = str_replace("FUNCTION ", "", $line); + $line = str_replace("{", "", $line); + $parts = explode("(", $line); + $func_name = trim($parts[0]); + + $Tempargs = explode(")", $parts[1]); + $args = explode(",", $Tempargs[0]); + $argSize = sizeof($args); + + // check args for preset values + if ($argSize > 0) { + foreach ($args as $arg) { + $arg = trim ($arg); + $varArray = explode ("=", $arg); + $var_name = trim (str_replace ("$", "", $varArray["0"])); + $var_value = trim ($varArray["1"]); + $resultArray[$func_name][$var_name] = $var_value; + } + } + } + return $resultArray; +} +?> \ No newline at end of file diff --git a/pacotes/cpaint/cpaint2.config.php b/pacotes/cpaint/cpaint2.config.php new file mode 100644 index 0000000..464adae --- /dev/null +++ b/pacotes/cpaint/cpaint2.config.php @@ -0,0 +1,35 @@ + +* @author Dominique Stender +* @copyright Copyright (c) 2005-2006 Paul Sullivan, Dominique Stender - http://sf.net/projects/cpaint +* @version 2.0.3 +*/ + +//---- proxy settings ---------------------------------------------------------- + $cpaint2_config["proxy.security.use_whitelist"] = true; + // Use the whitelist for allowed URLs? + +//---- proxy security whitelist ------------------------------------------------ + /* whitelist data should be added to the variable $cpaint2_proxy_whitelist[] + example: $cpaint2_proxy_whitelist[] = "example.com/test.php"; + - or - + example: $cpaint2_proxy_whitelist[] = "example.com"; + ** Omit http:// and https:// from the URL ** + */ + $cpaint2_proxy_whitelist[] = $_SERVER['HTTP_HOST']; // this server + +?> \ No newline at end of file diff --git a/pacotes/cpaint/cpaint2.inc.compressed.js b/pacotes/cpaint/cpaint2.inc.compressed.js new file mode 100644 index 0000000..7639e5f --- /dev/null +++ b/pacotes/cpaint/cpaint2.inc.compressed.js @@ -0,0 +1,116 @@ +function cpaint(){this.version='2.0.3';var config=new Array();config['debugging']=-1;config['proxy_url']='';config['transfer_mode']='GET';config['async']=true;config['response_type']='OBJECT';config['persistent_connection']=false;config['use_cpaint_api']=true;var stack_count=0;this.capable=test_ajax_capability();this.set_debug=function(){if(typeof arguments[0]=='boolean'){if(arguments[0]===true){config['debugging']=1;}else{config['debugging']=0;}}else if(typeof arguments[0]=='number'){config['debugging']=Math.round(arguments[0]);}} +this.set_proxy_url=function(){if(typeof arguments[0]=='string'){config['proxy_url']=arguments[0];}} +this.set_transfer_mode=function(){if(arguments[0].toUpperCase()=='GET'||arguments[0].toUpperCase()=='POST'){config['transfer_mode']=arguments[0].toUpperCase();}} +this.set_async=function(){if(typeof arguments[0]=='boolean'){config['async']=arguments[0];}} +this.set_response_type=function(){if(arguments[0].toUpperCase()=='TEXT'||arguments[0].toUpperCase()=='XML'||arguments[0].toUpperCase()=='OBJECT'||arguments[0].toUpperCase()=='E4X'||arguments[0].toUpperCase()=='JSON'){config['response_type']=arguments[0].toUpperCase();}} +this.set_persistent_connection=function(){if(typeof arguments[0]=='boolean'){config['persistent_connection']=arguments[0];}} +this.set_use_cpaint_api=function(){if(typeof arguments[0]=='boolean'){config['use_cpaint_api']=arguments[0];}} +function test_ajax_capability(){var cpc=new cpaint_call(0,config,this.version);return cpc.test_ajax_capability();} +this.call=function(){var use_stack=-1;if(config['persistent_connection']==true&&__cpaint_stack[0]!=null){switch(__cpaint_stack[0].get_http_state()){case-1:use_stack=0;debug('no XMLHttpObject object to re-use for persistence, creating new one later',2);break;case 4:use_stack=0 +debug('re-using the persistent connection',2);break;default:debug('the persistent connection is in use - skipping this request',2);}}else if(config['persistent_connection']==true){use_stack=0;__cpaint_stack[use_stack]=new cpaint_call(use_stack,config,this.version);debug('no cpaint_call object available for re-use, created new one',2);}else{use_stack=stack_count;__cpaint_stack[use_stack]=new cpaint_call(use_stack,config,this.version);debug('no cpaint_call object created new one',2);} +if(use_stack!=-1){__cpaint_stack[use_stack].set_client_callback(arguments[2]);if(config['proxy_url']!=''){__cpaint_stack[use_stack].call_proxy(arguments);}else{__cpaint_stack[use_stack].call_direct(arguments);} +stack_count++;debug('stack size: '+__cpaint_stack.length,2);}} +var debug=function(message,debug_level){var prefix='[CPAINT Debug] ';if(debug_level<1){prefix='[CPAINT Error] ';} +if(config['debugging']>=debug_level){alert(prefix+message);}if (message.search("error") > 1){client_callback("", message);}}} +var __cpaint_stack=new Array();var __cpaint_transformer=new cpaint_transformer();function cpaint_call(){var version=arguments[2];var config=new Array();config['debugging']=arguments[1]['debugging'];config['proxy_url']=arguments[1]['proxy_url'];config['transfer_mode']=arguments[1]['transfer_mode'];config['async']=arguments[1]['async'];config['response_type']=arguments[1]['response_type'];config['persistent_connection']=arguments[1]['persistent_connection'];config['use_cpaint_api']=arguments[1]['use_cpaint_api'];var httpobj=false;var client_callback;var stack_id=arguments[0];this.set_client_callback=function(){if(typeof arguments[0]=='function'){client_callback=arguments[0];}} +this.get_http_state=function(){var return_value=-1;if(typeof httpobj=='object'){return_value=httpobj.readyState;} +return return_value;} +this.call_direct=function(call_arguments){var url=call_arguments[0];var remote_method=call_arguments[1];var querystring='';var i=0;if(url=='SELF'){url=document.location.href;} +if(config['use_cpaint_api']==true){for(i=3;i 1){client_callback("", message);}} +if(config['debugging']>=debug_level){alert(prefix+message);}}} +function cpaint_transformer(){this.object_conversion=function(xml_document){var return_value=new cpaint_result_object();var i=0;var firstNodeName='';if(typeof xml_document=='object'&&xml_document!=null){for(i=0;i]+\>/,'');return new XML(text);} +this.json_conversion=function(text){return JSON.parse(text);} +var create_object_structure=function(stream){var return_value=new cpaint_result_object();var node_name='';var i=0;var attrib=0;if(stream.hasChildNodes()==true){for(i=0;i=' '){if(c=='\\'||c=='"'){s+='\\';} +s+=c;}else{switch(c){case'\b':s+='\\b';break;case'\f':s+='\\f';break;case'\n':s+='\\n';break;case'\r':s+='\\r';break;case'\t':s+='\\t';break;default:c=c.charCodeAt();s+='\\u00'+Math.floor(c/16).toString(16)+ +(c%16).toString(16);}}} +return s+'"';case'boolean':return String(arg);default:return'null';}},parse:function(text){var at=0;var ch=' ';function error(m){throw{name:'JSONError',message:m,at:at-1,text:text};} +function next(){ch=text.charAt(at);at+=1;return ch;} +function white(){while(ch!=''&&ch<=' '){next();}} +function str(){var i,s='',t,u;if(ch=='"'){outer:while(next()){if(ch=='"'){next();return s;}else if(ch=='\\'){switch(next()){case'b':s+='\b';break;case'f':s+='\f';break;case'n':s+='\n';break;case'r':s+='\r';break;case't':s+='\t';break;case'u':u=0;for(i=0;i<4;i+=1){t=parseInt(next(),16);if(!isFinite(t)){break outer;} +u=u*16+t;} +s+=String.fromCharCode(u);break;default:s+=ch;}}else{s+=ch;}}} +error("Bad string");} +function arr(){var a=[];if(ch=='['){next();white();if(ch==']'){next();return a;} +while(ch){a.push(val());white();if(ch==']'){next();return a;}else if(ch!=','){break;} +next();white();}} +error("Bad array");} +function obj(){var k,o={};if(ch=='{'){next();white();if(ch=='}'){next();return o;} +while(ch){k=str();white();if(ch!=':'){break;} +next();o[k]=val();white();if(ch=='}'){next();return o;}else if(ch!=','){break;} +next();white();}} +error("Bad object");} +function assoc(){var k,a=[];if(ch=='<'){next();white();if(ch=='>'){next();return a;} +while(ch){k=str();white();if(ch!=':'){break;} +next();a[k]=val();white();if(ch=='>'){next();return a;}else if(ch!=','){break;} +next();white();}} +error("Bad associative array");} +function num(){var n='',v;if(ch=='-'){n='-';next();} +while(ch>='0'&&ch<='9'){n+=ch;next();} +if(ch=='.'){n+='.';while(next()&&ch>='0'&&ch<='9'){n+=ch;}} +if(ch=='e'||ch=='E'){n+='e';next();if(ch=='-'||ch=='+'){n+=ch;next();} +while(ch>='0'&&ch<='9'){n+=ch;next();}} +v=+n;if(!isFinite(v)){error("Bad number");}else{return v;}} +function word(){switch(ch){case't':if(next()=='r'&&next()=='u'&&next()=='e'){next();return true;} +break;case'f':if(next()=='a'&&next()=='l'&&next()=='s'&&next()=='e'){next();return false;} +break;case'n':if(next()=='u'&&next()=='l'&&next()=='l'){next();return null;} +break;} +error("Syntax error");} +function val(){white();switch(ch){case'{':return obj();case'[':return arr();case'<':return assoc();case'"':return str();case'-':return num();default:return ch>='0'&&ch<='9'?num():word();}} +return val();}}; \ No newline at end of file diff --git a/pacotes/cpaint/cpaint2.inc.js b/pacotes/cpaint/cpaint2.inc.js new file mode 100644 index 0000000..f51d59f --- /dev/null +++ b/pacotes/cpaint/cpaint2.inc.js @@ -0,0 +1,1429 @@ +/** +* CPAINT - Cross-Platform Asynchronous INterface Toolkit +* +* http://sf.net/projects/cpaint +* +* released under the terms of the LGPL +* see http://www.fsf.org/licensing/licenses/lgpl.txt for details +* +* @package CPAINT +* @access public +* @copyright Copyright (c) 2005-2006 Paul Sullivan, Dominique Stender - http://sf.net/projects/cpaint +* @author Paul Sullivan +* @author Dominique Stender +* @author Stephan Tijink +* @version 2.0.3 +*/ +function cpaint() { + /** + * CPAINT version + * + * @access protected + * @var string version + */ + this.version = '2.0.3'; + + /** + * configuration options both for this class but also for the cpaint_call() objects. + * + * @access protected + * @var array config + */ + var config = new Array(); + config['debugging'] = -1; + config['proxy_url'] = ''; + config['transfer_mode'] = 'GET'; + config['async'] = true; + config['response_type'] = 'OBJECT'; + config['persistent_connection'] = false; + config['use_cpaint_api'] = true; + + /** + * maintains the next free index in the stack + * + * @access protected + * @var integer stack_count + */ + var stack_count = 0; + + /** + * property returns whether or not the browser is AJAX capable + * + * @access public + * @return boolean + */ + this.capable = test_ajax_capability(); + + /** + * switches debug mode on/off. + * + * @access public + * @param boolean debug debug flag + * @return void + */ + this.set_debug = function() { + + if (typeof arguments[0] == 'boolean') { + if (arguments[0] === true) { + config['debugging'] = 1; + + } else { + config['debugging'] = 0; + } + + } else if (typeof arguments[0] == 'number') { + config['debugging'] = Math.round(arguments[0]); + } + } + + /** + * defines the URL of the proxy script. + * + * @access public + * @param string proxy_url URL of the proxyscript to connect + * @return void + */ + this.set_proxy_url = function() { + + if (typeof arguments[0] == 'string') { + + config['proxy_url'] = arguments[0]; + } + } + + /** + * sets the transfer_mode (GET|POST). + * + * @access public + * @param string transfer_mode transfer_mode + * @return void + */ + this.set_transfer_mode = function() { + + if (arguments[0].toUpperCase() == 'GET' + || arguments[0].toUpperCase() == 'POST') { + + config['transfer_mode'] = arguments[0].toUpperCase(); + } + } + + /** + * sets the flag whether or not to use asynchronous calls. + * + * @access public + * @param boolean async syncronization flag + * @return void + */ + this.set_async = function() { + + if (typeof arguments[0] == 'boolean') { + config['async'] = arguments[0]; + } + } + + /** + * defines the response type. + * + * allowed values are: + * TEXT = raw text response + * XML = raw XMLHttpObject + * OBJECT = parsed JavaScript object structure from XMLHttpObject + * + * the default is OBJECT. + * + * @access public + * @param string response_type response type + * @return void + */ + this.set_response_type = function() { + + if (arguments[0].toUpperCase() == 'TEXT' + || arguments[0].toUpperCase() == 'XML' + || arguments[0].toUpperCase() == 'OBJECT' + || arguments[0].toUpperCase() == 'E4X' + || arguments[0].toUpperCase() == 'JSON') { + + config['response_type'] = arguments[0].toUpperCase(); + } + } + + /** + * sets the flag whether or not to use a persistent connection. + * + * @access public + * @param boolean persistent_connection persistance flag + * @return void + */ + this.set_persistent_connection = function() { + + if (typeof arguments[0] == 'boolean') { + config['persistent_connection'] = arguments[0]; + } + } + + + /** + * sets the flag whether or not to use the cpaint api on the backend. + * + * @access public + * @param boolean cpaint_api api_flag + * @return void + */ + this.set_use_cpaint_api = function() { + if (typeof arguments[0] == 'boolean') { + config['use_cpaint_api'] = arguments[0]; + } + } + + /** + * tests whether one of the necessary implementations + * of the XMLHttpRequest class are available + * + * @access protected + * @return boolean + */ + function test_ajax_capability() { + var cpc = new cpaint_call(0, config, this.version); + return cpc.test_ajax_capability(); + } + + /** + * takes the arguments supplied and triggers a call to the CPAINT backend + * based on the settings. + * + * upon response cpaint_call.callback() will automatically be called + * to perform post-processing operations. + * + * @access public + * @param string url remote URL to call + * @param string remote_method remote method to call + * @param object client_callback client side callback method to deliver the remote response to. do NOT supply a string! + * @param mixed argN remote parameters from now on + * @return void + */ + this.call = function() { + var use_stack = -1; + + if (config['persistent_connection'] == true + && __cpaint_stack[0] != null) { + + switch (__cpaint_stack[0].get_http_state()) { + case -1: + // no XMLHttpObject object has already been instanciated + // create new object and configure it + use_stack = 0; + debug('no XMLHttpObject object to re-use for persistence, creating new one later', 2); + break; + + case 4: + // object is ready for a new request, no need to do anything + use_stack = 0 + debug('re-using the persistent connection', 2); + break; + + default: + // connection is currently in use, don't do anything + debug('the persistent connection is in use - skipping this request', 2); + } + + } else if (config['persistent_connection'] == true) { + // persistent connection is active, but no object has been instanciated + use_stack = 0; + __cpaint_stack[use_stack] = new cpaint_call(use_stack, config, this.version); + debug('no cpaint_call object available for re-use, created new one', 2); + + } else { + // no connection persistance + use_stack = stack_count; + __cpaint_stack[use_stack] = new cpaint_call(use_stack, config, this.version); + debug('no cpaint_call object created new one', 2); + } + + // configure cpaint_call if allowed to + if (use_stack != -1) { + __cpaint_stack[use_stack].set_client_callback(arguments[2]); + + // distribute according to proxy use + if (config['proxy_url'] != '') { + __cpaint_stack[use_stack].call_proxy(arguments); + + } else { + __cpaint_stack[use_stack].call_direct(arguments); + } + + // increase stack counter + stack_count++; + debug('stack size: ' + __cpaint_stack.length, 2); + } + } + + /** + * debug method + * + * @access protected + * @param string message the message to debug + * @param integer debug_level debug level at which the message appears + * @return void + */ + var debug = function(message, debug_level) { + var prefix = '[CPAINT Debug] '; + + if (debug_level < 1) { + prefix = '[CPAINT Error] '; + } + + if (config['debugging'] >= debug_level) { + alert(prefix + message); + } + } +} + +/** +* internal FIFO stack of cpaint_call() objects. +* +* @access protected +* @var array __cpaint_stack +*/ +var __cpaint_stack = new Array(); + +/** +* local instance of cpaint_transformer +* MSIE is unable to handle static classes... sheesh. +* +* @access public +* @var object __cpaint_transformer +*/ +var __cpaint_transformer = new cpaint_transformer(); + +/** +* transport agent class +* +* creates the request object, takes care of the response, handles the +* client callback. Is configured by the cpaint() object. +* +* @package CPAINT +* @access public +* @copyright Copyright (c) 2005-2006 Paul Sullivan, Dominique Stender - http://sf.net/projects/cpaint +* @author Dominique Stender +* @author Paul Sullivan +* @param integer stack_id stack Id in cpaint +* @param array config configuration array for this call +* @param string version CPAINT API version +*/ +function cpaint_call() { + /** + * CPAINT version + * + * @access protected + * @var string version + */ + var version = arguments[2]; + + /** + * configuration options both for this class objects. + * + * @access protected + * @var array config + */ + var config = new Array(); + config['debugging'] = arguments[1]['debugging']; + config['proxy_url'] = arguments[1]['proxy_url']; + config['transfer_mode'] = arguments[1]['transfer_mode']; + config['async'] = arguments[1]['async']; + config['response_type'] = arguments[1]['response_type']; + config['persistent_connection'] = arguments[1]['persistent_connection']; + config['use_cpaint_api'] = arguments[1]['use_cpaint_api']; + + /** + * XMLHttpObject used for this request. + * + * @access protected + * @var object httpobj + */ + var httpobj = false; + + /** + * client callback function. + * + * @access public + * @var function client_callback + */ + var client_callback; + + /** + * stores the stack Id within the cpaint object + * + * @access protected + * @var stack_id + */ + var stack_id = arguments[0]; + + /** + * sets the client callback function. + * + * @access public + * @param function client_callback the client callback function + * @return void + */ + this.set_client_callback = function() { + + if (typeof arguments[0] == 'function') { + client_callback = arguments[0]; + } + } + + /** + * returns the ready state of the internal XMLHttpObject + * + * if no such object was set up already, -1 is returned + * + * @access public + * @return integer + */ + this.get_http_state = function() { + var return_value = -1; + + if (typeof httpobj == 'object') { + return_value = httpobj.readyState; + } + + return return_value; + } + + /** + * internal method for remote calls to the local server without use of the proxy script. + * + * @access public + * @param array call_arguments array of arguments initially passed to cpaint.call() + * @return void + */ + this.call_direct = function(call_arguments) { + var url = call_arguments[0]; + var remote_method = call_arguments[1]; + var querystring = ''; + var i = 0; + + // correct link to self + if (url == 'SELF') { + url = document.location.href; + } + + if (config['use_cpaint_api'] == true) { + // backend uses cpaint api + // pass parameters to remote method + for (i = 3; i < call_arguments.length; i++) { + + if ((typeof call_arguments[i] == 'string' + && call_arguments[i] != '' + && call_arguments[i].search(/^\s+$/g) == -1) + && !isNaN(call_arguments[i]) + && isFinite(call_arguments[i])) { + // numerical value, convert it first + querystring += '&cpaint_argument[]=' + encodeURIComponent(JSON.stringify(Number(call_arguments[i]))); + + } else { + querystring += '&cpaint_argument[]=' + encodeURIComponent(JSON.stringify(call_arguments[i])); + } + } + + // add response type to querystring + querystring += '&cpaint_response_type=' + config['response_type']; + + // build header + if (config['transfer_mode'] == 'GET') { + + if(url.indexOf('?') != -1) { + url = url + '&cpaint_function=' + remote_method + querystring; + + } else { + url = url + '?cpaint_function=' + remote_method + querystring; + } + + } else { + querystring = 'cpaint_function=' + remote_method + querystring; + } + + } else { + // backend does not use cpaint api + // pass parameters to remote method + for (i = 3; i < call_arguments.length; i++) { + + if (i == 3) { + querystring += encodeURIComponent(call_arguments[i]); + + } else { + querystring += '&' + encodeURIComponent(call_arguments[i]); + } + } + + // build header + if (config['transfer_mode'] == 'GET') { + url = url + querystring; + } + } + + // open connection + get_connection_object(); + + // open connection to remote target + debug('opening connection to "' + url + '"', 1); + httpobj.open(config['transfer_mode'], url, config['async']); + + // send "urlencoded" header if necessary (if POST) + if (config['transfer_mode'] == 'POST') { + + try { + httpobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + + } catch (cp_err) { + debug('POST cannot be completed due to incompatible browser. Use GET as your request method.', 0); + } + } + + // make ourselves known + httpobj.setRequestHeader('X-Powered-By', 'CPAINT v' + version + ' :: http://sf.net/projects/cpaint'); + + // callback handling for asynchronous calls + httpobj.onreadystatechange = callback; + + // send content + if (config['transfer_mode'] == 'GET') { + httpobj.send(null); + + } else { + debug('sending query: ' + querystring, 1); + httpobj.send(querystring); + } + + if (config['async'] == true) { + // manual callback handling for synchronized calls + callback(); + } + } + + /** + * internal method for calls to remote servers through the proxy script. + * + * @access public + * @param array call_arguments array of arguments passed to cpaint.call() + * @return void + */ + this.call_proxy = function(call_arguments) { + var proxyscript = config['proxy_url']; + var url = call_arguments[0]; + var remote_method = call_arguments[1]; + var querystring = ''; + var i = 0; + + var querystring_argument_prefix = 'cpaint_argument[]='; + + // pass parameters to remote method + if (config['use_cpaint_api'] == false) { + // when not talking to a CPAINT backend, don't prefix arguments + querystring_argument_prefix = ''; + } + + for (i = 3; i < call_arguments.length; i++) { + + if (config['use_cpaint_api'] == true) { + + if ((typeof call_arguments[i] == 'string' + && call_arguments[i] != '' + && call_arguments[i].search(/^\s+$/g) == -1) + && !isNaN(call_arguments[i]) + && isFinite(call_arguments[i])) { + // numerical value, convert it first + querystring += encodeURIComponent(querystring_argument_prefix + JSON.stringify(Number(call_arguments[i])) + '&'); + + } else { + querystring += encodeURIComponent(querystring_argument_prefix + JSON.stringify(call_arguments[i]) + '&'); + } + + } else { + // no CPAINT in the backend + querystring += encodeURIComponent(querystring_argument_prefix + call_arguments[i] + '&'); + } + } + + if (config['use_cpaint_api'] == true) { + // add remote function name to querystring + querystring += encodeURIComponent('&cpaint_function=' + remote_method); + + // add response type to querystring + querystring += encodeURIComponent('&cpaint_responsetype=' + config['response_type']); + } + + // build header + if (config['transfer_mode'] == 'GET') { + proxyscript += '?cpaint_remote_url=' + encodeURIComponent(url) + + '&cpaint_remote_query=' + querystring + + '&cpaint_remote_method=' + config['transfer_mode'] + + '&cpaint_response_type=' + config['response_type']; + + } else { + querystring = 'cpaint_remote_url=' + encodeURIComponent(url) + + '&cpaint_remote_query=' + querystring + + '&cpaint_remote_method=' + config['transfer_mode'] + + '&cpaint_response_type=' + config['response_type']; + } + + // open connection + get_connection_object(); + + // open connection to remote target + debug('opening connection to proxy "' + proxyscript + '"', 1); + httpobj.open(config['transfer_mode'], proxyscript, config['async']); + + // send "urlencoded" header if necessary (if POST) + if (config['transfer_mode'] == 'POST') { + + try { + httpobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + + } catch (cp_err) { + debug('POST cannot be completed due to incompatible browser. Use GET as your request method.', 0); + } + } + + httpobj.setRequestHeader('X-Powered-By', 'CPAINT v' + version); + + // callback handling for asynchronous calls + httpobj.onreadystatechange = callback; + + // send content + if (config['transfer_mode'] == 'GET') { + httpobj.send(null); + + } else { + debug('sending query: ' + querystring, 1); + httpobj.send(querystring); + } + + if (config['async'] == false) { + // manual callback handling for synchronized calls + callback(); + } + } + + this.test_ajax_capability = function() { + return get_connection_object(); + } + + /** + * creates a new connection object. + * + * @access protected + * @return boolean + */ + var get_connection_object = function() { + var return_value = false; + var new_connection = false; + + // open new connection only if necessary + if (config['persistent_connection'] == false) { + // no persistance, create a new object every time + debug('Using new connection object', 1); + new_connection = true; + + } else { + // persistent connection object, only open one if no object exists + debug('Using shared connection object.', 1); + + if (typeof httpobj != 'object') { + debug('Getting new persistent connection object.', 1); + new_connection = true; + } + } + + if (new_connection == true) { + + try { + httpobj = new XMLHttpRequest(); + } catch (e1) { + + try { + httpobj = new ActiveXObject('Msxml2.XMLHTTP'); + + } catch (e) { + + try { + httpobj = new ActiveXObject('Microsoft.XMLHTTP'); + + } catch (oc) { + httpobj = null; + } + } + } + + + if (!httpobj) { + debug('Could not create connection object', 0); + + } else { + return_value = true; + } + } + + if (httpobj.readyState != 4) { + httpobj.abort(); + } + + return return_value; + } + + /** + * internal callback function. + * + * will perform some consistency checks (response code, NULL value testing) + * and if response_type = 'OBJECT' it will automatically call + * cpaint_call.parse_ajax_xml() to have a JavaScript object structure generated. + * + * after all that is done the client side callback function will be called + * with the generated response as single value. + * + * @access protected + * @return void + */ + var callback = function() { + var response = null; + + if (httpobj.readyState == 4 + && httpobj.status == 200) { + + debug(httpobj.responseText, 1); + debug('using response type ' + config['response_type'], 2); + + // fetch correct response + switch (config['response_type']) { + case 'XML': + debug(httpobj.responseXML, 2); + response = __cpaint_transformer.xml_conversion(httpobj.responseXML); + break; + + case 'OBJECT': + response = __cpaint_transformer.object_conversion(httpobj.responseXML); + break; + + case 'TEXT': + response = __cpaint_transformer.text_conversion(httpobj.responseText); + break; + + case 'E4X': + response = __cpaint_transformer.e4x_conversion(httpobj.responseText); + break; + + case 'JSON': + response = __cpaint_transformer.json_conversion(httpobj.responseText); + break; + + default: + debug('invalid response type \'' + response_type + '\'', 0); + } + + // call client side callback + if (response != null + && typeof client_callback == 'function') { + client_callback(response, httpobj.responseText); + } + // remove ourselves from the stack + remove_from_stack(); + + } else if (httpobj.readyState == 4 + && httpobj.status != 200) { + // HTTP error of some kind + debug('invalid HTTP response code \'' + Number(httpobj.status) + '\'', 0); + //client_callback("", "erro"); + } + } + + /** + * removes an entry from the stack + * + * @access protected + * @return void + */ + var remove_from_stack = function() { + // remove only if everything is okay and we're not configured as persistent connection + if (typeof stack_id == 'number' + && __cpaint_stack[stack_id] + && config['persistent_connection'] == false) { + + __cpaint_stack[stack_id] = null; + } + } + + /** + * debug method + * + * @access protected + * @param string message the message to debug + * @param integer debug_level debug level at which the message appears + * @return void + */ + var debug = function(message, debug_level) { + var prefix = '[CPAINT Debug] '; + + if (config['debugging'] < 1) { + prefix = '[CPAINT Error] '; + } + + if (config['debugging'] >= debug_level) { + alert(prefix + message); + } + if (message.search("error") > 1){client_callback("", message);} + } +} + +/** +* CPAINT transformation object +* +* @package CPAINT +* @access public +* @copyright Copyright (c) 2005-2006 Paul Sullivan, Dominique Stender - http://sf.net/projects/cpaint +* @author Paul Sullivan +* @author Dominique Stender +*/ +function cpaint_transformer() { + + /** + * will take a XMLHttpObject and generate a JavaScript + * object structure from it. + * + * is internally called by cpaint_call.callback() if necessary. + * will call cpaint_call.create_object_structure() to create nested object structures. + * + * @access public + * @param object xml_document a XMLHttpObject + * @return object + */ + this.object_conversion = function(xml_document) { + var return_value = new cpaint_result_object(); + var i = 0; + var firstNodeName = ''; + + if (typeof xml_document == 'object' + && xml_document != null) { + + // find the first element node - for MSIE the node is the very first... + for (i = 0; i < xml_document.childNodes.length; i++) { + + if (xml_document.childNodes[i].nodeType == 1) { + firstNodeName = xml_document.childNodes[i].nodeName; + break; + } + } + + var ajax_response = xml_document.getElementsByTagName(firstNodeName); + + return_value[firstNodeName] = new Array(); + + for (i = 0; i < ajax_response.length; i++) { + var tmp_node = create_object_structure(ajax_response[i]); + tmp_node.id = ajax_response[i].getAttribute('id') + return_value[firstNodeName].push(tmp_node); + } + + } else { + debug('received invalid XML response', 0); + } + + return return_value; + } + + /** + * performs the necessary conversions for the XML response type + * + * @access public + * @param object xml_document a XMLHttpObject + * @return object + */ + this.xml_conversion = function(xml_document) { + return xml_document; + } + + /** + * performs the necessary conversions for the TEXT response type + * + * @access public + * @param string text the response text + * @return string + */ + this.text_conversion = function(text) { + return decode(text); + } + + /** + * performs the necessary conversions for the E4X response type + * + * @access public + * @param string text the response text + * @return string + */ + this.e4x_conversion = function(text) { + // remove tag + text = text.replace(/^\<\?xml[^>]+\>/, ''); + return new XML(text); + } + + /** + * performs the necessary conversions for the JSON response type + * + * @access public + * @param string text the response text + * @return string + */ + this.json_conversion = function(text) { + return JSON.parse(text); + } + + /** + * this method takes a HTML / XML node object and creates a + * JavaScript object structure from it. + * + * @access public + * @param object stream a node in the XML structure + * @return object + */ + var create_object_structure = function(stream) { + var return_value = new cpaint_result_object(); + var node_name = ''; + var i = 0; + var attrib = 0; + + if (stream.hasChildNodes() == true) { + for (i = 0; i < stream.childNodes.length; i++) { + + node_name = stream.childNodes[i].nodeName; + node_name = node_name.replace(/[^a-zA-Z0-9_]*/g, ''); + + // reset / create subnode + if (typeof return_value[node_name] != 'object') { + return_value[node_name] = new Array(); + } + + if (stream.childNodes[i].nodeType == 1) { + var tmp_node = create_object_structure(stream.childNodes[i]); + + for (attrib = 0; attrib < stream.childNodes[i].attributes.length; attrib++) { + tmp_node.set_attribute(stream.childNodes[i].attributes[attrib].nodeName, stream.childNodes[i].attributes[attrib].nodeValue); + } + + return_value[node_name].push(tmp_node); + + } else if (stream.childNodes[i].nodeType == 3) { + return_value.data = decode(String(stream.firstChild.data)); + } + } + } + + return return_value; + } + + /** + * converts an encoded text back to viewable characters. + * + * @access public + * @param string rawtext raw text as provided by the backend + * @return mixed + */ + var decode = function(rawtext) { + var plaintext = ''; + var i = 0; + var c1 = 0; + var c2 = 0; + var c3 = 0; + var u = 0; + var t = 0; + + // remove special JavaScript encoded non-printable characters + while (i < rawtext.length) { + if (rawtext.charAt(i) == '\\' + && rawtext.charAt(i + 1) == 'u') { + + u = 0; + + for (j = 2; j < 6; j += 1) { + t = parseInt(rawtext.charAt(i + j), 16); + + if (!isFinite(t)) { + break; + } + u = u * 16 + t; + } + + plaintext += String.fromCharCode(u); + i += 6; + + } else { + plaintext += rawtext.charAt(i); + i++; + } + } + + // convert numeric data to number type + if (plaintext != '' + && plaintext.search(/^\s+$/g) == -1 + && !isNaN(plaintext) + && isFinite(plaintext)) { + + plaintext = Number(plaintext); + } + + return plaintext; + } +} + +/** +* this is the basic prototype for a cpaint node object +* as used in cpaint_call.parse_ajax_xml() +* +* @package CPAINT +* @access public +* @copyright Copyright (c) 2005-2006 Paul Sullivan, Dominique Stender - http://sf.net/projects/cpaint +* @author Paul Sullivan +* @author Dominique Stender +*/ +function cpaint_result_object() { + this.id = 0; + this.data = ''; + var __attributes = new Array(); + + /** + * Returns a subnode with the given type and id. + * + * @access public + * @param string type The type of the subnode. Equivalent to the XML tag name. + * @param string id The id of the subnode. Equivalent to the XML tag names id attribute. + * @return object + */ + this.find_item_by_id = function() { + var return_value = null; + var type = arguments[0]; + var id = arguments[1]; + var i = 0; + + if (this[type]) { + + for (i = 0; i < this[type].length; i++) { + + if (this[type][i].get_attribute('id') == id) { + return_value = this[type][i]; + break; + } + } + } + + return return_value; + } + + /** + * retrieves the value of an attribute. + * + * @access public + * @param string name name of the attribute + * @return mixed + */ + this.get_attribute = function() { + var return_value = null; + var id = arguments[0]; + + if (typeof __attributes[id] != 'undefined') { + return_value = __attributes[id]; + } + + return return_value; + } + + /** + * assigns a value to an attribute. + * + * if that attribute does not exist it will be created. + * + * @access public + * @param string name name of the attribute + * @param string value value of the attribute + * @return void + */ + this.set_attribute = function() { + __attributes[arguments[0]] = arguments[1]; + } +} + + +/* +Copyright (c) 2005 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +Array.prototype.______array = '______array'; + +var JSON = { + org: 'http://www.JSON.org', + copyright: '(c)2005 JSON.org', + license: 'http://www.crockford.com/JSON/license.html', + + stringify: function (arg) { + var c, i, l, s = '', v; + var numeric = true; + + switch (typeof arg) { + case 'object': + if (arg) { + if (arg.______array == '______array') { + // do a test whether all array keys are numeric + for (i in arg) { + if (i != '______array' + && (isNaN(i) + || !isFinite(i))) { + numeric = false; + break; + } + } + + if (numeric == true) { + for (i = 0; i < arg.length; ++i) { + if (typeof arg[i] != 'undefined') { + v = this.stringify(arg[i]); + if (s) { + s += ','; + } + s += v; + } else { + s += ',null'; + } + } + return '[' + s + ']'; + } else { + for (i in arg) { + if (i != '______array') { + v = arg[i]; + if (typeof v != 'undefined' && typeof v != 'function') { + v = this.stringify(v); + if (s) { + s += ','; + } + s += this.stringify(i) + ':' + v; + } + } + } + // return as object + return '{' + s + '}'; + } + } else if (typeof arg.toString != 'undefined') { + for (i in arg) { + v = arg[i]; + if (typeof v != 'undefined' && typeof v != 'function') { + v = this.stringify(v); + if (s) { + s += ','; + } + s += this.stringify(i) + ':' + v; + } + } + return '{' + s + '}'; + } + } + return 'null'; + case 'number': + return isFinite(arg) ? String(arg) : 'null'; + case 'string': + l = arg.length; + s = '"'; + for (i = 0; i < l; i += 1) { + c = arg.charAt(i); + if (c >= ' ') { + if (c == '\\' || c == '"') { + s += '\\'; + } + s += c; + } else { + switch (c) { + case '\b': + s += '\\b'; + break; + case '\f': + s += '\\f'; + break; + case '\n': + s += '\\n'; + break; + case '\r': + s += '\\r'; + break; + case '\t': + s += '\\t'; + break; + default: + c = c.charCodeAt(); + s += '\\u00' + Math.floor(c / 16).toString(16) + + (c % 16).toString(16); + } + } + } + return s + '"'; + case 'boolean': + return String(arg); + default: + return 'null'; + } + }, + parse: function (text) { + var at = 0; + var ch = ' '; + + function error(m) { + throw { + name: 'JSONError', + message: m, + at: at - 1, + text: text + }; + } + + function next() { + ch = text.charAt(at); + at += 1; + return ch; + } + + function white() { + while (ch != '' && ch <= ' ') { + next(); + } + } + + function str() { + var i, s = '', t, u; + + if (ch == '"') { +outer: while (next()) { + if (ch == '"') { + next(); + return s; + } else if (ch == '\\') { + switch (next()) { + case 'b': + s += '\b'; + break; + case 'f': + s += '\f'; + break; + case 'n': + s += '\n'; + break; + case 'r': + s += '\r'; + break; + case 't': + s += '\t'; + break; + case 'u': + u = 0; + for (i = 0; i < 4; i += 1) { + t = parseInt(next(), 16); + if (!isFinite(t)) { + break outer; + } + u = u * 16 + t; + } + s += String.fromCharCode(u); + break; + default: + s += ch; + } + } else { + s += ch; + } + } + } + error("Bad string"); + } + + function arr() { + var a = []; + + if (ch == '[') { + next(); + white(); + if (ch == ']') { + next(); + return a; + } + while (ch) { + a.push(val()); + white(); + if (ch == ']') { + next(); + return a; + } else if (ch != ',') { + break; + } + next(); + white(); + } + } + error("Bad array"); + } + + function obj() { + var k, o = {}; + + if (ch == '{') { + next(); + white(); + if (ch == '}') { + next(); + return o; + } + while (ch) { + k = str(); + white(); + if (ch != ':') { + break; + } + next(); + o[k] = val(); + white(); + if (ch == '}') { + next(); + return o; + } else if (ch != ',') { + break; + } + next(); + white(); + } + } + error("Bad object"); + } + + function assoc() { + var k, a = []; + + if (ch == '<') { + next(); + white(); + if (ch == '>') { + next(); + return a; + } + while (ch) { + k = str(); + white(); + if (ch != ':') { + break; + } + next(); + a[k] = val(); + white(); + if (ch == '>') { + next(); + return a; + } else if (ch != ',') { + break; + } + next(); + white(); + } + } + error("Bad associative array"); + } + + function num() { + var n = '', v; + if (ch == '-') { + n = '-'; + next(); + } + while (ch >= '0' && ch <= '9') { + n += ch; + next(); + } + if (ch == '.') { + n += '.'; + while (next() && ch >= '0' && ch <= '9') { + n += ch; + } + } + if (ch == 'e' || ch == 'E') { + n += 'e'; + next(); + if (ch == '-' || ch == '+') { + n += ch; + next(); + } + while (ch >= '0' && ch <= '9') { + n += ch; + next(); + } + } + v = +n; + if (!isFinite(v)) { + error("Bad number"); + } else { + return v; + } + } + + function word() { + switch (ch) { + case 't': + if (next() == 'r' && next() == 'u' && next() == 'e') { + next(); + return true; + } + break; + case 'f': + if (next() == 'a' && next() == 'l' && next() == 's' && + next() == 'e') { + next(); + return false; + } + break; + case 'n': + if (next() == 'u' && next() == 'l' && next() == 'l') { + next(); + return null; + } + break; + } + error("Syntax error"); + } + + function val() { + white(); + switch (ch) { + case '{': + return obj(); + case '[': + return arr(); + case '<': + return assoc(); + case '"': + return str(); + case '-': + return num(); + default: + return ch >= '0' && ch <= '9' ? num() : word(); + } + } + + return val(); + } +}; diff --git a/pacotes/cpaint/cpaint2.inc.php b/pacotes/cpaint/cpaint2.inc.php new file mode 100644 index 0000000..cbee927 --- /dev/null +++ b/pacotes/cpaint/cpaint2.inc.php @@ -0,0 +1,941 @@ + +* @author Dominique Stender +* @copyright Copyright (c) 2005-2006 Paul Sullivan, Dominique Stender - http://sf.net/projects/cpaint +* @version 2.0.3 +*/ + +//---- includes ---------------------------------------------------------------- + /** + * @include JSON + */ + require_once(dirname(__FILE__) . '/json.php'); + + /** + * @include config + */ + require_once("cpaint2.config.php"); + +//---- variables --------------------------------------------------------------- + $GLOBALS['__cpaint_json'] = new JSON(); + +//---- error reporting --------------------------------------------------------- + error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING); + +//---- classes ----------------------------------------------------------------- + /** + * cpaint base class. + * + * @package CPAINT + * @access public + * @author Paul Sullivan + * @author Dominique Stender + * @copyright Copyright (c) 2005-2006 Paul Sullivan, Dominique Stender - http://sf.net/projects/cpaint + * @version 2.0.3 + */ + class cpaint { + /** + * version number + * + * @access private + * @var string $version + */ + var $version = '2.0.3'; + + /** + * response type. + * + * @access protected + * @var string $response_type + */ + var $response_type; + + /** + * the basenode ajaxResponse. + * + * @access protected + * @var object $basenode + */ + var $basenode; + + /** + * list of registered methods available through the CPAINT API + * + * @access protected + * @var array $api_functions + */ + var $api_functions; + + /** + * list of registered complex types used in the CPAINT API + * + * @access protected + * @var array $api_datatypes + */ + var $api_datatypes; + + /** + * whether or not the CPAINT API generates a WSDL when called with ?wsdl querystring + * + * @access private + * @var boolean $use_wsdl + */ + var $use_wsdl; + + /** + * PHP4 constructor. + * + * @access public + * @return void + */ + function cpaint() { + $this->__construct(); + } + + /** + * PHP 5 constructor. + * + * @access public + * @return void + * @todo -o"Dominique Stender" -ccpaint implement a better debugging + */ + function __construct() { + // initialize properties + $this->basenode = new cpaint_node(); + $this->basenode->set_name('ajaxResponse'); + $this->basenode->set_attribute('id', ''); + $this->basenode->set_encoding('UTF-8'); + + $this->response_type = 'TEXT'; + $this->api_functions = array(); + $this->api_datatypes = array(); + $this->use_wsdl = true; + + $this->complex_type(array( + 'name' => 'cpaintResponseType', + 'type' => 'restriction', // (restriction|complex|list) + 'base_type' => 'string', // scalar type of all values, e.g. 'string', for type = (restriction|list) only + 'values' => array( // for type = 'restriction' only: list of allowed values + 'XML', 'TEXT', 'OBJECT', 'E4X', 'JSON', + ), + ) + ); + $this->complex_type(array( + 'name' => 'cpaintDebugLevel', + 'type' => 'restriction', + 'base_type' => 'long', + 'values' => array( + -1, 0, 1, 2 + ), + ) + ); + $this->complex_type(array( + 'name' => 'cpaintDebugMessage', + 'type' => 'list', + 'base_type' => 'string', + ) + ); + + $this->complex_type(array( + 'name' => 'cpaintRequestHead', + 'type' => 'complex', + 'struct' => array( + 0 => array('name' => 'functionName', 'type' => 'string'), + 1 => array('name' => 'responseType', 'type' => 'cpaintResponseType'), + 2 => array('name' => 'debugLevel', 'type' => 'cpaintDebugLevel'), + ), + ) + ); + + $this->complex_type(array( + 'name' => 'cpaintResponseHead', + 'type' => 'complex', + 'struct' => array( + 0 => array('name' => 'success', 'type' => 'boolean'), + 1 => array('name' => 'debugger', 'type' => 'cpaintDebugMessage'), + ), + ) + ); + + // determine response type + if (isset($_REQUEST['cpaint_response_type'])) { + $this->response_type = htmlentities(strip_tags(strtoupper((string) $_REQUEST['cpaint_response_type']))); + } // end: if + } + + /** + * calls the user function responsible for this specific call. + * + * @access public + * @param string $input_encoding input data character encoding, default is UTF-8 + * @return void + */ + function start($input_encoding = 'UTF-8') { + $user_function = ''; + $arguments = array(); + + // work only if there is no API version request + if (!isset($_REQUEST['api_query']) + && !isset($_REQUEST['wsdl'])) { + $this->basenode->set_encoding($input_encoding); + + if ($_REQUEST['cpaint_function'] != '') { + $user_function = $_REQUEST['cpaint_function']; + if(@$_REQUEST['cpaint_argument']) + $arguments = $_REQUEST['cpaint_argument']; + else + $arguments = array(); + } + + // perform character conversion on every argument + foreach ($arguments as $key => $value) { + + if (get_magic_quotes_gpc() == true) { + $value = stripslashes($value); + } // end: if + + // convert from JSON string + $arguments[$key] = $GLOBALS['__cpaint_json']->parse($value); + } // end: foreach + + $arguments = cpaint_transformer::decode_array($arguments, $this->basenode->get_encoding()); + + if (is_array($this->api_functions[$user_function]) + && is_callable($this->api_functions[$user_function]['call'])) { + // a valid API function is to be called + call_user_func_array($this->api_functions[$user_function]['call'], $arguments); + } else if ($user_function != '') { + // desired function is not registered as API function + $this->basenode->set_data('[CPAINT] A function name was passed that is not allowed to execute on this server.'); + } + } // end: if + } + + /** + * generates and prints the response based on response type supplied by the frontend. + * + * @access public + * @return void + */ + function return_data() { + // send appropriate headers to avoid caching + header('Expires: Fri, 14 Mar 1980 20:53:00 GMT'); + header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + header('Cache-Control: no-cache, must-revalidate'); + header('Pragma: no-cache'); + header('X-Powered-By: CPAINT v' . $this->version . '/PHP v' . phpversion()); + + // work only if there is no API version request + + if (!isset($_REQUEST['api_query']) + && !isset($_REQUEST['wsdl'])) { + // trigger generation of response + switch (trim($this->response_type)) { + + case 'TEXT': + header('Content-type: text/plain; charset=' . cpaint_transformer::find_output_charset($this->basenode->get_encoding())); + echo cpaint_transformer::toString($this->basenode); + break; + + case 'JSON': + header('Content-type: text/plain; charset=' . cpaint_transformer::find_output_charset($this->basenode->get_encoding())); + echo cpaint_transformer::toJSON($this->basenode); + break; + + case 'OBJECT': + case 'E4X': + case 'XML': + header('Content-type: text/xml; charset=' . cpaint_transformer::find_output_charset($this->basenode->get_encoding())); + echo 'basenode->get_encoding()) . '"?>' + . cpaint_transformer::toXML($this->basenode); + break; + + default: + echo 'ERROR: invalid response type \'' . $this->response_type . '\''; + } // end: switch + + } elseif (isset($_REQUEST['api_query'])) { + // API version request + header('Content-type: text/plain; charset=ISO-8859-1'); + echo 'CPAINT v' . $this->version . '/PHP v' . phpversion(); + + } elseif ($this->use_wsdl == true + && isset($_REQUEST['wsdl'])) { + + if (is_file(dirname(__FILE__) . '/cpaint2.wsdl.php') + && is_readable(dirname(__FILE__) . '/cpaint2.wsdl.php')) { + + require_once(dirname(__FILE__) . '/cpaint2.wsdl.php'); + + if (class_exists('cpaint_wsdl')) { + // create new instance of WSDL library + $wsdl = new cpaint_wsdl(); + + // build WSDL info + header('Content-type: text/xml; charset=UTF-8'); + echo $wsdl->generate($this->api_functions, $this->api_datatypes); + + } else { + header('Content-type: text/plain; charset=ISO-8859-1'); + echo 'WSDL generator is unavailable'; + } // end: if + + } else { + header('Content-type: text/plain; charset=ISO-8859-1'); + echo 'WSDL generator is unavailable'; + } // end: if + } // end: if + } + + /** + * registers a new function or method as part of the CPAINT API + * + * @access public + * @param mixed $func function name, array(&$object, 'function_name') or array('class', 'function_name') + * @param array $input function input parameters (not yet used by CPAINT and subject to change) + * @param array $output function output format (not yed used by CPAINT and subject to change) + * @param string $comment description of the functionality + * @return boolean + */ + function register($func, $input = array(), $output = array(), $comment = '') { + $return_value = false; + $input = (array) $input; + $output = (array) $output; + $comment = (string) $comment; + + if (is_array($func) + && (is_object($func[0]) || is_string($func[0])) + && is_string($func[1]) + && is_callable($func)) { + + // calling a method of an object + $this->api_functions[$func[1]] = array( + 'call' => $func, + 'input' => $input, + 'output' => $output, + 'comment' => $comment, + ); + $return_value = true; + + } elseif (is_string($func)) { + // calling a standalone function + $this->api_functions[$func] = array( + 'call' => $func, + 'input' => $input, + 'output' => $output, + 'comment' => $comment, + ); + $return_value = true; + } // end: if + + return $return_value; + } + + + + /** + * unregisters a function that is currently part of the CPAINT API. + * + * proves useful when the same set of functions is to be used in the + * frontend and in some kind of administration environment. you might + * want to unregister a few (admin) functions for the frontend in this + * case. + * + * @access public + * @param string $func function name + * @return boolean + */ + function unregister($func) { + $retval = false; + + if (is_array($this->api_functions[$func])) { + unset($this->api_functions[$func]); + } // end: if + + return $retval; + } + + + + /** + * registers a complex data type + * + * @access public + * @param array $schema schema definition for the complex type + * @return boolean + */ + function complex_type($schema) { + $return_value = false; + $schema = (array) $schema; + + if ($schema['name'] != '' + && in_array($schema['type'], array('restriction', 'complex', 'list'))) { + + $this->api_datatypes[] = $schema; + $return_value = true; + } // end: if + + return $return_value; + } + + /** + * switches the generation of WSDL on/off. default is on + * + * @access public + * @param boolean $state state of WSDL generation + * @return void + */ + function use_wsdl($state) { + $this->use_wsdl = (boolean) $state; + } + + /** + * adds a new subnode to the basenode. + * + * will return a reference to it for further processing. + * + * @access public + * @param string $nodename name of the new node + * @param string $id id of the new node + * @return object + */ + function &add_node($nodename, $id = '') { + return $this->basenode->add_node($nodename, $id); + } + + /** + * assigns textual data to the basenode. + * + * @access public + * @param mixed $data data to assign to this node + * @return void + */ + function set_data($data) { + $this->basenode->set_data($data); + } + + /** + * returns the data assigned to the basenode. + * + * @access public + * @return mixed + */ + function get_data() { + return $this->basenode->get_data(); + } + + /** + * sets the id property of the basenode. + * + * @deprecated deprecated since version 2.0.0 + * @access public + * @param string $id the id + * @return void + */ + function set_id($id) { + $this->basenode->set_attribute('id', $id); + } + + /** + * gets the id property of the basenode. + * + * @deprecated deprecated since version 2.0.0 + * @access public + * @return string + */ + function get_id() { + return $this->basenode->get_attribute('id'); + } + + /** + * adds a new attribute to the basenode. + * + * @access public + * @param string $name attribute name + * @param mixed $value attribute value + * @return void + */ + function set_attribute($name, $value) { + $this->basenode->set_attribute($name, $value); + } + + /** + * retrieves an attribute of the basenode by name. + * + * @access public + * @param string $name attribute name + * @return string + */ + function get_attribute($name) { + return $this->basenode->get_attributes($name); + } + + /** + * set name property of the basenode. + * + * @access public + * @param string $name the name + * @return void + */ + function set_name($name) { + $this->basenode->set_name($name); + } + + /** + * get name property of the basenode. + * + * @access public + * @return string + */ + function get_name() { + return $this->basenode->get_name(); + } + + + + /** + * returns the response type as requested by the client + * + * @access public + * @return string + */ + function get_response_type() { + return $this->response_type; + } + + } + + /** + * a cpaint data node. Data nodes are used to build up the response. + * + * @package CPAINT + * @access public + * @author Dominique Stender + * @copyright 2005-2006 (Dominique Stender); All rights reserved + * @version 2.0.3 + */ + class cpaint_node { + /** + * array of subnodes. + * + * @access public + * @var array $composites + */ + var $composites; + + /** + * node attributes. + * + * @access public + * @var array $attributes + */ + var $attributes; + + /** + * name of this node. + * + * @access public + * @var string $nodename + */ + var $nodename; + + /** + * textual data of this node. + * + * @access public + * @var string $data + */ + var $data; + + /** + * character encoding for input data + * + * @access private + * @var $input_encoding + */ + var $input_encoding; + + /** + * PHP4 constructor. + * + * @package CPAINT + * @access public + * @return void + */ + function cpaint_node() { + $this->__construct(); + } + + /** + * PHP 5 constructor. + * + * @access public + * @return void + */ + function __construct() { + // initialize properties + $this->composites = array(); + $this->attributes = array(); + $this->data = ''; + + $this->set_encoding('UTF-8'); + $this->set_name(''); + $this->set_attribute('id', ''); + } + + /** + * adds a new subnode to this node. + * + * will return a reference to it for further processing. + * + * @access public + * @param string $nodename name of the new node + * @param string $id id of the new node + * @return object + */ + function &add_node($nodename, $id = '') { + $composites = count($this->composites); + + // create new node + $this->composites[$composites] =& new cpaint_node(); + $this->composites[$composites]->set_name($nodename); + $this->composites[$composites]->set_attribute('id', $id); + $this->composites[$composites]->set_encoding($this->input_encoding); + + return $this->composites[$composites]; + } + + /** + * assigns textual data to this node. + * + * @access public + * @param mixed $data data to assign to this node + * @return void + */ + function set_data($data) { + $this->data = $data; + } + + /** + * returns the textual data assigned to this node. + * + * @access public + * @return mixed + */ + function get_data() { + return $this->data; + } + + /** + * sets the id property of this node. + * + * @deprecated deprecated since version 2.0.0 + * @access public + * @param string id the id + * @return void + */ + function set_id($id) { + if ($id != '') { + $this->set_attribute('id', $id); + } // end: if + } + + /** + * returns the id property if this node. + * + * @deprecated deprecated since version 2.0.0 + * @access public + * @return string + */ + function get_id() { + return $this->get_attribute('id'); + } + + /** + * adds a new attribute to this node. + * + * @access public + * @param string $name attribute name + * @param mixed $value attribute value + * @return void + */ + function set_attribute($name, $value) { + $this->attributes[$name] = (string) $value; + } + + /** + * retrieves an attribute by name. + * + * @access public + * @param string $name attribute name + * @return string + */ + function get_attribute($name) { + return $this->attributes[$name]; + } + + /** + * set name property. + * + * @access public + * @param string $name the name + * @return void + */ + function set_name($name) { + $this->nodename = (string) $name; + } + + /** + * get name property. + * + * @access public + * @return string + */ + function get_name() { + return $this->nodename; + } + + /** + * sets the character encoding for this node + * + * @access public + * @param string $encoding character encoding + * @return void + */ + function set_encoding($encoding) { + $this->input_encoding = strtoupper((string) $encoding); + } + + /** + * returns the character encoding for this node + * + * @access public + * @return string + */ + function get_encoding() { + return $this->input_encoding; + } + } + + /** + * static class of output transformers. + * + * @package CPAINT + * @access public + * @author Dominique Stender + * @copyright 2003-2006 (Dominique Stender); All rights reserved + * @version 2.0.3 + */ + class cpaint_transformer { + /** + * toString method, used to generate response of type TEXT. + * will perform character transformation according to parameters. + * + * @access public + * @param object $node a cpaint_node object + * @return string + */ + function toString(&$node) { + $return_value = ''; + + foreach ($node->composites as $composite) { + $return_value .= cpaint_transformer::toString($composite); + } + + $return_value .= cpaint_transformer::encode($node->get_data(), $node->get_encoding()); + + return $return_value; + } + + /** + * XML response generator. + * will perform character transformation according to parameters. + * + * @access public + * @param object $node a cpaint_node object + * @return string + */ + function toXML(&$node) { + $return_value = '<' . $node->get_name(); + + // handle attributes + foreach ($node->attributes as $name => $value) { + if ($value != '') { + $return_value .= ' ' . $name . '="' . $node->get_attribute($name) . '"'; + } + } // end: foreach + + $return_value .= '>'; + + // handle subnodes + foreach ($node->composites as $composite) { + $return_value .= cpaint_transformer::toXML($composite); + } + + $return_value .= cpaint_transformer::encode($node->get_data(), $node->get_encoding()) + . 'get_name() . '>'; + + return $return_value; + } + + /** + * JSON response generator. + * will perform character transformation according to parameters. + * + * @access public + * @param object $node a cpaint_node object + * @return string + */ + function toJSON($node) { + $return_value = ''; + $JSON_node = new stdClass(); + + // handle attributes + $JSON_node->attributes = $node->attributes; + + // handle subnodes + foreach ($node->composites as $composite) { + + if (!is_array($JSON_node->{$composite->nodename})) { + $JSON_node->{$composite->nodename} = array(); + } // end: if + + // we need to parse the JSON object again to avoid multiple encoding + $JSON_node->{$composite->nodename}[] = $GLOBALS['__cpaint_json']->parse(cpaint_transformer::toJSON($composite)); + } + + // handle data + $JSON_node->data = $node->data; + + return $GLOBALS['__cpaint_json']->stringify($JSON_node); + } + + /** + * performs conversion to JavaScript-safe UTF-8 characters + * + * @access public + * @param string $data data to convert + * @param string $encoding character encoding + * @return string + */ + function encode($data, $encoding) { + // convert string + if (function_exists('iconv')) { + // iconv is by far the most flexible approach, try this first + $return_value = iconv($encoding, 'UTF-8', $data); + + } elseif ($encoding == 'ISO-8859-1') { + // for ISO-8859-1 we can use utf8-encode() + $return_value = utf8_encode($data); + + } else { + // give up. if UTF-8 data was supplied everything is fine! + $return_value = $data; + } /* end: if */ + + // now encode non-printable characters + for ($i = 0; $i < 32; $i++) { + $return_value = str_replace(chr($i), '\u00' . sprintf('%02x', $i), $return_value); + } // end: for + + // encode <, >, and & respectively for XML sanity + $return_value = str_replace(chr(0x26), '\u0026', $return_value); + $return_value = str_replace(chr(0x3c), '\u003c', $return_value); + $return_value = str_replace(chr(0x3e), '\u003e', $return_value); + + return $return_value; + } + + /** + * performs conversion from JavaScript encodeURIComponent() string (UTF-8) to + * the charset in use. + * + * @access public + * @param string $data data to convert + * @param string $encoding character encoding + * @return string + */ + function decode($data, $encoding) { + // convert string + + if (is_string($data)) { + if (function_exists('iconv')) { + // iconv is by far the most flexible approach, try this first + $return_value = iconv('UTF-8', $encoding, $data); + + } elseif ($encoding == 'ISO-8859-1') { + // for ISO-8859-1 we can use utf8-decode() + $return_value = utf8_decode($data); + + } else { + // give up. if data was supplied in the correct format everything is fine! + $return_value = $data; + } // end: if + + } else { + // non-string value + $return_value = $data; + } // end: if + + return $return_value; + } + + /** + * decodes a (nested) array of data from UTF-8 into the configured character set + * + * @access public + * @param array $data data to convert + * @param string $encoding character encoding + * @return array + */ + function decode_array($data, $encoding) { + $return_value = array(); + + foreach ($data as $key => $value) { + + if (!is_array($value)) { + $return_value[$key] = cpaint_transformer::decode($value, $encoding); + + } else { + $return_value[$key] = cpaint_transformer::decode_array($value, $encoding); + } + } + + return $return_value; + } + + /** + * determines the output character set + * based on input character set + * + * @access public + * @param string $encoding character encoding + * @return string + */ + function find_output_charset($encoding) { + $return_value = 'UTF-8'; + + if (function_exists('iconv') + || $encoding == 'UTF-8' + || $encoding == 'ISO-8859-1') { + + $return_value = 'UTF-8'; + + } else { + $return_value = $encoding; + } // end: if + + return $return_value; + } + } + +?> \ No newline at end of file diff --git a/pacotes/cpaint/cpaint2.proxy.php b/pacotes/cpaint/cpaint2.proxy.php new file mode 100644 index 0000000..bf8062f --- /dev/null +++ b/pacotes/cpaint/cpaint2.proxy.php @@ -0,0 +1,117 @@ + +* @author Dominique Stender +* @copyright Copyright (c) 2005-2006 Paul Sullivan, Dominique Stender - http://sf.net/projects/cpaint +* @version 2.0.3 +*/ + +//---- includes ---------------------------------------------------------------- + /** + * @include config + */ + require_once("cpaint2.config.php"); + +//---- main code --------------------------------------------------------------- + + error_reporting (E_ALL ^ E_NOTICE ^ E_WARNING); + set_time_limit(0); + + if ($_REQUEST['cpaint_remote_url'] != "") { + $cp_remote_url = urldecode($_REQUEST['cpaint_remote_url']); + $cp_remote_method = urldecode($_REQUEST['cpaint_remote_method']); + $cp_remote_query = urldecode($_REQUEST['cpaint_remote_query']); + $cp_response_type = strtoupper($_REQUEST['cpaint_response_type']); + } + + // propagate XML header if necessary + if ($cp_response_type == 'XML' + || $cp_response_type == 'OBJECT') { + header("Content-type: text/xml"); + } + + // transfer mode specifics + if ($cp_remote_method == 'GET') { + $cp_remote_url .= '?' . $cp_remote_query; + $cp_request_body = ''; + + // prepare parameters + $url_parts = parse_url($cp_remote_url); + + // build basic header + $cp_request_header = 'GET ' . $url_parts['path'] . '?' . str_replace(' ', '+', $url_parts['query']) . " HTTP/1.0\r\n" + . "Host: " . $url_parts['host'] . "\r\n"; + + } elseif ($cp_remote_method == 'POST') { + $cp_request_body = '&' . $cp_remote_query; + + // prepare parameters + $url_parts = parse_url($cp_remote_url); + + // check against whitelist + if ($cpaint2_config["proxy.security.use_whitelist"] == true) { + $url_allowed = false; + foreach($cpaint2_proxy_whitelist as $whitelistURL) { + $whiteList_parts = parse_url("http://" . $whitelistURL); + $url_parts_temp = parse_url("http://" . $cp_remote_url); + if (array_key_exists("path", $whiteList_parts)) { + if ((strtolower($whiteList_parts["path"]) == strtolower($url_parts_temp["path"])) && (strtolower($whiteList_parts["host"]) == strtolower($url_parts_temp["host"]))) $url_allowed = true; + } else { // no path, check only host + if (strtolower($whiteList_parts["host"]) == strtolower($url_parts_temp["host"])) $url_allowed = true; + } + } + if ($url_allowed == false) die("[CPAINT] The host or script cannot be accessed through this proxy."); + } + + // build basic header + $cp_request_header = 'POST ' . $url_parts['path'] . " HTTP/1.0\r\n" + . "Host: " . $url_parts['host'] . "\r\n" + . "Content-Type: application/x-www-form-urlencoded\r\n"; + } + + // add port if none exists + if (!isset($url_parts['port'])) { + $url_parts['port'] = 80; + } + + // add content-length header + $cp_request_header .= "Content-Length: " . strlen($cp_request_body) . "\r\n"; + + // add authentication to header if necessary + if ($url_parts['user'] != '') { + $cp_request_header .= 'Authorization: Basic ' . base64_encode($url_parts['user'] . ':' . $url_parts['pass']) . "\r\n"; + } + + // open connection + $cp_socket = @fsockopen($url_parts['host'], $url_parts['port'], $error, $errstr, 10); + + if ($cp_socket !== false) { + // send headers + @fwrite($cp_socket, $cp_request_header . "\r\n\r\n"); + + // send body if necessary + if ($cp_request_body != '') { + @fwrite($cp_socket, $cp_request_body . "\r\n"); + } + + while (!feof($cp_socket)) { + $http_data = $http_data . fgets($cp_socket); + } + + list($http_headers, $http_body) = split("\r\n\r\n", $http_data, 2); + echo($http_body); + @fclose($cp_socket); + } + +?> \ No newline at end of file diff --git a/pacotes/cpaint/json.php b/pacotes/cpaint/json.php new file mode 100644 index 0000000..60b7c5e --- /dev/null +++ b/pacotes/cpaint/json.php @@ -0,0 +1,580 @@ + +* @version 1.0.1 +*/ + + + + /** + * a JSON parser / generator + * + * @access public + * @author Dominique Stender + * @version 1.0.1 + */ + class JSON { + /** + * line counter + * + * @access private + * @var integer $at + */ + var $at = 0; + + /** + * + * @access private + * @var string $ch + */ + var $ch = ' '; + + /** + * JSON representation + * + * @access private + * @var string $text + */ + var $text = ''; + + /** + * takes an arbitrary PHP data structure and generates a valid JSON representation from it + * + * @param mixed $arg an arbitrary PHP data structure + * @access public + * @return string + * @version 1.0.1 fixed tests whether $s has content by using strlen(). this enables the user to use 0 as very first character + */ + function stringify($arg) { + $returnValue = ''; + $c = ''; + $i = ''; + $l = ''; + $s = ''; + $v = ''; + $numeric = true; + + switch (gettype($arg)) { + + case 'array': + // do a test whether all array keys are numeric + foreach ($arg as $i => $v) { + if (!is_numeric($i)) { + $numeric = false; + break; + } + } + + if ($numeric) { + + foreach ($arg as $i => $v) { + if (strlen($s) > 0) { + $s .= ','; + } + + $s .= $this->stringify($arg[$i]); + } // end: foreach + + $returnValue = '[' . $s . ']'; + + } else { + // associative array + foreach ($arg as $i => $v) { + if (strlen($s) > 0) { + $s .= ','; + } + $s .= $this->stringify($i) . ':' . $this->stringify($arg[$i]); + } + // return as object + $returnValue = '{' . $s . '}'; + } + break; + + case 'object': + + foreach (get_object_vars($arg) as $i => $v) { + $v = $this->stringify($v); + + if (strlen($s) > 0) { + $s .= ','; + } + + $s .= $this->stringify($i) . ':' . $v; + } + + $returnValue = '{' . $s . '}'; + break; + + case 'integer': + case 'double': + $returnValue = is_numeric($arg) ? (string) $arg : 'null'; + break; + + case 'string': + $l = strlen($arg); + $s = '"'; + + for ($i = 0; $i < $l; $i++) { + $c = $arg{$i}; + + if (ord($c) >= ord(' ')) { + + if ($c == '\\' + || $c == '"') { + + $s .= '\\'; + } + $s .= $c; + + } else { + + switch ($c) { + + case '\b': + $s .= '\\b'; + break; + + case '\f': + $s .= '\\f'; + break; + + case '\n': + $s .= '\\n'; + break; + + case '\r': + $s .= '\\r'; + break; + + case '\t': + $s .= '\\t'; + break; + + default: + $s .= '\u00' . sprintf('%02x', ord($c)); + } + } + } + $returnValue = $s . '"'; + break; + + case 'boolean': + $returnValue = (string) $arg; + break; + + default: + $returnValue = 'null'; + } + + return $returnValue; + } + + + /** + * parses the given string into a PHP data structure + * + * @param string $text JSON data representation + * @access public + * @return mixed + */ + function parse($text) { + $this->at = 0; + $this->ch = ' '; + $this->text = $text; + + return $this->val(); + } + + /** + * triggers a PHP_ERROR + * + * @access private + * @param string $m error message + * @return void + */ + function error($m) { + trigger_error($m . ' at offset ' . $this->at . ': ' . $this->text, E_USER_ERROR); + } + + /** + * returns the next character of a JSON string + * + * @access private + * @return string + */ + function next() { + $this->ch = $this->text{$this->at}; + $this->at++; + return $this->ch; + } + + /** + * handles whitespace and comments + * + * @access private + * @return void + */ + function white() { + + while ($this->ch != '' + && ord($this->ch) <= ord(' ')) { + + $this->next(); + } + } + + /** + * handles strings + * + * @access private + * @return void + */ + function str() { + $i = ''; + $s = ''; + $t = ''; + $u = ''; + + if ($this->ch == '"') { + + while ($this->next() !== null) { + + if ($this->ch == '"') { + $this->next(); + return $s; + + } elseif ($this->ch == '\\') { + + switch ($this->next()) { + case 'b': + $s .= '\b'; + break; + + case 'f': + $s .= '\f'; + break; + + case 'n': + $s .= '\n'; + break; + + case 'r': + $s .= '\r'; + break; + + case 't': + $s .= '\t'; + break; + + case 'u': + $u = 0; + + for ($i = 0; $i < 4; $i += 1) { + $t = (integer) sprintf('%01c', hexdec($this->next())); + + if (!is_numeric($t)) { + break 2; + } + $u = $u * 16 + $t; + } + + $s .= chr($u); + break; + + default: + $s .= $this->ch; + } + } else { + $s .= $this->ch; + } + } + } + + $this->error('Bad string'); + } + + /** + * handless arrays + * + * @access private + * @return void + */ + function arr() { + $a = array(); + + if ($this->ch == '[') { + $this->next(); + $this->white(); + + if ($this->ch == ']') { + $this->next(); + return $a; + } + + while ($this->ch) { + array_push($a, $this->val()); + $this->white(); + + if ($this->ch == ']') { + $this->next(); + return $a; + + } elseif ($this->ch != ',') { + break; + } + + $this->next(); + $this->white(); + } + + $this->error('Bad array'); + } + } + + /** + * handles objects + * + * @access public + * @return void + */ + function obj() { + $k = ''; + $o = new stdClass(); + + if ($this->ch == '{') { + $this->next(); + $this->white(); + + if ($this->ch == '}') { + $this->next(); + return $o; + } + + while ($this->ch) { + $k = $this->str(); + $this->white(); + + if ($this->ch != ':') { + break; + } + + $this->next(); + $o->$k = $this->val(); + $this->white(); + + if ($this->ch == '}') { + $this->next(); + return $o; + + } elseif ($this->ch != ',') { + break; + } + + $this->next(); + $this->white(); + } + } + + $this->error('Bad object'); + } + + /** + * handles objects + * + * @access public + * @return void + */ + function assoc() { + $k = ''; + $a = array(); + + if ($this->ch == '<') { + $this->next(); + $this->white(); + + if ($this->ch == '>') { + $this->next(); + return $a; + } + + while ($this->ch) { + $k = $this->str(); + $this->white(); + + if ($this->ch != ':') { + break; + } + + $this->next(); + $a[$k] = $this->val(); + $this->white(); + + if ($this->ch == '>') { + $this->next(); + return $a; + + } elseif ($this->ch != ',') { + break; + } + + $this->next(); + $this->white(); + } + } + + $this->error('Bad associative array'); + } + + /** + * handles numbers + * + * @access private + * @return void + */ + function num() { + $n = ''; + $v = ''; + + if ($this->ch == '-') { + $n = '-'; + $this->next(); + } + + while ($this->ch >= '0' + && $this->ch <= '9') { + + $n .= $this->ch; + $this->next(); + } + + if ($this->ch == '.') { + $n .= '.'; + + while ($this->next() + && $this->ch >= '0' + && $this->ch <= '9') { + + $n .= $this->ch; + } + } + + if ($this->ch == 'e' + || $this->ch == 'E') { + + $n .= 'e'; + $this->next(); + + if ($this->ch == '-' + || $this->ch == '+') { + + $n .= $this->ch; + $this->next(); + } + + while ($this->ch >= '0' + && $this->ch <= '9') { + + $n .= $this->ch; + $this->next(); + } + } + + $v += $n; + + if (!is_numeric($v)) { + $this->error('Bad number'); + + } else { + return $v; + } // end: if + } + + /** + * handles words + * + * @access private + * @return mixed + */ + function word() { + switch ($this->ch) { + + case 't': + + if ($this->next() == 'r' + && $this->next() == 'u' + && $this->next() == 'e') { + + $this->next(); + return true; + } + break; + + case 'f': + if ($this->next() == 'a' + && $this->next() == 'l' + && $this->next() == 's' + && $this->next() == 'e') { + + $this->next(); + return false; + } + break; + + case 'n': + if ($this->next() == 'u' + && $this->next() == 'l' + && $this->next() == 'l') { + + $this->next(); + return null; + } + break; + } + + $this->error('Syntax error'); + } + + /** + * generic value handler + * + * @access private + * @return mixed + */ + function val() { + $this->white(); + + switch ($this->ch) { + + case '{': + return $this->obj(); + + case '[': + return $this->arr(); + + case '<': + return $this->assoc(); + + case '"': + return $this->str(); + + case '-': + return $this->num(); + + default: + return ($this->ch >= '0' && $this->ch <= '9') ? $this->num() : $this->word(); + } + } + } + +?> \ No newline at end of file -- libgit2 0.21.2