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 double undefined_float = 0.0;
32 void* float_clone(const void*_v) {
33 if(_v==&undefined_float)
34 return &undefined_float;
36 double*v2 = malloc(sizeof(double));
40 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;
50 if(v!=&undefined_float)
53 char float_equals(const void*_v1, const void*_v2) {
56 if(v1==&undefined_float || v2==&undefined_float)
68 // ----------------------------- uint ----------------------------------
70 int undefined_uint = 0;
72 ptroff_t uint_clone(const void*v) {
75 unsigned int uint_hash(const void*v) {return (ptroff_t)v;}
76 void uint_destroy(void*v) {}
77 char uint_equals(const void*v1, const void*v2) {return v1==v2;}
80 dup: (dup_func)uint_clone,
81 hash: (hash_func)uint_hash,
82 free: (free_func)uint_destroy,
83 equals: (equals_func)uint_equals
86 // ----------------------------- namespace ----------------------------------
88 unsigned int namespace_hash(namespace_t*n)
90 unsigned int hash = 0;
91 hash = crc32_add_byte(hash, n->access);
92 hash = crc32_add_string(hash, n->name);
96 unsigned char namespace_equals(const namespace_t*n1, const namespace_t*n2)
98 if(n1->access != n2->access)
100 if(!(n1->name) != !(n2->name))
102 if(n1->name && n2->name && strcmp(n1->name, n2->name))
107 char* namespace_to_string(namespace_t*ns)
110 U8 type = ns->access;
111 access = access2str(type);
112 char*string = malloc(strlen(access)+strlen(ns->name)+3);
113 sprintf(string, "[%s]%s", access, ns->name);
117 namespace_t* namespace_clone(namespace_t*other)
120 n->access = other->access;
121 n->name = strdup(other->name);
125 namespace_t* namespace_new(U8 access, const char*name)
127 namespace_t*ns = malloc(sizeof(namespace_t));
128 memset(ns, 0, sizeof(namespace_t));
130 if(access==0) { // autodetect access
131 char*n = strdup(name);
133 char*bracket = strchr(n, ']');
137 name += (bracket-n)+1;
138 if(!strcmp(a, "")) access=0x16;
139 else if(!strcmp(a, "undefined")) access=0x08; // public??
140 else if(!strcmp(a, "package")) access=0x16;
141 else if(!strcmp(a, "packageinternal")) access=0x17;
142 else if(!strcmp(a, "protected")) access=0x18;
143 else if(!strcmp(a, "explicit")) access=0x19;
144 else if(!strcmp(a, "staticprotected")) access=0x1a;
145 else if(!strcmp(a, "private")) access=0x05;
147 fprintf(stderr, "Undefined access level: [%s]\n", a);
157 ns->name = strdup(name);
161 namespace_t* namespace_new_undefined(const char*name) {
162 return namespace_new(0x08, name); // public?
164 namespace_t* namespace_new_package(const char*name) {
165 return namespace_new(0x16 , name);
167 namespace_t* namespace_new_packageinternal(const char*name) {
168 return namespace_new(0x17, name);
170 namespace_t* namespace_new_protected(const char*name) {
171 return namespace_new(0x18, name);
173 namespace_t* namespace_new_explicit(const char*name) {
174 return namespace_new(0x19, name);
176 namespace_t* namespace_new_staticprotected(const char*name) {
177 return namespace_new(0x1a, name);
179 namespace_t* namespace_new_private(const char*name) {
180 return namespace_new(0x05, name);
183 void namespace_destroy(namespace_t*n)
185 free(n->name);n->name=0;
190 type_t namespace_type = {
191 dup: (dup_func)namespace_clone,
192 hash: (hash_func)namespace_hash,
193 free: (free_func)namespace_destroy,
194 equals: (equals_func)namespace_equals
197 // ---------------------------namespace sets --------------------------------
199 unsigned int namespace_set_hash(namespace_set_t*set)
201 namespace_list_t*l = set->namespaces;
202 unsigned int hash = 0;
204 hash = crc32_add_byte(hash, l->namespace->access);
205 hash = crc32_add_string(hash, l->namespace->name);
211 int namespace_set_equals(namespace_set_t*m1, namespace_set_t*m2)
213 namespace_list_t*l1 = m1->namespaces;
214 namespace_list_t*l2 = m2->namespaces;
216 if(l1->namespace->access != l2->namespace->access)
218 if(!(l1->namespace->name) != !(l2->namespace->name))
220 if(strcmp(l1->namespace->name, l2->namespace->name))
230 namespace_set_t* namespace_set_clone(namespace_set_t*other)
232 NEW(namespace_set_t,set);
233 set->namespaces = list_new();
234 namespace_list_t*l = other->namespaces;
236 list_append(set->namespaces, namespace_clone(l->namespace));
241 namespace_set_t* namespace_set_new()
243 NEW(namespace_set_t,set);
244 set->namespaces = list_new();
247 char* namespace_set_to_string(namespace_set_t*set)
249 /* TODO: is the order of the namespaces important (does it
250 change the lookup order?). E.g. flex freely shuffles namespaces
252 If the order is not important, we can optimize constant pools by sorting
256 namespace_list_t*lns = set->namespaces;
258 char*s = namespace_to_string(lns->namespace);
263 char*desc = malloc(l+16);
265 lns = set->namespaces;
267 char*s = namespace_to_string(lns->namespace);
278 void namespace_set_destroy(namespace_set_t*set)
280 namespace_list_t*l = set->namespaces;
282 namespace_destroy(l->namespace);l->namespace=0;
285 list_free(set->namespaces);
289 type_t namespace_set_type = {
290 dup: (dup_func)namespace_set_clone,
291 hash: (hash_func)namespace_set_hash,
292 free: (free_func)namespace_set_destroy,
293 equals: (equals_func)namespace_set_equals
296 // ----------------------------- multiname ----------------------------------
298 unsigned int multiname_hash(multiname_t*m)
300 unsigned int hash = crc32_add_byte(0, m->type);
302 hash = crc32_add_string(hash, m->name);
305 hash = crc32_add_byte(hash, m->ns->access);
306 hash = crc32_add_string(hash, m->ns->name);
308 if(m->namespace_set) {
309 namespace_list_t*l = m->namespace_set->namespaces;
311 hash = crc32_add_byte(hash, l->namespace->access);
312 hash = crc32_add_string(hash, l->namespace->name);
319 int multiname_equals(multiname_t*m1, multiname_t*m2)
321 if(m1->type!=m2->type)
324 if((!m1->name) != (!m2->name))
326 if((!m1->ns) != (!m2->ns))
328 if((!m1->namespace_set) != (!m2->namespace_set))
331 if(m1->name && m2->name && strcmp(m1->name,m2->name))
333 if(m1->ns && m2->ns) {
334 if(!namespace_equals(m1->ns, m2->ns))
337 if(m1->namespace_set && m2->namespace_set) {
338 if(!namespace_set_equals(m1->namespace_set, m2->namespace_set))
344 multiname_t* multiname_new(namespace_t*ns, const char*name)
348 m->ns = namespace_clone(ns);
349 m->name = strdup(name);
353 multiname_t* multiname_clone(multiname_t*other)
356 m->type = other->type;
358 m->ns = namespace_clone(other->ns);
359 if(other->namespace_set)
360 m->namespace_set = namespace_set_clone(other->namespace_set);
362 m->name = strdup(other->name);
367 char* access2str(int type)
369 if(type==0x08) return "access08";
370 else if(type==0x16) return "package";
371 else if(type==0x17) return "packageinternal";
372 else if(type==0x18) return "protected";
373 else if(type==0x19) return "explicit";
374 else if(type==0x1A) return "staticprotected";
375 else if(type==0x05) return "private";
377 fprintf(stderr, "Undefined access type %02x\n", type);
382 char* multiname_to_string(multiname_t*m)
385 if(!m || m->type==0xff)
386 return strdup("--<UNDEFINED_MULTINAME>--");
388 int namelen = m->name?strlen(m->name):1;
390 if(m->type==QNAME || m->type==QNAMEA) {
391 mname = malloc(strlen(m->ns->name)+namelen+32);
393 if(m->type == QNAMEA)
394 strcat(mname, ",attr");
396 strcat(mname,access2str(m->ns->access));
398 strcat(mname, m->ns->name);
401 strcat(mname, m->name);
404 } else if(m->type==RTQNAME || m->type==RTQNAMEA) {
405 mname = malloc(namelen+32);
406 strcpy(mname, "<rt");
407 if(m->type == RTQNAMEA)
408 strcat(mname, ",attr");
411 strcat(mname, m->name);
414 } else if(m->type==RTQNAMEL) {
415 mname = strdup("<l>");
416 } else if(m->type==RTQNAMELA) {
417 mname = strdup("<l,attr>");
418 } else if(m->type==MULTINAME || m->type==MULTINAMEA) {
419 char*s = namespace_set_to_string(m->namespace_set);
420 mname = malloc(strlen(s)+namelen+16);
421 if(m->type == MULTINAME)
422 strcpy(mname,"<multi>");
424 strcpy(mname,"<multi,attr>");
428 strcat(mname, m->name);
432 } else if(m->type==MULTINAMEL || m->type==MULTINAMELA) {
433 char*s = namespace_set_to_string(m->namespace_set);
434 mname = malloc(strlen(s)+16);
435 if(m->type == MULTINAMEL)
436 strcpy(mname,"<l,multi>");
438 strcpy(mname,"<l,multi,attr>");
442 fprintf(stderr, "Invalid multiname type: %02x\n", m->type);
447 multiname_t* multiname_fromstring(const char*name2)
451 char*n = strdup(name2);
452 char*p = strstr(n, "::");
453 char*namespace=0,*name=0;
456 fprintf(stderr, "Error: single ':' in name\n");
464 if(strchr(namespace, ':')) {
465 fprintf(stderr, "Error: single ':' in namespace\n");
467 if(strchr(name, ':')) {
468 fprintf(stderr, "Error: single ':' in qualified name\n");
472 multiname_t*m = malloc(sizeof(multiname_t));
473 memset(m, 0, sizeof(multiname_t));
475 m->namespace_set = 0;
483 void multiname_destroy(multiname_t*m)
486 free((void*)m->name);m->name = 0;
489 namespace_destroy(m->ns);m->ns = 0;
491 if(m->namespace_set) {
492 namespace_set_destroy(m->namespace_set);m->namespace_set = 0;
497 type_t multiname_type = {
498 dup: (dup_func)multiname_clone,
499 hash: (hash_func)multiname_hash,
500 free: (free_func)multiname_destroy,
501 equals: (equals_func)multiname_equals
504 // ------------------------------- pool -------------------------------------
506 int pool_register_uint(pool_t*p, unsigned int i)
508 return array_append_if_new(p->x_uints, (void*)(ptroff_t)i, 0);
510 int pool_register_int(pool_t*p, int i)
512 return array_append_if_new(p->x_ints, (void*)(ptroff_t)i, 0);
514 int pool_register_float(pool_t*p, double d)
516 return array_append_if_new(p->x_floats, &d, 0);
518 int pool_register_string(pool_t*pool, const char*s)
521 return array_append_if_new(pool->x_strings, s, 0);
523 int pool_register_namespace(pool_t*pool, namespace_t*ns)
526 return array_append_if_new(pool->x_namespaces, ns, 0);
528 int pool_register_namespace_set(pool_t*pool, namespace_set_t*set)
531 return array_append_if_new(pool->x_namespace_sets, set, 0);
533 int pool_register_multiname(pool_t*pool, multiname_t*n)
536 return array_append_if_new(pool->x_multinames, n, 0);
538 int pool_register_multiname2(pool_t*pool, char*name)
541 multiname_t*n = multiname_fromstring(name);
542 return array_append_if_new(pool->x_multinames, n, 0);
546 int pool_find_uint(pool_t*pool, unsigned int x)
548 int i = array_find(pool->x_uints, (void*)(ptroff_t)x);
550 fprintf(stderr, "Couldn't find uint \"%d\" in constant pool\n", x);
555 int pool_find_int(pool_t*pool, int x)
557 int i = array_find(pool->x_ints, (void*)(ptroff_t)x);
559 fprintf(stderr, "Couldn't find int \"%d\" in constant pool\n", x);
564 int pool_find_float(pool_t*pool, double x)
566 int i = array_find(pool->x_ints, &x);
568 fprintf(stderr, "Couldn't find int \"%d\" in constant pool\n", x);
573 int pool_find_namespace(pool_t*pool, namespace_t*ns)
577 int i = array_find(pool->x_namespaces, ns);
579 char*s = namespace_to_string(ns);
580 fprintf(stderr, "Couldn't find namespace \"%s\" %08x in constant pool\n", s, ns);
586 int pool_find_namespace_set(pool_t*pool, namespace_set_t*set)
588 int i = array_find(pool->x_namespace_sets, set);
590 char*s = namespace_set_to_string(set);
591 fprintf(stderr, "Couldn't find namespace_set \"%s\" in constant pool\n", s);
597 int pool_find_string(pool_t*pool, const char*s)
599 int i = array_find(pool->x_strings, s);
601 fprintf(stderr, "Couldn't find string \"%s\" in constant pool\n", s);
607 int pool_find_multiname(pool_t*pool, multiname_t*name)
609 int i = array_find(pool->x_multinames, name);
611 char*s = multiname_to_string(name);
612 fprintf(stderr, "Couldn't find multiname \"%s\" in constant pool\n", s);
619 int pool_lookup_int(pool_t*pool, int i)
621 return *(int*)array_getkey(pool->x_ints, i);
623 unsigned int pool_lookup_uint(pool_t*pool, int i)
625 return *(unsigned int*)array_getkey(pool->x_uints, i);
627 double pool_lookup_float(pool_t*pool, int i)
629 return *(double*)array_getkey(pool->x_floats, i);
631 char*pool_lookup_string(pool_t*pool, int i)
633 return (char*)array_getkey(pool->x_strings, i);
635 namespace_t*pool_lookup_namespace(pool_t*pool, int i)
637 return (namespace_t*)array_getkey(pool->x_namespaces, i);
639 namespace_set_t*pool_lookup_namespace_set(pool_t*pool, int i)
641 return (namespace_set_t*)array_getkey(pool->x_namespace_sets, i);
643 multiname_t*pool_lookup_multiname(pool_t*pool, int i)
645 return (multiname_t*)array_getkey(pool->x_multinames, i);
652 p->x_ints = array_new2(&uint_type);
653 p->x_uints = array_new2(&uint_type);
654 p->x_floats = array_new2(&float_type);
655 p->x_strings = array_new2(&charptr_type);
656 p->x_namespaces = array_new2(&namespace_type);
657 p->x_namespace_sets = array_new2(&namespace_set_type);
658 p->x_multinames = array_new2(&multiname_type);
660 /* add a zero-index entry in each list */
662 array_append(p->x_ints, &undefined_uint, 0);
663 array_append(p->x_uints, &undefined_uint, 0);
664 array_append(p->x_floats, &undefined_float, 0);
666 pool_register_string(p, "--<UNDEFINED_STRING>--");
668 namespace_t*ns = namespace_new(0,"--<UNDEFINED NAMESPACE>--");
669 pool_register_namespace(p, ns);
670 namespace_destroy(ns);
672 namespace_set_t*nsset = namespace_set_new();
673 list_append(nsset->namespaces, namespace_new(0, "--<UNDEFINED NAMESPACE SET>--"));
674 pool_register_namespace_set(p, nsset);
675 namespace_set_destroy(nsset);
677 namespace_t*mns = namespace_new(0,"nons");
678 multiname_t*mname = multiname_new(mns,"--<UNDEFINED MULTINAME>--");
680 pool_register_multiname(p, mname);
681 multiname_destroy(mname);
682 namespace_destroy(mns);
690 void pool_read(pool_t*pool, TAG*tag)
692 int num_ints = swf_GetU30(tag);
693 DEBUG printf("%d ints\n", num_ints);
695 for(t=1;t<num_ints;t++) {
696 S32 v = swf_GetS30(tag);
697 DEBUG printf("int %d) %d\n", t, v);
698 array_append(pool->x_ints, (void*)(ptroff_t)v, 0);
701 int num_uints = swf_GetU30(tag);
702 DEBUG printf("%d uints\n", num_uints);
703 for(t=1;t<num_uints;t++) {
704 U32 v = swf_GetU30(tag);
705 DEBUG printf("uint %d) %d\n", t, v);
706 array_append(pool->x_uints, (void*)(ptroff_t)v, 0);
709 int num_floats = swf_GetU30(tag);
710 DEBUG printf("%d floats\n", num_floats);
711 for(t=1;t<num_floats;t++) {
712 double d = swf_GetD64(tag);
713 DEBUG printf("float %d) %f\n", t, d);
714 array_append(pool->x_floats, &d, 0);
717 int num_strings = swf_GetU30(tag);
718 DEBUG printf("%d strings\n", num_strings);
719 for(t=1;t<num_strings;t++) {
720 int len = swf_GetU30(tag);
721 char*s = malloc(len+1);
722 swf_GetBlock(tag, s, len);
724 array_append(pool->x_strings, s, 0);
726 DEBUG printf("%d) \"%s\"\n", t, pool->x_strings->d[t].name);
728 int num_namespaces = swf_GetU30(tag);
729 DEBUG printf("%d namespaces\n", num_namespaces);
730 for(t=1;t<num_namespaces;t++) {
731 U8 type = swf_GetU8(tag);
732 int namenr = swf_GetU30(tag);
733 const char*name = array_getkey(pool->x_strings, namenr);
734 namespace_t*ns = namespace_new(type, name);
735 array_append(pool->x_namespaces, ns, 0);
736 DEBUG printf("%d) \"%s\"\n", t, namespace_to_string(ns));
737 namespace_destroy(ns);
739 int num_sets = swf_GetU30(tag);
740 DEBUG printf("%d namespace sets\n", num_sets);
741 for(t=1;t<num_sets;t++) {
742 int count = swf_GetU30(tag);
745 NEW(namespace_set_t, nsset);
746 for(s=0;s<count;s++) {
747 int nsnr = swf_GetU30(tag);
748 namespace_t*ns = (namespace_t*)array_getkey(pool->x_namespaces, nsnr);
749 list_append(nsset->namespaces, namespace_clone(ns));
751 array_append(pool->x_namespace_sets, nsset, 0);
752 DEBUG printf("set %d) %s\n", t, namespace_set_to_string(nsset));
753 namespace_set_destroy(nsset);
756 int num_multinames = swf_GetU30(tag);
757 DEBUG printf("%d multinames\n", num_multinames);
758 for(t=1;t<num_multinames;t++) {
760 memset(&m, 0, sizeof(multiname_t));
761 m.type = swf_GetU8(tag);
762 if(m.type==0x07 || m.type==0x0d) {
763 int namespace_index = swf_GetU30(tag);
764 m.ns = (namespace_t*)array_getkey(pool->x_namespaces, namespace_index);
765 int name_index = swf_GetU30(tag);
766 if(name_index) // 0 = '*' (any)
767 m.name = array_getkey(pool->x_strings, name_index);
768 } else if(m.type==0x0f || m.type==0x10) {
769 int name_index = swf_GetU30(tag);
770 if(name_index) // 0 = '*' (any name)
771 m.name = array_getkey(pool->x_strings, name_index);
772 } else if(m.type==0x11 || m.type==0x12) {
773 } else if(m.type==0x09 || m.type==0x0e) {
774 int name_index = swf_GetU30(tag);
775 int namespace_set_index = swf_GetU30(tag);
777 m.name = array_getkey(pool->x_strings, name_index);
778 m.namespace_set = (namespace_set_t*)array_getkey(pool->x_namespace_sets, namespace_set_index);
779 } else if(m.type==0x1b || m.type==0x1c) {
780 int namespace_set_index = swf_GetU30(tag);
781 m.namespace_set = (namespace_set_t*)array_getkey(pool->x_namespace_sets, namespace_set_index);
783 printf("can't parse type %d multinames yet\n", m.type);
785 DEBUG printf("multiname %d) %s\n", t, multiname_to_string(&m));
786 array_append(pool->x_multinames, &m, 0);
790 void pool_write(pool_t*pool, TAG*tag)
794 /* make sure that all namespaces used by multinames / namespace sets
795 and all strings used by namespaces exist */
797 for(t=1;t<pool->x_multinames->num;t++) {
798 multiname_t*m = (multiname_t*)array_getkey(pool->x_multinames, t);
800 pool_register_namespace(pool, m->ns);
802 if(m->namespace_set) {
803 pool_register_namespace_set(pool, m->namespace_set);
806 pool_register_string(pool, m->name);
809 for(t=1;t<pool->x_namespace_sets->num;t++) {
810 namespace_set_t*set = (namespace_set_t*)array_getkey(pool->x_namespace_sets, t);
811 namespace_list_t*i = set->namespaces;
813 pool_register_namespace(pool, i->namespace);
817 for(t=1;t<pool->x_namespaces->num;t++) {
818 namespace_t*ns= (namespace_t*)array_getkey(pool->x_namespaces, t);
819 array_append_if_new(pool->x_strings, ns->name, 0);
823 swf_SetU30(tag, pool->x_ints->num>1?pool->x_ints->num:0);
824 for(t=1;t<pool->x_ints->num;t++) {
825 S32 val = (ptroff_t)array_getkey(pool->x_ints, t);
826 swf_SetS30(tag, val);
828 swf_SetU30(tag, pool->x_uints->num>1?pool->x_uints->num:0);
829 for(t=1;t<pool->x_uints->num;t++) {
830 swf_SetU30(tag, (ptroff_t)array_getkey(pool->x_uints, t));
832 swf_SetU30(tag, pool->x_floats->num>1?pool->x_floats->num:0);
833 for(t=1;t<pool->x_floats->num;t++) {
834 array_getvalue(pool->x_floats, t);
835 swf_SetD64(tag, 0.0); // fixme
837 swf_SetU30(tag, pool->x_strings->num>1?pool->x_strings->num:0);
838 for(t=1;t<pool->x_strings->num;t++) {
839 swf_SetU30String(tag, array_getkey(pool->x_strings, t));
841 swf_SetU30(tag, pool->x_namespaces->num>1?pool->x_namespaces->num:0);
842 for(t=1;t<pool->x_namespaces->num;t++) {
843 namespace_t*ns= (namespace_t*)array_getkey(pool->x_namespaces, t);
844 const char*name = ns->name;
845 int i = pool_find_string(pool, name);
846 swf_SetU8(tag, ns->access);
849 swf_SetU30(tag, pool->x_namespace_sets->num>1?pool->x_namespace_sets->num:0);
850 for(t=1;t<pool->x_namespace_sets->num;t++) {
851 namespace_set_t*set = (namespace_set_t*)array_getkey(pool->x_namespace_sets, t);
852 namespace_list_t*i = set->namespaces;
853 int len = list_length(i);
854 swf_SetU30(tag, len);
856 int index = pool_find_namespace(pool, i->namespace);
857 swf_SetU30(tag, index);
862 swf_SetU30(tag, pool->x_multinames->num>1?pool->x_multinames->num:0);
863 for(t=1;t<pool->x_multinames->num;t++) {
864 multiname_t*m = (multiname_t*)array_getkey(pool->x_multinames, t);
865 swf_SetU8(tag, m->type);
868 assert(m->type==0x07 || m->type==0x0d);
869 int i = pool_find_namespace(pool, m->ns);
870 if(i<0) fprintf(stderr, "internal error: unregistered namespace %02x %s %s\n", m->ns->access, access2str(m->ns->access), m->ns->name);
873 assert(m->type!=0x07 && m->type!=0x0d);
876 assert(m->type==0x09 || m->type==0x0e || m->type==0x07 || m->type==0x0d || m->type==0x0f || m->type==0x10);
877 int i = pool_find_string(pool, m->name);
878 if(i<0) fprintf(stderr, "internal error: unregistered name\n");
881 assert(m->type!=0x09 && m->type!=0x0e && m->type!=0x07 && m->type!=0x0d && m->type!=0x0f && m->type!=0x10);
883 if(m->namespace_set) {
884 assert(m->type==0x09 || m->type==0x0e || m->type==0x1c || m->type==0x1b);
885 int i = pool_find_namespace_set(pool, m->namespace_set);
886 if(i<0) fprintf(stderr, "internal error: unregistered namespace set\n");
889 assert(m->type!=0x09 && m->type!=0x0e && m->type!=0x1c && m->type!=0x1b);
895 void pool_destroy(pool_t*pool)
898 array_free(pool->x_ints);
899 array_free(pool->x_uints);
900 array_free(pool->x_floats);
901 array_free(pool->x_strings);
902 array_free(pool->x_namespaces);
903 array_free(pool->x_namespace_sets);
904 array_free(pool->x_multinames);