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);
561 multiname_t* multiname_fromstring(const char*name2)
565 char*n = strdup(name2);
566 char*p = strstr(n, "::");
567 char*namespace=0,*name=0;
570 fprintf(stderr, "Error: single ':' in name\n");
578 if(strchr(namespace, ':')) {
579 fprintf(stderr, "Error: single ':' in namespace\n");
581 if(strchr(name, ':')) {
582 fprintf(stderr, "Error: single ':' in qualified name\n");
586 multiname_t*m = malloc(sizeof(multiname_t));
587 memset(m, 0, sizeof(multiname_t));
589 m->namespace_set = 0;
590 m->ns = namespace_fromstring(namespace);
591 m->name = name?strdup(name):0;
596 void multiname_destroy(multiname_t*m)
600 free((void*)m->name);m->name = 0;
603 namespace_destroy(m->ns);m->ns = 0;
605 if(m->namespace_set) {
606 namespace_set_destroy(m->namespace_set);m->namespace_set = 0;
612 type_t multiname_type = {
613 dup: (dup_func)multiname_clone,
614 hash: (hash_func)multiname_hash,
615 free: (free_func)multiname_destroy,
616 equals: (equals_func)multiname_equals
619 // ------------------------------- pool -------------------------------------
621 int pool_register_uint(pool_t*p, unsigned int i)
623 int pos = array_append_if_new(p->x_uints, &i, 0);
627 int pool_register_int(pool_t*p, int i)
629 int pos = array_append_if_new(p->x_ints, &i, 0);
633 int pool_register_float(pool_t*p, double d)
635 int pos = array_append_if_new(p->x_floats, &d, 0);
639 int pool_register_string(pool_t*pool, const char*s)
642 int pos = array_append_if_new(pool->x_strings, s, 0);
646 int pool_register_namespace(pool_t*pool, namespace_t*ns)
649 int pos = array_append_if_new(pool->x_namespaces, ns, 0);
653 int pool_register_namespace_set(pool_t*pool, namespace_set_t*set)
656 int pos = array_append_if_new(pool->x_namespace_sets, set, 0);
660 int pool_register_multiname(pool_t*pool, multiname_t*n)
663 int pos = array_append_if_new(pool->x_multinames, n, 0);
670 int pool_register_multiname2(pool_t*pool, char*name)
673 multiname_t*n = multiname_fromstring(name);
674 int pos = array_append_if_new(pool->x_multinames, n, 0);
675 multiname_destroy(n);
681 int pool_find_uint(pool_t*pool, unsigned int x)
683 int i = array_find(pool->x_uints, &x);
685 fprintf(stderr, "Couldn't find uint \"%d\" in constant pool\n", x);
690 int pool_find_int(pool_t*pool, int x)
692 int i = array_find(pool->x_ints, &x);
694 fprintf(stderr, "Couldn't find int \"%d\" in constant pool\n", x);
699 int pool_find_float(pool_t*pool, double x)
701 int i = array_find(pool->x_ints, &x);
703 fprintf(stderr, "Couldn't find int \"%d\" in constant pool\n", x);
708 int pool_find_namespace(pool_t*pool, namespace_t*ns)
712 int i = array_find(pool->x_namespaces, ns);
714 char*s = namespace_to_string(ns);
715 fprintf(stderr, "Couldn't find namespace \"%s\" %08x in constant pool\n", s, ns);
721 int pool_find_namespace_set(pool_t*pool, namespace_set_t*set)
725 int i = array_find(pool->x_namespace_sets, set);
727 char*s = namespace_set_to_string(set);
728 fprintf(stderr, "Couldn't find namespace_set \"%s\" in constant pool\n", s);
734 int pool_find_string(pool_t*pool, const char*s)
738 int i = array_find(pool->x_strings, s);
740 fprintf(stderr, "Couldn't find string \"%s\" in constant pool\n", s);
745 int pool_find_multiname(pool_t*pool, multiname_t*name)
749 int i = array_find(pool->x_multinames, name);
751 char*s = multiname_to_string(name);
752 fprintf(stderr, "Couldn't find multiname \"%s\" in constant pool\n", s);
759 int pool_lookup_int(pool_t*pool, int i)
762 return *(int*)array_getkey(pool->x_ints, i);
764 unsigned int pool_lookup_uint(pool_t*pool, int i)
767 return *(unsigned int*)array_getkey(pool->x_uints, i);
769 double pool_lookup_float(pool_t*pool, int i)
771 if(!i) return __builtin_nan("");
772 return *(double*)array_getkey(pool->x_floats, i);
774 char*pool_lookup_string(pool_t*pool, int i)
776 return (char*)array_getkey(pool->x_strings, i);
778 namespace_t*pool_lookup_namespace(pool_t*pool, int i)
780 return (namespace_t*)array_getkey(pool->x_namespaces, i);
782 namespace_set_t*pool_lookup_namespace_set(pool_t*pool, int i)
784 return (namespace_set_t*)array_getkey(pool->x_namespace_sets, i);
786 multiname_t*pool_lookup_multiname(pool_t*pool, int i)
788 return (multiname_t*)array_getkey(pool->x_multinames, i);
795 p->x_ints = array_new2(&uint_type);
796 p->x_uints = array_new2(&uint_type);
797 p->x_floats = array_new2(&float_type);
798 p->x_strings = array_new2(&charptr_type);
799 p->x_namespaces = array_new2(&namespace_type);
800 p->x_namespace_sets = array_new2(&namespace_set_type);
801 p->x_multinames = array_new2(&multiname_type);
803 /* add a zero-index entry in each list */
805 array_append(p->x_ints, 0, 0);
806 array_append(p->x_uints, 0, 0);
807 array_append(p->x_floats, 0, 0);
808 array_append(p->x_strings, 0, 0);
809 array_append(p->x_namespaces, 0, 0);
810 array_append(p->x_namespace_sets, 0, 0);
811 array_append(p->x_multinames, 0, 0);
818 void pool_read(pool_t*pool, TAG*tag)
820 int num_ints = swf_GetU30(tag);
821 DEBUG printf("%d ints\n", num_ints);
823 for(t=1;t<num_ints;t++) {
824 S32 v = swf_GetS30(tag);
825 DEBUG printf("int %d) %d\n", t, v);
826 array_append(pool->x_ints, &v, 0);
829 int num_uints = swf_GetU30(tag);
830 DEBUG printf("%d uints\n", num_uints);
831 for(t=1;t<num_uints;t++) {
832 U32 v = swf_GetU30(tag);
833 DEBUG printf("uint %d) %d\n", t, v);
834 array_append(pool->x_uints, &v, 0);
837 int num_floats = swf_GetU30(tag);
838 DEBUG printf("%d floats\n", num_floats);
839 for(t=1;t<num_floats;t++) {
840 double d = swf_GetD64(tag);
841 DEBUG printf("float %d) %f\n", t, d);
842 array_append(pool->x_floats, &d, 0);
845 int num_strings = swf_GetU30(tag);
846 DEBUG printf("%d strings\n", num_strings);
847 for(t=1;t<num_strings;t++) {
848 int len = swf_GetU30(tag);
849 char*s = malloc(len+1);
850 swf_GetBlock(tag, s, len);
852 array_append(pool->x_strings, s, 0);
854 DEBUG printf("%d) \"%s\"\n", t, pool->x_strings->d[t].name);
856 int num_namespaces = swf_GetU30(tag);
857 DEBUG printf("%d namespaces\n", num_namespaces);
858 for(t=1;t<num_namespaces;t++) {
859 U8 type = swf_GetU8(tag);
860 int namenr = swf_GetU30(tag);
861 const char*name = "";
862 if(namenr) //spec page 22: "a value of zero denotes an empty string"
863 name = array_getkey(pool->x_strings, namenr);
864 namespace_t*ns = namespace_new(type, name);
865 array_append(pool->x_namespaces, ns, 0);
866 DEBUG printf("%d) %02x \"%s\"\n", t, type, namespace_to_string(ns));
867 namespace_destroy(ns);
869 int num_sets = swf_GetU30(tag);
870 DEBUG printf("%d namespace sets\n", num_sets);
871 for(t=1;t<num_sets;t++) {
872 int count = swf_GetU30(tag);
875 NEW(namespace_set_t, nsset);
876 for(s=0;s<count;s++) {
877 int nsnr = swf_GetU30(tag);
879 fprintf(stderr, "Zero entry in namespace set\n");
880 namespace_t*ns = (namespace_t*)array_getkey(pool->x_namespaces, nsnr);
881 list_append(nsset->namespaces, namespace_clone(ns));
883 array_append(pool->x_namespace_sets, nsset, 0);
884 DEBUG printf("set %d) %s\n", t, namespace_set_to_string(nsset));
885 namespace_set_destroy(nsset);
888 int num_multinames = swf_GetU30(tag);
889 DEBUG printf("%d multinames\n", num_multinames);
890 for(t=1;t<num_multinames;t++) {
892 memset(&m, 0, sizeof(multiname_t));
893 m.type = swf_GetU8(tag);
894 if(m.type==0x07 || m.type==0x0d) {
895 int namespace_index = swf_GetU30(tag);
896 m.ns = (namespace_t*)array_getkey(pool->x_namespaces, namespace_index);
897 int name_index = swf_GetU30(tag);
898 if(name_index) // 0 = '*' (any)
899 m.name = array_getkey(pool->x_strings, name_index);
900 } else if(m.type==0x0f || m.type==0x10) {
901 int name_index = swf_GetU30(tag);
902 if(name_index) // 0 = '*' (any name)
903 m.name = array_getkey(pool->x_strings, name_index);
904 } else if(m.type==0x11 || m.type==0x12) {
905 } else if(m.type==0x09 || m.type==0x0e) {
906 int name_index = swf_GetU30(tag);
907 int namespace_set_index = swf_GetU30(tag);
909 m.name = array_getkey(pool->x_strings, name_index);
910 m.namespace_set = (namespace_set_t*)array_getkey(pool->x_namespace_sets, namespace_set_index);
911 } else if(m.type==0x1b || m.type==0x1c) {
912 int namespace_set_index = swf_GetU30(tag);
913 m.namespace_set = (namespace_set_t*)array_getkey(pool->x_namespace_sets, namespace_set_index);
915 printf("can't parse type %d multinames yet\n", m.type);
917 DEBUG printf("multiname %d) %s\n", t, multiname_to_string(&m));
918 array_append(pool->x_multinames, &m, 0);
920 printf("%d ints\n", num_ints);
921 printf("%d uints\n", num_uints);
922 printf("%d strings\n", num_strings);
923 printf("%d namespaces\n", num_namespaces);
924 printf("%d namespace sets\n", num_sets);
925 printf("%d multinames\n", num_multinames);
928 void pool_write(pool_t*pool, TAG*tag)
932 /* make sure that all namespaces used by multinames / namespace sets
933 and all strings used by namespaces exist */
935 for(t=1;t<pool->x_multinames->num;t++) {
936 multiname_t*m = (multiname_t*)array_getkey(pool->x_multinames, t);
938 pool_register_namespace(pool, m->ns);
940 if(m->namespace_set) {
941 pool_register_namespace_set(pool, m->namespace_set);
944 pool_register_string(pool, m->name);
947 for(t=1;t<pool->x_namespace_sets->num;t++) {
948 namespace_set_t*set = (namespace_set_t*)array_getkey(pool->x_namespace_sets, t);
949 namespace_list_t*i = set->namespaces;
951 pool_register_namespace(pool, i->namespace);
955 for(t=1;t<pool->x_namespaces->num;t++) {
956 namespace_t*ns= (namespace_t*)array_getkey(pool->x_namespaces, t);
957 if(ns->name && ns->name[0])
958 array_append_if_new(pool->x_strings, ns->name, 0);
962 swf_SetU30(tag, pool->x_ints->num>1?pool->x_ints->num:0);
963 for(t=1;t<pool->x_ints->num;t++) {
964 S32 val = *(int*)array_getkey(pool->x_ints, t);
965 swf_SetS30(tag, val);
967 swf_SetU30(tag, pool->x_uints->num>1?pool->x_uints->num:0);
968 for(t=1;t<pool->x_uints->num;t++) {
969 swf_SetU30(tag, *(unsigned int*)array_getkey(pool->x_uints, t));
971 swf_SetU30(tag, pool->x_floats->num>1?pool->x_floats->num:0);
972 for(t=1;t<pool->x_floats->num;t++) {
973 array_getvalue(pool->x_floats, t);
974 swf_SetD64(tag, 0.0); // fixme
976 swf_SetU30(tag, pool->x_strings->num>1?pool->x_strings->num:0);
977 for(t=1;t<pool->x_strings->num;t++) {
978 swf_SetU30String(tag, array_getkey(pool->x_strings, t));
980 swf_SetU30(tag, pool->x_namespaces->num>1?pool->x_namespaces->num:0);
981 for(t=1;t<pool->x_namespaces->num;t++) {
982 namespace_t*ns= (namespace_t*)array_getkey(pool->x_namespaces, t);
983 swf_SetU8(tag, ns->access);
984 const char*name = ns->name;
987 i = pool_find_string(pool, name);
990 swf_SetU30(tag, pool->x_namespace_sets->num>1?pool->x_namespace_sets->num:0);
991 for(t=1;t<pool->x_namespace_sets->num;t++) {
992 namespace_set_t*set = (namespace_set_t*)array_getkey(pool->x_namespace_sets, t);
993 namespace_list_t*i = set->namespaces;
994 int len = list_length(i);
995 swf_SetU30(tag, len);
997 int index = pool_find_namespace(pool, i->namespace);
998 swf_SetU30(tag, index);
1003 swf_SetU30(tag, pool->x_multinames->num>1?pool->x_multinames->num:0);
1004 for(t=1;t<pool->x_multinames->num;t++) {
1005 multiname_t*m = (multiname_t*)array_getkey(pool->x_multinames, t);
1006 swf_SetU8(tag, m->type);
1009 assert(m->type==0x07 || m->type==0x0d);
1010 int i = pool_find_namespace(pool, m->ns);
1011 if(i<0) fprintf(stderr, "internal error: unregistered namespace %02x %s %s\n", m->ns->access, access2str(m->ns->access), m->ns->name);
1014 assert(m->type!=0x07 && m->type!=0x0d);
1017 assert(m->type==0x09 || m->type==0x0e || m->type==0x07 || m->type==0x0d || m->type==0x0f || m->type==0x10);
1018 int i = pool_find_string(pool, m->name);
1019 if(i<0) fprintf(stderr, "internal error: unregistered name\n");
1022 assert(m->type!=0x09 && m->type!=0x0e && m->type!=0x07 && m->type!=0x0d && m->type!=0x0f && m->type!=0x10);
1024 if(m->namespace_set) {
1025 assert(m->type==0x09 || m->type==0x0e || m->type==0x1c || m->type==0x1b);
1026 int i = pool_find_namespace_set(pool, m->namespace_set);
1027 if(i<0) fprintf(stderr, "internal error: unregistered namespace set\n");
1030 assert(m->type!=0x09 && m->type!=0x0e && m->type!=0x1c && m->type!=0x1b);
1036 void pool_destroy(pool_t*pool)
1039 array_free(pool->x_ints);
1040 array_free(pool->x_uints);
1041 array_free(pool->x_floats);
1042 array_free(pool->x_strings);
1043 array_free(pool->x_namespaces);
1044 array_free(pool->x_namespace_sets);
1045 array_free(pool->x_multinames);