Procházet zdrojové kódy

added enum and class support.

Nicolas Cannasse před 19 roky
rodič
revize
fceb7f00ef
2 změnil soubory, kde provedl 125 přidání a 22 odebrání
  1. 45 2
      std/haxe/Serializer.hx
  2. 80 20
      std/haxe/Unserializer.hx

+ 45 - 2
std/haxe/Serializer.hx

@@ -56,6 +56,8 @@ class Serializer {
 		o : object
 		g : object end
 		r : reference
+		c : class
+		w : enum
 	*/
 
 	function serializeString( s : String ) {
@@ -80,6 +82,27 @@ class Serializer {
 		return false;
 	}
 
+	function serializeEnum(v : Dynamic) {
+		buf.add("w");
+		serialize(v.__enum__.__ename__);
+		#if neko
+		serializeString(new String(v.tag));
+		if( v.args == null )
+			buf.add(0);
+		else {
+			var l : Int = untyped __dollar__asize(v.args);
+			buf.add(l);
+			for( i in 0...l )
+				serialize(v.args[i]);
+		}
+		#else true
+		serializeString(v[0]);
+		buf.add(v.length - 1);
+		for( i in 1...v.length )
+			serialize(v[i]);
+		#end
+	}
+
 	public function serialize( v : Dynamic ) {
 		if( v == null ) {
 			buf.add("n");
@@ -112,6 +135,14 @@ class Serializer {
 		if( Std.is(v,Array) ) {
 			if( serializeRef(v) )
 				return;
+			#if neko
+			#else true
+			var e = v.__enum__;
+			if( e != null && e.__ename__ != null ) {
+				serializeEnum(v);
+				return;
+			}
+			#end
 			var ucount = 0;
 			buf.add("a");
 			for( i in 0...v.length ) {
@@ -149,8 +180,20 @@ class Serializer {
 			return;
 		if( Reflect.isFunction(v) )
 			throw "Cannot serialize function";
-
-		buf.add("o");
+		var c = v.__class__;
+		if( c != null && c.__name__ != null ) {
+			buf.add("c");
+			serialize(c.__name__);
+		} else {
+			#if neko
+			var e = v.__enum__;
+			if( e != null && e.__ename__ != null ) {
+				serializeEnum(v);
+				return;
+			}
+			#end
+			buf.add("o");
+		}
 		var fl = Reflect.fields(v);
 		for( f in fl ) {
 			serializeString(f);

+ 80 - 20
std/haxe/Unserializer.hx

@@ -42,15 +42,16 @@ class Unserializer {
  		var k = 0;
  		var s = false;
  		while( true ) {
- 			var c = buf.charCodeAt(pos) - 48;
- 			if( Std.isNaN(c) )
- 				break;
- 			if( c == -3 ) {
+ 			var c = buf.charCodeAt(pos);
+			if( c == null )
+				break;
+ 			if( c == 45 ) { // negative sign
  				s = true;
  				pos++;
  				continue;
  			}
- 			if( c < 0 || c >= 10 )
+			c -= 48;
+ 			if( c < 0 || c > 9 )
  				break;
  			k = k * 10 + c;
  			pos++;
@@ -60,6 +61,24 @@ class Unserializer {
  		return k;
  	}
 
+	function unserializeObject() : Dynamic {
+ 		var o = Reflect.empty();
+ 		cache.push(o);
+ 		while( true ) {
+ 			if( pos >= length )
+ 				throw "Invalid object";
+ 			if( buf.charCodeAt(pos) == 103 ) /*g*/
+ 				break;
+ 			var k = unserialize();
+ 			if( !Std.is(k,String) )
+ 				throw "Invalid object key";
+ 			var v = unserialize();
+ 			Reflect.setField(o,k,v);
+ 		}
+ 		pos++;
+ 		return o;
+	}
+
  	public function unserialize() : Dynamic {
  		switch( buf.charCodeAt(pos++) ) {
  		case 110: // n
@@ -124,21 +143,7 @@ class Unserializer {
  			pos++;
  			return a;
  		case 111: // o
- 			var o = Reflect.empty();
- 			cache.push(o);
- 			while( true ) {
- 				if( pos >= length )
- 					throw "Invalid object";
- 				if( buf.charCodeAt(pos) == 103 ) /*g*/
- 					break;
- 				var k = unserialize();
- 				if( !Std.is(k,String) )
- 					throw "Invalid object key";
- 				var v = unserialize();
- 				Reflect.setField(o,k,v);
- 			}
- 			pos++;
- 			return o;
+			return unserializeObject();
  		case 114: // r
  			var n = readDigits();
  			if( n < 0 || n >= cache.length )
@@ -146,6 +151,61 @@ class Unserializer {
  			return cache[n];
  		case 120: // x
 			throw unserialize();
+		case 99: // c
+			var a : Array<String> = unserialize();
+            if( !Std.is(a,Array) )
+				throw "Invalid class name";
+			for(s in a)
+				if( !Std.is(s,String) )
+					throw "Invalid class name";
+			var cl = Reflect.resolveClass(a);
+			if( cl == null )
+				throw "Class not found " + a.join(".");
+			var o = unserializeObject();
+			Reflect.setPrototype(o,cl.prototype);
+			return o;
+		case 119: // w
+			var a : Array<String> = unserialize();
+            if( !Std.is(a,Array) )
+				throw "Invalid enum name";
+			for(s in a)
+				if( !Std.is(s,String) )
+					throw "Invalid enum name";
+			var e = Reflect.resolveEnum(a);
+			if( e == null )
+				throw "Enum not found " + a.join(".");
+			var tag = unserialize();
+			if( !Std.is(tag,String) )
+				throw "Invalid enum tag";
+			var constr = Reflect.field(e,tag);
+			if( constr == null )
+				throw "Unknown enum tag "+a.join(".")+"."+tag;
+			var nargs = readDigits();
+			var args = null;
+			if( nargs > 0 ) {
+				args = new Array();
+				while( nargs > 0 ) {
+					args.push(unserialize());
+					nargs -= 1;
+				}
+			}
+			#if neko
+				var v = {
+					tag : untyped tag.__s,
+					__string : function() { return untyped neko.Boot.__enum_str(this); },
+					__enum__ : e
+				};
+				if( args != null )
+					untyped v.args = args.__a;
+				return v;
+			#else true
+				if( args == null )
+					args = [tag];
+				else
+					args.unshift(tag);
+				untyped args.__enum__ = e;
+				return args; 
+			#end
  		default:
  		}
  		pos--;