/*
Wddx Serializer/Deserializer for Flash MX 2004 v1.0
Coded to work with ActionScript 2.0
--------------------------------------------------
Created by
Branden Hall (bhall@waxpraxis.org)
Dave Gallerizzo (dgallerizzo@figleaf.com)
Based on code by
Simeon Simeonov (simeons@allaire.com)
Nate Weiss (nweiss@icesinc.com)
Version History:
8/10/2000 - First created
9/5/2000 - Minor bug fix to the deserializer
9/15/2000 - Commented out Wddxserializetype creation in the
deserializer as they are not needed in most cases.
9/21/2000 - Simplified the use of the deserializer. No longer need
to create the XML object yourself and the load and
onLoad methods are part of the Wddx class.
9/30/2000 - Cleaned up code and removed load and onLoad methods.
Updated sample code.
12/28/2000 - Added new duplicate method to WddxRecordset object
1/10/2001 - Fixed problem where serialization caused text to always drop to lower
case. Thanks to Bill Tremblay for spotting this one!
1/17/2001 - Minor update to the serializer code so that it properly adds text nodes.
Thanks for the catch from Carlos Mathews!
Also, the deserialization of primitive types now results in primitives
rather than instances of the object wrapper
1/20/2001 - Quick fix to the deserializer for recordsets so that for..in loops can get
the elements of the recordset in the proper order.
2/5/2001 - Fix to the string deserialization so that it handles special characters
properly, thanks to Spike Washburn for this one!
11/9/2001 - Finished small optimizations, fixed encoding issues and fixed case preservation
issue.
11/16/01 - (bkruse@macromedia.com)- put all Wddx classes in Object.Wddx namespace to fix
scoping issues.
4/19/2002 - Fixed various small bugs with date and number serialization/deserialization
4/19/2002 - Removed Wddx classes from Wddx namespace and put into _global namespace
9/11/2003 - Converted to AS 2.0 by Jobe Makar. Divided into two classes: Wddx and WddxRecordset
Authors notes:
Serialization:
- Create an instance of the Wddx class
- Call the serialize method, passing it the object your wish
to serialize, it will return an XML object filled with the
serialized object.
Example:
var myXML:XML;
var foo:Wddx = new Wddx();
myXML = foo.serialize(bar);
Deserializtion:
- Get the XML you want to deserialize
- Create an instance of the Wddx class
- Call the serialize method of your Wddx
object and pass it your XML. It will return
the deserialized object.
Example:
var myXML:XML = new XML();
//
// XML is loaded here
//
var foo:Wddx = new Wddx();
var myObj:Object = foo.deserialize(myXML);
- Branden 9/30/00
*/
class Wddx {
// Build some tables needed for CDATA encoding
var et:Object = new Object();
var etRev:Object = new Object();
var at:Object = new Object();
var atRev:Object = new Object();
var timezoneString:String;
var preserveVarCase:Boolean = true;
var useTimezoneInfo:Boolean = true;
var packet:XML;
var wddxPacket:XMLNode;
var useTimeZoneInfo:String;
var tzOffset:Number;
function Wddx() {
for (var i = 0; i<256; ++i) {
if (i<32 && i != 9 && i != 10 && i != 13) {
var hex = i.toString(16);
if (hex.length == 1) {
hex = "0"+hex;
}
et[i] = "";
at[i] = "";
} else if (i<128) {
et[i] = chr(i);
at[i] = chr(i);
} else {
et[i] = ""+i.toString(16)+";";
etRev[""+i.toString(16)+";"] = chr(i);
at[i] = ""+i.toString(16)+";";
atRev[""+i.toString(16)+";"] = chr(i);
}
}
et[ord("<")] = "<";
et[ord(">")] = ">";
et[ord("&")] = "&";
etRev["<"] = "<";
etRev[">"] = ">";
etRev["&"] = "&";
at[ord("<")] = "<";
at[ord(">")] = ">";
at[ord("&")] = "&";
at[ord("'")] = "'";
at[ord("\"")] = """;
atRev["<"] = "<";
atRev[">"] = ">";
atRev["&"] = "&";
atRev["'"] = "'";
atRev["""] = "\"";
// Deal with timezone offsets
tzOffset = (new Date()).getTimezoneOffset();
if (tzOffset>=0) {
timezoneString = "-";
} else {
timezoneString = "+";
}
timezoneString += Math.floor(Math.abs(tzOffset)/60)+":"+(Math.abs(tzOffset)%60);
}
// Serialize a Flash object
function serialize(rootObj) {
delete wddxPacket;
var temp:XML = new XML();
packet = new XML();
packet.appendChild(temp.createElement("wddxPacket"));
wddxPacket = packet.firstChild;
wddxPacket.attributes["version"] = "1.0";
wddxPacket.appendChild(temp.createElement("header"));
wddxPacket.appendChild(temp.createElement("data"));
if (serializeValue(rootObj, wddxPacket.childNodes[1])) {
return packet;
} else {
return null;
}
}
// Determine the type of a Flash object and serialize it
function serializeValue(obj, node) {
var bSuccess:Boolean = true;
var val:String = obj.valueOf();
var tzString = null;
var temp:XML = new XML();
// null object
if (obj == null) {
node.appendChild(temp.createElement("null"));
// string object
} else if (typeof (val) == "string") {
serializeString(val, node);
// numeric objects (number or date)
} else if (typeof (val) == "number") {
// date object
if (typeof (obj.getTimezoneOffset) == "function") {
// deal with timezone offset if asked to
if (useTimeZoneInfo) {
tzString = timezoneString;
}
node.appendChild(temp.createElement("dateTime"));
node.lastChild.appendChild(temp.createTextNode(obj.getFullYear()+"-"+(obj.getMonth()+1)+"-"+obj.getDate()+"T"+obj.getHours()+":"+obj.getMinutes()+":"+obj.getSeconds()+tzString));
// number object
} else {
node.appendChild((new XML()).createElement("number"));
node.lastChild.appendChild((new XML()).createTextNode(val));
}
// boolean object
} else if (typeof (val) == "boolean") {
node.appendChild(temp.createElement("boolean"));
node.lastChild.attributes["value"] = val;
// actual objects
} else if (typeof (obj) == "object") {
// if it has a built in serializer, use it
if (typeof (obj.wddxSerialize) == "function") {
bSuccess = obj.wddxSerialize(this, node);
// array object
} else if (typeof (obj.join) == "function" && typeof (obj.reverse) == "function") {
node.appendChild(temp.createElement("array"));
node.lastChild.attributes["length"] = obj.length;
for (var i:Number = 0; bSuccess && i1) {
dataObj = "";
var i:Number = 0;
for (i=0; i=0; i--) {
if (node.childNodes[i].nodeName.toLowerCase() == "field") {
var attr:Object = this.deserializeAttr(node.childNodes[i].attributes["name"]);
dataObj[attr].wddxSerializationType = "field";
for (var j = (node.childNodes[i].childNodes.length-1); j>=0; j--) {
dataObj[attr][j] = new Object();
var tempObj:Object = this.deserializeNode(node.childNodes[i].childNodes[j]);
dataObj.setField(j, attr, tempObj);
}
}
}
// dataObj.wddxSerializationType = "recordset";
return dataObj;
}
}
function deserializeAttr(attr) {
var max:Number = attr.length;
var i:Number = 0;
var char:String;
var output:String = "";
while (i