Max 5 API Reference
00001 #include "ext.h" 00002 #include "ext_obex.h" 00003 #include "ext_strings.h" 00004 #include "jit.common.h" 00005 #include "jit.xml.h" 00006 #include "expat.h" 00007 #include "jit.charset.h" 00008 00009 #define XML_MAX_ATOM_COUNT 2048 00010 00011 /* 00012 a minimal DOM implementation informed by W3 Document Object Model (Core) Level: 00013 http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core.html 00014 00015 The DOM presents documents as a hierarchy of Node objects that also implement other, 00016 more specialized interfaces. Some types of nodes may have child nodes of various types, 00017 and others are leaf nodes that cannot have anything below them in the document structure. 00018 The node types, and which node types they may have as children, are as follows: 00019 00020 00021 - Document: Element (maximum of one), ProcessingInstruction, Comment, DocumentType 00022 * DocumentFragment: Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference 00023 (*) DocumentType: no children 00024 * EntityReference: Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference 00025 - Element: Element, Text, Comment, ProcessingInstruction, CDATASection, EntityReference 00026 - Attr: Text, EntityReference 00027 * ProcessingInstruction: no children 00028 - Comment: no children 00029 - Text: no children 00030 - CDATASection: no children 00031 * Entity: Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference 00032 * Notation: no children 00033 00034 currently no support for items marked with * 00035 later could move into kernel if desired 00036 00037 */ 00038 00039 t_class *_jit_xml_document_class=NULL; 00040 t_class *_jit_xml_element_class=NULL; 00041 t_class *_jit_xml_attribute_class=NULL; 00042 t_class *_jit_xml_text_class=NULL; 00043 t_class *_jit_xml_comment_class=NULL; 00044 t_class *_jit_xml_cdata_class=NULL; 00045 00046 00047 #ifdef __APPLE_CC__ 00048 t_symbol *ps_nobox,*ps_atomarray,*ps_nodevalue,*ps_specified; 00049 t_symbol *ps_document,*ps_element,*ps_attribute,*ps_text,*ps_comment,*ps_cdata; 00050 #else 00051 static t_symbol *ps_nobox,*ps_atomarray,*ps_nodevalue,*ps_specified; 00052 static t_symbol *ps_document,*ps_element,*ps_attribute,*ps_text,*ps_comment,*ps_cdata; 00053 #endif 00054 00055 void jit_xml_text_toatoms(char *s, long *ac, t_atom *av); 00056 void jit_xml_appendatom(t_atom *a, char *s); 00057 void jit_xml_atoms_totext(char *s, long ac, t_atom *av); 00058 void jit_xml_node_encode_and_write(t_jit_xml_node *x, t_filehandle fh, long *count, char *data); 00059 long jit_xml_document_decode(t_jit_xml_document *x, const char *data, char **outdata); 00060 void jit_xml_document_xmlparse_xmldecl(t_jit_xml_document *x, const char *version, const char *encoding, int standalone); 00061 void jit_xml_document_createheader(t_jit_xml_document *x, t_symbol *encoding); 00062 char *jit_xml_convert_entities(char *instr, long *len); 00063 00064 t_jit_err jit_xml_init(void) 00065 { 00066 t_class *c; 00067 long attrflags=0; 00068 void *attr; 00069 00070 ps_nobox = gensym("nobox"); 00071 ps_atomarray = gensym("atomarray"); 00072 ps_nodevalue = gensym("nodevalue"); 00073 ps_specified = gensym("specified"); 00074 ps_document = gensym("document"); 00075 ps_element = gensym("element"); 00076 ps_attribute = gensym("attribute"); 00077 ps_text = gensym("text"); 00078 ps_comment = gensym("comment"); 00079 ps_cdata = gensym("cdata"); 00080 00081 // jit_xml_doccument class --------------------------------------- 00082 00083 c = jit_class_new("jit_xml_document", (method)jit_xml_document_new, (method)jit_xml_document_free, 00084 (short)sizeof(t_jit_xml_document), A_GIMME, 0); 00085 00086 // A_CANT for now, (maybe later maked typed wrapper versions for exposing in patcher/javascript) 00087 jit_class_addmethod(c,(method)jit_xml_document_read, "read", A_GIMME, 0); 00088 jit_class_addmethod(c,(method)jit_xml_document_write, "write", A_GIMME, 0); 00089 jit_class_addmethod(c,(method)jit_xml_document_createelement, "createelement", A_CANT, 0); 00090 // jit_class_addmethod(c,(method)jit_xml_document_createdocumentfragment, "createdocumentfragment", A_CANT, 0); 00091 jit_class_addmethod(c,(method)jit_xml_document_createtextnode, "createtextnode", A_CANT, 0); 00092 jit_class_addmethod(c,(method)jit_xml_document_createcomment, "createcomment", A_CANT, 0); 00093 jit_class_addmethod(c,(method)jit_xml_document_createcdatasection, "createcdatasection", A_CANT, 0); 00094 // jit_class_addmethod(c,(method)jit_xml_document_createprocessinginstruction, "createprocessinginstruction", A_CANT, 0); 00095 jit_class_addmethod(c,(method)jit_xml_document_createattribute, "createattribute", A_CANT, 0); 00096 jit_class_addmethod(c,(method)jit_xml_document_getelementsbytagname, "getelementsbytagname", A_CANT, 0); 00097 jit_class_addmethod(c,(method)jit_xml_document_print, "print", 0); 00098 00099 jit_xml_node_addinterface(c); 00100 00101 //attrflags = JIT_ATTR_GET_DEFER_LOW | JIT_ATTR_SET_USURP_LOW ; 00102 attr = jit_object_new(_jit_sym_jit_attr_offset,"filename",_jit_sym_symbol,attrflags, 00103 (method)0L,(method)jit_xml_document_filename,calcoffset(t_jit_xml_document,filename)); 00104 jit_class_addattr(c,attr); 00105 00106 jit_class_register(c); 00107 _jit_xml_document_class = c; 00108 00109 00110 // jit_xml_element class --------------------------------------- 00111 00112 c = jit_class_new("jit_xml_element", (method)jit_xml_element_new, (method)jit_xml_element_free, 00113 (short)sizeof(t_jit_xml_element), A_GIMME, 0); 00114 00115 // A_CANT for now, (maybe later maked typed wrapper versions for exposing in patcher/javascript) 00116 jit_class_addmethod(c,(method)jit_xml_element_getattribute, "getattribute", A_CANT, 0); 00117 jit_class_addmethod(c,(method)jit_xml_element_setattribute, "setattribute", A_CANT, 0); 00118 jit_class_addmethod(c,(method)jit_xml_element_removeattribute, "removeattribute", A_CANT, 0); 00119 jit_class_addmethod(c,(method)jit_xml_element_getattributenode, "getattributenode", A_CANT, 0); 00120 jit_class_addmethod(c,(method)jit_xml_element_setattributenode, "setattributenode", A_CANT, 0); 00121 jit_class_addmethod(c,(method)jit_xml_element_removeattributenode, "removeattributenode", A_CANT, 0); 00122 jit_class_addmethod(c,(method)jit_xml_element_getelementsbytagname, "getelementsbytagname", A_CANT, 0); 00123 // jit_class_addmethod(c,(method)jit_xml_element_normalize, "normalize", A_CANT, 0); 00124 00125 jit_xml_node_addinterface(c); 00126 00127 attrflags = JIT_ATTR_SET_OPAQUE_USER; 00128 attr = jit_object_new(_jit_sym_jit_attr_offset,"tagname",_jit_sym_symbol,attrflags, 00129 (method)0L,(method)0L,calcoffset(t_jit_xml_node,nodename)); //mapping redundantly to nodename 00130 jit_class_addattr(c,attr); 00131 00132 jit_class_register(c); 00133 _jit_xml_element_class = c; 00134 00135 00136 // jit_xml_attribute class --------------------------------------- 00137 00138 c = jit_class_new("jit_xml_attribute", (method)jit_xml_attribute_new, (method)jit_xml_attribute_free, 00139 (short)sizeof(t_jit_xml_attribute), A_GIMME, 0); 00140 00141 jit_xml_node_addinterface(c); 00142 00143 attrflags = JIT_ATTR_SET_OPAQUE_USER; 00144 attr = jit_object_new(_jit_sym_jit_attr_offset,"name",_jit_sym_symbol,attrflags, 00145 (method)0L,(method)0L,calcoffset(t_jit_xml_node,nodename)); //mapping redundantly to nodename 00146 jit_class_addattr(c,attr); 00147 00148 attr = jit_object_new(_jit_sym_jit_attr_offset,"specified",_jit_sym_long,attrflags, 00149 (method)0L,(method)0L,calcoffset(t_jit_xml_attribute,specified)); 00150 jit_class_addattr(c,attr); 00151 00152 jit_class_register(c); 00153 _jit_xml_attribute_class = c; 00154 00155 00156 // jit_xml_text class --------------------------------------- 00157 00158 c = jit_class_new("jit_xml_text", (method)jit_xml_text_new, (method)jit_xml_text_free, 00159 (short)sizeof(t_jit_xml_text), A_GIMME, 0); 00160 00161 jit_class_addmethod(c,(method)jit_xml_text_splittext, "splittext", A_CANT, 0); 00162 jit_xml_charnode_addinterface(c); 00163 00164 jit_class_register(c); 00165 _jit_xml_text_class = c; 00166 00167 00168 // jit_xml_comment class --------------------------------------- 00169 00170 c = jit_class_new("jit_xml_comment", (method)jit_xml_comment_new, (method)jit_xml_comment_free, 00171 (short)sizeof(t_jit_xml_comment), A_GIMME, 0); 00172 00173 jit_xml_charnode_addinterface(c); 00174 00175 jit_class_register(c); 00176 _jit_xml_comment_class = c; 00177 00178 00179 // jit_xml_cdata class --------------------------------------- 00180 00181 c = jit_class_new("jit_xml_cdata", (method)jit_xml_cdata_new, (method)jit_xml_cdata_free, 00182 (short)sizeof(t_jit_xml_cdata), A_GIMME, 0); 00183 00184 jit_class_addmethod(c,(method)jit_xml_cdata_splittext, "splittext", A_CANT, 0); 00185 jit_xml_charnode_addinterface(c); 00186 00187 jit_class_register(c); 00188 _jit_xml_cdata_class = c; 00189 00190 return JIT_ERR_NONE; 00191 } 00192 00193 /*------------------------------------------------------------------------------ 00194 jit_xml_node 00195 -------------------------------------------------------------------------------*/ 00196 00197 00198 t_jit_err jit_xml_node_addinterface(t_class *c) 00199 { 00200 long attrflags = 0; 00201 t_jit_object *attr; 00202 00203 // node interface attributes. all except nodevalue are supposedly readonly 00204 attr = jit_object_new(_jit_sym_jit_attr_offset_array,"nodevalue",_jit_sym_atom,0/*no max*/,attrflags, 00205 (method)jit_xml_node_getnodevalue,(method)jit_xml_node_nodevalue, 00206 calcoffset(t_jit_xml_node,nodevaluecount),calcoffset(t_jit_xml_node,nodevalue)); 00207 jit_class_addattr(c,attr); 00208 00209 attrflags = JIT_ATTR_SET_OPAQUE_USER; 00210 attr = jit_object_new(_jit_sym_jit_attr_offset,"nodename",_jit_sym_symbol,attrflags, 00211 (method)0L,(method)0L,calcoffset(t_jit_xml_node,nodename)); 00212 jit_class_addattr(c,attr); 00213 00214 // in DOM spec nodetype is an integer, but we will be using symbols: element, attribute, text, comment, document, etc. 00215 attr = jit_object_new(_jit_sym_jit_attr_offset,"nodetype",_jit_sym_symbol,attrflags, 00216 (method)0L,(method)0L,calcoffset(t_jit_xml_node,nodetype)); 00217 jit_class_addattr(c,attr); 00218 00219 attr = jit_object_new(_jit_sym_jit_attr_offset,"parentnode",_jit_sym_object,attrflags, 00220 (method)0L,(method)0L,calcoffset(t_jit_xml_node,parentnode)); 00221 jit_class_addattr(c,attr); 00222 00223 attr = jit_object_new(_jit_sym_jit_attr_offset,"childnodes",_jit_sym_object,attrflags, 00224 (method)0L,(method)0L,calcoffset(t_jit_xml_node,childnodes)); 00225 jit_class_addattr(c,attr); 00226 00227 attr = jit_object_new(_jit_sym_jit_attr_offset,"firstchild",_jit_sym_object,attrflags, 00228 (method)0L,(method)0L,calcoffset(t_jit_xml_node,firstchild)); 00229 jit_class_addattr(c,attr); 00230 00231 attr = jit_object_new(_jit_sym_jit_attr_offset,"lastchild",_jit_sym_object,attrflags, 00232 (method)0L,(method)0L,calcoffset(t_jit_xml_node,lastchild)); 00233 jit_class_addattr(c,attr); 00234 00235 attr = jit_object_new(_jit_sym_jit_attr_offset,"previoussibling",_jit_sym_object,attrflags, 00236 (method)0L,(method)0L,calcoffset(t_jit_xml_node,previoussibling)); 00237 jit_class_addattr(c,attr); 00238 00239 attr = jit_object_new(_jit_sym_jit_attr_offset,"nextsibling",_jit_sym_object,attrflags, 00240 (method)0L,(method)0L,calcoffset(t_jit_xml_node,previoussibling)); 00241 jit_class_addattr(c,attr); 00242 00243 attr = jit_object_new(_jit_sym_jit_attr_offset,"attributes",_jit_sym_object,attrflags, 00244 (method)0L,(method)0L,calcoffset(t_jit_xml_node,attributes)); 00245 jit_class_addattr(c,attr); 00246 00247 attr = jit_object_new(_jit_sym_jit_attr_offset,"ownerdocument",_jit_sym_object,attrflags, 00248 (method)0L,(method)0L,calcoffset(t_jit_xml_node,ownerdocument)); 00249 jit_class_addattr(c,attr); 00250 00251 // node interface methods (maybe later maked typed wrapper versions for exposing in patcher/javascript) 00252 jit_class_addmethod(c,(method)jit_xml_node_insertbefore, "insertbefore", A_CANT, 0); 00253 jit_class_addmethod(c,(method)jit_xml_node_replacechild, "replacechild", A_CANT, 0); 00254 jit_class_addmethod(c,(method)jit_xml_node_removechild, "removechild", A_CANT, 0); 00255 jit_class_addmethod(c,(method)jit_xml_node_appendchild, "appendchild", A_CANT, 0); 00256 jit_class_addmethod(c,(method)jit_xml_node_haschildnodes, "haschildnodes", A_CANT, 0); 00257 jit_class_addmethod(c,(method)jit_xml_node_clonenode, "clonenode", A_CANT, 0); // need to implement 00258 // utilities 00259 jit_class_addmethod(c,(method)jit_xml_node_removeallchildren, "removeallchildren", A_CANT, 0); 00260 jit_class_addmethod(c,(method)jit_xml_node_setnodevalasstring, "setnodevalueasstring", A_CANT, 0); 00261 jit_class_addmethod(c,(method)jit_xml_node_getnodevalasstring, "getnodevalueasstring", A_CANT, 0); 00262 jit_class_addmethod(c,(method)jit_xml_node_nodevalue, "setnodevalueasatoms", A_CANT, 0); 00263 jit_class_addmethod(c,(method)jit_xml_node_getnodevalue, "getnodevalueasatoms", A_CANT, 0); // need to implement 00264 00265 return JIT_ERR_NONE; 00266 } 00267 00268 t_jit_err jit_xml_node_insertbefore(t_jit_xml_node *x, t_jit_xml_node *newchild, t_jit_xml_node *refchild) 00269 { 00270 long i; 00271 00272 if (newchild&&!x->childnodes) { 00273 x->childnodes = jit_linklist_new(); 00274 } 00275 if (x->childnodes) { 00276 jit_global_critical_enter(); 00277 if (refchild) 00278 i = jit_linklist_objptr2index(x->childnodes,refchild); 00279 else 00280 i = 0; 00281 00282 if (i<0) i=0; //always insert even if refchild not in nodelist 00283 00284 jit_linklist_insertindex(x->childnodes,newchild,i); 00285 // update sibling attributes 00286 newchild->previoussibling = jit_linklist_getindex(x->childnodes,i-1); 00287 newchild->nextsibling = jit_linklist_getindex(x->childnodes,i+1); 00288 if (newchild->previoussibling) 00289 newchild->previoussibling->nextsibling = newchild; 00290 if (newchild->nextsibling) 00291 newchild->nextsibling->previoussibling = newchild; 00292 // update parent/document attributes 00293 newchild->parentnode = x; 00294 newchild->ownerdocument = x->ownerdocument; 00295 // update children attributes 00296 x->firstchild = jit_linklist_getindex(x->childnodes,0); 00297 x->lastchild = jit_linklist_getindex(x->childnodes,jit_linklist_getsize(x->childnodes-1)); 00298 jit_global_critical_exit(); 00299 return JIT_ERR_NONE; 00300 } 00301 return JIT_ERR_GENERIC; 00302 } 00303 00304 t_jit_err jit_xml_node_replacechild(t_jit_xml_node *x, t_jit_xml_node *newchild, t_jit_xml_node *refchild) 00305 { 00306 long i; 00307 00308 if (x->childnodes&&refchild) { 00309 jit_global_critical_enter(); 00310 if ((i=jit_linklist_objptr2index(x->childnodes,refchild))>=0) { 00311 jit_linklist_insertindex(x->childnodes,newchild,i); 00312 jit_linklist_deleteindex(x->childnodes,i+1); 00313 // update sibling attributes 00314 newchild->previoussibling = jit_linklist_getindex(x->childnodes,i-1); 00315 newchild->nextsibling = jit_linklist_getindex(x->childnodes,i+1); 00316 if (newchild->previoussibling) 00317 newchild->previoussibling->nextsibling = newchild; 00318 if (newchild->nextsibling) 00319 newchild->nextsibling->previoussibling = newchild; 00320 // update parent/document attributes 00321 newchild->parentnode = x; 00322 newchild->ownerdocument = x->ownerdocument; 00323 // update children attributes 00324 x->firstchild = jit_linklist_getindex(x->childnodes,0); 00325 x->lastchild = jit_linklist_getindex(x->childnodes,jit_linklist_getsize(x->childnodes-1)); 00326 } 00327 jit_global_critical_exit(); 00328 // jit_object_free(refchild); //there might be some chance we don't want to free? 00329 return JIT_ERR_NONE; 00330 } 00331 return JIT_ERR_GENERIC; 00332 } 00333 00334 t_jit_err jit_xml_node_removechild(t_jit_xml_node *x, t_jit_xml_node *refchild) 00335 { 00336 long i; 00337 00338 if (x->childnodes&&refchild) { 00339 jit_global_critical_enter(); 00340 if ((i=jit_linklist_objptr2index(x->childnodes,refchild))>=0) { 00341 jit_linklist_deleteindex(x->childnodes,i); 00342 00343 // update children attributes 00344 x->firstchild = jit_linklist_getindex(x->childnodes,0); 00345 x->lastchild = jit_linklist_getindex(x->childnodes,jit_linklist_getsize(x->childnodes)-1); 00346 } 00347 jit_global_critical_exit(); 00348 // jit_object_free(refchild); //there might be some chance we don't want to free? 00349 return JIT_ERR_NONE; 00350 } 00351 return JIT_ERR_GENERIC; 00352 } 00353 00354 t_jit_err jit_xml_node_appendchild(t_jit_xml_node *x, t_jit_xml_node *newchild) 00355 { 00356 if (newchild&&!x->childnodes) { 00357 x->childnodes = jit_linklist_new(); 00358 } 00359 if (x->childnodes) { 00360 jit_global_critical_enter(); 00361 jit_linklist_append(x->childnodes,newchild); 00362 // update sibling attributes 00363 newchild->previoussibling = jit_linklist_getindex(x->childnodes,jit_linklist_getsize(x->childnodes)-2); 00364 newchild->nextsibling = NULL; 00365 if (newchild->previoussibling) 00366 newchild->previoussibling->nextsibling = newchild; 00367 // update parent/document attributes 00368 newchild->parentnode = x; 00369 newchild->ownerdocument = (x->ownerdocument) ? x->ownerdocument : (t_jit_xml_document *)x; 00370 // update children attributes 00371 x->firstchild = jit_linklist_getindex(x->childnodes,0); 00372 x->lastchild = newchild; 00373 jit_global_critical_exit(); 00374 return JIT_ERR_NONE; 00375 } 00376 return JIT_ERR_GENERIC; 00377 } 00378 00379 long jit_xml_node_haschildnodes(t_jit_xml_node *x) 00380 { 00381 return (long)((x->childnodes!=NULL)&&(jit_linklist_getsize(x->childnodes)>0)); 00382 } 00383 00384 t_jit_xml_node *jit_xml_node_clonenode(t_jit_xml_node *x, long deep) 00385 { 00386 // TODO: based on element type duplicate the entire structure 00387 return NULL; 00388 } 00389 00390 t_jit_err jit_xml_node_removeallchildren(t_jit_xml_node *x) 00391 { 00392 if (x->childnodes) { 00393 jit_object_free(x->childnodes); // might want to chuck rather than free? 00394 x->childnodes = NULL; 00395 } 00396 return JIT_ERR_NONE; 00397 } 00398 00399 t_jit_err jit_xml_node_nodevalue_clear(t_jit_xml_node *x); 00400 t_jit_err jit_xml_node_nodevalue_clear(t_jit_xml_node *x) 00401 { 00402 long i; 00403 00404 for (i=0;i<x->nodevaluecount;i++) { 00405 if ((x->nodevalue[i].a_type==A_OBJ)&&(x->nodevalue[i].a_w.w_obj!=NULL)) 00406 jit_object_free(x->nodevalue[i].a_w.w_obj); 00407 } 00408 // if (ac!=x->nodevaluecount) { // this was a bug 00409 if (x->nodevalue) 00410 jit_freebytes(x->nodevalue,x->nodevaluecount*sizeof(t_atom)); 00411 x->nodevalue = NULL; 00412 x->nodevaluecount = 0; 00413 // } 00414 if (x->nodeflags == NODE_VALUE_SET_AS_STRING && x->nodestring) { 00415 jit_freebytes(x->nodestring, strlen(x->nodestring) + 1); 00416 x->nodestring = NULL; 00417 } 00418 x->nodeflags = NODE_VALUE_NOT_SET; 00419 00420 return JIT_ERR_NONE; 00421 } 00422 00423 t_jit_err jit_xml_node_nodevalue(t_jit_xml_node *x, void *attr, long ac, t_atom *av) 00424 { 00425 long i; 00426 00427 jit_xml_node_nodevalue_clear(x); 00428 00429 if (ac&&av) { 00430 x->nodevaluecount = ac; 00431 x->nodevalue = (t_atom *)jit_getbytes(x->nodevaluecount*sizeof(t_atom)); 00432 for (i=0;i<ac;i++) 00433 x->nodevalue[i] = av[i]; 00434 00435 x->nodeflags = NODE_VALUE_SET_AS_ATOMS; 00436 } 00437 return JIT_ERR_NONE; 00438 } 00439 00440 t_jit_err jit_xml_node_getnodevalue(t_jit_xml_node *x, void *attr, long *ac, t_atom **av) 00441 { 00442 long i; 00443 00444 // ignore attr pointer, also using as method "getnodevalueasatoms" 00445 // later could handle object cases and parse into atoms or something? 00446 // maybe then would separate this fun and getnodevalues as atoms? 00447 00448 if (x->nodeflags == NODE_VALUE_SET_AS_ATOMS) { 00449 if (*ac&&*av) { 00450 //memory passed in, use it 00451 if ((*ac)>x->nodevaluecount) 00452 *ac = x->nodevaluecount; 00453 } else { 00454 *ac = x->nodevaluecount; 00455 if (x->nodevaluecount) 00456 *av = jit_getbytes(x->nodevaluecount*sizeof(t_atom)); 00457 else 00458 *av = NULL; 00459 } 00460 00461 for (i=0;i<(*ac);i++) 00462 (*av)[i] = x->nodevalue[i]; 00463 } else if (x->nodeflags == NODE_VALUE_SET_AS_STRING && x->nodestring) { 00464 t_atom argv[XML_MAX_ATOM_COUNT]; 00465 long argc = 0; 00466 00467 jit_xml_text_toatoms(x->nodestring, &argc, argv); 00468 00469 if (*ac&&*av) { 00470 //memory passed in, use it 00471 if ((*ac)>argc) 00472 *ac = argc; 00473 } else { 00474 *ac = argc; 00475 if (argc) 00476 *av = jit_getbytes(argc*sizeof(t_atom)); 00477 else 00478 *av = NULL; 00479 } 00480 00481 for (i = 0; i < (*ac); i++) { 00482 (*av)[i] = argv[i]; 00483 } 00484 } 00485 00486 return JIT_ERR_NONE; 00487 } 00488 00489 // need to implement getnodevalueasatoms which will serialize objects into atom vals? 00490 00491 00492 void jit_xml_text_toatoms(char *s, long *ac, t_atom *av) 00493 { 00494 long n,eaten; 00495 char *p; 00496 00497 *ac = 0; 00498 eaten = 0; 00499 n = strlen(s); 00500 p=(char *)jit_getbytes(n+1); 00501 //jit_object_post((t_object *)x,"text to atoms: %s",s); 00502 while (readatom(p, &s, &eaten, n, av)) { 00503 /* 00504 switch (av->a_type) { 00505 case A_SYM: 00506 jit_object_post((t_object *)x,"symbol: %s",av->a_w.w_sym->s_name); 00507 break; 00508 case A_LONG: 00509 jit_object_post((t_object *)x,"long: %d",av->a_w.w_long); 00510 break; 00511 case A_FLOAT: 00512 jit_object_post((t_object *)x,"float: %f",av->a_w.w_float); 00513 break; 00514 } 00515 */ 00516 (*ac)++; 00517 av++; 00518 } 00519 jit_freebytes(p,n+1); 00520 } 00521 00522 00523 void jit_xml_appendatom(t_atom *a, char *s) 00524 { 00525 char buf[512]; 00526 char fbuf[128]; 00527 char c,*p; 00528 00529 c = a->a_type; 00530 buf[0] = 0; 00531 if (c == A_SYM) 00532 sprintf(buf, "%s ", (a->a_w.w_sym) ? a->a_w.w_sym->s_name : ""); 00533 else if (c == A_OBJ) 00534 sprintf(buf, "%s ", object_classname(a->a_w.w_obj)->s_name); 00535 else if (c == A_LONG) 00536 sprintf(buf, "%ld ", a->a_w.w_long); 00537 else if (c == A_DOLLAR) 00538 sprintf(buf, "$%ld ", a->a_w.w_long); 00539 else if (c == A_FLOAT) { 00540 // chomp trailing zeros 00541 sprintf(fbuf,"%f",a->a_w.w_float); 00542 p = fbuf+strlen(fbuf)-1; 00543 while ((p>fbuf)&&(*p=='0')) { 00544 *p = 0; 00545 p--; 00546 } 00547 sprintf(buf,"%s ",fbuf); 00548 } 00549 else if (c == A_DOLLSYM) 00550 sprintf(buf,"$%s",a->a_w.w_sym->s_name); 00551 else 00552 return; 00553 //jit_object_post((t_object *)x,"appendatom %s",buf); 00554 strcat(s,buf); 00555 } 00556 00557 void jit_xml_atoms_totext(char *s, long ac, t_atom *av) 00558 { 00559 long i; 00560 long sl; 00561 00562 s[0] = 0; 00563 for (i=0; i < ac; i++,av++) 00564 jit_xml_appendatom(av,s); 00565 sl = strlen(s); 00566 if (s[sl-1] == ' ') 00567 s[sl-1] = 0; 00568 } 00569 00570 t_jit_err jit_xml_node_setnodevalasstring(t_jit_xml_node *x, char *s) 00571 { 00572 // t_atom av[1024]; 00573 // long ac=1024; 00574 // char tmp[1024]; 00575 00576 jit_xml_node_nodevalue_clear(x); 00577 00578 x->nodestring = (char *)jit_getbytes(strlen(s) + 1); 00579 strcpy(x->nodestring, s); 00580 00581 x->nodeflags = NODE_VALUE_SET_AS_STRING; 00582 00583 // jit_xml_text_toatoms(s,&ac,av); 00584 // object_attr_setvalueof(x,ps_nodevalue,ac,av); 00585 return JIT_ERR_NONE; 00586 } 00587 00588 t_jit_err jit_xml_node_getnodevalasstring(t_jit_xml_node *x, long *len, char **s) 00589 { 00590 char temp[8192]; 00591 char *tmp; 00592 t_atom *av=NULL; 00593 long i,ac=0; 00594 00595 if (x->nodeflags == NODE_VALUE_SET_AS_ATOMS) { 00596 temp[0]=0; 00597 00598 object_attr_getvalueof(x,ps_nodevalue,&ac,&av); 00599 jit_xml_atoms_totext(temp,ac,av); 00600 jit_freebytes((char *)av,sizeof(t_atom)*ac); 00601 tmp = &temp[0]; 00602 } else if (x->nodeflags == NODE_VALUE_SET_AS_STRING && x->nodestring) { 00603 tmp = x->nodestring; 00604 } 00605 if (*s&&*len) { 00606 //memory passed in, use it 00607 *len = MIN((long)strlen(tmp)+1,*len); 00608 } else { 00609 *len = strlen(tmp)+1; 00610 *s = jit_getbytes(*len); 00611 } 00612 for (i=0;i<((*len)-1);i++) { 00613 (*s)[i] = tmp[i]; 00614 } 00615 (*s)[i] = 0; 00616 00617 return JIT_ERR_NONE; 00618 } 00619 00620 t_jit_err jit_xml_node_new(t_jit_xml_node *x, t_symbol *nodetype) 00621 { 00622 x->nodename = _jit_sym_nothing; 00623 x->nodevalue = NULL; 00624 x->nodevaluecount = 0; 00625 x->nodetype = nodetype ? nodetype : _jit_sym_nothing; 00626 x->parentnode = NULL; 00627 x->childnodes = NULL; 00628 x->firstchild = NULL; 00629 x->lastchild = NULL; 00630 x->previoussibling = NULL; 00631 x->nextsibling = NULL; 00632 x->attributes = NULL; 00633 x->ownerdocument = NULL; 00634 x->nodestring = NULL; 00635 x->nodeflags = NODE_VALUE_NOT_SET; 00636 00637 return JIT_ERR_NONE; 00638 } 00639 00640 t_jit_err jit_xml_node_free(t_jit_xml_node *x) 00641 { 00642 if (x->childnodes) { 00643 jit_object_free(x->childnodes); 00644 x->childnodes = NULL; 00645 } 00646 if (x->attributes) { 00647 jit_object_free(x->attributes); 00648 x->attributes = NULL; 00649 } 00650 00651 jit_xml_node_nodevalue_clear(x); 00652 00653 x->nodename = _jit_sym_nothing; 00654 x->nodevalue = NULL; 00655 x->nodevaluecount = 0; 00656 x->nodetype = _jit_sym_nothing; 00657 x->parentnode = NULL; 00658 x->childnodes = NULL; 00659 x->firstchild = NULL; 00660 x->lastchild = NULL; 00661 x->previoussibling = NULL; 00662 x->nextsibling = NULL; 00663 x->ownerdocument = NULL; 00664 x->nodestring = NULL; 00665 x->nodeflags = NODE_VALUE_NOT_SET; 00666 00667 return JIT_ERR_NONE; 00668 } 00669 00670 00671 t_symbol *jit_xml_node_getnodevalue_sym(t_jit_xml_node *x) 00672 { 00673 long ac=0; 00674 t_atom *av=NULL; 00675 t_symbol *rv=_jit_sym_nothing; 00676 00677 if (x) { 00678 if (((jit_xml_node_getnodevalue(x,NULL,&ac,&av))==JIT_ERR_NONE)&&av) { 00679 if (ac&&av) { 00680 rv = jit_atom_getsym(av); 00681 jit_freebytes(av,sizeof(t_atom)*ac); 00682 } 00683 } 00684 } 00685 return rv; 00686 } 00687 00688 t_jit_err jit_xml_node_nodevalue_sym(t_jit_xml_node *x, t_symbol *s) 00689 { 00690 long ac=1; 00691 t_atom av[1]; 00692 t_jit_err rv=JIT_ERR_GENERIC; 00693 00694 if (x) { 00695 jit_atom_setsym(av,s); 00696 rv = jit_xml_node_nodevalue(x,NULL,ac,av); 00697 } 00698 return rv; 00699 } 00700 00701 long jit_xml_node_getnodevalue_long(t_jit_xml_node *x) 00702 { 00703 long ac=0; 00704 t_atom *av=NULL; 00705 long rv=0; 00706 00707 if (x) { 00708 if (((jit_xml_node_getnodevalue(x,NULL,&ac,&av))==JIT_ERR_NONE)&&av) { 00709 if (ac&&av) { 00710 rv = jit_atom_getlong(av); 00711 jit_freebytes(av,sizeof(t_atom)*ac); 00712 } 00713 } 00714 } 00715 return rv; 00716 } 00717 00718 t_jit_err jit_xml_node_nodevalue_long(t_jit_xml_node *x, long c) 00719 { 00720 long ac=1; 00721 t_atom av[1]; 00722 t_jit_err rv=JIT_ERR_GENERIC; 00723 00724 if (x) { 00725 jit_atom_setlong(av,c); 00726 rv = jit_xml_node_nodevalue(x,NULL,ac,av); 00727 } 00728 return rv; 00729 } 00730 00731 00732 float jit_xml_node_getnodevalue_float(t_jit_xml_node *x) 00733 { 00734 long ac=0; 00735 t_atom *av=NULL; 00736 float rv=0; 00737 00738 if (x) { 00739 if (((jit_xml_node_getnodevalue(x,NULL,&ac,&av))==JIT_ERR_NONE)&&av) { 00740 if (ac&&av) { 00741 rv = jit_atom_getfloat(av); 00742 jit_freebytes(av,sizeof(t_atom)*ac); 00743 } 00744 } 00745 } 00746 return rv; 00747 } 00748 00749 t_jit_err jit_xml_node_nodevalue_float(t_jit_xml_node *x, float f) 00750 { 00751 long ac=1; 00752 t_atom av[1]; 00753 t_jit_err rv=JIT_ERR_GENERIC; 00754 00755 if (x) { 00756 jit_atom_setfloat(av,f); 00757 rv = jit_xml_node_nodevalue(x,NULL,ac,av); 00758 } 00759 return rv; 00760 } 00761 00762 long jit_xml_node_getnodevalue_sym_array(t_jit_xml_node *x, long max, t_symbol **vals) 00763 { 00764 long i,ac=0; 00765 t_atom *av=NULL; 00766 00767 if (x&&vals) { 00768 if (((jit_xml_node_getnodevalue(x,NULL,&ac,&av))==JIT_ERR_NONE)&&av) { 00769 if (ac&&av) { 00770 max = MIN(max,ac); 00771 for (i=0;i<max;i++) { 00772 vals[i]=jit_atom_getsym(av+i); 00773 } 00774 jit_freebytes(av,sizeof(t_atom)*ac); 00775 } 00776 } 00777 } 00778 return ac; 00779 } 00780 00781 t_jit_err jit_xml_node_nodevalue_sym_array(void *x, long count, t_symbol **vals) 00782 { 00783 t_atom av[XML_MAX_ATOM_COUNT]; 00784 t_jit_err rv=JIT_ERR_GENERIC; 00785 long i; 00786 00787 if (x&&vals) { 00788 for (i=0;i<count;i++) 00789 jit_atom_setsym(av+i,vals[i]); 00790 rv = jit_xml_node_nodevalue(x,NULL,count,av); 00791 } 00792 return rv; 00793 } 00794 00795 long jit_xml_node_getnodevalue_long_array(t_jit_xml_node *x, long max, long *vals) 00796 { 00797 long i,ac=0; 00798 t_atom *av=NULL; 00799 00800 if (x&&vals) { 00801 if (((jit_xml_node_getnodevalue(x,NULL,&ac,&av))==JIT_ERR_NONE)&&av) { 00802 if (ac&&av) { 00803 max = MIN(max,ac); 00804 for (i=0;i<max;i++) { 00805 vals[i]=jit_atom_getlong(av+i); 00806 } 00807 jit_freebytes(av,sizeof(t_atom)*ac); 00808 } 00809 } 00810 } 00811 return ac; 00812 } 00813 00814 t_jit_err jit_xml_node_nodevalue_long_array(void *x, long count, long *vals) 00815 { 00816 t_atom av[XML_MAX_ATOM_COUNT]; 00817 t_jit_err rv=JIT_ERR_GENERIC; 00818 long i; 00819 00820 if (x&&vals) { 00821 for (i=0;i<count;i++) 00822 jit_atom_setlong(av+i,vals[i]); 00823 rv = jit_xml_node_nodevalue(x,NULL,count,av); 00824 } 00825 return rv; 00826 } 00827 00828 long jit_xml_node_getnodevalue_float_array(t_jit_xml_node *x, long max, float *vals) 00829 { 00830 long i,ac=0; 00831 t_atom *av=NULL; 00832 00833 if (x&&vals) { 00834 if (((jit_xml_node_getnodevalue(x,NULL,&ac,&av))==JIT_ERR_NONE)&&av) { 00835 if (ac&&av) { 00836 max = MIN(max,ac); 00837 for (i=0;i<max;i++) { 00838 vals[i]=jit_atom_getfloat(av+i); 00839 } 00840 jit_freebytes(av,sizeof(t_atom)*ac); 00841 } 00842 } 00843 } 00844 return ac; 00845 } 00846 00847 t_jit_err jit_xml_node_nodevalue_float_array(void *x, long count, float *vals) 00848 { 00849 t_atom av[XML_MAX_ATOM_COUNT]; 00850 t_jit_err rv=JIT_ERR_GENERIC; 00851 long i; 00852 00853 if (x&&vals) { 00854 for (i=0;i<count;i++) 00855 jit_atom_setfloat(av+i,vals[i]); 00856 rv = jit_xml_node_nodevalue(x,NULL,count,av); 00857 } 00858 return rv; 00859 } 00860 00861 void jit_xml_node_getelementsbytagname_helper(t_jit_xml_node *x, t_symbol *tagname, t_jit_linklist **list); 00862 void jit_xml_node_getelementsbytagname_helper(t_jit_xml_node *x, t_symbol *tagname, t_jit_linklist **list) 00863 { 00864 long i,count; 00865 t_jit_xml_node *node; 00866 00867 // depthfirst (preorder) traversal 00868 if (/*(x->nodetype==ps_element)&&*/(x->nodename==tagname)) { 00869 if (!(*list)) 00870 (*list) = jit_linklist_new(); 00871 jit_linklist_append(*list,x); 00872 } 00873 if (x->childnodes) { 00874 count = jit_linklist_getsize(x->childnodes); 00875 for (i=0;i<count;i++) { 00876 node = jit_linklist_getindex(x->childnodes,i); 00877 jit_xml_node_getelementsbytagname_helper(node,tagname,list); 00878 } 00879 } 00880 } 00881 00882 00883 00884 00885 /*------------------------------------------------------------------------------ 00886 jit_xml_charnode 00887 -------------------------------------------------------------------------------*/ 00888 00889 t_jit_err jit_xml_charnode_addinterface(t_class *c) 00890 { 00891 long attrflags = 0; 00892 t_jit_object *attr; 00893 00894 jit_xml_node_addinterface(c); 00895 00896 attrflags = JIT_ATTR_SET_OPAQUE_USER; 00897 attr = jit_object_new(_jit_sym_jit_attr_offset,"length",_jit_sym_long,attrflags, 00898 (method)0L,(method)0L,calcoffset(t_jit_xml_charnode,length)); 00899 jit_class_addattr(c,attr); 00900 00901 // chardata interface methods (maybe later maked typed wrapper versions for exposing in patcher/javascript) 00902 jit_class_addmethod(c,(method)jit_xml_charnode_substringdata, "substringdata", A_CANT, 0); 00903 jit_class_addmethod(c,(method)jit_xml_charnode_appenddata, "appenddata", A_CANT, 0); 00904 jit_class_addmethod(c,(method)jit_xml_charnode_insertdata, "insertdata", A_CANT, 0); 00905 jit_class_addmethod(c,(method)jit_xml_charnode_deletedata, "deletedata", A_CANT, 0); 00906 jit_class_addmethod(c,(method)jit_xml_charnode_replacedata, "replacedata", A_CANT, 0); 00907 00908 return JIT_ERR_NONE; 00909 } 00910 00911 char *jit_xml_charnode_substringdata(t_jit_xml_charnode *x, long offset, long count) 00912 { 00913 char *substr; 00914 long i; 00915 00916 if (x->data&&(x->length>0)) { 00917 offset = CLAMP(offset,0,x->length-1); 00918 count = CLAMP(count,0,x->length-1-offset); 00919 substr = jit_getbytes(count+1); 00920 for (i=0;i<count;i++) 00921 substr[i] = x->data[i]; 00922 substr[i] = 0; 00923 return substr; 00924 } else { 00925 return NULL; 00926 } 00927 } 00928 00929 t_jit_err jit_xml_charnode_appenddata(t_jit_xml_charnode *x, char *data) 00930 { 00931 char *newdata; 00932 char *olddata = x->data; 00933 long oldlen = x->length; 00934 long appendlen = strlen(data); 00935 long newlen = oldlen + appendlen; 00936 long i,j; 00937 00938 newdata = jit_getbytes(newlen+1); 00939 for (i=0;i<oldlen;i++) { 00940 newdata[i] = olddata[i]; 00941 } 00942 for (i=oldlen,j=0;i<newlen;i++,j++) { 00943 newdata[i] = data[j]; 00944 } 00945 newdata[newlen] = 0; 00946 x->data = newdata; 00947 x->length = newlen; 00948 if (olddata) 00949 jit_freebytes(olddata,oldlen+1); 00950 return JIT_ERR_NONE; 00951 } 00952 00953 t_jit_err jit_xml_charnode_insertdata(t_jit_xml_charnode *x, long offset, char *data) 00954 { 00955 char *newdata; 00956 char *olddata = x->data; 00957 long oldlen = x->length; 00958 long insertlen = strlen(data); 00959 long newlen = oldlen + insertlen; 00960 long i,j; 00961 00962 newdata = jit_getbytes(newlen+1); 00963 for (i=0;i<offset;i++) { 00964 newdata[i] = olddata[i]; 00965 } 00966 for (i=offset,j=0;j<insertlen;i++,j++) { 00967 newdata[i] = data[j]; 00968 } 00969 for (i=offset+insertlen,j=offset;i<newlen;i++,j++) { 00970 newdata[i] = olddata[j]; 00971 } 00972 newdata[newlen] = 0; 00973 x->data = newdata; 00974 x->length = newlen; 00975 if (olddata) 00976 jit_freebytes(olddata,oldlen+1); 00977 return JIT_ERR_NONE; 00978 } 00979 00980 t_jit_err jit_xml_charnode_deletedata(t_jit_xml_charnode *x, long offset, long count) 00981 { 00982 char *newdata; 00983 char *olddata = x->data; 00984 long oldlen = x->length; 00985 long newlen = CLAMP(oldlen-count,offset,oldlen); 00986 long i,j; 00987 00988 newdata = jit_getbytes(newlen+1); 00989 for (i=0;i<offset;i++) { 00990 newdata[i] = olddata[i]; 00991 } 00992 for (i=offset,j=offset+(oldlen-newlen);j<newlen;i++,j++) { 00993 newdata[i] = olddata[j]; 00994 } 00995 newdata[newlen] = 0; 00996 x->data = newdata; 00997 x->length = newlen; 00998 if (olddata) 00999 jit_freebytes(olddata,oldlen+1); 01000 return JIT_ERR_NONE; 01001 } 01002 01003 t_jit_err jit_xml_charnode_replacedata(t_jit_xml_charnode *x, long offset, long count, char *data) 01004 { 01005 // could be more efficient, but hey... 01006 jit_xml_charnode_deletedata(x,offset,count); 01007 jit_xml_charnode_insertdata(x,offset,data); 01008 return JIT_ERR_NONE; 01009 } 01010 01011 t_jit_err jit_xml_charnode_new(t_jit_xml_charnode *x, t_symbol *nodetype) 01012 { 01013 x->data = NULL; 01014 x->length = 0; 01015 jit_xml_node_new((t_jit_xml_node *)x,nodetype); 01016 x->node.nodename = nodetype; 01017 return JIT_ERR_NONE; 01018 } 01019 01020 t_jit_err jit_xml_charnode_free(t_jit_xml_charnode *x) 01021 { 01022 if (x->data) 01023 jit_freebytes(x->data,x->length+1); 01024 x->data = NULL; 01025 x->length = 0; 01026 jit_xml_node_free((t_jit_xml_node *)x); 01027 return JIT_ERR_NONE; 01028 } 01029 01030 01031 /*------------------------------------------------------------------------------ 01032 jit_xml_document 01033 -------------------------------------------------------------------------------*/ 01034 01035 01036 // probably only accessed as a gettable attribute, but leaving this here as placeholder 01037 void jit_xml_document_filename(t_jit_xml_document *x, t_object *attr, long argc, t_atom *argv) 01038 { 01039 t_symbol *filename=_jit_sym_nothing; 01040 01041 if (argc&&argv) { 01042 filename = jit_atom_getsym(argv); 01043 } 01044 x->filename = filename; 01045 } 01046 01047 t_jit_err jit_xml_document_read(t_jit_xml_document *x, t_symbol *s, long ac, t_atom *av) //later make gimmeback? 01048 { 01049 char cname[512]; 01050 char tmp[MAX_PATH_CHARS]; 01051 short path; 01052 long type; 01053 long typelist = 'TEXT'; 01054 t_filehandle fh; 01055 t_handle texthandle; 01056 long err,rv = 0; 01057 long size; 01058 char *txt; 01059 XML_Parser parser; 01060 t_atom a[2]; 01061 t_jit_err jerr=JIT_ERR_GENERIC; 01062 01063 strcpy(cname, "<none>"); 01064 if (ac && av && av->a_type == A_SYM) { 01065 strcpy(cname, av->a_w.w_sym->s_name); 01066 if (locatefile_extended(cname, &path, &type, NULL, 0 /*&typelist, 1*/)) { 01067 //jit_object_error((t_object *)x,"jit_xml_document_read: could not find file %s",cname); 01068 goto out; 01069 } 01070 } 01071 else { 01072 if (open_dialog(cname, &path, &type, NULL, 0 /*&typelist, 1*/)) 01073 goto out; 01074 } 01075 01076 if (err = path_opensysfile(cname, path, &fh, READ_PERM)) { 01077 //jit_object_error((t_object *)x,"jit_xml_document_read: could not open file %s",cname); 01078 goto out; 01079 } 01080 x->filename = gensym(cname); 01081 x->path = path; 01082 01083 // should delete any existing childnodes (and attributes, etc?) 01084 jit_object_free(x->node.childnodes); 01085 x->node.childnodes = NULL; 01086 01087 texthandle = sysmem_newhandle(1); 01088 if (!texthandle) { 01089 jit_object_error((t_object *)x,"jit_xml_document: could not allocate buffer for reading file"); 01090 sysmem_freehandle(texthandle); 01091 sysfile_close(fh); 01092 goto out; 01093 } 01094 01095 x->parsernode = (t_jit_xml_node *)x; 01096 x->parserdepth = 0; 01097 01098 sysfile_readtextfile(fh,texthandle,0,TEXT_LB_UNIX); 01099 size = sysmem_handlesize(texthandle); 01100 sysmem_resizehandle(texthandle,size+1L); 01101 txt = *texthandle; 01102 txt[size] = 0; 01103 01104 //jit_object_post((t_object *)x,"jit_xml_document: read file okay"); 01105 if (parser = XML_ParserCreate(NULL)) { 01106 XML_SetUserData(parser, x); 01107 XML_SetXmlDeclHandler(parser, (XML_XmlDeclHandler)jit_xml_document_xmlparse_xmldecl); 01108 XML_SetElementHandler(parser, 01109 (XML_StartElementHandler) jit_xml_document_xmlparse_element_start, 01110 (XML_EndElementHandler)jit_xml_document_xmlparse_element_end); 01111 XML_SetDefaultHandler(parser, (XML_CharacterDataHandler) jit_xml_document_xmlparse_default); 01112 XML_SetCharacterDataHandler(parser, (XML_CharacterDataHandler) jit_xml_document_xmlparse_characterdata); 01113 XML_SetCommentHandler(parser, (XML_CommentHandler) jit_xml_document_xmlparse_comment); 01114 XML_SetDoctypeDeclHandler(parser, 01115 (XML_StartDoctypeDeclHandler) jit_xml_document_xmlparse_doctype_start, 01116 (XML_EndDoctypeDeclHandler) jit_xml_document_xmlparse_doctype_end); 01117 XML_SetCdataSectionHandler(parser, 01118 (XML_StartCdataSectionHandler) jit_xml_document_xmlparse_cdata_start, 01119 (XML_EndCdataSectionHandler) jit_xml_document_xmlparse_cdata_end); 01120 // TODO: entity handlers? 01121 if (!XML_Parse(parser, txt, size, true)) { 01122 long i,byteoffset,linenumber=1; 01123 char *sp; 01124 01125 byteoffset = XML_GetCurrentByteIndex(parser); 01126 jit_object_error((t_object *)x,"jit_xml_document: error reading file at byte offset %d / %s", 01127 byteoffset, XML_ErrorString(XML_GetErrorCode(parser))); 01128 sp = txt; 01129 while (sp && sp<(txt+byteoffset)) { 01130 if (*sp++=='\n') 01131 linenumber++; 01132 } 01133 sp = txt+byteoffset; 01134 for (i=0;(i<255)&&(*sp)&&(sp<(txt+size))&&(*sp!='\n')&&(*sp!='\r');i++,sp++) 01135 tmp[i] = *sp; 01136 tmp[i] = 0; 01137 jit_object_error((t_object *)x,"line (%d): %s",linenumber,tmp); 01138 } 01139 else { 01140 rv = 1; 01141 jerr = JIT_ERR_NONE; 01142 } 01143 XML_ParserFree(parser); 01144 } else jit_object_error((t_object *)x,"jit_xml_document: could not allocate memory for parser"); 01145 01146 sysmem_freehandle(texthandle); 01147 sysfile_close(fh); 01148 01149 out: 01150 atom_setsym(&a[0], gensym(cname)); 01151 atom_setlong(&a[1], rv); 01152 // deal with a gimmeback 01153 return jerr; 01154 } 01155 01156 long jit_xml_document_decode(t_jit_xml_document *x, const char *data, char **outdata) 01157 { 01158 t_jit_charset_converter *conv; 01159 t_symbol *srcenc = x->encoding; 01160 char *cvtbuffer = NULL; 01161 long cvtbuffersize = 0; 01162 #ifdef MAC_VERSION 01163 t_symbol *dstenc = ps_macroman; 01164 #else 01165 t_symbol *dstenc = ps_ms_ansi; 01166 #endif 01167 t_jit_err err; 01168 01169 *outdata = NULL; 01170 01171 if (conv = (t_jit_charset_converter *)jit_object_new(ps_jit_charset_converter, srcenc, dstenc)) { 01172 err = (t_jit_err)jit_object_method(conv, ps_convert, data, strlen(data) + 1, &cvtbuffer, &cvtbuffersize); 01173 if (!err) { 01174 *outdata = cvtbuffer; 01175 return cvtbuffersize; 01176 } 01177 jit_object_free(conv); 01178 } 01179 return 0; 01180 } 01181 01182 void jit_xml_document_xmlparse_xmldecl(t_jit_xml_document *x, const char *version, const char *encoding, int standalone) 01183 { 01184 jit_xml_document_createheader(x, gensym((char *)encoding)); 01185 } 01186 01187 void jit_xml_document_xmlparse_element_start(t_jit_xml_document *x, const char *el, const char **attr) 01188 { 01189 int i; 01190 t_jit_xml_element *element; 01191 t_jit_xml_attribute *attribute; 01192 char *cstr; 01193 long size; 01194 01195 size = jit_xml_document_decode(x, el, &cstr); 01196 01197 element = jit_xml_document_createelement(x,gensym((char *)cstr)); 01198 jit_xml_node_appendchild((t_jit_xml_node *)x->parsernode,(t_jit_xml_node *)element); 01199 sysmem_freeptr(cstr); 01200 01201 x->parsernode = (t_jit_xml_node *)element; 01202 x->parserdepth++; 01203 //jit_object_post((t_object *)x,"start element %s, depth = %d",element->node.nodename->s_name,x->parserdepth); 01204 01205 for (i=0;attr[i];i+=2) { 01206 //jit_object_post((t_object *)x,"attribute %s = %s",attr[i],attr[i+1]); 01207 size = jit_xml_document_decode(x, attr[i], &cstr); 01208 attribute = jit_xml_document_createattribute(x,gensym((char *)cstr)); 01209 sysmem_freeptr(cstr); 01210 01211 size = jit_xml_document_decode(x, attr[i + 1], &cstr); 01212 jit_xml_node_setnodevalasstring((t_jit_xml_node *)attribute,(char *)cstr); 01213 sysmem_freeptr(cstr); 01214 01215 jit_attr_setlong(attribute,ps_specified,1); 01216 jit_xml_element_setattributenode(element,attribute); 01217 } 01218 } 01219 01220 void jit_xml_document_xmlparse_element_end(t_jit_xml_document *x, const char *el) 01221 { 01222 //jit_object_post((t_object *)x,"end element %s",el); 01223 // I don't think we need to do anything here right now aside from perhaps determine if single tag? 01224 x->parserdepth--; 01225 if (x->parsernode) 01226 x->parsernode = x->parsernode->parentnode; 01227 } 01228 01229 void jit_xml_document_xmlparse_default(t_jit_xml_document *x, const char *s, int len) 01230 { 01231 //char tmp[256]; 01232 01233 //strncpy(tmp,s,MIN(255,len)); 01234 //tmp[MIN(256,len)] = 0; 01235 //jit_object_post((t_object *)x,"default: len=%d, %s",len,tmp); 01236 } 01237 01238 void jit_xml_document_xmlparse_characterdata(t_jit_xml_document *x, const char *s, int len) 01239 { 01240 char tmp[4096]; 01241 char *cstr; 01242 long size; 01243 01244 // could dynamically allocate if necessary 01245 strncpy(tmp,s,MIN(4095,len)); 01246 tmp[MIN(4095,len)] = 0; 01247 01248 size = jit_xml_document_decode(x, tmp, &cstr); 01249 01250 if (x->parsernode->nodetype==ps_cdata) { 01251 //jit_object_post((t_object *)x,"appending to CDATA: %s",tmp); 01252 jit_xml_charnode_appenddata((t_jit_xml_charnode *)x->parsernode,cstr); 01253 } else { 01254 t_jit_xml_text *text=NULL; 01255 01256 if (x->parsernode->lastchild&&(x->parsernode->lastchild->nodetype==ps_text)) 01257 text = (t_jit_xml_text *)x->parsernode->lastchild; 01258 if (!text){ 01259 //jit_object_post((t_object *)x,"creating text node for %s containing %s",x->parsernode->nodename->s_name,tmp); 01260 text = jit_xml_document_createtextnode(x,cstr); 01261 jit_xml_node_appendchild((t_jit_xml_node *)x->parsernode,(t_jit_xml_node *)text); 01262 } else { 01263 //jit_object_post((t_object *)x,"appending to exisiting child text of %s with %s",x->parsernode->nodename->s_name,tmp); 01264 jit_xml_charnode_appenddata((t_jit_xml_charnode *)text,cstr); 01265 } 01266 } 01267 sysmem_freeptr(cstr); 01268 } 01269 01270 void jit_xml_document_xmlparse_cdata_start(t_jit_xml_document *x) 01271 { 01272 t_jit_xml_cdata *cdata; 01273 01274 //jit_object_post((t_object *)x,"cdata start"); 01275 cdata = jit_xml_document_createcdatasection(x,NULL); 01276 jit_xml_node_appendchild((t_jit_xml_node *)x->parsernode,(t_jit_xml_node *)cdata); 01277 01278 x->parsernode = (t_jit_xml_node *)cdata; 01279 x->parserdepth++; 01280 } 01281 01282 void jit_xml_document_xmlparse_cdata_end(t_jit_xml_document *x) 01283 { 01284 //jit_object_post((t_object *)x,"cdata end"); 01285 x->parserdepth--; 01286 if (x->parsernode) 01287 x->parsernode = x->parsernode->parentnode; 01288 } 01289 01290 void jit_xml_document_xmlparse_comment(t_jit_xml_document *x, const char *s) 01291 { 01292 t_jit_xml_comment *comment; 01293 char *cstr; 01294 long size; 01295 01296 size = jit_xml_document_decode(x, s, &cstr); 01297 01298 comment = (t_jit_xml_comment *)jit_xml_document_createcomment(x,(char *)cstr); 01299 jit_xml_node_appendchild((t_jit_xml_node *)x->parsernode,(t_jit_xml_node *)comment); 01300 01301 sysmem_freeptr(cstr); 01302 } 01303 01304 void jit_xml_document_xmlparse_doctype_start(t_jit_xml_document *x, const char *s) 01305 { 01306 // TODO 01307 //jit_object_post((t_object *)x,"doctype start: %s",tmp); 01308 } 01309 01310 void jit_xml_document_xmlparse_doctype_end(t_jit_xml_document *x) 01311 { 01312 // TODO 01313 //jit_object_post((t_object *)x,"doctype end"); 01314 } 01315 01316 t_jit_err jit_xml_document_write(t_jit_xml_document *x, t_symbol *s, long ac, t_atom *av) 01317 { 01318 long i,childcount,position; 01319 long err; 01320 char cname[512]; 01321 char tmp[256]; 01322 short path=0; 01323 long type = 'TEXT'; 01324 t_filehandle fh; 01325 01326 // could see if object already had name/vol and overwrite 01327 01328 strcpy(cname, "untitled.xml"); 01329 if (ac && av && av->a_type == A_SYM) { 01330 strcpy(cname, av->a_w.w_sym->s_name); 01331 } 01332 else { 01333 if (saveasdialog_extended(cname, &path, &type, &type, 1)) { 01334 //cancelled 01335 goto out; 01336 } 01337 } 01338 01339 if (err = path_createsysfile(cname, path, type, &fh)) { 01340 jit_object_error((t_object *)x,"jit_xml_document_write: could not open file %s",cname); 01341 goto out; 01342 } 01343 x->filename = gensym(cname); 01344 x->path = path; 01345 01346 if (x->hasheader) { 01347 char tmp[1024]; 01348 long count; 01349 01350 sprintf(tmp, "<?xml version=\"1.0\" encoding=\"%s\" standalone=\"yes\"?>\n\n", x->encoding->s_name); 01351 count = strlen(tmp); 01352 jit_xml_node_encode_and_write((t_jit_xml_node *)x, fh, &count, tmp); 01353 } 01354 01355 if (x->node.childnodes) { 01356 childcount = jit_linklist_getsize(x->node.childnodes); 01357 for (i=0;i<childcount;i++) { 01358 jit_xml_node_write((t_jit_xml_node *)jit_linklist_getindex(x->node.childnodes,i),fh,0); 01359 } 01360 } 01361 sysfile_getpos(fh, &position); 01362 sysfile_seteof(fh, position); 01363 sysfile_close(fh); 01364 01365 out: 01366 return JIT_ERR_NONE; 01367 } 01368 01369 // this is inefficient, but works 01370 void jit_xml_node_encode_and_write(t_jit_xml_node *x, t_filehandle fh, long *count, char *data) 01371 { 01372 t_jit_charset_converter *conv; 01373 char *cvtbuffer = NULL; 01374 long cvtbuffersize = 0; 01375 t_symbol *dstenc; 01376 #ifdef MAC_VERSION 01377 t_symbol *srcenc = ps_macroman; 01378 #else 01379 t_symbol *srcenc = ps_ms_ansi; 01380 #endif 01381 t_jit_err err; 01382 t_jit_xml_document *doc; 01383 01384 if (!x->ownerdocument) 01385 doc = (t_jit_xml_document *)x; 01386 else 01387 doc = x->ownerdocument; 01388 01389 dstenc = doc->encoding; 01390 01391 if (conv = (t_jit_charset_converter *)jit_object_new(ps_jit_charset_converter, srcenc, dstenc)) { 01392 err = (t_jit_err)jit_object_method(conv, ps_convert, data, *count, &cvtbuffer, &cvtbuffersize); 01393 if (!err) { 01394 long bytecount = cvtbuffersize; 01395 sysfile_write(fh, &bytecount, cvtbuffer); 01396 sysmem_freeptr(cvtbuffer); 01397 *count = bytecount; 01398 } 01399 jit_object_free(conv); 01400 } 01401 } 01402 01403 #ifdef MAC_VERSION 01404 #define ENTITY_quot '"' 01405 #define ENTITY_amp '&' 01406 #define ENTITY_lt '<' 01407 #define ENTITY_gt '>' 01408 #else 01409 #define ENTITY_quot 34 01410 #define ENTITY_amp 38 01411 #define ENTITY_lt 60 01412 #define ENTITY_gt 62 01413 #endif 01414 01415 char *jit_xml_convert_entities(char *instr, long *len) 01416 { 01417 char *outstr = NULL, *os = NULL; 01418 long inlen = *len; 01419 long outlen = inlen; 01420 long i; 01421 char now; 01422 01423 for (i = 0; i < inlen; i++) { 01424 now = instr[i]; 01425 switch (now) { 01426 case ENTITY_quot: outlen += 5; break; 01427 case ENTITY_amp: outlen += 4; break; 01428 case ENTITY_lt: outlen += 3; break; 01429 case ENTITY_gt: outlen += 3; break; 01430 default: break; 01431 } 01432 } 01433 if (outlen != inlen) { 01434 os = sysmem_newptrclear(outlen + 1); 01435 outstr = os; 01436 for (i = 0; i < inlen; i++) { 01437 now = instr[i]; 01438 switch (now) { 01439 case ENTITY_quot: strcat(outstr, """); outstr += 6; break; 01440 case ENTITY_amp: strcat(outstr, "&"); outstr += 5; break; 01441 case ENTITY_lt: strcat(outstr, "<"); outstr += 4; break; 01442 case ENTITY_gt: strcat(outstr, ">"); outstr += 4; break; 01443 default: *outstr++ = now; break; 01444 } 01445 } 01446 *len = outlen; 01447 return os; 01448 } 01449 else return NULL; 01450 } 01451 01452 void jit_xml_node_write(t_jit_xml_node *x, t_filehandle fh, long depth) 01453 { 01454 char tmp[8096],tmp2[8096]; 01455 long i,attrcount,childcount,len,count; 01456 t_jit_xml_attribute *attr; 01457 char *p,*p2,*cvt; 01458 01459 if (!x) 01460 return; 01461 01462 tmp[0] = 0; 01463 01464 //jit_object_post((t_object *)x,"trying to write: %s",x->nodetype->s_name); 01465 if (x->nodetype==ps_text) { 01466 // TODO: support other kinds of formatting 01467 // for now, strip whitespace + use tabbed formatting 01468 p = ((t_jit_xml_charnode *)x)->data; 01469 len = ((t_jit_xml_charnode *)x)->length; 01470 // strip leading white space 01471 while (len&&*p&&((*p=='\r')||(*p=='\n')||(*p=='\t')||(*p==' '))) { 01472 len--;p++; 01473 } 01474 while (len) { 01475 tmp[0] = 0; 01476 for (i=0;i<depth;i++) 01477 strcat(tmp,"\t"); 01478 count = strlen(tmp); 01479 jit_xml_node_encode_and_write(x,fh,&count,tmp); 01480 //move up to any line break 01481 p2 = p; 01482 count = 0; 01483 while ((count<len)&&*p2&&(*p2!='\r')&&(*p2!='\n')) { 01484 count++;p2++; 01485 } 01486 len -= count; 01487 jit_xml_node_encode_and_write(x,fh,&count,p); 01488 p = p2; 01489 // write new line 01490 count = 1; 01491 jit_xml_node_encode_and_write(x,fh,&count,"\n"); 01492 // strip trailing white space (leading for next line) 01493 while (len&&*p&&((*p=='\r')||(*p=='\n')||(*p=='\t')||(*p==' '))) { 01494 len--;p++; 01495 } 01496 } 01497 } else if (x->nodetype==ps_cdata) { 01498 for (i=0;i<depth;i++) 01499 strcat(tmp,"\t"); 01500 strcat(tmp,"<![CDATA["); 01501 count = strlen(tmp); 01502 jit_xml_node_encode_and_write(x,fh,&count,tmp); 01503 01504 count = ((t_jit_xml_charnode *)x)->length; 01505 jit_xml_node_encode_and_write(x,fh,&count,((t_jit_xml_charnode *)x)->data); 01506 01507 tmp[0]=0; 01508 //for (i=0;i<depth;i++) 01509 // strcat(tmp,"\t"); 01510 strcat(tmp,"]]>"); 01511 strcat(tmp,"\n"); //newline, could be native 01512 count = strlen(tmp); 01513 jit_xml_node_encode_and_write(x,fh,&count,tmp); 01514 } else if (x->nodetype==ps_comment) { 01515 for (i=0;i<depth;i++) 01516 strcat(tmp,"\t"); 01517 strcat(tmp,"<!--"); 01518 count = strlen(tmp); 01519 jit_xml_node_encode_and_write(x,fh,&count,tmp); 01520 01521 count = ((t_jit_xml_charnode *)x)->length; 01522 jit_xml_node_encode_and_write(x,fh,&count,((t_jit_xml_charnode *)x)->data); 01523 01524 tmp[0]=0; 01525 //for (i=0;i<depth;i++) 01526 // strcat(tmp,"\t"); 01527 strcat(tmp,"-->"); 01528 strcat(tmp,"\n"); //newline, could be native 01529 count = strlen(tmp); 01530 jit_xml_node_encode_and_write(x,fh,&count,tmp); 01531 } else { 01532 for (i=0;i<depth;i++) 01533 strcat(tmp,"\t"); 01534 strcat(tmp,"<"); 01535 strcat(tmp,x->nodename->s_name); 01536 if (x->attributes) { 01537 attrcount = jit_linklist_getsize(x->attributes); 01538 for (i=0;i<attrcount;i++) { 01539 attr = jit_linklist_getindex(x->attributes,i); 01540 strcat(tmp," "); 01541 strcat(tmp,attr->node.nodename->s_name); 01542 strcat(tmp,"=\""); 01543 len = 8096; 01544 p = tmp2; 01545 jit_xml_node_getnodevalasstring((t_jit_xml_node *)attr,&len,&p); 01546 if ((cvt = jit_xml_convert_entities(p, &len))) { 01547 strcat(tmp, cvt); 01548 sysmem_freeptr(cvt); 01549 } else { 01550 strcat(tmp,p); 01551 } 01552 strcat(tmp,"\""); 01553 } 01554 } 01555 if (x->childnodes) 01556 childcount = jit_linklist_getsize(x->childnodes); 01557 else 01558 childcount = 0; 01559 01560 if (childcount>0) { 01561 strcat(tmp,">"); 01562 strcat(tmp,"\n"); //newline, could be native 01563 count = strlen(tmp); 01564 jit_xml_node_encode_and_write(x,fh,&count,tmp); 01565 for (i=0;i<childcount;i++) { 01566 jit_xml_node_write((t_jit_xml_node *)jit_linklist_getindex(x->childnodes,i),fh,depth+1); 01567 } 01568 tmp[0] = 0; 01569 for (i=0;i<depth;i++) 01570 strcat(tmp,"\t"); 01571 sprintf(tmp,"%s</%s>",tmp,x->nodename->s_name); 01572 strcat(tmp,"\n"); //newline, could be native 01573 count = strlen(tmp); 01574 jit_xml_node_encode_and_write(x,fh,&count,tmp); 01575 } else { 01576 //singletag 01577 strcat(tmp," />"); 01578 strcat(tmp,"\n"); //newline, could be native 01579 count = strlen(tmp); 01580 jit_xml_node_encode_and_write(x,fh,&count,tmp); 01581 } 01582 } 01583 } 01584 01585 void jit_xml_node_print(t_jit_xml_node *x, long depth) 01586 { 01587 char tmp[1024],tmp2[1024]; 01588 long i,attrcount,childcount,len; 01589 t_jit_xml_attribute *attr; 01590 char *p; 01591 01592 if (!x) 01593 return; 01594 01595 tmp[0] = 0; 01596 for (i=0;i<depth;i++) 01597 strcat(tmp," "); 01598 strcat(tmp,"<"); 01599 strcat(tmp,x->nodename->s_name); 01600 if (x->attributes) { 01601 attrcount = jit_linklist_getsize(x->attributes); 01602 for (i=0;i<attrcount;i++) { 01603 attr = jit_linklist_getindex(x->attributes,i); 01604 strcat(tmp," "); 01605 strcat(tmp,attr->node.nodename->s_name); 01606 strcat(tmp,"=\""); 01607 len = 1024; 01608 p = tmp2; 01609 jit_xml_node_getnodevalasstring((t_jit_xml_node *)attr,&len,&p); 01610 strcat(tmp,p); 01611 strcat(tmp,"\""); 01612 } 01613 } 01614 if (x->childnodes) 01615 childcount = jit_linklist_getsize(x->childnodes); 01616 else 01617 childcount = 0; 01618 01619 if (childcount>0) { 01620 strcat(tmp,">"); 01621 jit_object_post((t_object *)x,tmp); 01622 for (i=0;i<childcount;i++) { 01623 jit_xml_node_print((t_jit_xml_node *)jit_linklist_getindex(x->childnodes,i),depth+1); 01624 } 01625 tmp[0] = 0; 01626 for (i=0;i<depth;i++) 01627 strcat(tmp," "); 01628 jit_object_post((t_object *)x,"%s</%s>",tmp,x->nodename->s_name); 01629 } else { 01630 //singletag 01631 strcat(tmp," />"); 01632 jit_object_post((t_object *)x,tmp); 01633 } 01634 } 01635 01636 void jit_xml_document_print(t_jit_xml_document *x) 01637 { 01638 long i,childcount; 01639 01640 if (x->node.childnodes) { 01641 childcount = jit_linklist_getsize(x->node.childnodes); 01642 for (i=0;i<childcount;i++) { 01643 jit_xml_node_print((t_jit_xml_node *)jit_linklist_getindex(x->node.childnodes,i),0); 01644 } 01645 } 01646 } 01647 01648 void jit_xml_document_createheader(t_jit_xml_document *x, t_symbol *encoding) 01649 { 01650 if (encoding == ps_utf_8 || 01651 encoding == ps_utf_16 || 01652 encoding == ps_iso_8859_1 || 01653 encoding == ps_us_ascii) 01654 { 01655 x->hasheader = true; 01656 x->encoding = encoding; 01657 } else { 01658 x->hasheader = false; 01659 x->encoding = ps_utf_8; 01660 } 01661 } 01662 01663 t_jit_xml_element *jit_xml_document_createelement(t_jit_xml_document *x, t_symbol *tagname) 01664 { 01665 t_jit_xml_element *element; 01666 01667 element = jit_object_new(gensym("jit_xml_element")); 01668 element->node.nodename = tagname; 01669 element->node.ownerdocument = x; 01670 01671 return element; 01672 } 01673 01674 t_jit_xml_text *jit_xml_document_createtextnode(t_jit_xml_document *x, char *data) 01675 { 01676 t_jit_xml_text *text; 01677 01678 text = jit_object_new(gensym("jit_xml_text")); 01679 if (data) 01680 jit_xml_charnode_replacedata((t_jit_xml_charnode *)text,0,strlen(data),data); 01681 text->charnode.node.ownerdocument = x; 01682 01683 return text; 01684 } 01685 01686 t_jit_xml_comment *jit_xml_document_createcomment(t_jit_xml_document *x, char *data) 01687 { 01688 t_jit_xml_comment *comment; 01689 01690 comment = jit_object_new(gensym("jit_xml_comment")); 01691 if (data) 01692 jit_xml_charnode_replacedata((t_jit_xml_charnode *)comment,0,strlen(data),data); 01693 comment->charnode.node.ownerdocument = x; 01694 01695 return comment; 01696 } 01697 01698 t_jit_xml_cdata *jit_xml_document_createcdatasection(t_jit_xml_document *x, char *data) 01699 { 01700 t_jit_xml_cdata *cdata; 01701 01702 cdata = jit_object_new(gensym("jit_xml_cdata")); 01703 if (data) 01704 jit_xml_charnode_replacedata((t_jit_xml_charnode *)cdata,0,strlen(data),data); 01705 cdata->charnode.node.ownerdocument = x; 01706 01707 return cdata; 01708 } 01709 01710 t_jit_xml_attribute *jit_xml_document_createattribute(t_jit_xml_document *x, t_symbol *name) 01711 { 01712 t_jit_xml_attribute *attribute; 01713 01714 attribute = jit_object_new(gensym("jit_xml_attribute")); 01715 attribute->node.nodename = name; 01716 attribute->node.ownerdocument = x; 01717 01718 return attribute; 01719 } 01720 01721 t_jit_linklist *jit_xml_document_getelementsbytagname(t_jit_xml_document *x, t_symbol *tagname) 01722 { 01723 01724 t_jit_linklist *elements=NULL; 01725 // depthfirst (preorder) traversal 01726 jit_xml_node_getelementsbytagname_helper((t_jit_xml_node *)x,tagname,&elements); 01727 return elements; 01728 } 01729 01730 void *jit_xml_document_new(t_symbol *s, long argc, t_atom *argv) 01731 { 01732 t_jit_xml_document *x; 01733 01734 if (x = (t_jit_xml_document *)object_alloc(_jit_xml_document_class)) { 01735 jit_xml_node_new((t_jit_xml_node *)x,ps_document); 01736 x->filename = _jit_sym_nothing; 01737 x->path = 0; 01738 x->parserdepth = 0; 01739 x->parsernode = NULL; 01740 x->hasheader = false; 01741 x->encoding = ps_utf_8; 01742 } 01743 01744 return x; 01745 } 01746 01747 void jit_xml_document_free(t_jit_xml_document *x) 01748 { 01749 jit_xml_node_free((t_jit_xml_node *)x); 01750 } 01751 01752 01753 /*------------------------------------------------------------------------------ 01754 jit_xml_element 01755 -------------------------------------------------------------------------------*/ 01756 01757 // jit_class_addmethod(c,(method)jit_xml_element_normalize, "normalize", A_CANT, 0); //todo 01758 01759 t_jit_err jit_xml_element_getattribute(t_jit_xml_element *x, t_symbol *attrname, long *ac, t_atom **av) 01760 { 01761 t_jit_xml_attribute *attr=NULL; 01762 01763 if (x&&x->node.attributes) { 01764 jit_linklist_findfirst(x->node.attributes,(void **)&attr,(t_cmpfn)jit_xml_attr_symcompare,attrname); 01765 if (attr) { 01766 return object_attr_getvalueof(attr,ps_nodevalue,ac,av); 01767 } 01768 } 01769 return JIT_ERR_GENERIC; 01770 } 01771 01772 t_jit_err jit_xml_element_setattribute(t_jit_xml_element *x, t_symbol *attrname, long ac, t_atom *av) 01773 { 01774 t_jit_xml_attribute *attr=NULL; 01775 01776 if (x) { 01777 if (!x->node.attributes) 01778 x->node.attributes = jit_linklist_new(); 01779 jit_linklist_findfirst(x->node.attributes,(void **)&attr,(t_cmpfn)jit_xml_attr_symcompare,attrname); 01780 if (attr) { 01781 return object_attr_setvalueof(attr,ps_nodevalue,ac,av); 01782 } else { 01783 attr = jit_xml_document_createattribute(x->node.ownerdocument,attrname); 01784 object_attr_setvalueof((t_jit_xml_node *)attr,ps_nodevalue,ac,av); 01785 jit_xml_element_setattributenode(x,attr); 01786 } 01787 } 01788 return JIT_ERR_GENERIC; 01789 } 01790 01791 t_jit_err jit_xml_element_removeattribute(t_jit_xml_element *x, t_symbol *attrname) 01792 { 01793 t_jit_xml_attribute *attr=NULL; 01794 long i; 01795 01796 jit_linklist_findfirst(x->node.attributes,(void **)&attr,(t_cmpfn)jit_xml_attr_symcompare,attrname); 01797 if (attr) { 01798 i = jit_linklist_objptr2index(x->node.attributes,(t_jit_object *)attr); 01799 if (i>=0) { 01800 jit_linklist_deleteindex(x->node.attributes,i); 01801 return JIT_ERR_NONE; 01802 } 01803 } 01804 return JIT_ERR_GENERIC; 01805 } 01806 01807 t_jit_xml_attribute *jit_xml_element_getattributenode(t_jit_xml_element *x, t_symbol *attrname) 01808 { 01809 t_jit_xml_attribute *attr=NULL; 01810 01811 if (x&&x->node.attributes) 01812 jit_linklist_findfirst(x->node.attributes,(void **)&attr,(t_cmpfn)jit_xml_attr_symcompare,attrname); 01813 return attr; 01814 } 01815 01816 t_jit_xml_attribute *jit_xml_element_setattributenode(t_jit_xml_element *x, t_jit_xml_attribute *attr) 01817 { 01818 t_jit_xml_attribute *oldattr=NULL; 01819 long i; 01820 01821 if (!x->node.attributes) 01822 x->node.attributes = jit_linklist_new(); 01823 jit_linklist_findfirst(x->node.attributes,(void **)&oldattr,(t_cmpfn)jit_xml_attr_symcompare,attr->node.nodename); 01824 if (oldattr) { 01825 i = jit_linklist_objptr2index(x->node.attributes,(t_jit_object *)attr); 01826 if (i>=0) { 01827 jit_linklist_deleteindex(x->node.attributes,i); 01828 } 01829 } 01830 jit_linklist_append(x->node.attributes,attr); 01831 return NULL; // we free the node, not the caller as the DOM spec suggests 01832 } 01833 01834 t_jit_xml_attribute * jit_xml_element_removeattributenode(t_jit_xml_element *x, t_jit_xml_attribute *attr) 01835 { 01836 t_jit_xml_attribute *oldattr=NULL; 01837 long i; 01838 01839 if (x&&x->node.attributes) { 01840 jit_linklist_findfirst(x->node.attributes,(void **)&oldattr,(t_cmpfn)jit_xml_attr_symcompare,attr->node.nodename); 01841 if (oldattr) { 01842 i = jit_linklist_objptr2index(x->node.attributes,(t_jit_object *)oldattr); 01843 if (i>=0) { 01844 jit_linklist_deleteindex(x->node.attributes,i); 01845 } 01846 } 01847 } 01848 return NULL; // we free the node, not the caller as the DOM spec suggests 01849 } 01850 01851 t_jit_linklist *jit_xml_element_getelementsbytagname(t_jit_xml_element *x, t_symbol *tagname) 01852 { 01853 01854 t_jit_linklist *elements=NULL; 01855 // depthfirst (preorder) traversal 01856 jit_xml_node_getelementsbytagname_helper((t_jit_xml_node *)x,tagname,&elements); 01857 return elements; 01858 } 01859 01860 01861 long jit_xml_element_symcompare(t_jit_xml_attribute *x,t_symbol *name) 01862 { 01863 return (name&&(x->node.nodename==name)); 01864 } 01865 01866 void *jit_xml_element_new(t_symbol *s, long argc, t_atom *argv) 01867 { 01868 t_jit_xml_element *x; 01869 01870 if (x = (t_jit_xml_element *)object_alloc(_jit_xml_element_class)) { 01871 jit_xml_node_new((t_jit_xml_node *)x,ps_element); 01872 x->singletag = 0; // yes??? 01873 } 01874 01875 return x; 01876 } 01877 01878 void jit_xml_element_free(t_jit_xml_element *x) 01879 { 01880 jit_xml_node_free((t_jit_xml_node *)x); 01881 } 01882 01883 // utils 01884 t_symbol *jit_xml_element_getattribute_sym(t_jit_xml_element *x, t_symbol *attrname) 01885 { 01886 long ac=0; 01887 t_atom *av=NULL; 01888 t_symbol *rv=_jit_sym_nothing; 01889 01890 if (x&&attrname) { 01891 if (((jit_xml_element_getattribute(x,attrname,&ac,&av))==JIT_ERR_NONE)&&av) { 01892 if (ac&&av) { 01893 rv = jit_atom_getsym(av); 01894 jit_freebytes(av,sizeof(t_atom)*ac); 01895 } 01896 } 01897 } 01898 return rv; 01899 } 01900 01901 t_jit_err jit_xml_element_setattribute_sym(t_jit_xml_element *x, t_symbol *attrname, t_symbol *s) 01902 { 01903 long ac=1; 01904 t_atom av[1]; 01905 t_jit_err rv=JIT_ERR_GENERIC; 01906 01907 if (x&&attrname) { 01908 jit_atom_setsym(av,s); 01909 rv = jit_xml_element_setattribute(x,attrname,ac,av); 01910 } 01911 return rv; 01912 } 01913 01914 long jit_xml_element_getattribute_long(t_jit_xml_element *x, t_symbol *attrname) 01915 { 01916 long ac=0; 01917 t_atom *av=NULL; 01918 long rv=0; 01919 01920 if (x&&attrname) { 01921 if (((jit_xml_element_getattribute(x,attrname,&ac,&av))==JIT_ERR_NONE)&&av) { 01922 if (ac&&av) { 01923 rv = jit_atom_getlong(av); 01924 jit_freebytes(av,sizeof(t_atom)*ac); 01925 } 01926 } 01927 } 01928 return rv; 01929 } 01930 01931 t_jit_err jit_xml_element_setattribute_long(t_jit_xml_element *x, t_symbol *attrname, long c) 01932 { 01933 long ac=1; 01934 t_atom av[1]; 01935 t_jit_err rv=JIT_ERR_GENERIC; 01936 01937 if (x&&attrname) { 01938 jit_atom_setlong(av,c); 01939 rv = jit_xml_element_setattribute(x,attrname,ac,av); 01940 } 01941 return rv; 01942 } 01943 01944 01945 float jit_xml_element_getattribute_float(t_jit_xml_element *x, t_symbol *attrname) 01946 { 01947 long ac=0; 01948 t_atom *av=NULL; 01949 float rv=0; 01950 01951 if (x&&attrname) { 01952 if (((jit_xml_element_getattribute(x,attrname,&ac,&av))==JIT_ERR_NONE)&&av) { 01953 if (ac&&av) { 01954 rv = jit_atom_getfloat(av); 01955 jit_freebytes(av,sizeof(t_atom)*ac); 01956 } 01957 } 01958 } 01959 return rv; 01960 } 01961 01962 t_jit_err jit_xml_element_setattribute_float(t_jit_xml_element *x, t_symbol *attrname, float f) 01963 { 01964 long ac=1; 01965 t_atom av[1]; 01966 t_jit_err rv=JIT_ERR_GENERIC; 01967 01968 if (x&&attrname) { 01969 jit_atom_setfloat(av,f); 01970 rv = jit_xml_element_setattribute(x,attrname,ac,av); 01971 } 01972 return rv; 01973 } 01974 01975 long jit_xml_element_getattribute_sym_array(t_jit_xml_element *x, t_symbol *attrname, long max, t_symbol **vals) 01976 { 01977 long i,ac=0; 01978 t_atom *av=NULL; 01979 01980 if (x&&attrname&&vals) { 01981 if (((jit_xml_element_getattribute(x,attrname,&ac,&av))==JIT_ERR_NONE)&&av) { 01982 if (ac&&av) { 01983 max = MIN(max,ac); 01984 for (i=0;i<max;i++) { 01985 vals[i]=jit_atom_getsym(av+i); 01986 } 01987 jit_freebytes(av,sizeof(t_atom)*ac); 01988 } 01989 } 01990 } 01991 return ac; 01992 } 01993 01994 t_jit_err jit_xml_element_setattribute_sym_array(void *x, t_symbol *attrname, long count, t_symbol **vals) 01995 { 01996 t_atom av[XML_MAX_ATOM_COUNT]; 01997 t_jit_err rv=JIT_ERR_GENERIC; 01998 long i; 01999 02000 if (x&&attrname&&vals) { 02001 for (i=0;i<count;i++) 02002 jit_atom_setsym(av+i,vals[i]); 02003 rv = jit_xml_element_setattribute(x,attrname,count,av); 02004 } 02005 return rv; 02006 } 02007 02008 long jit_xml_element_getattribute_long_array(t_jit_xml_element *x, t_symbol *attrname, long max, long *vals) 02009 { 02010 long i,ac=0; 02011 t_atom *av=NULL; 02012 02013 if (x&&attrname&&vals) { 02014 if (((jit_xml_element_getattribute(x,attrname,&ac,&av))==JIT_ERR_NONE)&&av) { 02015 if (ac&&av) { 02016 max = MIN(max,ac); 02017 for (i=0;i<max;i++) { 02018 vals[i]=jit_atom_getlong(av+i); 02019 } 02020 jit_freebytes(av,sizeof(t_atom)*ac); 02021 } 02022 } 02023 } 02024 return ac; 02025 } 02026 02027 t_jit_err jit_xml_element_setattribute_long_array(void *x, t_symbol *attrname, long count, long *vals) 02028 { 02029 t_atom av[XML_MAX_ATOM_COUNT]; 02030 t_jit_err rv=JIT_ERR_GENERIC; 02031 long i; 02032 02033 if (x&&attrname&&vals) { 02034 for (i=0;i<count;i++) 02035 jit_atom_setlong(av+i,vals[i]); 02036 rv = jit_xml_element_setattribute(x,attrname,count,av); 02037 } 02038 return rv; 02039 } 02040 02041 long jit_xml_element_getattribute_float_array(t_jit_xml_element *x, t_symbol *attrname, long max, float *vals) 02042 { 02043 long i,ac=0; 02044 t_atom *av=NULL; 02045 02046 if (x&&attrname&&vals) { 02047 if (((jit_xml_element_getattribute(x,attrname,&ac,&av))==JIT_ERR_NONE)&&av) { 02048 if (ac&&av) { 02049 max = MIN(max,ac); 02050 for (i=0;i<max;i++) { 02051 vals[i]=jit_atom_getfloat(av+i); 02052 } 02053 jit_freebytes(av,sizeof(t_atom)*ac); 02054 } 02055 } 02056 } 02057 return ac; 02058 } 02059 02060 t_jit_err jit_xml_element_setattribute_float_array(void *x, t_symbol *attrname, long count, float *vals) 02061 { 02062 t_atom av[XML_MAX_ATOM_COUNT]; 02063 t_jit_err rv=JIT_ERR_GENERIC; 02064 long i; 02065 02066 if (x&&attrname&&vals) { 02067 for (i=0;i<count;i++) 02068 jit_atom_setfloat(av+i,vals[i]); 02069 rv = jit_xml_element_setattribute(x,attrname,count,av); 02070 } 02071 return rv; 02072 } 02073 02074 02075 /*------------------------------------------------------------------------------ 02076 jit_xml_attribute 02077 -------------------------------------------------------------------------------*/ 02078 02079 long jit_xml_attr_symcompare(t_jit_xml_attribute *x,t_symbol *name) 02080 { 02081 return (name&&(x->node.nodename==name)); 02082 } 02083 02084 void *jit_xml_attribute_new(t_symbol *s, long argc, t_atom *argv) 02085 { 02086 t_jit_xml_attribute *x; 02087 02088 if (x = (t_jit_xml_attribute *)object_alloc(_jit_xml_attribute_class)) { 02089 jit_xml_node_new((t_jit_xml_node *)x,ps_attribute); 02090 x->specified = 0; 02091 } 02092 02093 return x; 02094 } 02095 02096 void jit_xml_attribute_free(t_jit_xml_attribute *x) 02097 { 02098 jit_xml_node_free((t_jit_xml_node *)x); 02099 } 02100 02101 /*------------------------------------------------------------------------------ 02102 jit_xml_text 02103 -------------------------------------------------------------------------------*/ 02104 02105 void *jit_xml_text_new(t_symbol *s, long argc, t_atom *argv) 02106 { 02107 t_jit_xml_text *x; 02108 02109 if (x = (t_jit_xml_text *)object_alloc(_jit_xml_text_class)) { 02110 jit_xml_charnode_new((t_jit_xml_charnode *)x,ps_text); 02111 } 02112 02113 return x; 02114 } 02115 02116 t_jit_xml_text *jit_xml_text_splittext(t_jit_xml_text *x, long offset) 02117 { 02118 // TODO 02119 return NULL; 02120 } 02121 02122 void jit_xml_text_free(t_jit_xml_text *x) 02123 { 02124 jit_xml_charnode_free((t_jit_xml_charnode *)x); 02125 } 02126 02127 /*------------------------------------------------------------------------------ 02128 jit_xml_comment 02129 -------------------------------------------------------------------------------*/ 02130 02131 02132 void *jit_xml_comment_new(t_symbol *s, long argc, t_atom *argv) 02133 { 02134 t_jit_xml_comment *x; 02135 02136 if (x = (t_jit_xml_comment *)object_alloc(_jit_xml_comment_class)) { 02137 jit_xml_charnode_new((t_jit_xml_charnode *)x,ps_comment); 02138 } 02139 02140 return x; 02141 } 02142 02143 void jit_xml_comment_free(t_jit_xml_comment *x) 02144 { 02145 jit_xml_charnode_free((t_jit_xml_charnode *)x); 02146 } 02147 02148 02149 /*------------------------------------------------------------------------------ 02150 jit_xml_cdata 02151 -------------------------------------------------------------------------------*/ 02152 02153 02154 void *jit_xml_cdata_new(t_symbol *s, long argc, t_atom *argv) 02155 { 02156 t_jit_xml_cdata *x; 02157 02158 if (x = (t_jit_xml_cdata *)object_alloc(_jit_xml_cdata_class)) { 02159 jit_xml_charnode_new((t_jit_xml_charnode *)x,ps_cdata); 02160 } 02161 02162 return x; 02163 } 02164 02165 t_jit_xml_cdata *jit_xml_cdata_splittext(t_jit_xml_cdata *x, long offset) 02166 { 02167 // TODO 02168 return NULL; 02169 } 02170 02171 void jit_xml_cdata_free(t_jit_xml_cdata *x) 02172 { 02173 jit_xml_charnode_free((t_jit_xml_charnode *)x); 02174 } 02175 02176 02177 02178
Copyright © 2008, Cycling '74