wddx_mx.as
上传用户:lctyggxszx
上传日期:2022-06-30
资源大小:280k
文件大小:19k
- /*
- WDDX Serializer/Deserializer for Flash MX v1.0
- --------------------------------------------------
- Created by
- Branden Hall (bhall@figleaf.com)
- 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
- 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:
- myXML = new XML();
- foo = 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:
- myXML = new XML();
- //
- // XML is loaded here
- //
- foo = new WDDX();
- myObj = foo.deserialize(myXML);
-
- - Branden 9/30/00
- */
- //-------------------------------------------------------------------------------------------------
- // WddxRecordset object
- //-------------------------------------------------------------------------------------------------
- // WddxRecordset([flagPreserveFieldCase]) creates an empty recordset.
- // WddxRecordset(columns [, flagPreserveFieldCase]) creates a recordset
- // with a given set of columns provided as an array of strings.
- // WddxRecordset(columns, rows [, flagPreserveFieldCase]) creates a
- // recordset with these columns and some number of rows.
- // In all cases, flagPreserveFieldCase determines whether the exact case
- // of field names is preserved. If omitted, the default value is false
- // which means that all field names will be lowercased.
- _global.WddxRecordset = function () {
- // Add default properties
- this.preserveFieldCase = true;
- // Add extensions
- if (typeof (wddxRecordsetExtensions) == "object") {
- for (prop in wddxRecordsetExtensions) {
- // Hook-up method to WddxRecordset object
- this[prop] = wddxRecordsetExtensions[prop];
- }
- }
- // Perfom any needed initialization
- if (arguments.length>0) {
- if (typeof (val=arguments[0].valueOf()) == "boolean") {
- // Case preservation flag is provided as 1st argument
- this.preserveFieldCase = arguments[0];
- } else {
- // First argument is the array of column names
- var cols = arguments[0];
- // Second argument could be the length or the preserve case flag
- var nLen = 0;
- if (arguments.length>1) {
- if (typeof (val=arguments[1].valueOf()) == "boolean") {
- // Case preservation flag is provided as 2nd argument
- this.preserveFieldCase = arguments[1];
- } else {
- // Explicitly specified recordset length
- nLen = arguments[1];
- if (arguments.length>2) {
- // Case preservation flag is provided as 3rd argument
- this.preserveFieldCase = arguments[2];
- }
- }
- }
- for (var i = 0; i<cols.length; ++i) {
- var colValue = new Array(nLen);
- for (var j = 0; j<nLen; ++j) {
- colValue[j] = null;
- }
- this[this.preserveFieldCase ? cols[i] : cols[i].toLowerCase()] = colValue;
- }
- }
- }
- }
- // duplicate() returns a new copy of the current recordset
- wddxRecordset.prototype.duplicate = function(){
- copy = new WddxRecordset();
- for (i in this){
- if (i.toUpper() == "PRESERVEFIELDCASE"){
- copy[i] = this[i];
- }else{
- if (this[i].isColumn()){
- copy.addColumn(i);
- for (j in this[i]){
- copy.setField(j, i, this.getField(j, i));
- }
- }
- }
- }
- return (copy);
- }
- // isColumn(name) returns true/false based on whether this is a column name
- WddxRecordset.prototype.isColumn = function(name) {
- return (typeof (this[name]) == "object" && name.indexOf("_private_") == -1);
- }
- // getRowCount() returns the number of rows in the recordset
- WddxRecordset.prototype.getRowCount = function() {
- var nRowCount = 0;
- for (col in this) {
- if (this.isColumn(col)) {
- nRowCount = this[col].length;
- break;
- }
- }
- return nRowCount;
- }
- // addColumn(name) adds a column with that name and length == getRowCount()
- WddxRecordset.prototype.addColumn = function(name) {
- var nLen = this.getRowCount();
- var colValue = new Array(nLen);
- for (var i = 0; i<nLen; ++i) {
- colValue[i] = null;
- }
- this[this.preserveFieldCase ? name : name.toLowerCase()] = colValue;
- }
- // addRows() adds n rows to all columns of the recordset
- WddxRecordset.prototype.addRows = function(n) {
- for (col in this) {
- if (this.isColumn(col)) {
- var nLen = this[col].length;
- for (var i = nLen; i<nLen+n; ++i) {
- this[col][i] = "";
- }
- }
- }
- }
- // getField() returns the element in a given (row, col) position
- WddxRecordset.prototype.getField = function(row, col) {
- return this[this.preserveFieldCase ? col : col.toLowerCase()][row];
- }
- // setField() sets the element in a given (row, col) position to value
- WddxRecordset.prototype.setField = function (row, col, value) {
- this[this.preserveFieldCase ? col : col.toLowerCase()][row] = value;
- }
- // wddxSerialize() serializes a recordset
- // returns true/false
- WddxRecordset.prototype.wddxSerialize = function(serializer, node) {
- var colNamesList = "";
- var colNames = new Array();
- var i = 0;
- for (col in this) {
- if (this.isColumn(col)) {
- colNames[i++] = col;
- if (colNamesList.length>0) {
- colNamesList+=",";
- }
- colNamesList+=col;
- }
- }
- var nRows = this.getRowCount();
- node.appendChild((new XML()).createElement("recordset"));
- node.lastChild.attributes["rowCount"] = nRows;
- node.lastChild.attributes["fieldNames"] = colNamesList;
- var bSuccess = true;
- for (i=0; bSuccess && i<colNames.length; i++) {
- var name = colNames[i];
- node.lastChild.appendChild((new XML()).createElement("field"));
- node.lastChild.lastChild.attributes["name"] = name;
- for (var row = 0; bSuccess && row<nRows; row++) {
- bSuccess = serializer.serializeValue(this[name][row], node.lastChild.lastChild);
- }
- }
- return bSuccess;
- }
- //-------------------------------------------------------------------------------------------------
- // Wddx object
- //-------------------------------------------------------------------------------------------------
- // Base wddx object
- _global.Wddx = function() {
-
- // Build some tables needed for CDATA encoding
- var et = new Object();
- var etRev = new Object();
- var at = new Object();
- var atRev = new Object();
- 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] = "<char code='"+hex+"'/>";
- at[i] = "";
- } else if (i<128) {
- et[i] = chr(i);
- at[i] = chr(i);
- } else {
- et[i] = "&#x"+i.toString(16)+";";
- etRev["&#x"+i.toString(16)+";"] = chr(i);
- at[i] = "&#x"+i.toString(16)+";";
- atRev["&#x"+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["""] = """;
- this.et = et;
- this.at = at;
- this.atRev = atRev;
- this.etRev = etRev;
- // Deal with timezone offsets
- var tzOffset = (new Date()).getTimezoneOffset();
- if (tzOffset>=0) {
- this.timezoneString = "-";
- } else {
- this.timezoneString = "+";
- }
- this.timezoneString+=Math.floor(Math.abs(tzOffset)/60)+":"+(Math.abs(tzOffset)%60);
- this.preserveVarCase = true;
- this.useTimezoneInfo = true;
- }
- // Serialize a Flash object
- Wddx.prototype.serialize = function(rootObj) {
- delete(this.wddxPacket);
- var temp = new XML();
- this.packet = new XML();
- this.packet.appendChild(temp.createElement("wddxPacket"));
- this.wddxPacket = this.packet.firstChild;
- this.wddxPacket.attributes["version"] = "1.0";
- this.wddxPacket.appendChild(temp.createElement("header"));
- this.wddxPacket.appendChild(temp.createElement("data"));
- if (this.serializeValue(rootObj, this.wddxPacket.childNodes[1])) {
- return this.packet;
- } else {
- return null;
- }
- }
- // Determine the type of a Flash object and serialize it
- Wddx.prototype.serializeValue = function(obj, node) {
- var bSuccess = true;
- var val = obj.valueOf();
- var tzString = null;
- var temp = new XML();
- // null object
- if (obj == null) {
- node.appendChild(temp.createElement("null"));
- // string object
- } else if (typeof (val) == "string") {
- this.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 (this.useTimeZoneInfo) {
- tzString = this.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 = 0; bSuccess && i<obj.length; ++i) {
- bSuccess = this.serializeValue(obj[i], node.lastChild);
- }
- // generic object
- } else {
- node.appendChild(temp.createElement("struct"));
- if (typeof (obj.wddxSerializationType) == 'string') {
- node.lastChild.attributes["type"] = obj.wddxSerializationType;
- }
- for (prop in obj) {
- if (prop != 'wddxSerializationType') {
- bSuccess = this.serializeVariable(prop, obj[prop], node.lastChild);
- if (!bSuccess) {
- break;
- }
- }
- }
- }
- } else {
- // Error: undefined values or functions
- bSuccess = false;
- }
- // Successful serialization
- return bSuccess;
- }
- // Serialize a Flash varible
- Wddx.prototype.serializeVariable = function(name, obj, node) {
- var bSuccess = true;
- var temp = new XML();
- if (typeof (obj) != "function") {
- node.appendChild(temp.createElement("var"));
- node.lastChild.attributes["name"] = this.preserveVarCase ? this.serializeAttr(name) : this.serializeAttr(name.toLowerCase());
- bSuccess = this.serializeValue(obj, node.lastChild);
- }
- return bSuccess;
- }
- // Serialize a Flash String
- Wddx.prototype.serializeString = function(s, node) {
- var tempString;
- var temp = new XML();
- var max = s.length;
- node.appendChild(temp.createElement("string"));
- for (var i = 0; i<max; ++i) {
- var char = substring(s, i+1, 1);
- tempString+=(this.et[ord(substring(s, i+1, 1))]);
- }
- node.lastChild.appendChild(temp.createTextNode(tempString));
- }
- // Serialize attributes of a Flash variable
- Wddx.prototype.serializeAttr = function(s) {
- var tempString;
- var max = s.length;
- for (var i = 0; i<max; ++i) {
- tempString+=(this.at[ord(substring(s, i+1, 1))]);
- }
- return (tempString);
- }
- // wddx deserializer
- Wddx.prototype.deserialize = function(wddxPacket) {
- if (typeof(wddxPacket)!="object"){
- wddxPacket = new XML(wddxPacket);
- }
- var wddxRoot = new XML();
- var wddxChildren = new Array();
- var temp;
- var dataObj = new Object();
- // Get first node that is not Null
- while (wddxPacket.nodeName == null){
- wddxPacket = wddxPacket.firstChild;
- }
- wddxRoot = wddxPacket;
- if (wddxRoot.nodeName.toLowerCase() == "wddxpacket") {
- wddxChildren = wddxRoot.childNodes;
- temp = 0;
- // dig down until we find the data node or run out of nodes
- while (wddxChildren[temp].nodeName.toLowerCase() != "data" && temp<wddxChildren.length) {
- ++temp;
- }
-
- // if we found a data node then deserialize its contents
- if (temp<wddxChildren.length) {
- dataObj = this.deserializeNode(wddxChildren[temp].firstChild);
- return dataObj;
- } else {
- return null;
- }
- } else {
- return null;
- }
- }
- // deserialize a single node of a WDDX packet
- Wddx.prototype.deserializeNode = function (node) {
- // get the name of the node
- nodeType = node.nodeName.toLowerCase();
-
- // number node
- if (nodeType == "number") {
- var dataObj = node.firstChild.nodeValue;
- // dataObj.wddxSerializationType = "number";
- return Number(dataObj);
- // boolean node
- } else if (nodeType == "boolean") {
- var dataObj = (String(node.attributes.value).toLowerCase() == "true");
- // dataObj.wddxSerializationType = "boolean";
- return dataObj;
- // string node
- } else if (nodeType == "string") {
- var dataObj;
- if (node.childNodes.length > 1) {
- dataObj = ""
- var i = 0;
- for(i=0; i<node.childNodes.length; i++){
- if (node.childNodes[i].nodeType == 3){
- //this is a text node
- dataObj = dataObj + this.deserializeString(node.childNodes[i].nodeValue);
- } else if (node.childNodes[i].nodeName == 'char') {
- dataObj += chr(parseInt(node.childNodes[i].attributes["code"], 16));
- }
- }
- } else{
- dataObj = this.deserializeString(node.firstChild.nodeValue);
- }
- // dataObj.wddxSerializationType = "string";
- return dataObj;
- // array node
- } else if (nodeType == "array") {
- var dataObj = new Array();
- temp = 0;
- for (var i = 0; i<node.attributes["length"]; ++i) {
- dataObj[i] = this.deserializeNode(node.childNodes[i].cloneNode(true));
- }
- // dataObj.wddxSerializationType = "array";
- return dataObj;
- // datetime node
- } else if (nodeType == "datetime") {
- var dtString = node.firstChild.nodeValue;
- var tPos = dtString.indexOf("T");
- var tzPos = dtString.indexOf("+");
- var dateArray = new Array();
- var timeArray = new Array();
- var tzArray = new Array();
- var dataObj = new Date();
- if (tzPos == -1) {
- tzPos = dtString.lastIndexOf("-");
- if (tzPos<tPos) {
- tzPos = -1;
- }
- }
- // slice the datetime node value into the date, time, and timezone info
- dateArray = (dtString.slice(0, tPos)).split("-");
- timeArray = (dtString.slice(tPos+1,tzPos)).split(":");
- tzArray = (dtString.slice(tzPos)).split(":");
- // set the time and date of the object
- dataObj.setFullYear(parseInt(dateArray[0]), parseInt(dateArray[1])-1, parseInt(dateArray[2]));
- dataObj.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
- // deal with timezone offset if there is one
- if (tzPos != -1) {
- tzOffset = parseInt(tzArray[0])*60+parseInt(tzArray[1]);
- dataObj.setMinutes(dataObj.getMinutes()-(dataObj.getTimezoneOffset()+tzOffset));
- }
- // dataObj.wddxSerializationType = "datetime";
- return dataObj;
- // struct node
- } else if (nodeType == "struct") {
- var dataObj = new Object();
- for (var i = 0; i<node.childNodes.length; i++) {
- if (node.childNodes[i].nodeName.toLowerCase() == "var") {
- dataObj[this.deserializeAttr(node.childNodes[i].attributes["name"])] = this.deserializeNode(node.childNodes[i].firstChild);
- }
- }
- // dataObj.wddxSerializationType = "struct";
- return dataObj;
- // recordset node
- } else if (nodeType == "recordset") {
- var dataObj = new WddxRecordset((node.attributes["fieldNames"]).split(",").reverse(), parseInt(node.attributes["rowCount"]));
- for (var i = (node.childNodes.length-1); i>=0; i--) {
- if (node.childNodes[i].nodeName.toLowerCase() == "field") {
- var attr = 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();
- tempObj = this.deserializeNode(node.childNodes[i].childNodes[j]);
- dataObj.setField(j, attr, tempObj);
- }
- }
- }
- // dataObj.wddxSerializationType = "recordset";
- return dataObj;
- }
- }
- Wddx.prototype.deserializeAttr = function(attr){
- var max = attr.length;
- var i=0;
- var char;
- var output = "";
- while (i<max){
- char = substring(attr, i+1, 1);
- if (char == "&"){
- var buff = char;
- do{
- char = substring(attr, i+1, 1);
- buff += char;
- ++i;
- }while (char != ";");
- output += this.atRev[buff];
- }else{
- output += char;
- }
- ++i;
- }
- return output;
- }
- Wddx.prototype.deserializeString = function(str){
- var max = str.length;
- var i=0;
- var char;
- var output = "";
- while (i<max){
- char = substring(str, i+1, 1);
- if (char == "&"){
- var buff = char;
- do{
- ++i;
- char = substring(str, i+1, 1);
- buff += char;
- }while (char != ";");
- output += this.etRev[buff];
- }else{
- output += char;
- }
- ++i;
- }
- trace(output);
- return output;
- }