3 Routines for handling Flash2 AVM2 ABC contantpool entries.
5 Extension module for the rfxswf library.
6 Part of the swftools package.
8 Copyright (c) 2008 Matthias Kramm <kramm@quiss.org>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
28 // ----------------------------- float ----------------------------------
30 void* float_clone(const void*_v) {
34 double*v2 = malloc(sizeof(double));
38 unsigned int float_hash(const void*_v) {
41 const unsigned char*b=_v;
45 h = crc32_add_byte(h, b[t]);
48 void float_destroy(void*_v) {
49 double*v = (double*)_v;
53 char float_equals(const void*_v1, const void*_v2) {
68 // ----------------------------- uint ----------------------------------
70 unsigned int undefined_uint = 0;
72 void*uint_clone(const void*_v) {
75 const unsigned int*v1=_v;
76 unsigned int*v2 = malloc(sizeof(unsigned int));
80 unsigned int uint_hash(const void*_v) {
83 const unsigned int*v=_v;
86 void uint_destroy(void*_v) {
87 unsigned int*v = (unsigned int*)_v;
91 char uint_equals(const void*_v1, const void*_v2) {
92 const unsigned int*v1=_v1;
93 const unsigned int*v2=_v2;
100 dup: (dup_func)uint_clone,
101 hash: (hash_func)uint_hash,
102 free: (free_func)uint_destroy,
103 equals: (equals_func)uint_equals
106 // ----------------------------- namespace ----------------------------------
108 unsigned int namespace_hash(namespace_t*n)
112 unsigned int hash = 0;
113 hash = crc32_add_byte(hash, n->access);
114 hash = crc32_add_string(hash, n->name);
118 unsigned char namespace_equals(const namespace_t*n1, const namespace_t*n2)
122 if(n1->access != n2->access)
124 if(!(n1->name) != !(n2->name))
126 if(n1->name && n2->name && strcmp(n1->name, n2->name))
131 char*escape_string(const char*str)
134 return strdup("NULL");
136 unsigned const char*s=str;
149 char*newstr = malloc(len+1);
154 dest+=sprintf(dest, "\\%d", *s);
157 dest+=sprintf(dest, "\\r");
159 dest+=sprintf(dest, "\\n");
161 dest+=sprintf(dest, "\\t");
163 dest+=sprintf(dest, "\\%2o", *s);
167 dest+=sprintf(dest, "\\x%02x", *s);
175 char* namespace_to_string(namespace_t*ns)
178 return strdup("NULL");
180 U8 type = ns->access;
181 access = access2str(type);
182 char*s = escape_string(ns->name);
183 char*string = (char*)malloc(strlen(access)+strlen(s)+3);
184 int l = sprintf(string, "[%s]%s", access, s);
189 namespace_t* namespace_clone(namespace_t*other)
194 n->access = other->access;
195 n->name = other->name?strdup(other->name):0;
199 namespace_t* namespace_fromstring(const char*name)
201 namespace_t*ns = malloc(sizeof(namespace_t));
202 memset(ns, 0, sizeof(namespace_t));
205 char*n = strdup(name);
206 char*bracket = strchr(n, ']');
210 name += (bracket-n)+1;
211 if(!strcmp(a, "")) access=0x16;
212 else if(!strcmp(a, "undefined")) access=0x08; // public??
213 else if(!strcmp(a, "package")) access=0x16;
214 else if(!strcmp(a, "packageinternal")) access=0x17;
215 else if(!strcmp(a, "protected")) access=0x18;
216 else if(!strcmp(a, "explicit")) access=0x19;
217 else if(!strcmp(a, "staticprotected")) access=0x1a;
218 else if(!strcmp(a, "private")) access=0x05;
220 fprintf(stderr, "Undefined access level: [%s]\n", a);
226 ns->name = strdup(name);
231 ns->name = strdup(name);
236 namespace_t* namespace_new(U8 access, const char*name)
238 namespace_t*ns = malloc(sizeof(namespace_t));
240 /* not sure what namespaces with empty strings are good for, but they *do* exist */
241 ns->name = name?strdup(name):0;
244 namespace_t* namespace_new_undefined(const char*name) {
245 return namespace_new(0x08, name); // public?
247 namespace_t* namespace_new_package(const char*name) {
248 return namespace_new(0x16 , name);
250 namespace_t* namespace_new_packageinternal(const char*name) {
251 return namespace_new(0x17, name);
253 namespace_t* namespace_new_protected(const char*name) {
254 return namespace_new(0x18, name);
256 namespace_t* namespace_new_explicit(const char*name) {
257 return namespace_new(0x19, name);
259 namespace_t* namespace_new_staticprotected(const char*name) {
260 return namespace_new(0x1a, name);
262 namespace_t* namespace_new_private(const char*name) {
263 return namespace_new(0x05, name);
266 void namespace_destroy(namespace_t*n)
269 free(n->name);n->name=0;
275 type_t namespace_type = {
276 dup: (dup_func)namespace_clone,
277 hash: (hash_func)namespace_hash,
278 free: (free_func)namespace_destroy,
279 equals: (equals_func)namespace_equals
282 // ---------------------------namespace sets --------------------------------
284 unsigned int namespace_set_hash(namespace_set_t*set)
288 namespace_list_t*l = set->namespaces;
289 unsigned int hash = 0;
291 hash = crc32_add_byte(hash, l->namespace->access);
292 hash = crc32_add_string(hash, l->namespace->name);
298 int namespace_set_equals(namespace_set_t*m1, namespace_set_t*m2)
302 namespace_list_t*l1 = m1->namespaces;
303 namespace_list_t*l2 = m2->namespaces;
305 if(l1->namespace->access != l2->namespace->access)
307 if(!(l1->namespace->name) != !(l2->namespace->name))
309 if(l1->namespace->name && l2->namespace->name && strcmp(l1->namespace->name, l2->namespace->name))
319 namespace_set_t* namespace_set_clone(namespace_set_t*other)
323 NEW(namespace_set_t,set);
324 set->namespaces = list_new();
325 namespace_list_t*l = other->namespaces;
327 list_append(set->namespaces, namespace_clone(l->namespace));
332 namespace_set_t* namespace_set_new()
334 NEW(namespace_set_t,set);
335 set->namespaces = list_new();
338 char* namespace_set_to_string(namespace_set_t*set)
341 return strdup("NULL");
342 /* TODO: is the order of the namespaces important (does it
343 change the lookup order?). E.g. flex freely shuffles namespaces
345 If the order is not important, we can optimize constant pools by sorting
349 namespace_list_t*lns = set->namespaces;
351 char*s = namespace_to_string(lns->namespace);
356 char*desc = malloc(l+16);
358 lns = set->namespaces;
360 char*s = namespace_to_string(lns->namespace);
371 void namespace_set_destroy(namespace_set_t*set)
374 namespace_list_t*l = set->namespaces;
376 namespace_destroy(l->namespace);l->namespace=0;
379 list_free(set->namespaces);
384 type_t namespace_set_type = {
385 dup: (dup_func)namespace_set_clone,
386 hash: (hash_func)namespace_set_hash,
387 free: (free_func)namespace_set_destroy,
388 equals: (equals_func)namespace_set_equals
391 // ----------------------------- multiname ----------------------------------
393 unsigned int multiname_hash(multiname_t*m)
397 unsigned int hash = crc32_add_byte(0, m->type);
399 hash = crc32_add_string(hash, m->name);
402 hash = crc32_add_byte(hash, m->ns->access);
403 hash = crc32_add_string(hash, m->ns->name);
405 if(m->namespace_set) {
406 namespace_list_t*l = m->namespace_set->namespaces;
408 hash = crc32_add_byte(hash, l->namespace->access);
409 hash = crc32_add_string(hash, l->namespace->name);
416 int multiname_equals(multiname_t*m1, multiname_t*m2)
420 if(m1->type!=m2->type)
423 if((!m1->name) != (!m2->name))
425 if((!m1->ns) != (!m2->ns))
427 if((!m1->namespace_set) != (!m2->namespace_set))
430 if(m1->name && m2->name && strcmp(m1->name,m2->name))
432 if(m1->ns && m2->ns) {
433 if(!namespace_equals(m1->ns, m2->ns))
436 if(m1->namespace_set && m2->namespace_set) {
437 if(!namespace_set_equals(m1->namespace_set, m2->namespace_set))
443 multiname_t* multiname_new(namespace_t*ns, const char*name)
447 m->ns = namespace_clone(ns);
448 m->name = strdup(name);
452 multiname_t* multiname_clone(multiname_t*other)
457 m->type = other->type;
459 m->ns = namespace_clone(other->ns);
460 if(other->namespace_set)
461 m->namespace_set = namespace_set_clone(other->namespace_set);
463 m->name = strdup(other->name);
468 char* access2str(int type)
470 if(type==0x08) return "access08";
471 else if(type==0x16) return "package";
472 else if(type==0x17) return "packageinternal";
473 else if(type==0x18) return "protected";
474 else if(type==0x19) return "explicit";
475 else if(type==0x1A) return "staticprotected";
476 else if(type==0x05) return "private";
478 fprintf(stderr, "Undefined access type %02x\n", type);
484 char multiname_late_namespace(multiname_t*m)
488 return (m->type==RTQNAME || m->type==RTQNAMEA ||
489 m->type==RTQNAMEL || m->type==RTQNAMELA);
492 char multiname_late_name(multiname_t*m)
496 return m->type==RTQNAMEL || m->type==RTQNAMELA ||
497 m->type==MULTINAMEL || m->type==MULTINAMELA;
500 char* multiname_to_string(multiname_t*m)
504 return strdup("NULL");
506 return strdup("--<MULTINAME 0xff>--");
508 char*name = m->name?escape_string(m->name):strdup("*");
509 int namelen = strlen(name);
511 if(m->type==QNAME || m->type==QNAMEA) {
512 char*nsname = escape_string(m->ns->name);
513 mname = malloc(strlen(nsname)+namelen+32);
515 if(m->type == QNAMEA)
516 strcat(mname, ",attr");
518 strcat(mname,access2str(m->ns->access));
520 strcat(mname, nsname);
524 } else if(m->type==RTQNAME || m->type==RTQNAMEA) {
525 mname = malloc(namelen+32);
526 strcpy(mname, "<rt");
527 if(m->type == RTQNAMEA)
528 strcat(mname, ",attr");
531 } else if(m->type==RTQNAMEL) {
532 mname = strdup("<rt,l>");
533 } else if(m->type==RTQNAMELA) {
534 mname = strdup("<rt,l,attr>");
535 } else if(m->type==MULTINAME || m->type==MULTINAMEA) {
536 char*s = namespace_set_to_string(m->namespace_set);
537 mname = malloc(strlen(s)+namelen+16);
538 if(m->type == MULTINAME)
539 strcpy(mname,"<multi>");
541 strcpy(mname,"<multi,attr>");
546 } else if(m->type==MULTINAMEL || m->type==MULTINAMELA) {
547 char*s = namespace_set_to_string(m->namespace_set);
548 mname = malloc(strlen(s)+16);
549 if(m->type == MULTINAMEL)
550 strcpy(mname,"<l,multi>");
552 strcpy(mname,"<l,multi,attr>");
556 fprintf(stderr, "Invalid multiname type: %02x\n", m->type);
562 multiname_t* multiname_fromstring(const char*name2)
566 char*n = strdup(name2);
567 char*p = strstr(n, "::");
568 char*namespace=0,*name=0;
571 fprintf(stderr, "Error: single ':' in name\n");
579 if(strchr(namespace, ':')) {
580 fprintf(stderr, "Error: single ':' in namespace\n");
582 if(strchr(name, ':')) {
583 fprintf(stderr, "Error: single ':' in qualified name\n");
587 multiname_t*m = malloc(sizeof(multiname_t));
588 memset(m, 0, sizeof(multiname_t));
590 m->namespace_set = 0;
591 m->ns = namespace_fromstring(namespace);
592 m->name = name?strdup(name):0;
597 void multiname_destroy(multiname_t*m)
601 free((void*)m->name);m->name = 0;
604 namespace_destroy(m->ns);m->ns = 0;
606 if(m->namespace_set) {
607 namespace_set_destroy(m->namespace_set);m->namespace_set = 0;
613 type_t multiname_type = {
614 dup: (dup_func)multiname_clone,
615 hash: (hash_func)multiname_hash,
616 free: (free_func)multiname_destroy,
617 equals: (equals_func)multiname_equals
620 // ------------------------------- pool -------------------------------------
622 int pool_register_uint(pool_t*p, unsigned int i)
624 int pos = array_append_if_new(p->x_uints, &i, 0);
628 int pool_register_int(pool_t*p, int i)
630 int pos = array_append_if_new(p->x_ints, &i, 0);
634 int pool_register_float(pool_t*p, double d)
636 int pos = array_append_if_new(p->x_floats, &d, 0);
640 int pool_register_string(pool_t*pool, const char*s)
643 int pos = array_append_if_new(pool->x_strings, s, 0);
647 int pool_register_namespace(pool_t*pool, namespace_t*ns)
650 int pos = array_append_if_new(pool->x_namespaces, ns, 0);
654 int pool_register_namespace_set(pool_t*pool, namespace_set_t*set)
657 int pos = array_append_if_new(pool->x_namespace_sets, set, 0);
661 int pool_register_multiname(pool_t*pool, multiname_t*n)
664 int pos = array_append_if_new(pool->x_multinames, n, 0);
671 int pool_register_multiname2(pool_t*pool, char*name)
674 multiname_t*n = multiname_fromstring(name);
675 int pos = array_append_if_new(pool->x_multinames, n, 0);
676 multiname_destroy(n);
682 int pool_find_uint(pool_t*pool, unsigned int x)
684 int i = array_find(pool->x_uints, &x);
686 fprintf(stderr, "Couldn't find uint \"%d\" in constant pool\n", x);
691 int pool_find_int(pool_t*pool, int x)
693 int i = array_find(pool->x_ints, &x);
695 fprintf(stderr, "Couldn't find int \"%d\" in constant pool\n", x);
700 int pool_find_float(pool_t*pool, double x)
702 int i = array_find(pool->x_ints, &x);
704 fprintf(stderr, "Couldn't find int \"%d\" in constant pool\n", x);
709 int pool_find_namespace(pool_t*pool, namespace_t*ns)
713 int i = array_find(pool->x_namespaces, ns);
715 char*s = namespace_to_string(ns);
716 fprintf(stderr, "Couldn't find namespace \"%s\" %08x in constant pool\n", s, ns);
722 int pool_find_namespace_set(pool_t*pool, namespace_set_t*set)
726 int i = array_find(pool->x_namespace_sets, set);
728 char*s = namespace_set_to_string(set);
729 fprintf(stderr, "Couldn't find namespace_set \"%s\" in constant pool\n", s);
735 int pool_find_string(pool_t*pool, const char*s)
739 int i = array_find(pool->x_strings, s);
741 fprintf(stderr, "Couldn't find string \"%s\" in constant pool\n", s);
746 int pool_find_multiname(pool_t*pool, multiname_t*name)
750 int i = array_find(pool->x_multinames, name);
752 char*s = multiname_to_string(name);
753 fprintf(stderr, "Couldn't find multiname \"%s\" in constant pool\n", s);
760 int pool_lookup_int(pool_t*pool, int i)
763 return *(int*)array_getkey(pool->x_ints, i);
765 unsigned int pool_lookup_uint(pool_t*pool, int i)
768 return *(unsigned int*)array_getkey(pool->x_uints, i);
770 double pool_lookup_float(pool_t*pool, int i)
772 if(!i) return __builtin_nan("");
773 return *(double*)array_getkey(pool->x_floats, i);
775 char*pool_lookup_string(pool_t*pool, int i)
777 return (char*)array_getkey(pool->x_strings, i);
779 namespace_t*pool_lookup_namespace(pool_t*pool, int i)
781 return (namespace_t*)array_getkey(pool->x_namespaces, i);
783 namespace_set_t*pool_lookup_namespace_set(pool_t*pool, int i)
785 return (namespace_set_t*)array_getkey(pool->x_namespace_sets, i);
787 multiname_t*pool_lookup_multiname(pool_t*pool, int i)
789 return (multiname_t*)array_getkey(pool->x_multinames, i);
796 p->x_ints = array_new2(&uint_type);
797 p->x_uints = array_new2(&uint_type);
798 p->x_floats = array_new2(&float_type);
799 p->x_strings = array_new2(&charptr_type);
800 p->x_namespaces = array_new2(&namespace_type);
801 p->x_namespace_sets = array_new2(&namespace_set_type);
802 p->x_multinames = array_new2(&multiname_type);
804 /* add a zero-index entry in each list */
806 array_append(p->x_ints, 0, 0);
807 array_append(p->x_uints, 0, 0);
808 array_append(p->x_floats, 0, 0);
809 array_append(p->x_strings, 0, 0);
810 array_append(p->x_namespaces, 0, 0);
811 array_append(p->x_namespace_sets, 0, 0);
812 array_append(p->x_multinames, 0, 0);
819 void pool_read(pool_t*pool, TAG*tag)
821 int num_ints = swf_GetU30(tag);
822 DEBUG printf("%d ints\n", num_ints);
824 for(t=1;t<num_ints;t++) {
825 S32 v = swf_GetS30(tag);
826 DEBUG printf("int %d) %d\n", t, v);
827 array_append(pool->x_ints, &v, 0);
830 int num_uints = swf_GetU30(tag);
831 DEBUG printf("%d uints\n", num_uints);
832 for(t=1;t<num_uints;t++) {
833 U32 v = swf_GetU30(tag);
834 DEBUG printf("uint %d) %d\n", t, v);
835 array_append(pool->x_uints, &v, 0);
838 int num_floats = swf_GetU30(tag);
839 DEBUG printf("%d floats\n", num_floats);
840 for(t=1;t<num_floats;t++) {
841 double d = swf_GetD64(tag);
842 DEBUG printf("float %d) %f\n", t, d);
843 array_append(pool->x_floats, &d, 0);
846 int num_strings = swf_GetU30(tag);
847 DEBUG printf("%d strings\n", num_strings);
848 for(t=1;t<num_strings;t++) {
849 int len = swf_GetU30(tag);
850 char*s = malloc(len+1);
851 swf_GetBlock(tag, s, len);
853 array_append(pool->x_strings, s, 0);
855 DEBUG printf("%d) \"%s\"\n", t, pool->x_strings->d[t].name);
857 int num_namespaces = swf_GetU30(tag);
858 DEBUG printf("%d namespaces\n", num_namespaces);
859 for(t=1;t<num_namespaces;t++) {
860 U8 type = swf_GetU8(tag);
861 int namenr = swf_GetU30(tag);
862 const char*name = "";
863 if(namenr) //spec page 22: "a value of zero denotes an empty string"
864 name = array_getkey(pool->x_strings, namenr);
865 namespace_t*ns = namespace_new(type, name);
866 array_append(pool->x_namespaces, ns, 0);
867 DEBUG printf("%d) %02x \"%s\"\n", t, type, namespace_to_string(ns));
868 namespace_destroy(ns);
870 int num_sets = swf_GetU30(tag);
871 DEBUG printf("%d namespace sets\n", num_sets);
872 for(t=1;t<num_sets;t++) {
873 int count = swf_GetU30(tag);
876 NEW(namespace_set_t, nsset);
877 for(s=0;s<count;s++) {
878 int nsnr = swf_GetU30(tag);
880 fprintf(stderr, "Zero entry in namespace set\n");
881 namespace_t*ns = (namespace_t*)array_getkey(pool->x_namespaces, nsnr);
882 list_append(nsset->namespaces, namespace_clone(ns));
884 array_append(pool->x_namespace_sets, nsset, 0);
885 DEBUG printf("set %d) %s\n", t, namespace_set_to_string(nsset));
886 namespace_set_destroy(nsset);
889 int num_multinames = swf_GetU30(tag);
890 DEBUG printf("%d multinames\n", num_multinames);
891 for(t=1;t<num_multinames;t++) {
893 memset(&m, 0, sizeof(multiname_t));
894 m.type = swf_GetU8(tag);
895 if(m.type==0x07 || m.type==0x0d) {
896 int namespace_index = swf_GetU30(tag);
897 m.ns = (namespace_t*)array_getkey(pool->x_namespaces, namespace_index);
898 int name_index = swf_GetU30(tag);
899 if(name_index) // 0 = '*' (any)
900 m.name = array_getkey(pool->x_strings, name_index);
901 } else if(m.type==0x0f || m.type==0x10) {
902 int name_index = swf_GetU30(tag);
903 if(name_index) // 0 = '*' (any name)
904 m.name = array_getkey(pool->x_strings, name_index);
905 } else if(m.type==0x11 || m.type==0x12) {
906 } else if(m.type==0x09 || m.type==0x0e) {
907 int name_index = swf_GetU30(tag);
908 int namespace_set_index = swf_GetU30(tag);
910 m.name = array_getkey(pool->x_strings, name_index);
911 m.namespace_set = (namespace_set_t*)array_getkey(pool->x_namespace_sets, namespace_set_index);
912 } else if(m.type==0x1b || m.type==0x1c) {
913 int namespace_set_index = swf_GetU30(tag);
914 m.namespace_set = (namespace_set_t*)array_getkey(pool->x_namespace_sets, namespace_set_index);
916 printf("can't parse type %d multinames yet\n", m.type);
918 DEBUG printf("multiname %d) %s\n", t, multiname_to_string(&m));
919 array_append(pool->x_multinames, &m, 0);
921 printf("%d ints\n", num_ints);
922 printf("%d uints\n", num_uints);
923 printf("%d strings\n", num_strings);
924 printf("%d namespaces\n", num_namespaces);
925 printf("%d namespace sets\n", num_sets);
926 printf("%d multinames\n", num_multinames);
929 void pool_write(pool_t*pool, TAG*tag)
933 /* make sure that all namespaces used by multinames / namespace sets
934 and all strings used by namespaces exist */
936 for(t=1;t<pool->x_multinames->num;t++) {
937 multiname_t*m = (multiname_t*)array_getkey(pool->x_multinames, t);
939 pool_register_namespace(pool, m->ns);
941 if(m->namespace_set) {
942 pool_register_namespace_set(pool, m->namespace_set);
945 pool_register_string(pool, m->name);
948 for(t=1;t<pool->x_namespace_sets->num;t++) {
949 namespace_set_t*set = (namespace_set_t*)array_getkey(pool->x_namespace_sets, t);
950 namespace_list_t*i = set->namespaces;
952 pool_register_namespace(pool, i->namespace);
956 for(t=1;t<pool->x_namespaces->num;t++) {
957 namespace_t*ns= (namespace_t*)array_getkey(pool->x_namespaces, t);
958 if(ns->name && ns->name[0])
959 array_append_if_new(pool->x_strings, ns->name, 0);
963 swf_SetU30(tag, pool->x_ints->num>1?pool->x_ints->num:0);
964 for(t=1;t<pool->x_ints->num;t++) {
965 S32 val = *(int*)array_getkey(pool->x_ints, t);
966 swf_SetS30(tag, val);
968 swf_SetU30(tag, pool->x_uints->num>1?pool->x_uints->num:0);
969 for(t=1;t<pool->x_uints->num;t++) {
970 swf_SetU30(tag, *(unsigned int*)array_getkey(pool->x_uints, t));
972 swf_SetU30(tag, pool->x_floats->num>1?pool->x_floats->num:0);
973 for(t=1;t<pool->x_floats->num;t++) {
974 array_getvalue(pool->x_floats, t);
975 swf_SetD64(tag, 0.0); // fixme
977 swf_SetU30(tag, pool->x_strings->num>1?pool->x_strings->num:0);
978 for(t=1;t<pool->x_strings->num;t++) {
979 swf_SetU30String(tag, array_getkey(pool->x_strings, t));
981 swf_SetU30(tag, pool->x_namespaces->num>1?pool->x_namespaces->num:0);
982 for(t=1;t<pool->x_namespaces->num;t++) {
983 namespace_t*ns= (namespace_t*)array_getkey(pool->x_namespaces, t);
984 swf_SetU8(tag, ns->access);
985 const char*name = ns->name;
988 i = pool_find_string(pool, name);
991 swf_SetU30(tag, pool->x_namespace_sets->num>1?pool->x_namespace_sets->num:0);
992 for(t=1;t<pool->x_namespace_sets->num;t++) {
993 namespace_set_t*set = (namespace_set_t*)array_getkey(pool->x_namespace_sets, t);
994 namespace_list_t*i = set->namespaces;
995 int len = list_length(i);
996 swf_SetU30(tag, len);
998 int index = pool_find_namespace(pool, i->namespace);
999 swf_SetU30(tag, index);
1004 swf_SetU30(tag, pool->x_multinames->num>1?pool->x_multinames->num:0);
1005 for(t=1;t<pool->x_multinames->num;t++) {
1006 multiname_t*m = (multiname_t*)array_getkey(pool->x_multinames, t);
1007 swf_SetU8(tag, m->type);
1010 assert(m->type==0x07 || m->type==0x0d);
1011 int i = pool_find_namespace(pool, m->ns);
1012 if(i<0) fprintf(stderr, "internal error: unregistered namespace %02x %s %s\n", m->ns->access, access2str(m->ns->access), m->ns->name);
1015 assert(m->type!=0x07 && m->type!=0x0d);
1018 assert(m->type==0x09 || m->type==0x0e || m->type==0x07 || m->type==0x0d || m->type==0x0f || m->type==0x10);
1019 int i = pool_find_string(pool, m->name);
1020 if(i<0) fprintf(stderr, "internal error: unregistered name\n");
1023 assert(m->type!=0x09 && m->type!=0x0e && m->type!=0x07 && m->type!=0x0d && m->type!=0x0f && m->type!=0x10);
1025 if(m->namespace_set) {
1026 assert(m->type==0x09 || m->type==0x0e || m->type==0x1c || m->type==0x1b);
1027 int i = pool_find_namespace_set(pool, m->namespace_set);
1028 if(i<0) fprintf(stderr, "internal error: unregistered namespace set\n");
1031 assert(m->type!=0x09 && m->type!=0x0e && m->type!=0x1c && m->type!=0x1b);
1037 void pool_destroy(pool_t*pool)
1040 array_free(pool->x_ints);
1041 array_free(pool->x_uints);
1042 array_free(pool->x_floats);
1043 array_free(pool->x_strings);
1044 array_free(pool->x_namespaces);
1045 array_free(pool->x_namespace_sets);
1046 array_free(pool->x_multinames);