} else {
fprintf(stderr, "Invalid multiname type: %02x\n", m->type);
}
+ free(name);
return mname;
}
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)
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);
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)
}
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++) {
}
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_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);
#include "../rfxswf.h"
DECLARE(pool);
+DECLARE(constant);
+DECLARE_LIST(constant);
DECLARE(multiname);
DECLARE(namespace);
DECLARE(namespace_set);
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;
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);