// ----------------------------- float ----------------------------------
-double undefined_float = 0.0;
-
void* float_clone(const void*_v) {
- if(_v==&undefined_float)
- return &undefined_float;
+ if(_v==0)
+ return 0;
const double*v1=_v;
double*v2 = malloc(sizeof(double));
*v2 = *v1;
return v2;
}
unsigned int float_hash(const void*_v) {
+ if(!_v)
+ return 0;
const unsigned char*b=_v;
unsigned int h=0;
int t;
}
void float_destroy(void*_v) {
double*v = (double*)_v;
- if(v!=&undefined_float)
+ if(v)
free(v);
}
char float_equals(const void*_v1, const void*_v2) {
const double*v1=_v1;
const double*v2=_v2;
- if(v1==&undefined_float || v2==&undefined_float)
- return 0;
+ if(!v1 || !v2)
+ return v1==v2;
return *v1==*v2;
}
// ----------------------------- uint ----------------------------------
-int undefined_uint = 0;
+unsigned int undefined_uint = 0;
-ptroff_t uint_clone(const void*v) {
- return (ptroff_t)v;
+void*uint_clone(const void*_v) {
+ if(!_v)
+ return 0;
+ const unsigned int*v1=_v;
+ unsigned int*v2 = malloc(sizeof(unsigned int));
+ *v2 = *v1;
+ return v2;
+}
+unsigned int uint_hash(const void*_v) {
+ if(!_v)
+ return 0;
+ const unsigned int*v=_v;
+ return *v;
+}
+void uint_destroy(void*_v) {
+ unsigned int*v = (unsigned int*)_v;
+ if(v)
+ free(v);
+}
+char uint_equals(const void*_v1, const void*_v2) {
+ const unsigned int*v1=_v1;
+ const unsigned int*v2=_v2;
+ if(!v1 || !v2)
+ return v1==v2;
+ return *v1==*v2;
}
-unsigned int uint_hash(const void*v) {return (ptroff_t)v;}
-void uint_destroy(void*v) {}
-char uint_equals(const void*v1, const void*v2) {return v1==v2;}
type_t uint_type = {
dup: (dup_func)uint_clone,
unsigned int namespace_hash(namespace_t*n)
{
+ if(!n)
+ return 0;
unsigned int hash = 0;
hash = crc32_add_byte(hash, n->access);
hash = crc32_add_string(hash, n->name);
unsigned char namespace_equals(const namespace_t*n1, const namespace_t*n2)
{
+ if(!n1 || !n2)
+ return n1==n2;
if(n1->access != n2->access)
return 0;
if(!(n1->name) != !(n2->name))
return 1;
}
-char* namespace_to_string(namespace_t*ns)
+char*escape_string(const char*str)
{
+ if(!str)
+ return strdup("NULL");
+ int len=0;
+ unsigned const char*s=str;
+ while(*s) {
+ if(*s<10) {
+ len+=2; // \d
+ } else if(*s<32) {
+ len+=3; // \dd
+ } else if(*s<127) {
+ len++;
+ } else {
+ len+=4; // \xhh
+ }
+ s++;
+ }
+ char*newstr = malloc(len+1);
+ char*dest = newstr;
+ s=str;
+ while(*s) {
+ if(*s<9) {
+ dest+=sprintf(dest, "\\%d", *s);
+ } else if(*s<32) {
+ if(*s==13)
+ dest+=sprintf(dest, "\\r");
+ else if(*s==10)
+ dest+=sprintf(dest, "\\n");
+ else if(*s==9)
+ dest+=sprintf(dest, "\\t");
+ else
+ dest+=sprintf(dest, "\\%2o", *s);
+ } else if(*s<127) {
+ *dest++=*s;
+ } else {
+ dest+=sprintf(dest, "\\x%02x", *s);
+ }
+ s++;
+ }
+ *dest = 0;
+ return newstr;
+}
+
+char* namespace_tostring(namespace_t*ns)
+{
+ if(!ns)
+ return strdup("NULL");
char*access = 0;
U8 type = ns->access;
access = access2str(type);
- char*string = malloc(strlen(access)+strlen(ns->name)+3);
- sprintf(string, "[%s]%s", access, ns->name);
+ char*s = escape_string(ns->name);
+ char*string = (char*)malloc(strlen(access)+strlen(s)+7);
+ if(!s)
+ sprintf(string, "[%s]NULL", access, s);
+ else if(!*s)
+ sprintf(string, "[%s]\"\"", access, s);
+ else
+ sprintf(string, "[%s]", access, s);
+
+ free(s);
return string;
}
namespace_t* namespace_clone(namespace_t*other)
{
+ if(!other)
+ return 0;
NEW(namespace_t,n);
n->access = other->access;
- n->name = strdup(other->name);
+ n->name = other->name?strdup(other->name):0;
return n;
}
-namespace_t* namespace_new(U8 access, const char*name)
+namespace_t* namespace_fromstring(const char*name)
{
namespace_t*ns = malloc(sizeof(namespace_t));
memset(ns, 0, sizeof(namespace_t));
-
- if(access==0) { // autodetect access
- char*n = strdup(name);
- if(n[0] == '[') {
- char*bracket = strchr(n, ']');
- if(bracket) {
- *bracket = 0;
- char*a = n+1;
- name += (bracket-n)+1;
- if(!strcmp(a, "")) access=0x16;
- else if(!strcmp(a, "undefined")) access=0x08; // public??
- else if(!strcmp(a, "package")) access=0x16;
- else if(!strcmp(a, "packageinternal")) access=0x17;
- else if(!strcmp(a, "protected")) access=0x18;
- else if(!strcmp(a, "explicit")) access=0x19;
- else if(!strcmp(a, "staticprotected")) access=0x1a;
- else if(!strcmp(a, "private")) access=0x05;
- else {
- fprintf(stderr, "Undefined access level: [%s]\n", a);
- return 0;
- }
- }
- } else {
- access = 0x16;
- }
- free(n);
+ if(name[0] == '[') {
+ U8 access;
+ char*n = strdup(name);
+ char*bracket = strchr(n, ']');
+ if(bracket) {
+ *bracket = 0;
+ char*a = n+1;
+ name += (bracket-n)+1;
+ if(!strcmp(a, "")) access=0x16;
+ else if(!strcmp(a, "undefined")) access=0x08; // public??
+ else if(!strcmp(a, "package")) access=0x16;
+ else if(!strcmp(a, "public")) access=0x16;
+ else if(!strcmp(a, "packageinternal")) access=0x17;
+ else if(!strcmp(a, "protected")) access=0x18;
+ else if(!strcmp(a, "explicit")) access=0x19;
+ else if(!strcmp(a, "staticprotected")) access=0x1a;
+ else if(!strcmp(a, "private")) access=0x05;
+ else {
+ fprintf(stderr, "Undefined access level: [%s]\n", a);
+ free(n);
+ return 0;
+ }
+ }
+ ns->access = access;
+ ns->name = strdup(name);
+ free(n);
+ return ns;
+ } else {
+ ns->access = 0x16;
+ ns->name = strdup(name);
+ return ns;
}
+}
+
+namespace_t* namespace_new(U8 access, const char*name)
+{
+ namespace_t*ns = malloc(sizeof(namespace_t));
ns->access = access;
- ns->name = strdup(name);
+ /* not sure what namespaces with empty strings are good for, but they *do* exist */
+ ns->name = name?strdup(name):0;
return ns;
}
-
namespace_t* namespace_new_undefined(const char*name) {
return namespace_new(0x08, name); // public?
}
void namespace_destroy(namespace_t*n)
{
- free(n->name);n->name=0;
- n->access=0x00;
- free(n);
+ if(n) {
+ free(n->name);n->name=0;
+ n->access=0x00;
+ free(n);
+ }
}
type_t namespace_type = {
unsigned int namespace_set_hash(namespace_set_t*set)
{
+ if(!set)
+ return 0;
namespace_list_t*l = set->namespaces;
unsigned int hash = 0;
while(l) {
int namespace_set_equals(namespace_set_t*m1, namespace_set_t*m2)
{
+ if(!m1 || !m2)
+ return m1==m2;
namespace_list_t*l1 = m1->namespaces;
namespace_list_t*l2 = m2->namespaces;
while(l1 && l2) {
return 0;
if(!(l1->namespace->name) != !(l2->namespace->name))
return 0;
- if(strcmp(l1->namespace->name, l2->namespace->name))
+ if(l1->namespace->name && l2->namespace->name && strcmp(l1->namespace->name, l2->namespace->name))
return 0;
l1 = l1->next;
l2 = l2->next;
namespace_set_t* namespace_set_clone(namespace_set_t*other)
{
+ if(!other)
+ return 0;
NEW(namespace_set_t,set);
set->namespaces = list_new();
namespace_list_t*l = other->namespaces;
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");
/* TODO: is the order of the namespaces important (does it
change the lookup order?). E.g. flex freely shuffles namespaces
around.
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;
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;
void namespace_set_destroy(namespace_set_t*set)
{
- namespace_list_t*l = set->namespaces;
- while(l) {
- namespace_destroy(l->namespace);l->namespace=0;
- l = l->next;
+ if(set) {
+ namespace_list_t*l = set->namespaces;
+ while(l) {
+ namespace_destroy(l->namespace);l->namespace=0;
+ l = l->next;
+ }
+ list_free(set->namespaces);
+ free(set);
}
- list_free(set->namespaces);
- free(set);
}
type_t namespace_set_type = {
unsigned int multiname_hash(multiname_t*m)
{
+ if(!m)
+ return 0;
unsigned int hash = crc32_add_byte(0, m->type);
if(m->name) {
hash = crc32_add_string(hash, m->name);
int multiname_equals(multiname_t*m1, multiname_t*m2)
{
+ if(!m1 || !m2)
+ return m1==m2;
if(m1->type!=m2->type)
return 0;
{
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;
}
multiname_t* multiname_clone(multiname_t*other)
{
+ if(!other)
+ return 0;
NEW(multiname_t,m);
m->type = other->type;
if(other->ns)
char* access2str(int type)
{
if(type==0x08) return "access08";
- else if(type==0x16) return "package";
+ else if(type==0x16) return "public";
else if(type==0x17) return "packageinternal";
else if(type==0x18) return "protected";
else if(type==0x19) return "explicit";
}
}
-char* multiname_to_string(multiname_t*m)
+
+char multiname_late_namespace(multiname_t*m)
+{
+ if(!m)
+ return 0;
+ return (m->type==RTQNAME || m->type==RTQNAMEA ||
+ m->type==RTQNAMEL || m->type==RTQNAMELA);
+}
+
+char multiname_late_name(multiname_t*m)
+{
+ if(!m)
+ return 0;
+ return m->type==RTQNAMEL || m->type==RTQNAMELA ||
+ m->type==MULTINAMEL || m->type==MULTINAMELA;
+}
+
+char* multiname_tostring(multiname_t*m)
{
char*mname = 0;
- if(!m || m->type==0xff)
- return strdup("--<UNDEFINED_MULTINAME>--");
+ if(!m)
+ return strdup("NULL");
+ if(m->type==0xff)
+ return strdup("--<MULTINAME 0xff>--");
- int namelen = m->name?strlen(m->name):1;
+ char*name = m->name?escape_string(m->name):strdup("*");
+ int namelen = strlen(name);
if(m->type==QNAME || m->type==QNAMEA) {
- mname = malloc(strlen(m->ns->name)+namelen+32);
+ char*nsname = escape_string(m->ns->name);
+ mname = malloc(strlen(nsname)+namelen+32);
strcpy(mname, "<q");
if(m->type == QNAMEA)
strcat(mname, ",attr");
strcat(mname, ">[");
strcat(mname,access2str(m->ns->access));
strcat(mname, "]");
- strcat(mname, m->ns->name);
+ strcat(mname, nsname);
+ free(nsname);
strcat(mname, "::");
- if(m->name)
- strcat(mname, m->name);
- else
- strcat(mname, "*");
+ strcat(mname, name);
} else if(m->type==RTQNAME || m->type==RTQNAMEA) {
mname = malloc(namelen+32);
strcpy(mname, "<rt");
if(m->type == RTQNAMEA)
strcat(mname, ",attr");
strcat(mname, ">");
- if(m->name)
- strcat(mname, m->name);
- else
- strcat(mname, "*");
+ strcat(mname, name);
} else if(m->type==RTQNAMEL) {
- mname = strdup("<l>");
+ mname = strdup("<rt,l>");
} else if(m->type==RTQNAMELA) {
- mname = strdup("<l,attr>");
+ mname = strdup("<rt,l,attr>");
} 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,"<multi>");
strcpy(mname,"<multi,attr>");
strcat(mname, s);
strcat(mname, "::");
- if(m->name)
- strcat(mname, m->name);
- else
- strcat(mname, "*");
+ 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,"<l,multi>");
} else {
fprintf(stderr, "Invalid multiname type: %02x\n", m->type);
}
+ free(name);
return mname;
}
memset(m, 0, sizeof(multiname_t));
m->type = QNAME;
m->namespace_set = 0;
- NEW(namespace_t,ns);
- ns->name= namespace;
- m->ns = ns;
- m->name = name;
+ m->ns = namespace_fromstring(namespace);
+ m->name = name?strdup(name):0;
+ free(n);
return m;
}
void multiname_destroy(multiname_t*m)
{
- if(m->name) {
- free((void*)m->name);m->name = 0;
- }
- if(m->ns) {
- namespace_destroy(m->ns);m->ns = 0;
- }
- if(m->namespace_set) {
- namespace_set_destroy(m->namespace_set);m->namespace_set = 0;
+ if(m) {
+ if(m->name) {
+ free((void*)m->name);m->name = 0;
+ }
+ if(m->ns) {
+ namespace_destroy(m->ns);m->ns = 0;
+ }
+ if(m->namespace_set) {
+ namespace_set_destroy(m->namespace_set);m->namespace_set = 0;
+ }
+ m->type=0;
+ free(m);
}
- free(m);
}
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 = string_new4(s);
+ c->type = CONSTANT_STRING;
+ return c;
+}
+constant_t* constant_new_string2(const char*s, int len)
+{
+ NEW(constant_t,c);
+ c->s = string_new3(s, len);
+ 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) {
+ string_t s = pool_lookup_string2(pool, index);
+ c->s = string_dup3(&s);
+ } 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[32];
+ 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) {
+ char buf[1024];
+ sprintf(buf, "%f", c->f);
+ return strdup(buf);
+ } else if(c->type == CONSTANT_STRING) {
+ /* should we escape the string? \0 bytes won't be printed */
+ return strdup_n(c->s->str,c->s->len);
+ } 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_string2(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) {
+ string_free(c->s);
+ } 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)
{
- return array_append_if_new(p->x_uints, (void*)(ptroff_t)i, 0);
+ int pos = array_append_if_new(p->x_uints, &i, 0);
+ assert(pos!=0);
+ return pos;
}
int pool_register_int(pool_t*p, int i)
{
- return array_append_if_new(p->x_ints, (void*)(ptroff_t)i, 0);
+ int pos = array_append_if_new(p->x_ints, &i, 0);
+ assert(pos!=0);
+ return pos;
}
int pool_register_float(pool_t*p, double d)
{
- return array_append_if_new(p->x_floats, &d, 0);
+ int pos = array_append_if_new(p->x_floats, &d, 0);
+ assert(pos!=0);
+ return pos;
}
-int pool_register_string(pool_t*pool, const char*s)
+int pool_register_string(pool_t*pool, const char*str)
{
- if(!s) return 0;
- return array_append_if_new(pool->x_strings, s, 0);
+ if(!str) return 0;
+ string_t s = string_new2(str);
+ int pos = array_append_if_new(pool->x_strings, &s, 0);
+ assert(pos!=0);
+ return pos;
+}
+int pool_register_string2(pool_t*pool, string_t*s)
+{
+ if(!s || !s->str) return 0;
+ int pos = array_append_if_new(pool->x_strings, s, 0);
+ assert(pos!=0);
+ return pos;
}
int pool_register_namespace(pool_t*pool, namespace_t*ns)
{
if(!ns) return 0;
- return array_append_if_new(pool->x_namespaces, ns, 0);
+ int pos = array_append_if_new(pool->x_namespaces, ns, 0);
+ assert(pos!=0);
+ return pos;
}
int pool_register_namespace_set(pool_t*pool, namespace_set_t*set)
{
if(!set) return 0;
- return array_append_if_new(pool->x_namespace_sets, set, 0);
+ int pos = array_append_if_new(pool->x_namespace_sets, set, 0);
+ assert(pos!=0);
+ return pos;
}
int pool_register_multiname(pool_t*pool, multiname_t*n)
{
if(!n) return 0;
- return array_append_if_new(pool->x_multinames, n, 0);
+ int pos = array_append_if_new(pool->x_multinames, n, 0);
+ assert(pos!=0);
+ return pos;
}
int pool_register_multiname2(pool_t*pool, char*name)
{
if(!name) return 0;
multiname_t*n = multiname_fromstring(name);
- return array_append_if_new(pool->x_multinames, n, 0);
+ int pos = array_append_if_new(pool->x_multinames, n, 0);
+ multiname_destroy(n);
+ assert(pos!=0);
+ return pos;
}
int pool_find_uint(pool_t*pool, unsigned int x)
{
- int i = array_find(pool->x_uints, (void*)(ptroff_t)x);
- if(i<0) {
+ int i = array_find(pool->x_uints, &x);
+ if(i<=0) {
fprintf(stderr, "Couldn't find uint \"%d\" in constant pool\n", x);
return 0;
}
}
int pool_find_int(pool_t*pool, int x)
{
- int i = array_find(pool->x_ints, (void*)(ptroff_t)x);
- if(i<0) {
+ int i = array_find(pool->x_ints, &x);
+ if(i<=0) {
fprintf(stderr, "Couldn't find int \"%d\" in constant pool\n", x);
return 0;
}
int pool_find_float(pool_t*pool, double x)
{
int i = array_find(pool->x_ints, &x);
- if(i<0) {
+ if(i<=0) {
fprintf(stderr, "Couldn't find int \"%d\" in constant pool\n", x);
return 0;
}
if(!ns)
return 0;
int i = array_find(pool->x_namespaces, ns);
- if(i<0) {
- char*s = namespace_to_string(ns);
+ if(i<=0) {
+ char*s = namespace_tostring(ns);
fprintf(stderr, "Couldn't find namespace \"%s\" %08x in constant pool\n", s, ns);
free(s);
return 0;
}
int pool_find_namespace_set(pool_t*pool, namespace_set_t*set)
{
+ if(!set)
+ return 0;
int i = array_find(pool->x_namespace_sets, set);
- if(i<0) {
- char*s = namespace_set_to_string(set);
+ if(i<=0) {
+ char*s = namespace_set_tostring(set);
fprintf(stderr, "Couldn't find namespace_set \"%s\" in constant pool\n", s);
free(s);
return 0;
}
return i;
}
-int pool_find_string(pool_t*pool, const char*s)
+int pool_find_string(pool_t*pool, const char*str)
{
- int i = array_find(pool->x_strings, s);
- if(i<0) {
+ if(!str)
+ return 0;
+ string_t s = string_new2(str);
+ int i = array_find(pool->x_strings, &s);
+ if(i<=0) {
fprintf(stderr, "Couldn't find string \"%s\" in constant pool\n", s);
- *(int*)0=0;
return 0;
}
return i;
}
int pool_find_multiname(pool_t*pool, multiname_t*name)
{
+ if(!name)
+ return 0;
int i = array_find(pool->x_multinames, name);
- if(i<0) {
- char*s = multiname_to_string(name);
+ if(i<=0) {
+ char*s = multiname_tostring(name);
fprintf(stderr, "Couldn't find multiname \"%s\" in constant pool\n", s);
free(s);
return 0;
int pool_lookup_int(pool_t*pool, int i)
{
+ if(!i) return 0;
return *(int*)array_getkey(pool->x_ints, i);
}
unsigned int pool_lookup_uint(pool_t*pool, int i)
{
+ if(!i) return 0;
return *(unsigned int*)array_getkey(pool->x_uints, i);
}
double pool_lookup_float(pool_t*pool, int i)
{
+ if(!i) return __builtin_nan("");
return *(double*)array_getkey(pool->x_floats, i);
}
-char*pool_lookup_string(pool_t*pool, int i)
+const char*pool_lookup_string(pool_t*pool, int i)
{
- return (char*)array_getkey(pool->x_strings, i);
+ string_t*s = array_getkey(pool->x_strings, i);
+ if(!s) return 0;
+ return s->str;
+}
+string_t pool_lookup_string2(pool_t*pool, int i)
+{
+ string_t*s = array_getkey(pool->x_strings, i);
+ return *s;
}
namespace_t*pool_lookup_namespace(pool_t*pool, int i)
{
p->x_ints = array_new2(&uint_type);
p->x_uints = array_new2(&uint_type);
p->x_floats = array_new2(&float_type);
- p->x_strings = array_new2(&charptr_type);
+ p->x_strings = array_new2(&stringstruct_type);
p->x_namespaces = array_new2(&namespace_type);
p->x_namespace_sets = array_new2(&namespace_set_type);
p->x_multinames = array_new2(&multiname_type);
/* add a zero-index entry in each list */
- array_append(p->x_ints, &undefined_uint, 0);
- array_append(p->x_uints, &undefined_uint, 0);
- array_append(p->x_floats, &undefined_float, 0);
-
- pool_register_string(p, "--<UNDEFINED_STRING>--");
-
- namespace_t*ns = namespace_new(0,"--<UNDEFINED NAMESPACE>--");
- pool_register_namespace(p, ns);
- namespace_destroy(ns);
-
- namespace_set_t*nsset = namespace_set_new();
- list_append(nsset->namespaces, namespace_new(0, "--<UNDEFINED NAMESPACE SET>--"));
- pool_register_namespace_set(p, nsset);
- namespace_set_destroy(nsset);
-
- namespace_t*mns = namespace_new(0,"nons");
- multiname_t*mname = multiname_new(mns,"--<UNDEFINED MULTINAME>--");
- mname->type = 0xff;
- pool_register_multiname(p, mname);
- multiname_destroy(mname);
- namespace_destroy(mns);
-
+ array_append(p->x_ints, 0, 0);
+ array_append(p->x_uints, 0, 0);
+ array_append(p->x_floats, 0, 0);
+ array_append(p->x_strings, 0, 0);
+ array_append(p->x_namespaces, 0, 0);
+ array_append(p->x_namespace_sets, 0, 0);
+ array_append(p->x_multinames, 0, 0);
return p;
}
DEBUG printf("%d ints\n", num_ints);
int t;
for(t=1;t<num_ints;t++) {
- S32 v = swf_GetS30(tag);
+ S32 v = swf_GetABCS32(tag);
DEBUG printf("int %d) %d\n", t, v);
- array_append(pool->x_ints, (void*)(ptroff_t)v, 0);
+ array_append(pool->x_ints, &v, 0);
}
int num_uints = swf_GetU30(tag);
DEBUG printf("%d uints\n", num_uints);
for(t=1;t<num_uints;t++) {
- U32 v = swf_GetU30(tag);
+ U32 v = swf_GetABCU32(tag);
DEBUG printf("uint %d) %d\n", t, v);
- array_append(pool->x_uints, (void*)(ptroff_t)v, 0);
+ array_append(pool->x_uints, &v, 0);
}
int num_floats = swf_GetU30(tag);
DEBUG printf("%d strings\n", num_strings);
for(t=1;t<num_strings;t++) {
int len = swf_GetU30(tag);
- char*s = malloc(len+1);
- swf_GetBlock(tag, s, len);
- s[len] = 0;
- array_append(pool->x_strings, s, 0);
- free(s);
- DEBUG printf("%d) \"%s\"\n", t, pool->x_strings->d[t].name);
+ string_t s = string_new(&tag->data[tag->pos], len);
+ swf_GetBlock(tag, 0, len);
+ array_append(pool->x_strings, &s, 0);
+ DEBUG printf("%d) \"%s\"\n", t, ((string_t*)array_getkey(pool->x_strings, t))->str);
}
int num_namespaces = swf_GetU30(tag);
DEBUG printf("%d namespaces\n", num_namespaces);
for(t=1;t<num_namespaces;t++) {
U8 type = swf_GetU8(tag);
int namenr = swf_GetU30(tag);
- const char*name = array_getkey(pool->x_strings, namenr);
+ const char*name = 0;
+ if(namenr)
+ name = pool_lookup_string(pool, namenr);
namespace_t*ns = namespace_new(type, name);
array_append(pool->x_namespaces, ns, 0);
- DEBUG printf("%d) \"%s\"\n", t, namespace_to_string(ns));
+ DEBUG printf("%d) %02x \"%s\"\n", t, type, namespace_tostring(ns));
namespace_destroy(ns);
}
int num_sets = swf_GetU30(tag);
NEW(namespace_set_t, nsset);
for(s=0;s<count;s++) {
int nsnr = swf_GetU30(tag);
+ if(!nsnr)
+ fprintf(stderr, "Zero entry in namespace set\n");
namespace_t*ns = (namespace_t*)array_getkey(pool->x_namespaces, nsnr);
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);
}
m.ns = (namespace_t*)array_getkey(pool->x_namespaces, namespace_index);
int name_index = swf_GetU30(tag);
if(name_index) // 0 = '*' (any)
- m.name = array_getkey(pool->x_strings, name_index);
+ m.name = pool_lookup_string(pool, name_index);
} else if(m.type==0x0f || m.type==0x10) {
int name_index = swf_GetU30(tag);
if(name_index) // 0 = '*' (any name)
- m.name = array_getkey(pool->x_strings, name_index);
+ m.name = pool_lookup_string(pool, name_index);
} else if(m.type==0x11 || m.type==0x12) {
} else if(m.type==0x09 || m.type==0x0e) {
int name_index = swf_GetU30(tag);
int namespace_set_index = swf_GetU30(tag);
if(name_index)
- m.name = array_getkey(pool->x_strings, name_index);
+ m.name = pool_lookup_string(pool, name_index);
m.namespace_set = (namespace_set_t*)array_getkey(pool->x_namespace_sets, namespace_set_index);
} else if(m.type==0x1b || m.type==0x1c) {
int namespace_set_index = swf_GetU30(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);
}
}
}
for(t=1;t<pool->x_namespaces->num;t++) {
namespace_t*ns= (namespace_t*)array_getkey(pool->x_namespaces, t);
- 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])
+ pool_register_string(pool, ns->name);
}
+ //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++) {
- S32 val = (ptroff_t)array_getkey(pool->x_ints, t);
- swf_SetS30(tag, val);
+ S32 val = *(int*)array_getkey(pool->x_ints, t);
+ swf_SetABCS32(tag, val);
}
swf_SetU30(tag, pool->x_uints->num>1?pool->x_uints->num:0);
for(t=1;t<pool->x_uints->num;t++) {
- swf_SetU30(tag, (ptroff_t)array_getkey(pool->x_uints, t));
+ swf_SetABCU32(tag, *(unsigned int*)array_getkey(pool->x_uints, t));
}
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++) {
- swf_SetU30String(tag, array_getkey(pool->x_strings, t));
+ string_t str = pool_lookup_string2(pool, t);
+ swf_SetU30String(tag, str.str, str.len);
}
swf_SetU30(tag, pool->x_namespaces->num>1?pool->x_namespaces->num:0);
for(t=1;t<pool->x_namespaces->num;t++) {
namespace_t*ns= (namespace_t*)array_getkey(pool->x_namespaces, t);
- const char*name = ns->name;
- int i = pool_find_string(pool, name);
swf_SetU8(tag, ns->access);
+ const char*name = ns->name;
+ int i = 0;
+
+ //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);