wddx_mx.as
上传用户:lctyggxszx
上传日期:2022-06-30
资源大小:280k
文件大小:19k
源码类别:

FlashMX/Flex源码

开发平台:

C#

  1. /*
  2. WDDX Serializer/Deserializer for Flash MX v1.0
  3. -------------------------------------------------- 
  4. Created by 
  5. Branden Hall (bhall@figleaf.com)
  6. Dave Gallerizzo (dgallerizzo@figleaf.com)
  7. Based on code by
  8. Simeon Simeonov (simeons@allaire.com)
  9. Nate Weiss (nweiss@icesinc.com)
  10. Version History:
  11. 8/10/2000 - First created
  12. 9/5/2000  - Minor bug fix to the deserializer
  13. 9/15/2000 - Commented out wddxserializetype creation in the 
  14.  deserializer as they are not needed in most cases.
  15. 9/21/2000 - Simplified the use of the deserializer. No longer need
  16.             to create the XML object yourself and the load and
  17. onLoad methods are part of the WDDX class.
  18. 9/30/2000 - Cleaned up code and removed load and onLoad methods.
  19. Updated sample code.
  20. 12/28/2000 - Added new duplicate method to WddxRecordset object
  21. 1/10/2001 - Fixed problem where serialization caused text to always drop to lower
  22. case. Thanks to Bill Tremblay for spotting this one!
  23. 1/17/2001 - Minor update to the serializer code so that it properly adds text nodes.
  24. Thanks for the catch from Carlos Mathews! 
  25. Also, the deserialization of primitive types now results in primitives 
  26. rather than instances of the object wrapper
  27. 1/20/2001 - Quick fix to the deserializer for recordsets so that for..in loops can get
  28. the elements of the recordset in the proper order.
  29. 2/5/2001  - Fix to the string deserialization so that it handles special characters 
  30. properly, thanks to Spike Washburn for this one!
  31. 11/9/2001 - Finished small optimizations, fixed encoding issues and fixed case preservation
  32. issue.
  33. 11/16/01  - (bkruse@macromedia.com)- put all WDDX classes in Object.WDDX namespace to fix
  34. scoping issues.
  35. 4/19/2002 - Fixed various small bugs with date and number serialization/deserialization
  36. 4/19/2002 - Removed WDDX classes from WDDX namespace and put into _global namespace
  37. Authors notes: 
  38. Serialization:
  39. - Create an instance of the wddx class
  40. - Call the serialize method, passing it the object your wish
  41.   to serialize, it will return an XML object filled with the
  42.   serialized object.
  43. Example:
  44. myXML = new XML();
  45. foo = new WDDX();
  46. myXML = foo.serialize(bar);
  47.  
  48. Deserializtion:
  49. - Get the XML you want to deserialize
  50. - Create an instance of the WDDX class
  51. - Call the serialize method of your WDDX
  52.   object and pass it your XML. It will return
  53.   the deserialized object.
  54. Example:
  55. myXML = new XML();
  56. //
  57. // XML is loaded here
  58. //
  59. foo = new WDDX();
  60. myObj = foo.deserialize(myXML);
  61. - Branden 9/30/00
  62. */
  63. //-------------------------------------------------------------------------------------------------
  64. //  WddxRecordset object
  65. //-------------------------------------------------------------------------------------------------
  66. //  WddxRecordset([flagPreserveFieldCase]) creates an empty recordset.
  67. //  WddxRecordset(columns [, flagPreserveFieldCase]) creates a recordset 
  68. //  with a given set of columns provided as an array of strings.
  69. //  WddxRecordset(columns, rows [, flagPreserveFieldCase]) creates a 
  70. //  recordset with these columns and some number of rows.
  71. //  In all cases, flagPreserveFieldCase determines whether the exact case
  72. //  of field names is preserved. If omitted, the default value is false
  73. //  which means that all field names will be lowercased.
  74. _global.WddxRecordset = function () {
  75. //  Add default properties
  76. this.preserveFieldCase = true;
  77. //  Add extensions
  78. if (typeof (wddxRecordsetExtensions) == "object") {
  79. for (prop in wddxRecordsetExtensions) {
  80. //  Hook-up method to WddxRecordset object
  81. this[prop] = wddxRecordsetExtensions[prop];
  82. }
  83. }
  84. //  Perfom any needed initialization
  85. if (arguments.length>0) {
  86. if (typeof (val=arguments[0].valueOf()) == "boolean") {
  87. //  Case preservation flag is provided as 1st argument
  88. this.preserveFieldCase = arguments[0];
  89. } else {
  90. //  First argument is the array of column names
  91. var cols = arguments[0];
  92. //  Second argument could be the length or the preserve case flag
  93. var nLen = 0;
  94. if (arguments.length>1) {
  95. if (typeof (val=arguments[1].valueOf()) == "boolean") {
  96. //  Case preservation flag is provided as 2nd argument
  97. this.preserveFieldCase = arguments[1];
  98. } else {
  99. //  Explicitly specified recordset length
  100. nLen = arguments[1];
  101. if (arguments.length>2) {
  102. //  Case preservation flag is provided as 3rd argument
  103. this.preserveFieldCase = arguments[2];
  104. }
  105. }
  106. }
  107. for (var i = 0; i<cols.length; ++i) {
  108. var colValue = new Array(nLen);
  109. for (var j = 0; j<nLen; ++j) {
  110. colValue[j] = null;
  111. }
  112. this[this.preserveFieldCase ? cols[i] : cols[i].toLowerCase()] = colValue;
  113. }
  114. }
  115. }
  116. }
  117. //  duplicate() returns a new copy of the current recordset
  118. wddxRecordset.prototype.duplicate = function(){
  119. copy = new WddxRecordset();
  120. for (i in this){
  121. if (i.toUpper() == "PRESERVEFIELDCASE"){
  122. copy[i] = this[i];
  123. }else{
  124. if (this[i].isColumn()){
  125. copy.addColumn(i);
  126. for (j in this[i]){
  127. copy.setField(j, i, this.getField(j, i));
  128. }
  129. }
  130. }
  131. }
  132. return (copy);
  133. }
  134. //  isColumn(name) returns true/false based on whether this is a column name
  135. WddxRecordset.prototype.isColumn = function(name) {
  136. return (typeof (this[name]) == "object" && name.indexOf("_private_") == -1);
  137. }
  138. //  getRowCount() returns the number of rows in the recordset
  139. WddxRecordset.prototype.getRowCount = function() {
  140. var nRowCount = 0;
  141. for (col in this) {
  142. if (this.isColumn(col)) {
  143. nRowCount = this[col].length;
  144. break;
  145. }
  146. }
  147. return nRowCount;
  148. }
  149. //  addColumn(name) adds a column with that name and length == getRowCount()
  150. WddxRecordset.prototype.addColumn = function(name) {
  151. var nLen = this.getRowCount();
  152. var colValue = new Array(nLen);
  153. for (var i = 0; i<nLen; ++i) {
  154. colValue[i] = null;
  155. }
  156. this[this.preserveFieldCase ? name : name.toLowerCase()] = colValue;
  157. }
  158. //  addRows() adds n rows to all columns of the recordset
  159. WddxRecordset.prototype.addRows = function(n) {
  160. for (col in this) {
  161. if (this.isColumn(col)) {
  162. var nLen = this[col].length;
  163. for (var i = nLen; i<nLen+n; ++i) {
  164. this[col][i] = "";
  165. }
  166. }
  167. }
  168. }
  169. //  getField() returns the element in a given (row, col) position
  170. WddxRecordset.prototype.getField = function(row, col) {
  171. return this[this.preserveFieldCase ? col : col.toLowerCase()][row];
  172. }
  173. //  setField() sets the element in a given (row, col) position to value
  174. WddxRecordset.prototype.setField = function (row, col, value) {
  175. this[this.preserveFieldCase ? col : col.toLowerCase()][row] = value;
  176. }
  177. //  wddxSerialize() serializes a recordset
  178. //  returns true/false
  179. WddxRecordset.prototype.wddxSerialize = function(serializer, node) {
  180. var colNamesList = "";
  181. var colNames = new Array();
  182. var i = 0;
  183. for (col in this) {
  184. if (this.isColumn(col)) {
  185. colNames[i++] = col;
  186. if (colNamesList.length>0) {
  187. colNamesList+=",";
  188. }
  189. colNamesList+=col;
  190. }
  191. }
  192. var nRows = this.getRowCount();
  193. node.appendChild((new XML()).createElement("recordset"));
  194. node.lastChild.attributes["rowCount"] = nRows;
  195. node.lastChild.attributes["fieldNames"] = colNamesList;
  196. var bSuccess = true;
  197. for (i=0; bSuccess && i<colNames.length; i++) {
  198. var name = colNames[i];
  199. node.lastChild.appendChild((new XML()).createElement("field"));
  200. node.lastChild.lastChild.attributes["name"] = name;
  201. for (var row = 0; bSuccess && row<nRows; row++) {
  202. bSuccess = serializer.serializeValue(this[name][row], node.lastChild.lastChild);
  203. }
  204. }
  205. return bSuccess;
  206. }
  207. //-------------------------------------------------------------------------------------------------
  208. //  Wddx object
  209. //-------------------------------------------------------------------------------------------------
  210. // Base wddx object
  211. _global.Wddx = function() {
  212. // Build some tables needed for CDATA encoding
  213. var et = new Object();
  214. var etRev = new Object();
  215. var at = new Object();
  216. var atRev = new Object();
  217. for (var i = 0; i<256; ++i) {
  218. if (i<32 && i != 9 && i != 10 && i != 13) {
  219. var hex = i.toString(16);
  220. if (hex.length == 1) {
  221. hex = "0"+hex;
  222. }
  223. et[i] = "<char code='"+hex+"'/>";
  224. at[i] = "";
  225. } else if (i<128) {
  226. et[i] = chr(i);
  227. at[i] = chr(i);
  228. } else {
  229. et[i] = "&#x"+i.toString(16)+";";
  230. etRev["&#x"+i.toString(16)+";"] = chr(i);
  231. at[i] = "&#x"+i.toString(16)+";";
  232. atRev["&#x"+i.toString(16)+";"] = chr(i);
  233. }
  234. }
  235. et[ord("<")] = "&lt;";
  236. et[ord(">")] = "&gt;";
  237. et[ord("&")] = "&amp;";
  238. etRev["&lt;"] = "<";
  239. etRev["&gt;"] = ">";
  240. etRev["&amp;"] = "&";
  241. at[ord("<")] = "&lt;";
  242. at[ord(">")] = "&gt;";
  243. at[ord("&")] = "&amp;";
  244. at[ord("'")] = "&apos;";
  245. at[ord(""")] = "&quot;";
  246. atRev["&lt;"] = "<";
  247. atRev["&gt;"] = ">";
  248. atRev["&amp;"] = "&";
  249. atRev["&apos;"] = "'";
  250. atRev["&quot;"] = """;
  251. this.et = et;
  252. this.at = at;
  253. this.atRev = atRev;
  254. this.etRev = etRev;
  255. // Deal with timezone offsets
  256. var tzOffset = (new Date()).getTimezoneOffset();
  257. if (tzOffset>=0) {
  258. this.timezoneString = "-";
  259. } else {
  260. this.timezoneString = "+";
  261. }
  262. this.timezoneString+=Math.floor(Math.abs(tzOffset)/60)+":"+(Math.abs(tzOffset)%60);
  263. this.preserveVarCase = true;
  264. this.useTimezoneInfo = true;
  265. }
  266. // Serialize a Flash object
  267. Wddx.prototype.serialize = function(rootObj) {
  268. delete(this.wddxPacket);
  269. var temp = new XML();
  270. this.packet = new XML();
  271. this.packet.appendChild(temp.createElement("wddxPacket"));
  272. this.wddxPacket = this.packet.firstChild;
  273. this.wddxPacket.attributes["version"] = "1.0";
  274. this.wddxPacket.appendChild(temp.createElement("header"));
  275. this.wddxPacket.appendChild(temp.createElement("data"));
  276. if (this.serializeValue(rootObj, this.wddxPacket.childNodes[1])) {
  277. return this.packet;
  278. } else {
  279. return null;
  280. }
  281. }
  282. // Determine the type of a Flash object and serialize it
  283. Wddx.prototype.serializeValue = function(obj, node) {
  284. var bSuccess = true;
  285. var val = obj.valueOf();
  286. var tzString = null;
  287. var temp = new XML();
  288. //  null object
  289. if (obj == null) {
  290. node.appendChild(temp.createElement("null"));
  291. // string object
  292. } else if (typeof (val) == "string") {
  293. this.serializeString(val, node);
  294. //  numeric objects (number or date)
  295. } else if (typeof (val) == "number") {
  296. //  date object
  297. if (typeof (obj.getTimezoneOffset) == "function") {
  298. //  deal with timezone offset if asked to
  299. if (this.useTimeZoneInfo) {
  300. tzString = this.timezoneString;
  301. }
  302. node.appendChild(temp.createElement("dateTime"));
  303. node.lastChild.appendChild(temp.createTextNode(obj.getFullYear()+"-"+(obj.getMonth()+1)+"-"+obj.getDate()+"T"+obj.getHours()+":"+obj.getMinutes()+":"+obj.getSeconds()+tzString));
  304. //  number object
  305. } else {
  306. node.appendChild((new XML()).createElement("number"));
  307. node.lastChild.appendChild((new XML()).createTextNode(val));
  308. }
  309. //  boolean object
  310. } else if (typeof (val) == "boolean") {
  311. node.appendChild(temp.createElement("boolean"));
  312. node.lastChild.attributes["value"] = val;
  313. //  actual objects
  314. } else if (typeof (obj) == "object") {
  315. //  if it has a built in serializer, use it
  316. if (typeof (obj.wddxSerialize) == "function") {
  317. bSuccess = obj.wddxSerialize(this, node);
  318. //  array object
  319. } else if (typeof (obj.join) == "function" && typeof (obj.reverse) == "function") {
  320. node.appendChild(temp.createElement("array"));
  321. node.lastChild.attributes["length"] = obj.length;
  322. for (var i = 0; bSuccess && i<obj.length; ++i) {
  323. bSuccess = this.serializeValue(obj[i], node.lastChild);
  324. }
  325. //  generic object
  326. } else {
  327. node.appendChild(temp.createElement("struct"));
  328. if (typeof (obj.wddxSerializationType) == 'string') {
  329. node.lastChild.attributes["type"] = obj.wddxSerializationType;
  330. }
  331. for (prop in obj) {
  332. if (prop != 'wddxSerializationType') {
  333. bSuccess = this.serializeVariable(prop, obj[prop], node.lastChild);
  334. if (!bSuccess) {
  335. break;
  336. }
  337. }
  338. }
  339. }
  340. } else {
  341. //  Error: undefined values or functions
  342. bSuccess = false;
  343. }
  344. //  Successful serialization
  345. return bSuccess;
  346. }
  347. // Serialize a Flash varible
  348. Wddx.prototype.serializeVariable = function(name, obj, node) {
  349. var bSuccess = true;
  350. var temp = new XML();
  351. if (typeof (obj) != "function") {
  352. node.appendChild(temp.createElement("var"));
  353. node.lastChild.attributes["name"] = this.preserveVarCase ? this.serializeAttr(name) : this.serializeAttr(name.toLowerCase());
  354. bSuccess = this.serializeValue(obj, node.lastChild);
  355. }
  356. return bSuccess;
  357. }
  358. // Serialize a Flash String
  359. Wddx.prototype.serializeString = function(s, node) {
  360. var tempString;
  361. var temp = new XML();
  362. var max = s.length;
  363. node.appendChild(temp.createElement("string"));
  364. for (var i = 0; i<max; ++i) {
  365. var char = substring(s, i+1, 1);
  366. tempString+=(this.et[ord(substring(s, i+1, 1))]);
  367. }
  368. node.lastChild.appendChild(temp.createTextNode(tempString));
  369. }
  370. // Serialize attributes of a Flash variable
  371. Wddx.prototype.serializeAttr = function(s) {
  372. var tempString;
  373. var max = s.length;
  374. for (var i = 0; i<max; ++i) {
  375. tempString+=(this.at[ord(substring(s, i+1, 1))]);
  376. }
  377. return (tempString);
  378. }
  379. // wddx deserializer
  380. Wddx.prototype.deserialize = function(wddxPacket) {
  381. if (typeof(wddxPacket)!="object"){
  382. wddxPacket = new XML(wddxPacket);
  383. }
  384. var wddxRoot = new XML();
  385. var wddxChildren = new Array();
  386. var temp;
  387. var dataObj = new Object();
  388. // Get first node that is not Null
  389. while (wddxPacket.nodeName == null){
  390. wddxPacket = wddxPacket.firstChild;
  391. }
  392. wddxRoot  = wddxPacket; 
  393. if (wddxRoot.nodeName.toLowerCase() == "wddxpacket") {
  394. wddxChildren = wddxRoot.childNodes;
  395. temp = 0;
  396. // dig down until we find the data node or run out of nodes
  397. while (wddxChildren[temp].nodeName.toLowerCase() != "data" && temp<wddxChildren.length) {
  398. ++temp;
  399. }
  400. // if we found a data node then deserialize its contents
  401. if (temp<wddxChildren.length) {
  402. dataObj = this.deserializeNode(wddxChildren[temp].firstChild);
  403. return dataObj;
  404. } else {
  405. return null;
  406. }
  407. } else {
  408. return null;
  409. }
  410. }
  411. // deserialize a single node of a WDDX packet
  412. Wddx.prototype.deserializeNode = function (node) {
  413. // get the name of the node
  414. nodeType = node.nodeName.toLowerCase();
  415. // number node 
  416. if (nodeType == "number") {
  417. var dataObj = node.firstChild.nodeValue;
  418. // dataObj.wddxSerializationType = "number";
  419. return Number(dataObj);
  420. // boolean node
  421. } else if (nodeType == "boolean") {
  422. var dataObj = (String(node.attributes.value).toLowerCase() == "true");
  423. // dataObj.wddxSerializationType = "boolean";
  424. return dataObj;
  425. // string node
  426. } else if (nodeType == "string") {
  427. var dataObj;
  428. if (node.childNodes.length > 1) {
  429. dataObj = ""
  430. var i = 0;
  431. for(i=0; i<node.childNodes.length; i++){
  432. if (node.childNodes[i].nodeType == 3){
  433. //this is a text node
  434. dataObj = dataObj + this.deserializeString(node.childNodes[i].nodeValue);
  435. } else if (node.childNodes[i].nodeName == 'char') {
  436. dataObj += chr(parseInt(node.childNodes[i].attributes["code"], 16));
  437. }   
  438. }
  439. } else{
  440. dataObj = this.deserializeString(node.firstChild.nodeValue);
  441. }
  442. // dataObj.wddxSerializationType = "string";
  443. return dataObj;
  444. // array node
  445. } else if (nodeType == "array") {
  446. var dataObj = new Array();
  447. temp = 0;
  448. for (var i = 0; i<node.attributes["length"]; ++i) {
  449. dataObj[i] = this.deserializeNode(node.childNodes[i].cloneNode(true));
  450. }
  451. // dataObj.wddxSerializationType = "array";
  452. return dataObj;
  453. // datetime node
  454. } else if (nodeType == "datetime") {
  455. var dtString = node.firstChild.nodeValue;
  456. var tPos = dtString.indexOf("T");
  457. var tzPos = dtString.indexOf("+");
  458. var dateArray = new Array();
  459. var timeArray = new Array();
  460. var tzArray = new Array();
  461. var dataObj = new Date();
  462. if (tzPos == -1) {
  463. tzPos = dtString.lastIndexOf("-");
  464. if (tzPos<tPos) {
  465. tzPos = -1;
  466. }
  467. }
  468. // slice the datetime node value into the date, time, and timezone info
  469. dateArray = (dtString.slice(0, tPos)).split("-");
  470. timeArray = (dtString.slice(tPos+1,tzPos)).split(":");
  471. tzArray = (dtString.slice(tzPos)).split(":");
  472. // set the time and date of the object
  473. dataObj.setFullYear(parseInt(dateArray[0]), parseInt(dateArray[1])-1, parseInt(dateArray[2]));
  474. dataObj.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
  475. // deal with timezone offset if there is one
  476. if (tzPos != -1) {
  477. tzOffset = parseInt(tzArray[0])*60+parseInt(tzArray[1]);
  478. dataObj.setMinutes(dataObj.getMinutes()-(dataObj.getTimezoneOffset()+tzOffset));
  479. }
  480. // dataObj.wddxSerializationType = "datetime";
  481. return dataObj;
  482. // struct node
  483. } else if (nodeType == "struct") {
  484. var dataObj = new Object();
  485. for (var i = 0; i<node.childNodes.length; i++) {
  486. if (node.childNodes[i].nodeName.toLowerCase() == "var") {
  487. dataObj[this.deserializeAttr(node.childNodes[i].attributes["name"])] = this.deserializeNode(node.childNodes[i].firstChild);
  488. }
  489. }
  490. // dataObj.wddxSerializationType = "struct";
  491. return dataObj;
  492. // recordset node
  493. } else if (nodeType == "recordset") {
  494. var dataObj = new WddxRecordset((node.attributes["fieldNames"]).split(",").reverse(), parseInt(node.attributes["rowCount"]));
  495. for (var i = (node.childNodes.length-1); i>=0; i--) {
  496. if (node.childNodes[i].nodeName.toLowerCase() == "field") {
  497. var attr = this.deserializeAttr(node.childNodes[i].attributes["name"])
  498. dataObj[attr].wddxSerializationType = "field";
  499. for (var j = (node.childNodes[i].childNodes.length-1); j>=0; j--) {
  500. dataObj[attr][j] = new Object();
  501. tempObj = this.deserializeNode(node.childNodes[i].childNodes[j]);
  502. dataObj.setField(j, attr, tempObj);
  503. }
  504. }
  505. }
  506. // dataObj.wddxSerializationType = "recordset";
  507. return dataObj;
  508. }
  509. }
  510. Wddx.prototype.deserializeAttr = function(attr){
  511. var max = attr.length;
  512. var i=0;
  513. var char;
  514. var output = "";
  515. while (i<max){
  516. char  = substring(attr, i+1, 1);
  517. if (char == "&"){
  518. var buff = char;
  519. do{
  520. char  = substring(attr, i+1, 1);
  521. buff += char;
  522. ++i;
  523. }while (char != ";");
  524. output += this.atRev[buff];
  525. }else{
  526. output += char;
  527. }
  528. ++i;
  529. }
  530. return output;
  531. }
  532. Wddx.prototype.deserializeString = function(str){
  533. var max = str.length;
  534. var i=0;
  535. var char;
  536. var output = "";
  537. while (i<max){
  538. char  = substring(str, i+1, 1);
  539. if (char == "&"){
  540. var buff = char;
  541. do{
  542. ++i;
  543. char  = substring(str, i+1, 1);
  544. buff += char;
  545. }while (char != ";");
  546. output += this.etRev[buff];
  547. }else{
  548. output += char;
  549. }
  550. ++i;
  551. }
  552. trace(output);
  553. return output;
  554. }