您的位置:首页 > Web前端 > JavaScript

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;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: