X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fas3%2Fpool.c;h=ffea0e6b2c053361be114f7923d899cc268730ca;hb=8d78dadd6a8cd35d085109414a9aa4a1fa9e9d8e;hp=77f401eaab4108cdf7d278f756628aaf45c744a8;hpb=b66793aae0b5e65b24c1799083787e635e2b485d;p=swftools.git diff --git a/lib/as3/pool.c b/lib/as3/pool.c index 77f401e..ffea0e6 100644 --- a/lib/as3/pool.c +++ b/lib/as3/pool.c @@ -172,7 +172,7 @@ char*escape_string(const char*str) return newstr; } -char* namespace_to_string(namespace_t*ns) +char* namespace_tostring(namespace_t*ns) { if(!ns) return strdup("NULL"); @@ -335,7 +335,7 @@ namespace_set_t* namespace_set_new() set->namespaces = list_new(); return set; } -char* namespace_set_to_string(namespace_set_t*set) +char* namespace_set_tostring(namespace_set_t*set) { if(!set) return strdup("NULL"); @@ -348,7 +348,7 @@ char* namespace_set_to_string(namespace_set_t*set) int l = 0; namespace_list_t*lns = set->namespaces; while(lns) { - char*s = namespace_to_string(lns->namespace); + char*s = namespace_tostring(lns->namespace); l += strlen(s)+1; free(s); lns = lns->next; @@ -357,7 +357,7 @@ char* namespace_set_to_string(namespace_set_t*set) strcpy(desc, "{"); lns = set->namespaces; while(lns) { - char*s = namespace_to_string(lns->namespace); + char*s = namespace_tostring(lns->namespace); strcat(desc, s); free(s); lns = lns->next; @@ -444,7 +444,11 @@ multiname_t* multiname_new(namespace_t*ns, const char*name) { NEW(multiname_t,m); m->type = QNAME; - m->ns = namespace_clone(ns); + if(!ns) { + m->ns = namespace_new_packageinternal(""); + } else { + m->ns = namespace_clone(ns); + } m->name = strdup(name); return m; } @@ -497,7 +501,7 @@ char multiname_late_name(multiname_t*m) m->type==MULTINAMEL || m->type==MULTINAMELA; } -char* multiname_to_string(multiname_t*m) +char* multiname_tostring(multiname_t*m) { char*mname = 0; if(!m) @@ -533,7 +537,7 @@ char* multiname_to_string(multiname_t*m) } else if(m->type==RTQNAMELA) { mname = strdup(""); } else if(m->type==MULTINAME || m->type==MULTINAMEA) { - char*s = namespace_set_to_string(m->namespace_set); + char*s = namespace_set_tostring(m->namespace_set); mname = malloc(strlen(s)+namelen+16); if(m->type == MULTINAME) strcpy(mname,""); @@ -544,7 +548,7 @@ char* multiname_to_string(multiname_t*m) strcat(mname, name); free(s); } else if(m->type==MULTINAMEL || m->type==MULTINAMELA) { - char*s = namespace_set_to_string(m->namespace_set); + char*s = namespace_set_tostring(m->namespace_set); mname = malloc(strlen(s)+16); if(m->type == MULTINAMEL) strcpy(mname,""); @@ -617,6 +621,174 @@ 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 = namespace_clone(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 = strdup(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_tostring(constant_t*c) +{ + if(!c) + return 0; + char buf[30]; + if(NS_TYPE(c->type)) { + return namespace_tostring(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); + /*if(c->type!=c->ns->access) { + printf("%02x<->%02x\n", c->type, c->ns->access); + }*/ + 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) @@ -712,7 +884,7 @@ int pool_find_namespace(pool_t*pool, namespace_t*ns) return 0; int i = array_find(pool->x_namespaces, ns); if(i<=0) { - char*s = namespace_to_string(ns); + char*s = namespace_tostring(ns); fprintf(stderr, "Couldn't find namespace \"%s\" %08x in constant pool\n", s, ns); free(s); return 0; @@ -725,7 +897,7 @@ int pool_find_namespace_set(pool_t*pool, namespace_set_t*set) return 0; int i = array_find(pool->x_namespace_sets, set); if(i<=0) { - char*s = namespace_set_to_string(set); + char*s = namespace_set_tostring(set); fprintf(stderr, "Couldn't find namespace_set \"%s\" in constant pool\n", s); free(s); return 0; @@ -749,7 +921,7 @@ int pool_find_multiname(pool_t*pool, multiname_t*name) return 0; int i = array_find(pool->x_multinames, name); if(i<=0) { - char*s = multiname_to_string(name); + char*s = multiname_tostring(name); fprintf(stderr, "Couldn't find multiname \"%s\" in constant pool\n", s); free(s); return 0; @@ -859,12 +1031,12 @@ void pool_read(pool_t*pool, TAG*tag) for(t=1;tx_strings, namenr); namespace_t*ns = namespace_new(type, name); array_append(pool->x_namespaces, ns, 0); - DEBUG printf("%d) %02x \"%s\"\n", t, type, namespace_to_string(ns)); + DEBUG printf("%d) %02x \"%s\"\n", t, type, namespace_tostring(ns)); namespace_destroy(ns); } int num_sets = swf_GetU30(tag); @@ -882,7 +1054,7 @@ void pool_read(pool_t*pool, TAG*tag) list_append(nsset->namespaces, namespace_clone(ns)); } array_append(pool->x_namespace_sets, nsset, 0); - DEBUG printf("set %d) %s\n", t, namespace_set_to_string(nsset)); + DEBUG printf("set %d) %s\n", t, namespace_set_tostring(nsset)); namespace_set_destroy(nsset); } @@ -915,15 +1087,9 @@ void pool_read(pool_t*pool, TAG*tag) } else { printf("can't parse type %d multinames yet\n", m.type); } - DEBUG printf("multiname %d) %s\n", t, multiname_to_string(&m)); + DEBUG printf("multiname %d) %s\n", t, multiname_tostring(&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) @@ -955,10 +1121,17 @@ void pool_write(pool_t*pool, TAG*tag) } for(t=1;tx_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;tx_ints->num;t++) { @@ -971,8 +1144,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;tx_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;tx_strings->num;t++) { @@ -984,8 +1157,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);