Flash ActionScript JSON 的一个源代码
2014-12-24 09:37
531 查看
转自:http://blog.sina.com.cn/s/blog_7cf671ed0100qdc8.html
Source Code: JSON.as package framework.json { import flash.utils.describeType; public final class JSON { public static function encode(object:*):String { return new JSONEncoder(object).encode(); } public static function decode(jsonString:String):* { return new JSONDecoder(jsonString).decode(); } internal static const TYPE_ARRAY:String = "Array"; internal static const TYPE_BOOLEAN:String = "Boolean"; internal static const TYPE_DATE:String = "Date"; internal static const TYPE_NUMBER:String = "Number"; internal static const TYPE_INT:String = "int"; internal static const TYPE_UINT:String = "uint"; internal static const TYPE_STRING:String = "String"; internal static const VALUE_NULL:String = "null"; internal static const VALUE_TRUE:String = "true"; internal static const VALUE_FALSE:String = "false"; internal static const SYMBOL_LEFT_BRACE:String = '{'; internal static const SYMBOL_RIGHT_BRACE:String = '}'; internal static const SYMBOL_LEFT_BRACKET:String = '['; internal static const SYMBOL_RIGHT_BRACKET:String = ']'; internal static const SYMBOL_COLON:String = ':'; internal static const SYMBOL_COMMA:String = ','; internal static const SYMBOL_QUOTE:String = '"'; internal static const SYMBOL_T:String = 't'; internal static const SYMBOL_F:String = 'f'; internal static const SYMBOL_CLASS:String = 'class'; internal static const WRITE_ONLY_FLAG:String = "writeonly"; internal static function getProperties(o:Object):XMLList { var typeDescription:XML = describeType(o); return typeDescription..accessor.(@access != WRITE_ONLY_FLAG) + typeDescription..variable; } public function JSON(privateJSON:PrivateJSON) {} } } class PrivateJSON {} JSONEncoder.as package framework.json { import flash.utils.getQualifiedClassName; internal final class JSONEncoder { private var _obj:*; public function JSONEncoder(object:*) { _obj = object; } public function encode():String { var r:String; if (_obj is String) r = encodeString(_obj as String); else if (_obj is Number) r = encodeNumber(_obj as Number); else if (_obj is Date) r = encodeDate(_obj as Date); else if (_obj is Boolean) r = encodeBoolean(_obj as Boolean); else if (_obj is Array) r = encodeArray(_obj as Array); else if (_obj is Object) r = encodeObject(_obj); else r = JSON.VALUE_NULL; return r; } private function encodeString(s:String):String { return JSON.SYMBOL_QUOTE + escape(s) + JSON.SYMBOL_QUOTE; } private function encodeNumber(n:Number):String { return isFinite(n) ? n.toString() : JSON.VALUE_NULL; } private function encodeBoolean(b:Boolean):String { return b ? JSON.VALUE_TRUE : JSON.VALUE_FALSE; } private function encodeDate(d:Date):String { return d.getTime().toString(); } private function encodeArray(a:Array):String { var r:String = JSON.SYMBOL_LEFT_BRACKET; if (a.length > 0) { for each (var v:* in a) { if (v != null) { if (v is String) r += encodeString(v as String); else if (v is Number) r += encodeNumber(v as Number); else if (v is Date) r += encodeDate(v as Date); else if (v is Boolean) r += encodeBoolean(v as Boolean); else if (v is Array) r += encodeArray(v as Array); else r += encodeObject(v); r += JSON.SYMBOL_COMMA; } } r = r.substr(0, r.length - 1); } return r + JSON.SYMBOL_RIGHT_BRACKET; } private function encodeObject(o:Object):String { var r:String = JSON.SYMBOL_LEFT_BRACE + JSON.SYMBOL_QUOTE + JSON.SYMBOL_CLASS + JSON.SYMBOL_QUOTE + JSON.SYMBOL_COLON + JSON.SYMBOL_QUOTE + escape(getQualifiedClassName(o).replace("::", ".")) + JSON.SYMBOL_QUOTE + JSON.SYMBOL_COMMA; var properties:XMLList = JSON.getProperties(o); var propertyName:String; var propertyType:String; var propertyValue:*; for each (var property:XML in properties) { propertyName = property.@name; propertyType = property.@type; propertyValue = o[propertyName]; r += JSON.SYMBOL_QUOTE; r += propertyName; r += JSON.SYMBOL_QUOTE; r += JSON.SYMBOL_COLON; if (propertyValue == null) r += JSON.VALUE_NULL; else { if (propertyType == JSON.TYPE_STRING) r += encodeString(propertyValue as String); else if ((propertyType == JSON.TYPE_NUMBER) || (propertyType == JSON.TYPE_INT) || (propertyType == JSON.TYPE_UINT)) r += encodeNumber(propertyValue as Number); else if (propertyType == JSON.TYPE_DATE) r += encodeDate(propertyValue as Date); else if (propertyType == JSON.TYPE_BOOLEAN) r += encodeBoolean(propertyValue as Boolean); else if (propertyType == JSON.TYPE_ARRAY) r += encodeArray(propertyValue as Array); else r += encodeObject(propertyValue); } r += JSON.SYMBOL_COMMA; } return r.substr(0, r.length - 1) + JSON.SYMBOL_RIGHT_BRACE; } } } JSONDecoder.as package framework.json { import flash.utils.getDefinitionByName; internal final class JSONDecoder { private var _jsonString:String; private var _jsonLength:int; private var _position:int; private var _currentChar:String; public function JSONDecoder(jsonString:String) { _jsonString = jsonString; _jsonLength = jsonString.length; _position = 0; nextChar(); skipWhiteSpace(); } public function decode():* { var s:String; var r:Object; switch(_currentChar) { case JSON.SYMBOL_LEFT_BRACE: r = parseObject(); break; case JSON.SYMBOL_LEFT_BRACKET: r = parseArray(); break; case JSON.SYMBOL_T: case JSON.SYMBOL_F: r = parseBoolean(); break; case JSON.SYMBOL_QUOTE: r = parseString(); break; default: r = parseNumber(); } if (r != null) r = convert(r); return r; } private function parseObject():Object { var r:Object = new Object(); var n:String; var i:int; nextChar(); while (!(_currentChar == JSON.SYMBOL_RIGHT_BRACE || _position >= _jsonLength)) { n = ""; while (_currentChar != JSON.SYMBOL_COLON) { if (_currentChar == JSON.SYMBOL_RIGHT_BRACE || _position >= _jsonLength) { nextChar(); return r; } n += _currentChar; nextChar(); } if ((i = n.lastIndexOf(JSON.SYMBOL_COMMA)) != -1) n = n.substr(i + 1); n = fixPropertyName(n); nextChar(); skipWhiteSpace(); switch (_currentChar) { case JSON.SYMBOL_QUOTE: r = parseString(); break; case JSON.SYMBOL_T: case JSON.SYMBOL_F: r = parseBoolean(); break; case JSON.SYMBOL_LEFT_BRACKET: r = parseArray(); break; case JSON.SYMBOL_LEFT_BRACE: r = parseObject(); break; case JSON.SYMBOL_COMMA: r = null; break; default: r = parseNumber(); } } nextChar(); return r; } private function parseArray():Array { var r:Array = new Array(); nextChar(); while (!(_currentChar == JSON.SYMBOL_RIGHT_BRACKET || _position >= _jsonLength)) { switch (_currentChar) { case JSON.SYMBOL_QUOTE: r.push(parseString()); break; case JSON.SYMBOL_T: case JSON.SYMBOL_F: r.push(parseBoolean()); break; case JSON.SYMBOL_LEFT_BRACKET: r.push(parseArray()); break; case JSON.SYMBOL_LEFT_BRACE: r.push(parseObject()); break; default: r.push(parseNumber()); } while (_currentChar != JSON.SYMBOL_COMMA) { if (_currentChar == JSON.SYMBOL_RIGHT_BRACKET || _position >= _jsonLength) { nextChar(); return r; } nextChar(); } nextChar(); skipWhiteSpace(); } nextChar(); return r; } private function parseNumber():Object { var r:Object; if (isDigit(_currentChar) || _currentChar == '-') r = readNumber(); return r; } private function parseBoolean():Object { var r:Object; var s:String = _currentChar + nextChar() + nextChar() + nextChar(); if (s == JSON.VALUE_TRUE) r = Boolean(true); else { s += nextChar(); if (s == JSON.VALUE_FALSE) r = Boolean(false); } return r; } private function parseString():Object { var r:Object; var idx:int = _jsonString.indexOf(JSON.SYMBOL_QUOTE, _position); if (idx == -1) _position = _jsonLength; else { r = (_jsonString.substring(_position, idx)); _position = idx + 1; } nextChar(); return r; } private function nextChar():String { return _currentChar = _jsonString.charAt(_position++); } private function skipWhiteSpace():void { while ((_currentChar == ' ') || (_currentChar == '\t') || (_currentChar == '\n') || (_currentChar == '\r')) { nextChar(); if (_position >= _jsonLength) break; } } private function readNumber():Object { var s:String = ""; if (_currentChar == '-') { s += _currentChar; nextChar(); } if (!isDigit(_currentChar)) return null; if (_currentChar == '0') { s += _currentChar; nextChar(); if (isDigit(_currentChar)) return null; } else { while (isDigit(_currentChar)) { s += _currentChar; nextChar(); } } if (_currentChar == '.') { s += _currentChar; nextChar(); if (!isDigit(_currentChar)) return null; while (isDigit(_currentChar)) { s += _currentChar; nextChar(); } } if (_currentChar == 'e' || _currentChar == 'E') { s += _currentChar; nextChar(); if (_currentChar == '+' || _currentChar == '-') { s += _currentChar; nextChar(); if (!isDigit(_currentChar)) return null; while (isDigit(_currentChar)) { s += _currentChar; nextChar(); } } } return Number(s); } private static function isDigit(ch:String):Boolean { return ( ch >= '0' && ch <= '9' ); } private static function fixPropertyName(name:String):String { var r:String = ""; var s:String; var loops:int = name.length; for (var i:int = 0; i < loops; i++) { s = name.charAt(i); if (!((s == ' ') || (s == '\t') || (s == '\n') || (s == '\r') || (s == '"') || (s == '\''))) r += s; } return r; } private static function convertArray(a:Array):Array { var r:Array = new Array(); for each (var e:* in a) { if ((e is String) || (e is Number) || (e is Date) || (e is Boolean)) r.push(e); else if (e is Array) r.push(convertArray(e)); else if (e is Object) r.push(convertObject(e)); } return r; } private static function convertObject(obj:Object):* { var r:Object; var clsName:String = obj[JSON.SYMBOL_CLASS]; if (clsName != null) { try { var clazz:Class = getDefinitionByName((clsName)) as Class; var o:Object = new clazz(); var properties:XMLList = JSON.getProperties(o); var propertyName:String; var propertyType:String; var propertyValue:*; var dateProperty:Date; for each (var property:XML in properties) { propertyName = property.@name; propertyType = property.@type; propertyValue = obj[propertyName]; if ((propertyType == JSON.TYPE_STRING) || (propertyType == JSON.TYPE_NUMBER) || (propertyType == JSON.TYPE_INT) || (propertyType == JSON.TYPE_UINT) || (propertyType == JSON.TYPE_BOOLEAN)) { o[propertyName] = propertyValue; } else if (propertyType == JSON.TYPE_DATE) { dateProperty = new Date(); dateProperty.setTime(propertyValue); o[propertyName] = dateProperty; } else if (propertyType == JSON.TYPE_ARRAY) { if (propertyValue != null) o[propertyName] = convertArray(propertyValue); } else { if (propertyValue != null) o[propertyName] = convertObject(propertyValue); } } r = o; } catch (e:Error) { trace(e); } } else r = obj; return r; } private static function convert(obj:Object):* { var r:Object; if ((obj is String) || (obj is Number) || (obj is Date) || (obj is Boolean)) r = obj; else if (obj is Array) r = convertArray(obj as Array); else if (obj is Object) r = convertObject(obj); else r = obj; return r; } } }
相关文章推荐
- 战速决Flash ActionScript 3.0 - 以文本形式、XML形式和JSON形式与ASP.NET通信续
- 积少成多Flash ActionScript 3.0(3) - 基础之以文本形式、XML形式和JSON形式与ASP.NET通信
- Flash ActionScript 3.0 - 以文本形式、XML形式和JSON形式与页面通信
- 积少成多Flash ActionScript 3.0(3) - 基础之以文本形式、XML形式和JSON形式与ASP.NET通信
- 【转载】战速决Flash ActionScript 3.0 - 以文本形式、XML形式和JSON形式与ASP.NET通信续
- Flash ActionScript (21)一个简单实用的loading代码
- C#与Flash ActionScript 2.0通过xml操作数据库(一)
- Flash Actionscript2.0 Astar 寻路类
- Flash Actionscript 2.0 在 FMS 中检测麦克风 摄像头状态的类
- Flash ActionScript视频教程
- Flash Actionscript 2.0中的函数与事件 之 函数类(Function Class)
- 做了个非常简单的Flash验证码(附源代码) 转载于http://www.cordyblog.cn/?action=show&amp;id=68
- Flash Action Script总结【非此即彼问题】
- Flash 8 ActionScript Bible (Bible)
- 一个Flash做的很漂亮的VISTA时钟(含源代码)
- 有关Flash ActionScript 3编程的总结
- 《Flash ActionScript 3 殿堂之路》读书笔记
- 关于Flash Actionscript脚本与HTML页面JavaScript脚本通讯的方法
- Reporting Services Step by Step 第七章Action一节源代码的一个小问题!
- ( Flash ActionScript)SharedObject类_01