mirror of
https://github.com/ACSPRI/queXS
synced 2024-04-02 12:12:16 +00:00
Import from DCARF SVN
This commit is contained in:
152
include/pear/data/HTML_AJAX/js/serializer/JSON.js
Normal file
152
include/pear/data/HTML_AJAX/js/serializer/JSON.js
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
The global object JSON contains two methods.
|
||||
|
||||
JSON.stringify(value) takes a JavaScript value and produces a JSON text.
|
||||
The value must not be cyclical.
|
||||
|
||||
JSON.parse(text) takes a JSON text and produces a JavaScript value. It will
|
||||
throw a 'JSONError' exception if there is an error.
|
||||
*/
|
||||
var HTML_AJAX_JSON = {
|
||||
copyright: '(c)2005 JSON.org',
|
||||
license: 'http://www.crockford.com/JSON/license.html',
|
||||
/*
|
||||
Stringify a JavaScript value, producing a JSON text.
|
||||
*/
|
||||
stringify: function (v) {
|
||||
var a = [];
|
||||
|
||||
/*
|
||||
Emit a string.
|
||||
*/
|
||||
function e(s) {
|
||||
a[a.length] = s;
|
||||
}
|
||||
|
||||
/*
|
||||
Convert a value.
|
||||
*/
|
||||
function g(x) {
|
||||
var c, i, l, v;
|
||||
|
||||
switch (typeof x) {
|
||||
case 'object':
|
||||
if (x) {
|
||||
if (x instanceof Array) {
|
||||
e('[');
|
||||
l = a.length;
|
||||
for (i = 0; i < x.length; i += 1) {
|
||||
v = x[i];
|
||||
if (typeof v != 'undefined' &&
|
||||
typeof v != 'function') {
|
||||
if (l < a.length) {
|
||||
e(',');
|
||||
}
|
||||
g(v);
|
||||
}
|
||||
}
|
||||
e(']');
|
||||
return;
|
||||
} else if (typeof x.valueOf == 'function') {
|
||||
e('{');
|
||||
l = a.length;
|
||||
for (i in x) {
|
||||
v = x[i];
|
||||
if (typeof v != 'undefined' &&
|
||||
typeof v != 'function' &&
|
||||
(!v || typeof v != 'object' ||
|
||||
typeof v.valueOf == 'function')) {
|
||||
if (l < a.length) {
|
||||
e(',');
|
||||
}
|
||||
g(i);
|
||||
e(':');
|
||||
g(v);
|
||||
}
|
||||
}
|
||||
return e('}');
|
||||
}
|
||||
}
|
||||
e('null');
|
||||
return;
|
||||
case 'number':
|
||||
e(isFinite(x) ? +x : 'null');
|
||||
return;
|
||||
case 'string':
|
||||
l = x.length;
|
||||
e('"');
|
||||
for (i = 0; i < l; i += 1) {
|
||||
c = x.charAt(i);
|
||||
if (c >= ' ') {
|
||||
if (c == '\\' || c == '"') {
|
||||
e('\\');
|
||||
}
|
||||
e(c);
|
||||
} else {
|
||||
switch (c) {
|
||||
case '\b':
|
||||
e('\\b');
|
||||
break;
|
||||
case '\f':
|
||||
e('\\f');
|
||||
break;
|
||||
case '\n':
|
||||
e('\\n');
|
||||
break;
|
||||
case '\r':
|
||||
e('\\r');
|
||||
break;
|
||||
case '\t':
|
||||
e('\\t');
|
||||
break;
|
||||
default:
|
||||
c = c.charCodeAt();
|
||||
e('\\u00' + Math.floor(c / 16).toString(16) +
|
||||
(c % 16).toString(16));
|
||||
}
|
||||
}
|
||||
}
|
||||
e('"');
|
||||
return;
|
||||
case 'boolean':
|
||||
e(String(x));
|
||||
return;
|
||||
default:
|
||||
e('null');
|
||||
return;
|
||||
}
|
||||
}
|
||||
g(v);
|
||||
return a.join('');
|
||||
},
|
||||
/*
|
||||
Parse a JSON text, producing a JavaScript value.
|
||||
*/
|
||||
parse: function (text) {
|
||||
return
|
||||
(/^(\s+|[,:{}\[\]]|"(\\["\\\/bfnrtu]|[^\x00-\x1f"\\]+)*"|-?\d+(\.\d*)?([eE][+-]?\d+)?|true|false|null)+$/.test(text))
|
||||
&&
|
||||
eval('(' + text + ')');
|
||||
}
|
||||
};
|
||||
145
include/pear/data/HTML_AJAX/js/serializer/UrlSerializer.js
Normal file
145
include/pear/data/HTML_AJAX/js/serializer/UrlSerializer.js
Normal file
@@ -0,0 +1,145 @@
|
||||
// {{{ HTML_AJAX_Serialize_Urlencoded
|
||||
/**
|
||||
* URL-encoding serializer
|
||||
*
|
||||
* This class can be used to serialize and unserialize data in a
|
||||
* format compatible with PHP's handling of HTTP query strings.
|
||||
* Due to limitations of the format, all input is serialized as an
|
||||
* array or a string. See examples/serialize.url.examples.php
|
||||
*
|
||||
* @version 0.0.1
|
||||
* @copyright 2005 Arpad Ray <arpad@php.net>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
*
|
||||
* See Main.js for Author/license details
|
||||
*/
|
||||
function HTML_AJAX_Serialize_Urlencoded() {}
|
||||
HTML_AJAX_Serialize_Urlencoded.prototype = {
|
||||
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
base: '_HTML_AJAX',
|
||||
_keys: [],
|
||||
error: false,
|
||||
message: "",
|
||||
cont: "",
|
||||
// {{{ serialize
|
||||
/**
|
||||
* Serializes a variable
|
||||
*
|
||||
* @param mixed inp the variable to serialize
|
||||
* @return string a string representation of the input,
|
||||
* which can be reconstructed by unserialize()
|
||||
*/
|
||||
serialize: function(input, _internal) {
|
||||
if (typeof input == 'undefined') {
|
||||
return '';
|
||||
}
|
||||
if (!_internal) {
|
||||
this._keys = [];
|
||||
}
|
||||
var ret = '', first = true;
|
||||
for (i = 0; i < this._keys.length; i++) {
|
||||
ret += (first ? HTML_AJAX_Util.encodeUrl(this._keys[i]) : '[' + HTML_AJAX_Util.encodeUrl(this._keys[i]) + ']');
|
||||
first = false;
|
||||
}
|
||||
ret += '=';
|
||||
switch (HTML_AJAX_Util.getType(input)) {
|
||||
case 'string':
|
||||
case 'number':
|
||||
ret += HTML_AJAX_Util.encodeUrl(input.toString());
|
||||
break;
|
||||
case 'boolean':
|
||||
ret += (input ? '1' : '0');
|
||||
break;
|
||||
case 'array':
|
||||
case 'object':
|
||||
ret = '';
|
||||
for (i in input) {
|
||||
this._keys.push(i);
|
||||
ret += this.serialize(input[i], true) + '&';
|
||||
this._keys.pop();
|
||||
}
|
||||
ret = ret.substr(0, ret.length - 1);
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
// }}}
|
||||
// {{{ unserialize
|
||||
/**
|
||||
* Reconstructs a serialized variable
|
||||
*
|
||||
* @param string inp the string to reconstruct
|
||||
* @return array an array containing the variable represented by the input string, or void on failure
|
||||
*/
|
||||
unserialize: function(input) {
|
||||
if (!input.length || input.length == 0) {
|
||||
// null
|
||||
return;
|
||||
}
|
||||
if (!/^(\w+(\[[^\[\]]*\])*=[^&]*(&|$))+$/.test(input)) {
|
||||
this.raiseError("invalidly formed input", input);
|
||||
return;
|
||||
}
|
||||
input = input.split("&");
|
||||
var pos, key, keys, val, _HTML_AJAX = [];
|
||||
if (input.length == 1) {
|
||||
return HTML_AJAX_Util.decodeUrl(input[0].substr(this.base.length + 1));
|
||||
}
|
||||
for (var i in input) {
|
||||
pos = input[i].indexOf("=");
|
||||
if (pos < 1 || input[i].length - pos - 1 < 1) {
|
||||
this.raiseError("input is too short", input[i]);
|
||||
return;
|
||||
}
|
||||
key = HTML_AJAX_Util.decodeUrl(input[i].substr(0, pos));
|
||||
val = HTML_AJAX_Util.decodeUrl(input[i].substr(pos + 1));
|
||||
key = key.replace(/\[((\d*\D+)+)\]/g, '["$1"]');
|
||||
keys = key.split(']');
|
||||
for (j in keys) {
|
||||
if (!keys[j].length || keys[j].length == 0) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
if (eval('typeof ' + keys[j] + ']') == 'undefined') {
|
||||
var ev = keys[j] + ']=[];';
|
||||
eval(ev);
|
||||
}
|
||||
} catch (e) {
|
||||
this.raiseError("error evaluating key", ev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
eval(key + '="' + val + '";');
|
||||
} catch (e) {
|
||||
this.raiseError("error evaluating value", input);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return _HTML_AJAX;
|
||||
},
|
||||
// }}}
|
||||
// {{{ getError
|
||||
/**
|
||||
* Gets the last error message
|
||||
*
|
||||
* @return string the last error message from unserialize()
|
||||
*/
|
||||
getError: function() {
|
||||
return this.message + "\n" + this.cont;
|
||||
},
|
||||
// }}}
|
||||
// {{{ raiseError
|
||||
/**
|
||||
* Raises an eror (called by unserialize().)
|
||||
*
|
||||
* @param string message the error message
|
||||
* @param string cont the remaining unserialized content
|
||||
*/
|
||||
raiseError: function(message, cont) {
|
||||
this.error = 1;
|
||||
this.message = message;
|
||||
this.cont = cont;
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
// }}}
|
||||
301
include/pear/data/HTML_AJAX/js/serializer/haSerializer.js
Normal file
301
include/pear/data/HTML_AJAX/js/serializer/haSerializer.js
Normal file
@@ -0,0 +1,301 @@
|
||||
/**
|
||||
* HTML_AJAX_Serialize_HA - custom serialization
|
||||
*
|
||||
* This class is used with the JSON serializer and the HTML_AJAX_Action php class
|
||||
* to allow users to easily write data handling and dom manipulation related to
|
||||
* ajax actions directly from their php code
|
||||
*
|
||||
* See Main.js for Author/license details
|
||||
*/
|
||||
function HTML_AJAX_Serialize_HA() { }
|
||||
HTML_AJAX_Serialize_HA.prototype =
|
||||
{
|
||||
/**
|
||||
* Takes data from JSON - which should be parseable into a nice array
|
||||
* reads the action to take and pipes it to the right method
|
||||
*
|
||||
* @param string payload incoming data from php
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
unserialize: function(payload)
|
||||
{
|
||||
var actions = eval(payload);
|
||||
for(var i = 0; i < actions.length; i++)
|
||||
{
|
||||
var action = actions[i];
|
||||
switch(action.action)
|
||||
{
|
||||
case 'prepend':
|
||||
this._prependAttr(action.id, action.attributes);
|
||||
break;
|
||||
case 'append':
|
||||
this._appendAttr(action.id, action.attributes);
|
||||
break;
|
||||
case 'assign':
|
||||
this._assignAttr(action.id, action.attributes);
|
||||
break;
|
||||
case 'clear':
|
||||
this._clearAttr(action.id, action.attributes);
|
||||
break;
|
||||
case 'create':
|
||||
this._createNode(action.id, action.tag, action.attributes, action.type);
|
||||
break;
|
||||
case 'replace':
|
||||
this._replaceNode(action.id, action.tag, action.attributes);
|
||||
break;
|
||||
case 'remove':
|
||||
this._removeNode(action.id);
|
||||
break;
|
||||
case 'script':
|
||||
this._insertScript(action.data);
|
||||
break;
|
||||
case 'alert':
|
||||
this._insertAlert(action.data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
/* Dispatch Methods */
|
||||
_prependAttr: function(id, attributes)
|
||||
{
|
||||
var node = document.getElementById(id);
|
||||
this._setAttrs(node, attributes, 'prepend');
|
||||
},
|
||||
_appendAttr: function(id, attributes)
|
||||
{
|
||||
var node = document.getElementById(id);
|
||||
this._setAttrs(node, attributes, 'append');
|
||||
},
|
||||
_assignAttr: function(id, attributes)
|
||||
{
|
||||
var node = document.getElementById(id);
|
||||
this._setAttrs(node, attributes);
|
||||
},
|
||||
_clearAttr: function(id, attributes)
|
||||
{
|
||||
var node = document.getElementById(id);
|
||||
for(var i = 0; i < attributes.length; i++)
|
||||
{
|
||||
if(attributes[i] == 'innerHTML')
|
||||
{
|
||||
HTML_AJAX_Util.setInnerHTML(node, '');
|
||||
}
|
||||
// value can't be removed
|
||||
else if(attributes[i] == 'value')
|
||||
{
|
||||
node.value = '';
|
||||
}
|
||||
// I'd use hasAttribute first but IE is stupid stupid stupid
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
node.removeAttribute(attributes[i]);
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
node[i] = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
_createNode: function(id, tag, attributes, type)
|
||||
{
|
||||
var newnode = document.createElement(tag);
|
||||
this._setAttrs(newnode, attributes);
|
||||
switch(type)
|
||||
{
|
||||
case 'append':
|
||||
document.getElementById(id).appendChild(newnode);
|
||||
break
|
||||
case 'prepend':
|
||||
var parent = document.getElementById(id);
|
||||
var sibling = parent.firstChild;
|
||||
parent.insertBefore(newnode, sibling);
|
||||
break;
|
||||
case 'insertBefore':
|
||||
var sibling = document.getElementById(id);
|
||||
var parent = sibling.parentNode;
|
||||
parent.insertBefore(newnode, sibling);
|
||||
break;
|
||||
//this one is tricky, if it's the last one we use append child...ewww
|
||||
case 'insertAfter':
|
||||
var sibling = document.getElementById(id);
|
||||
var parent = sibling.parentNode;
|
||||
var next = sibling.nextSibling;
|
||||
if(next == null)
|
||||
{
|
||||
parent.appendChild(newnode);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.insertBefore(newnode, next);
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
_replaceNode: function(id, tag, attributes)
|
||||
{
|
||||
var node = document.getElementById(id);
|
||||
var parent = node.parentNode;
|
||||
var newnode = document.createElement(tag);
|
||||
this._setAttrs(newnode, attributes);
|
||||
parent.replaceChild(newnode, node);
|
||||
},
|
||||
_removeNode: function(id)
|
||||
{
|
||||
var node = document.getElementById(id);
|
||||
if(node)
|
||||
{
|
||||
var parent = node.parentNode;
|
||||
parent.removeChild(node);
|
||||
}
|
||||
},
|
||||
_insertScript: function(data)
|
||||
{
|
||||
eval(data);
|
||||
},
|
||||
_insertAlert: function(data)
|
||||
{
|
||||
alert(data);
|
||||
},
|
||||
/* Helper Methods */
|
||||
// should we move this to HTML_AJAX_Util???, just does the - case which we need for style
|
||||
_camelize: function(instr)
|
||||
{
|
||||
var p = instr.split('-');
|
||||
var out = p[0];
|
||||
for(var i = 1; i < p.length; i++) {
|
||||
out += p[i].charAt(0).toUpperCase()+p[i].substring(1);
|
||||
}
|
||||
return out;
|
||||
},
|
||||
_setAttrs: function(node, attributes, type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case 'prepend':
|
||||
for (var i in attributes)
|
||||
{
|
||||
// innerHTML is extremely flakey - use util method for it
|
||||
if(i == 'innerHTML')
|
||||
{
|
||||
HTML_AJAX_Util.setInnerHTML(node, attributes[i], 'append');
|
||||
}
|
||||
//IE doesn't support setAttribute on style so we need to break it out and set each property individually
|
||||
else if(i == 'style')
|
||||
{
|
||||
var styles = [];
|
||||
if(attributes[i].indexOf(';'))
|
||||
{
|
||||
styles = attributes[i].split(';');
|
||||
}
|
||||
else
|
||||
{
|
||||
styles.push(attributes[i]);
|
||||
}
|
||||
for(var i = 0; i < styles.length; i++)
|
||||
{
|
||||
var r = styles[i].match(/^\s*(.+)\s*:\s*(.+)\s*$/);
|
||||
if(r)
|
||||
{
|
||||
node.style[this._camelize(r[1])] = r[2] + node.style[this._camelize(r[1])];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
node[i] = attributes[i] + node[i];
|
||||
}
|
||||
catch(e){}
|
||||
node.setAttribute(i, attributes[i] + node[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'append':
|
||||
{
|
||||
for (var i in attributes)
|
||||
{
|
||||
// innerHTML is extremely flakey - use util method for it
|
||||
if(i == 'innerHTML')
|
||||
{
|
||||
HTML_AJAX_Util.setInnerHTML(node, attributes[i], 'append');
|
||||
}
|
||||
//IE doesn't support setAttribute on style so we need to break it out and set each property individually
|
||||
else if(i == 'style')
|
||||
{
|
||||
var styles = [];
|
||||
if(attributes[i].indexOf(';'))
|
||||
{
|
||||
styles = attributes[i].split(';');
|
||||
}
|
||||
else
|
||||
{
|
||||
styles.push(attributes[i]);
|
||||
}
|
||||
for(var i = 0; i < styles.length; i++)
|
||||
{
|
||||
var r = styles[i].match(/^\s*(.+)\s*:\s*(.+)\s*$/);
|
||||
if(r)
|
||||
{
|
||||
node.style[this._camelize(r[1])] = node.style[this._camelize(r[1])] + r[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
node[i] = node[i] + attributes[i];
|
||||
}
|
||||
catch(e){}
|
||||
node.setAttribute(i, node[i] + attributes[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
for (var i in attributes)
|
||||
{
|
||||
//innerHTML hack bailout
|
||||
if(i == 'innerHTML')
|
||||
{
|
||||
HTML_AJAX_Util.setInnerHTML(node, attributes[i]);
|
||||
}
|
||||
else if(i == 'style')
|
||||
{
|
||||
var styles = [];
|
||||
if(attributes[i].indexOf(';'))
|
||||
{
|
||||
styles = attributes[i].split(';');
|
||||
}
|
||||
else
|
||||
{
|
||||
styles.push(attributes[i]);
|
||||
}
|
||||
for(var i = 0; i < styles.length; i++)
|
||||
{
|
||||
var r = styles[i].match(/^\s*(.+)\s*:\s*(.+)\s*$/);
|
||||
if(r)
|
||||
{
|
||||
node.style[this._camelize(r[1])] = r[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
node[i] = attributes[i];
|
||||
}
|
||||
catch(e){}
|
||||
node.setAttribute(i, attributes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
244
include/pear/data/HTML_AJAX/js/serializer/phpSerializer.js
Normal file
244
include/pear/data/HTML_AJAX/js/serializer/phpSerializer.js
Normal file
@@ -0,0 +1,244 @@
|
||||
// {{{ HTML_AJAX_Serialize_PHP
|
||||
/**
|
||||
* PHP serializer
|
||||
*
|
||||
* This class can be used to serialize and unserialize data in a
|
||||
* format compatible with PHP's native serialization functions.
|
||||
*
|
||||
* @version 0.0.3
|
||||
* @copyright 2005 Arpad Ray <arpad@php.net>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
*
|
||||
* See Main.js for Author/license details
|
||||
*/
|
||||
|
||||
function HTML_AJAX_Serialize_PHP() {}
|
||||
HTML_AJAX_Serialize_PHP.prototype = {
|
||||
error: false,
|
||||
message: "",
|
||||
cont: "",
|
||||
defaultEncoding: 'UTF-8',
|
||||
contentType: 'application/php-serialized; charset: UTF-8',
|
||||
// {{{ serialize
|
||||
/**
|
||||
* Serializes a variable
|
||||
*
|
||||
* @param mixed inp the variable to serialize
|
||||
* @return string a string representation of the input,
|
||||
* which can be reconstructed by unserialize()
|
||||
* @author Arpad Ray <arpad@rajeczy.com>
|
||||
* @author David Coallier <davidc@php.net>
|
||||
*/
|
||||
serialize: function(inp) {
|
||||
var type = HTML_AJAX_Util.getType(inp);
|
||||
var val;
|
||||
switch (type) {
|
||||
case "undefined":
|
||||
val = "N";
|
||||
break;
|
||||
case "boolean":
|
||||
val = "b:" + (inp ? "1" : "0");
|
||||
break;
|
||||
case "number":
|
||||
val = (Math.round(inp) == inp ? "i" : "d") + ":" + inp;
|
||||
break;
|
||||
case "string":
|
||||
val = "s:" + inp.length + ":\"" + inp + "\"";
|
||||
break;
|
||||
case "array":
|
||||
val = "a";
|
||||
case "object":
|
||||
if (type == "object") {
|
||||
var objname = inp.constructor.toString().match(/(\w+)\(\)/);
|
||||
if (objname == undefined) {
|
||||
return;
|
||||
}
|
||||
objname[1] = this.serialize(objname[1]);
|
||||
val = "O" + objname[1].substring(1, objname[1].length - 1);
|
||||
}
|
||||
var count = 0;
|
||||
var vals = "";
|
||||
var okey;
|
||||
for (key in inp) {
|
||||
okey = (key.match(/^[0-9]+$/) ? parseInt(key) : key);
|
||||
vals += this.serialize(okey) +
|
||||
this.serialize(inp[key]);
|
||||
count++;
|
||||
}
|
||||
val += ":" + count + ":{" + vals + "}";
|
||||
break;
|
||||
}
|
||||
if (type != "object" && type != "array") val += ";";
|
||||
return val;
|
||||
},
|
||||
// }}}
|
||||
// {{{ unserialize
|
||||
/**
|
||||
* Reconstructs a serialized variable
|
||||
*
|
||||
* @param string inp the string to reconstruct
|
||||
* @return mixed the variable represented by the input string, or void on failure
|
||||
*/
|
||||
unserialize: function(inp) {
|
||||
this.error = 0;
|
||||
if (inp == "" || inp.length < 2) {
|
||||
this.raiseError("input is too short");
|
||||
return;
|
||||
}
|
||||
var val, kret, vret, cval;
|
||||
var type = inp.charAt(0);
|
||||
var cont = inp.substring(2);
|
||||
var size = 0, divpos = 0, endcont = 0, rest = "", next = "";
|
||||
|
||||
switch (type) {
|
||||
case "N": // null
|
||||
if (inp.charAt(1) != ";") {
|
||||
this.raiseError("missing ; for null", cont);
|
||||
}
|
||||
// leave val undefined
|
||||
rest = cont;
|
||||
break;
|
||||
case "b": // boolean
|
||||
if (!/[01];/.test(cont.substring(0,2))) {
|
||||
this.raiseError("value not 0 or 1, or missing ; for boolean", cont);
|
||||
}
|
||||
val = (cont.charAt(0) == "1");
|
||||
rest = cont.substring(1);
|
||||
break;
|
||||
case "s": // string
|
||||
val = "";
|
||||
divpos = cont.indexOf(":");
|
||||
if (divpos == -1) {
|
||||
this.raiseError("missing : for string", cont);
|
||||
break;
|
||||
}
|
||||
size = parseInt(cont.substring(0, divpos));
|
||||
if (size == 0) {
|
||||
if (cont.length - divpos < 4) {
|
||||
this.raiseError("string is too short", cont);
|
||||
break;
|
||||
}
|
||||
rest = cont.substring(divpos + 4);
|
||||
break;
|
||||
}
|
||||
if ((cont.length - divpos - size) < 4) {
|
||||
this.raiseError("string is too short", cont);
|
||||
break;
|
||||
}
|
||||
if (cont.substring(divpos + 2 + size, divpos + 4 + size) != "\";") {
|
||||
this.raiseError("string is too long, or missing \";", cont);
|
||||
}
|
||||
val = cont.substring(divpos + 2, divpos + 2 + size);
|
||||
rest = cont.substring(divpos + 4 + size);
|
||||
break;
|
||||
case "i": // integer
|
||||
case "d": // float
|
||||
var dotfound = 0;
|
||||
for (var i = 0; i < cont.length; i++) {
|
||||
cval = cont.charAt(i);
|
||||
if (isNaN(parseInt(cval)) && !(type == "d" && cval == "." && !dotfound++)) {
|
||||
endcont = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!endcont || cont.charAt(endcont) != ";") {
|
||||
this.raiseError("missing or invalid value, or missing ; for int/float", cont);
|
||||
}
|
||||
val = cont.substring(0, endcont);
|
||||
val = (type == "i" ? parseInt(val) : parseFloat(val));
|
||||
rest = cont.substring(endcont + 1);
|
||||
break;
|
||||
case "a": // array
|
||||
if (cont.length < 4) {
|
||||
this.raiseError("array is too short", cont);
|
||||
return;
|
||||
}
|
||||
divpos = cont.indexOf(":", 1);
|
||||
if (divpos == -1) {
|
||||
this.raiseError("missing : for array", cont);
|
||||
return;
|
||||
}
|
||||
size = parseInt(cont.substring(0, divpos));
|
||||
cont = cont.substring(divpos + 2);
|
||||
val = new Array();
|
||||
if (cont.length < 1) {
|
||||
this.raiseError("array is too short", cont);
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < size; i++) {
|
||||
kret = this.unserialize(cont, 1);
|
||||
if (this.error || kret[0] == undefined || kret[1] == "") {
|
||||
this.raiseError("missing or invalid key, or missing value for array", cont);
|
||||
return;
|
||||
}
|
||||
vret = this.unserialize(kret[1], 1);
|
||||
if (this.error) {
|
||||
this.raiseError("invalid value for array", cont);
|
||||
return;
|
||||
}
|
||||
val[kret[0]] = vret[0];
|
||||
cont = vret[1];
|
||||
}
|
||||
if (cont.charAt(0) != "}") {
|
||||
this.raiseError("missing ending }, or too many values for array", cont);
|
||||
return;
|
||||
}
|
||||
rest = cont.substring(1);
|
||||
break;
|
||||
case "O": // object
|
||||
divpos = cont.indexOf(":");
|
||||
if (divpos == -1) {
|
||||
this.raiseError("missing : for object", cont);
|
||||
return;
|
||||
}
|
||||
size = parseInt(cont.substring(0, divpos));
|
||||
var objname = cont.substring(divpos + 2, divpos + 2 + size);
|
||||
if (cont.substring(divpos + 2 + size, divpos + 4 + size) != "\":") {
|
||||
this.raiseError("object name is too long, or missing \":", cont);
|
||||
return;
|
||||
}
|
||||
var objprops = this.unserialize("a:" + cont.substring(divpos + 4 + size), 1);
|
||||
if (this.error) {
|
||||
this.raiseError("invalid object properties", cont);
|
||||
return;
|
||||
}
|
||||
rest = objprops[1];
|
||||
var objout = "function " + objname + "(){";
|
||||
for (key in objprops[0]) {
|
||||
objout += "this." + key + "=objprops[0]['" + key + "'];";
|
||||
}
|
||||
objout += "}val=new " + objname + "();";
|
||||
eval(objout);
|
||||
break;
|
||||
default:
|
||||
this.raiseError("invalid input type", cont);
|
||||
}
|
||||
return (arguments.length == 1 ? val : [val, rest]);
|
||||
},
|
||||
// }}}
|
||||
// {{{ getError
|
||||
/**
|
||||
* Gets the last error message
|
||||
*
|
||||
* @return string the last error message from unserialize()
|
||||
*/
|
||||
getError: function() {
|
||||
return this.message + "\n" + this.cont;
|
||||
},
|
||||
// }}}
|
||||
// {{{ raiseError
|
||||
/**
|
||||
* Raises an eror (called by unserialize().)
|
||||
*
|
||||
* @param string message the error message
|
||||
* @param string cont the remaining unserialized content
|
||||
*/
|
||||
raiseError: function(message, cont) {
|
||||
this.error = 1;
|
||||
this.message = message;
|
||||
this.cont = cont;
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
// }}}
|
||||
|
||||
Reference in New Issue
Block a user