added constant_t implementation
authorkramm <kramm>
Mon, 24 Nov 2008 16:16:21 +0000 (16:16 +0000)
committerkramm <kramm>
Mon, 24 Nov 2008 16:16:21 +0000 (16:16 +0000)
lib/as3/pool.c
lib/as3/pool.h

index d624c37..7aa34ac 100644 (file)
@@ -555,6 +555,7 @@ char* multiname_to_string(multiname_t*m)
     } else {
         fprintf(stderr, "Invalid multiname type: %02x\n", m->type);
     }
+    free(name);
     return mname;
 }
 
@@ -616,6 +617,171 @@ type_t multiname_type = {
     equals: (equals_func)multiname_equals
 };
 
+
+// ------------------------------- constants -------------------------------------
+
+#define NS_TYPE(x) ((x) == 0x08 || (x) == 0x16 || (x) == 0x17 || (x) == 0x18 ||  \
+                                   (x) == 0x19 || (x) == 0x1a || (x) == 0x05)
+
+#define UNIQUE_CONSTANT(x) ((x) == CONSTANT_TRUE || (x) == CONSTANT_FALSE || (x) == CONSTANT_NULL || (x) == CONSTANT_UNDEFINED)
+
+constant_t* constant_new_int(int i) 
+{
+    NEW(constant_t,c);
+    c->i = i;
+    c->type = CONSTANT_INT;
+    return c;
+}
+constant_t* constant_new_uint(unsigned int u)
+{
+    NEW(constant_t,c);
+    c->u = u;
+    c->type = CONSTANT_UINT;
+    return c;
+}
+constant_t* constant_new_float(double f)
+{
+    NEW(constant_t,c);
+    c->f = f;
+    c->type = CONSTANT_FLOAT;
+    return c;
+}
+constant_t* constant_new_string(char*s)
+{
+    NEW(constant_t,c);
+    c->s = strdup(s);
+    c->type = CONSTANT_STRING;
+    return c;
+}
+constant_t* constant_new_namespace(namespace_t*ns)
+{
+    NEW(constant_t,c);
+    c->ns = namespace_clone(ns);
+    c->type = ns->access;
+    assert(NS_TYPE(c->type));
+    return c;
+}
+constant_t* constant_new_true()
+{
+    NEW(constant_t,c);
+    c->type = CONSTANT_TRUE;
+    return c;
+}
+constant_t* constant_new_false()
+{
+    NEW(constant_t,c);
+    c->type = CONSTANT_FALSE;
+    return c;
+}
+constant_t* constant_new_null()
+{
+    NEW(constant_t,c);
+    c->type = CONSTANT_NULL;
+    return c;
+}
+constant_t* constant_new_undefined()
+{
+    NEW(constant_t,c);
+    c->type = CONSTANT_UNDEFINED;
+    return c;
+}
+constant_t* constant_fromindex(pool_t*pool, int index, int type)
+{
+    if(!index) {
+        /* even for nonvalued constants (like TRUE/FALSE etc.), a nonzero
+           index is present to indicate that a type is coming */
+        return 0;
+    } 
+    NEW(constant_t,c);
+    c->type = type;
+    if(NS_TYPE(c->type)) {
+        c->ns =  pool_lookup_namespace(pool, index);
+    } else if(c->type == CONSTANT_INT) {
+        c->i =  pool_lookup_int(pool, index);
+    } else if(c->type == CONSTANT_UINT) {
+        c->u =  pool_lookup_uint(pool, index);
+    } else if(c->type == CONSTANT_FLOAT) {
+        c->f =  pool_lookup_float(pool, index);
+    } else if(c->type == CONSTANT_STRING) {
+        c->s =  pool_lookup_string(pool, index);
+    } else if(UNIQUE_CONSTANT(c->type)) {
+        // ok
+    } else {
+        fprintf(stderr, "invalid constant type %02x\n", c->type);
+    }
+    return c;
+}
+char* constant_to_string(constant_t*c)
+{
+    if(!c)
+        return 0;
+    char buf[30];
+    if(NS_TYPE(c->type)) {
+        return namespace_to_string(c->ns);
+    } else if(c->type == CONSTANT_INT) {
+        sprintf(buf, "%d", c->i);
+        return strdup(buf);
+    } else if(c->type == CONSTANT_UINT) {
+        sprintf(buf, "%u", c->u);
+        return strdup(buf);
+    } else if(c->type == CONSTANT_FLOAT) {
+        sprintf(buf, "%f", c->f);
+        return strdup(buf);
+    } else if(c->type == CONSTANT_STRING) {
+        return strdup(c->s);
+    } else if(c->type == CONSTANT_TRUE) {
+        return strdup("true");
+    } else if(c->type == CONSTANT_FALSE) {
+        return strdup("false");
+    } else if(c->type == CONSTANT_NULL) {
+        return strdup("null");
+    } else if(c->type == CONSTANT_UNDEFINED) {
+        return strdup("undefined");
+    } else {
+        fprintf(stderr, "invalid constant type %02x\n", c->type);
+        return 0;
+    }
+}
+char constant_has_index(constant_t*c) 
+{
+    if(!c)
+        return 0;
+    return !UNIQUE_CONSTANT(c->type);
+}
+int constant_get_index(pool_t*pool, constant_t*c)
+{
+    if(!c)
+        return 0;
+    if(NS_TYPE(c->type)) {
+        assert(c->ns);
+        assert(c->type == c->ns->access);
+        return pool_register_namespace(pool, c->ns);
+    } else if(c->type == CONSTANT_INT) {
+        return pool_register_int(pool, c->i);
+    } else if(c->type == CONSTANT_UINT) {
+        return pool_register_uint(pool, c->u);
+    } else if(c->type == CONSTANT_FLOAT) {
+        return pool_register_float(pool, c->f);
+    } else if(c->type == CONSTANT_STRING) {
+        return pool_register_string(pool, c->s);
+    } else if(!constant_has_index(c)) {
+        return 1;
+    } else {
+        fprintf(stderr, "invalid constant type %02x\n", c->type);
+        return 0;
+    }
+}
+void constant_free(constant_t*c)
+{
+    if(!c)
+        return;
+    if(c->type == CONSTANT_STRING) {
+        free(c->s);c->s=0;
+    } else if (NS_TYPE(c->type)) {
+        namespace_destroy(c->ns);c->ns=0;
+    }
+    free(c);
+}
 // ------------------------------- pool -------------------------------------
 
 int pool_register_uint(pool_t*p, unsigned int i)
@@ -858,8 +1024,8 @@ void pool_read(pool_t*pool, TAG*tag)
     for(t=1;t<num_namespaces;t++) {
        U8 type = swf_GetU8(tag);
        int namenr = swf_GetU30(tag);
-       const char*name = ""; 
-        if(namenr) //spec page 22: "a value of zero denotes an empty string"
+       const char*name = 0; 
+        if(namenr)
             name = array_getkey(pool->x_strings, namenr);
         namespace_t*ns = namespace_new(type, name);
        array_append(pool->x_namespaces, ns, 0);
@@ -917,12 +1083,6 @@ void pool_read(pool_t*pool, TAG*tag)
         DEBUG printf("multiname %d) %s\n", t, multiname_to_string(&m));
        array_append(pool->x_multinames, &m, 0);
     }
-    printf("%d ints\n", num_ints);
-    printf("%d uints\n", num_uints);
-    printf("%d strings\n", num_strings);
-    printf("%d namespaces\n", num_namespaces);
-    printf("%d namespace sets\n", num_sets);
-    printf("%d multinames\n", num_multinames);
 } 
 
 void pool_write(pool_t*pool, TAG*tag)
@@ -954,10 +1114,17 @@ void pool_write(pool_t*pool, TAG*tag)
     }
     for(t=1;t<pool->x_namespaces->num;t++) {
        namespace_t*ns= (namespace_t*)array_getkey(pool->x_namespaces, t);
-        if(ns->name && ns->name[0])
-            array_append_if_new(pool->x_strings, ns->name, 0);
+        /*  The spec says (page 22): "a value of zero denotes an empty string".
+            However when actually using zero strings as empty namespaces, the
+            flash player breaks.*/
+        //if(ns->name && ns->name[0])
+        array_append_if_new(pool->x_strings, ns->name, 0);
     }
 
+    //pool_register_int(pool, 15);
+    //pool_register_int(pool, 1);
+    //pool_register_int(pool, 0);
+    
     /* write data */
     swf_SetU30(tag, pool->x_ints->num>1?pool->x_ints->num:0);
     for(t=1;t<pool->x_ints->num;t++) {
@@ -970,8 +1137,8 @@ void pool_write(pool_t*pool, TAG*tag)
     }
     swf_SetU30(tag, pool->x_floats->num>1?pool->x_floats->num:0);
     for(t=1;t<pool->x_floats->num;t++) {
-        array_getvalue(pool->x_floats, t);
-        swf_SetD64(tag, 0.0); // fixme
+        double d = pool_lookup_float(pool, t);
+        swf_SetD64(tag, d);
     }
     swf_SetU30(tag, pool->x_strings->num>1?pool->x_strings->num:0);
     for(t=1;t<pool->x_strings->num;t++) {
@@ -983,8 +1150,10 @@ void pool_write(pool_t*pool, TAG*tag)
        swf_SetU8(tag, ns->access);
        const char*name = ns->name;
        int i = 0;
-        if(name && name[0])
-            i = pool_find_string(pool, name);
+        
+        //if(name && name[0])
+        i = pool_find_string(pool, name);
+
        swf_SetU30(tag, i);
     }
     swf_SetU30(tag, pool->x_namespace_sets->num>1?pool->x_namespace_sets->num:0);
index 52df041..504ca5e 100644 (file)
@@ -28,6 +28,8 @@
 #include "../rfxswf.h"
 
 DECLARE(pool);
+DECLARE(constant);
+DECLARE_LIST(constant);
 DECLARE(multiname);
 DECLARE(namespace);
 DECLARE(namespace_set);
@@ -46,16 +48,74 @@ struct _pool {
     array_t*x_multinames;
 };
 
+typedef enum access_type
+{ACCESS_STANDARD=0x16,
+ ACCESS_PACKAGE=0x16,
+ ACCESS_PACKAGEINTERNAL=0x17,
+ ACCESS_PROTECTED=0x18,
+ ACCESS_EXPLICIT=0x19,
+ ACCESS_STATICPROTECTED=0x1a,
+ ACCESS_PRIVATE=0x05
+} access_type_t;
+
+
+typedef enum constant_type
+{
+CONSTANT_STRING=0x01,
+CONSTANT_INT=0x03,
+CONSTANT_UINT=0x04,
+CONSTANT_FLOAT=0x06,
+CONSTANT_TRUE=0x0B,
+CONSTANT_FALSE=0x0A,
+CONSTANT_NULL=0x0C,
+CONSTANT_UNDEFINED=0x00,
+CONSTANT_NAMESPACE=0x08,
+CONSTANT_NAMESPACE_PACKAGE=0x16,
+CONSTANT_NAMESPACE_PACKAGEINTERNAL=0x17,
+CONSTANT_NAMESPACE_PROTECTED=0x18,
+CONSTANT_NAMESPACE_EXPLICIT=0x19,
+CONSTANT_NAMESPACE_STATICPROTECTED=0x1A,
+CONSTANT_NAMESPACE_PRIVATE=0x05,
+} contant_type_t;
+
+struct _constant {
+    union {
+        double f;
+        int i;
+        unsigned int u;
+        char*s;
+        namespace_t*ns;
+    };
+    int type;
+};
+
+constant_t* constant_new_int(int x);
+constant_t* constant_new_uint(unsigned int x);
+constant_t* constant_new_float(double x);
+constant_t* constant_new_string(char*s);
+constant_t* constant_new_namespace(namespace_t*ns);
+constant_t* constant_new_true();
+constant_t* constant_new_false();
+constant_t* constant_new_null();
+constant_t* constant_new_undefined();
+char constant_has_index(constant_t*c);
+constant_t* constant_fromindex(pool_t*pool, int index, int type);
+char* constant_to_string(constant_t*c);
+int constant_get_index(pool_t*pool, constant_t*c);
+void constant_free(constant_t*c);
+
 typedef enum multiname_type
 {QNAME=0x07,
- QNAMEA=0x0D,
  RTQNAME=0x0F,
- RTQNAMEA=0x10,
  RTQNAMEL=0x11,
- RTQNAMELA=0x12,
  MULTINAME=0x09,
- MULTINAMEA=0x0E,
  MULTINAMEL=0x1B,
+ QNAMEA=0x0D,
+ RTQNAMEA=0x10,
+ RTQNAMELA=0x12,
+ MULTINAMEA=0x0E,
  MULTINAMELA=0x1C
 } multiname_type_t;
 
@@ -101,6 +161,9 @@ int pool_find_string(pool_t*pool, const char*s);
 int pool_find_multiname(pool_t*pool, multiname_t*name);
 
 /* object -> integer (lookup/creation) */
+int pool_register_int(pool_t*p, int i);
+int pool_register_uint(pool_t*p, unsigned int i);
+int pool_register_float(pool_t*p, double d);
 int pool_register_string(pool_t*pool, const char*s);
 int pool_register_namespace(pool_t*pool, namespace_t*ns);
 int pool_register_namespace_set(pool_t*pool, namespace_set_t*set);