1 /*--------------------------------------------------------------------------- 2 | Copyright (C) 1999 Jochen C. Loewer (loewerj@hotmail.com) 3 +---------------------------------------------------------------------------- 4 | 5 | $Id$ 6 | 7 | 8 | A DOM interface upon the expat XML parser for the C language 9 | according to the W3C recommendation REC-DOM-Level-1-19981001 10 | 11 | 12 | The contents of this file are subject to the Mozilla Public License 13 | Version 1.1 (the "License"); you may not use this file except in 14 | compliance with the License. You may obtain a copy of the License at 15 | http://www.mozilla.org/MPL/ 16 | 17 | Software distributed under the License is distributed on an "AS IS" 18 | basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 19 | License for the specific language governing rights and limitations 20 | under the License. 21 | 22 | The Original Code is tDOM. 23 | 24 | The Initial Developer of the Original Code is Jochen Loewer 25 | Portions created by Jochen Loewer are Copyright (C) 1998, 1999 26 | Jochen Loewer. All Rights Reserved. 27 | 28 | Contributor(s): 29 | 30 | 31 | written by Jochen Loewer 32 | April 5, 1999 33 | 34 \--------------------------------------------------------------------------*/ 35 36 #ifndef __DOM_H__ 37 #define __DOM_H__ 38 39 #include <tcl.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <ctype.h> 43 #include <bsdxml.h> 44 45 /* 46 * tDOM provides it's own memory allocator which is optimized for 47 * low heap usage. It uses the native Tcl allocator underneath, 48 * though, but it is not very MT-friendly. Therefore, you might 49 * use the (normal) Tcl allocator with USE_NORMAL_ALLOCATOR 50 * defined during compile time. Actually, the symbols name is 51 * a misnomer. It should have benn called "USE_TCL_ALLOCATOR" 52 * but I did not want to break any backward compatibility. 53 */ 54 55 #ifndef USE_NORMAL_ALLOCATOR 56 # define MALLOC malloc 57 # define FREE free 58 # define REALLOC realloc 59 # define tdomstrdup strdup 60 #else 61 # define domAllocInit() 62 # define domAlloc MALLOC 63 # define domFree FREE 64 # if defined(TCL_MEM_DEBUG) || defined(NS_AOLSERVER) 65 # define MALLOC Tcl_Alloc 66 # define FREE(a) Tcl_Free((char*)(a)) 67 # define REALLOC Tcl_Realloc 68 # define tdomstrdup(s) (char*)strcpy(MALLOC(strlen((s))+1),(char*)s) 69 # else 70 # define MALLOC malloc 71 # define FREE free 72 # define REALLOC realloc 73 # define tdomstrdup strdup 74 # endif /* TCL_MEM_DEBUG */ 75 #endif /* USE_NORMAL_ALLOCATOR */ 76 77 #if defined(TCL_MEM_DEBUG) || defined(NS_AOLSERVER) my_malloc(size_t size)78 static void* my_malloc(size_t size){return Tcl_Alloc(size);} my_free(void * ptr)79 static void my_free(void *ptr){Tcl_Free((char*)ptr);} my_realloc(void * ptr,size_t size)80 static void* my_realloc(void *ptr,size_t size){return Tcl_Realloc(ptr,size);} 81 static XML_Memory_Handling_Suite memsuite = { 82 my_malloc, my_realloc, my_free 83 }; 84 # define MEM_SUITE &memsuite 85 #else 86 # define MEM_SUITE NULL 87 #endif 88 89 /* 90 * Beginning with 8.6, interp->errorLine isn't public visible anymore 91 * (TIP 330) 92 */ 93 #if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6) 94 # define Tcl_GetErrorLine(interp) (interp)->errorLine 95 #endif 96 97 /* 98 * Starting with Tcl 8.2 the Tcl_Panic() is defined properly 99 * over the stubs table. 100 * Also, we have a proper Tcl_GetString() shortcut afterwards. 101 */ 102 #if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 2) 103 # define Tcl_Panic panic 104 # define Tcl_GetString(a) Tcl_GetStringFromObj((a), NULL) 105 #endif 106 107 #define domPanic(msg) Tcl_Panic((msg)); 108 109 /* 110 * If compiled against threaded Tcl core, we must take 111 * some extra care about process-wide globals and the 112 * way we name Tcl object accessor commands. 113 */ 114 #ifndef TCL_THREADS 115 extern unsigned long domUniqueNodeNr; 116 extern unsigned long domUniqueDocNr; 117 extern Tcl_HashTable tdom_tagNames; 118 extern Tcl_HashTable tdom_attrNames; 119 # define TDomNotThreaded(x) x 120 # define TDomThreaded(x) 121 # define HASHTAB(doc,tab) tab 122 # define NODE_NO(doc) ++domUniqueNodeNr 123 # define DOC_NO(doc) ++domUniqueDocNr 124 #else 125 # define TDomNotThreaded(x) 126 # define TDomThreaded(x) x 127 # define HASHTAB(doc,tab) (doc)->tab 128 # define NODE_NO(doc) ((doc)->nodeCounter)++ 129 # define DOC_NO(doc) (unsigned long)(doc) 130 #endif /* TCL_THREADS */ 131 132 #define DOC_CMD(s,doc) sprintf((s), "domDoc%p", (void *)(doc)) 133 #define NODE_CMD(s,node) sprintf((s), "domNode%p", (void *)(node)) 134 #define XSLT_CMD(s,doc) sprintf((s), "XSLTcmd%p", (void *)(doc)) 135 136 #define XML_NAMESPACE "http://www.w3.org/XML/1998/namespace" 137 #define XMLNS_NAMESPACE "http://www.w3.org/2000/xmlns" 138 139 #define UTF8_1BYTE_CHAR(c) ( 0 == ((c) & 0x80)) 140 #define UTF8_2BYTE_CHAR(c) ( 0xC0 == ((c) & 0xE0)) 141 #define UTF8_3BYTE_CHAR(c) ( 0xE0 == ((c) & 0xF0)) 142 #define UTF8_4BYTE_CHAR(c) ( 0xF0 == ((c) & 0xF8)) 143 144 #define UTF8_CHAR_LEN(c) \ 145 UTF8_1BYTE_CHAR((c)) ? 1 : \ 146 (UTF8_2BYTE_CHAR((c)) ? 2 : \ 147 (UTF8_3BYTE_CHAR((c)) ? 3 : \ 148 (UTF8_4BYTE_CHAR((c)) ? 4 : 0))) 149 150 /* The following 2 defines are out of the expat code */ 151 152 /* A 2 byte UTF-8 representation splits the characters 11 bits 153 between the bottom 5 and 6 bits of the bytes. 154 We need 8 bits to index into pages, 3 bits to add to that index and 155 5 bits to generate the mask. */ 156 #define UTF8_GET_NAMING2(pages, byte) \ 157 (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ 158 + ((((byte)[0]) & 3) << 1) \ 159 + ((((byte)[1]) >> 5) & 1)] \ 160 & (1 << (((byte)[1]) & 0x1F))) 161 162 /* A 3 byte UTF-8 representation splits the characters 16 bits 163 between the bottom 4, 6 and 6 bits of the bytes. 164 We need 8 bits to index into pages, 3 bits to add to that index and 165 5 bits to generate the mask. */ 166 #define UTF8_GET_NAMING3(pages, byte) \ 167 (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \ 168 + ((((byte)[1]) >> 2) & 0xF)] \ 169 << 3) \ 170 + ((((byte)[1]) & 3) << 1) \ 171 + ((((byte)[2]) >> 5) & 1)] \ 172 & (1 << (((byte)[2]) & 0x1F))) 173 174 #define UTF8_GET_NAMING_NMTOKEN(p, n) \ 175 ((n) == 1 \ 176 ? nameChar7Bit[(int)(*(p))] \ 177 : ((n) == 2 \ 178 ? UTF8_GET_NAMING2(namePages, (const unsigned char *)(p)) \ 179 : ((n) == 3 \ 180 ? UTF8_GET_NAMING3(namePages, (const unsigned char *)(p)) \ 181 : 0))) 182 183 #define UTF8_GET_NAMING_NCNMTOKEN(p, n) \ 184 ((n) == 1 \ 185 ? NCnameChar7Bit[(int)(*(p))] \ 186 : ((n) == 2 \ 187 ? UTF8_GET_NAMING2(namePages, (const unsigned char *)(p)) \ 188 : ((n) == 3 \ 189 ? UTF8_GET_NAMING3(namePages, (const unsigned char *)(p)) \ 190 : 0))) 191 192 #define UTF8_GET_NAME_START(p, n) \ 193 ((n) == 1 \ 194 ? nameStart7Bit[(int)(*(p))] \ 195 : ((n) == 2 \ 196 ? UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)(p)) \ 197 : ((n) == 3 \ 198 ? UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)(p)) \ 199 : 0))) 200 201 #define UTF8_GET_NCNAME_START(p, n) \ 202 ((n) == 1 \ 203 ? NCnameStart7Bit[(int)(*(p))] \ 204 : ((n) == 2 \ 205 ? UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)(p)) \ 206 : ((n) == 3 \ 207 ? UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)(p)) \ 208 : 0))) 209 210 #define UTF8_XMLCHAR3(p) \ 211 (*(p) == 0xED \ 212 ? ((p)[1] < 0xA0 ? 1 : 0) \ 213 : (*(p) == 0xEF \ 214 ? ((p)[1] == 0xBF \ 215 ? ((p)[2] == 0xBE || (p)[2] == 0xBF ? 0 : 1) \ 216 : 1) \ 217 : 1)) \ 218 219 /* This definition is lax in the sense, that it accepts every 4 byte 220 * utf-8 character beyond #xFFFF as valid, no matter, if Unicode has 221 * (so far) defined a character for that encoding point. Additionally, 222 * this define does not care about the discouraged characters beyond 223 * #xFFFF (but after all, they are only discouraged, not 224 * forbidden). */ 225 #define UTF8_XMLCHAR(p, n) \ 226 ((n) == 1 \ 227 ? CharBit[(int)(*(p))] \ 228 : ((n) == 2 \ 229 ? 1 \ 230 : ((n) == 3 \ 231 ? (UTF8_XMLCHAR3(p)) \ 232 : ((n) == 4 \ 233 ? 1 : 0)))) 234 235 #include "../expat/nametab.h" 236 237 static const unsigned char nameChar7Bit[] = { 238 /* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 239 /* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 240 /* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 241 /* 0x18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 242 /* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 243 /* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 244 /* 0x30 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 245 /* 0x38 */ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 246 /* 0x40 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 247 /* 0x48 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 248 /* 0x50 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 249 /* 0x58 */ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 250 /* 0x60 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 251 /* 0x68 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 252 /* 0x70 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 253 /* 0x78 */ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 254 }; 255 256 static const unsigned char NCnameChar7Bit[] = { 257 /* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 258 /* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 259 /* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 260 /* 0x18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 261 /* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 262 /* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 263 /* 0x30 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 264 /* 0x38 */ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 265 /* 0x40 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 266 /* 0x48 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 267 /* 0x50 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 268 /* 0x58 */ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 269 /* 0x60 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 270 /* 0x68 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 271 /* 0x70 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 272 /* 0x78 */ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 273 }; 274 275 276 static const unsigned char nameStart7Bit[] = { 277 /* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 278 /* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 279 /* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 280 /* 0x18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 281 /* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 282 /* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 283 /* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 284 /* 0x38 */ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 285 /* 0x40 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 286 /* 0x48 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 287 /* 0x50 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 288 /* 0x58 */ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 289 /* 0x60 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 290 /* 0x68 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 291 /* 0x70 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 292 /* 0x78 */ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 293 }; 294 295 296 static const unsigned char NCnameStart7Bit[] = { 297 /* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 298 /* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 299 /* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 300 /* 0x18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 301 /* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 302 /* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 303 /* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 304 /* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 305 /* 0x40 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 306 /* 0x48 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 307 /* 0x50 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 308 /* 0x58 */ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 309 /* 0x60 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 310 /* 0x68 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 311 /* 0x70 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 312 /* 0x78 */ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 313 }; 314 315 static const unsigned char CharBit[] = { 316 /* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 317 /* 0x08 */ 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 318 /* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 319 /* 0x18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 320 /* 0x20 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 321 /* 0x28 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 322 /* 0x30 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 323 /* 0x38 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 324 /* 0x40 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 325 /* 0x48 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 326 /* 0x50 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 327 /* 0x58 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 328 /* 0x60 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 329 /* 0x68 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 330 /* 0x70 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 331 /* 0x78 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 332 }; 333 334 335 #define isNameStart(x) UTF8_GET_NAME_START((x),UTF8_CHAR_LEN(*(x))) 336 #define isNCNameStart(x) UTF8_GET_NCNAME_START((x),UTF8_CHAR_LEN(*(x))) 337 #define isNameChar(x) UTF8_GET_NAMING_NMTOKEN((x),UTF8_CHAR_LEN(*(x))) 338 #define isNCNameChar(x) UTF8_GET_NAMING_NCNMTOKEN((x),UTF8_CHAR_LEN(*(x))) 339 340 #define IS_XML_WHITESPACE(c) ((c)==' ' || (c)=='\n' || (c)=='\r' || (c)=='\t') 341 342 /*-------------------------------------------------------------------------- 343 | DOMString 344 | 345 \-------------------------------------------------------------------------*/ 346 typedef char* domString; /* should 16-bit unicode character !!*/ 347 348 349 /*-------------------------------------------------------------------------- 350 | domNodeType 351 | 352 \-------------------------------------------------------------------------*/ 353 #if defined(_AIX) 354 # define ELEMENT_NODE 1 355 # define ATTRIBUTE_NODE 2 356 # define TEXT_NODE 3 357 # define CDATA_SECTION_NODE 4 358 # define ENTITY_REFERENCE_NODE 5 359 # define ENTITY_NODE 6 360 # define PROCESSING_INSTRUCTION_NODE 7 361 # define COMMENT_NODE 8 362 # define DOCUMENT_NODE 9 363 # define DOCUMENT_TYPE_NODE 10 364 # define DOCUMENT_FRAGMENT_NODE 11 365 # define NOTATION_NODE 12 366 # define ALL_NODES 100 367 368 # define domNodeType int 369 370 #else 371 372 typedef enum { 373 374 ELEMENT_NODE = 1, 375 ATTRIBUTE_NODE = 2, 376 TEXT_NODE = 3, 377 CDATA_SECTION_NODE = 4, 378 ENTITY_REFERENCE_NODE = 5, 379 ENTITY_NODE = 6, 380 PROCESSING_INSTRUCTION_NODE = 7, 381 COMMENT_NODE = 8, 382 DOCUMENT_NODE = 9, 383 DOCUMENT_TYPE_NODE = 10, 384 DOCUMENT_FRAGMENT_NODE = 11, 385 NOTATION_NODE = 12, 386 ALL_NODES = 100 387 } domNodeType; 388 389 #endif 390 391 /*-------------------------------------------------------------------------- 392 | flags - indicating some internal features about nodes 393 | 394 \-------------------------------------------------------------------------*/ 395 typedef unsigned int domNodeFlags; 396 397 #define HAS_LINE_COLUMN 1 398 #define VISIBLE_IN_TCL 2 399 #define IS_DELETED 4 400 #define HAS_BASEURI 8 401 #define DISABLE_OUTPUT_ESCAPING 16 402 403 typedef unsigned int domAttrFlags; 404 405 #define IS_ID_ATTRIBUTE 1 406 #define IS_NS_NODE 2 407 408 typedef unsigned int domDocFlags; 409 410 #define OUTPUT_DEFAULT_INDENT 1 411 #define NEEDS_RENUMBERING 2 412 #define DONT_FREE 4 413 #define IGNORE_XMLNS 8 414 #define DOCUMENT_CMD 16 415 #define VAR_TRACE 32 416 417 /*-------------------------------------------------------------------------- 418 | a index to the namespace records 419 | 420 \-------------------------------------------------------------------------*/ 421 typedef unsigned int domNameSpaceIndex; 422 423 424 425 /*-------------------------------------------------------------------------- 426 | domException 427 | 428 \-------------------------------------------------------------------------*/ 429 typedef enum { 430 431 OK = 0, 432 INDEX_SIZE_ERR = 1, 433 DOMSTRING_SIZE_ERR = 2, 434 HIERARCHY_REQUEST_ERR = 3, 435 WRONG_DOCUMENT_ERR = 4, 436 INVALID_CHARACTER_ERR = 5, 437 NO_DATA_ALLOWED_ERR = 6, 438 NO_MODIFICATION_ALLOWED_ERR = 7, 439 NOT_FOUND_ERR = 8, 440 NOT_SUPPORTED_ERR = 9, 441 INUSE_ATTRIBUTE_ERR = 10 442 443 } domException; 444 445 /*-------------------------------------------------------------------------- 446 | domDocInfo 447 | 448 \-------------------------------------------------------------------------*/ 449 typedef struct domDocInfo { 450 451 /* 'name' is always the name of the documentElement, no struct element 452 needed for this */ 453 domString publicId; 454 domString systemId; 455 domString internalSubset; 456 /* Currently missing, according to DOM 2: 'entities' and 'notations'. */ 457 /* The following struct elements describes additional 'requested' 458 facets of the document, following the xslt rec, section 16 */ 459 float version; 460 char *encoding; 461 int omitXMLDeclaration; 462 int standalone; 463 Tcl_HashTable *cdataSectionElements; 464 domString method; 465 domString mediaType; 466 467 } domDocInfo; 468 469 /*-------------------------------------------------------------------------- 470 | domDocument 471 | 472 \-------------------------------------------------------------------------*/ 473 typedef struct domDocument { 474 475 domNodeType nodeType : 8; 476 domDocFlags nodeFlags : 8; 477 domNameSpaceIndex dummy : 16; 478 unsigned long documentNumber; 479 struct domNode *documentElement; 480 struct domNode *fragments; 481 #ifdef TCL_THREADS 482 struct domNode *deletedNodes; 483 #endif 484 struct domNS **namespaces; 485 int nsptr; 486 int nslen; 487 char **prefixNSMappings; /* Stores doc global prefix ns 488 mappings for resolving of 489 prefixes in seletNodes expr */ 490 #ifdef TCL_THREADS 491 unsigned int nodeCounter; 492 #endif 493 struct domNode *rootNode; 494 Tcl_HashTable *ids; 495 Tcl_HashTable *unparsedEntities; 496 Tcl_HashTable *baseURIs; 497 Tcl_HashTable *xpathCache; 498 char *extResolver; 499 domDocInfo *doctype; 500 TDomThreaded ( 501 Tcl_HashTable tdom_tagNames; /* Names of tags found in doc */ 502 Tcl_HashTable tdom_attrNames; /* Names of tag attributes */ 503 unsigned int refCount; /* # of object commands attached */ 504 struct _domlock *lock; /* Lock for this document */ 505 ) 506 } domDocument; 507 508 /*-------------------------------------------------------------------------- 509 | domLock 510 | 511 \-------------------------------------------------------------------------*/ 512 513 #ifdef TCL_THREADS 514 typedef struct _domlock { 515 domDocument* doc; /* The DOM document to be locked */ 516 int numrd; /* # of readers waiting for lock */ 517 int numwr; /* # of writers waiting for lock */ 518 int lrcnt; /* Lock ref count, > 0: # of shared 519 * readers, -1: exclusive writer */ 520 Tcl_Mutex mutex; /* Mutex for serializing access */ 521 Tcl_Condition rcond; /* Condition var for reader locks */ 522 Tcl_Condition wcond; /* Condition var for writer locks */ 523 struct _domlock *next; /* Next doc lock in global list */ 524 } domlock; 525 526 #define LOCK_READ 0 527 #define LOCK_WRITE 1 528 529 #endif 530 531 532 /*-------------------------------------------------------------------------- 533 | namespace 534 | 535 \-------------------------------------------------------------------------*/ 536 typedef struct domNS { 537 538 char *uri; 539 char *prefix; 540 int index; 541 542 } domNS; 543 544 545 #define MAX_PREFIX_LEN 80 546 547 /*--------------------------------------------------------------------------- 548 | type domActiveNS 549 | 550 \--------------------------------------------------------------------------*/ 551 typedef struct _domActiveNS { 552 553 int depth; 554 domNS *namespace; 555 556 } domActiveNS; 557 558 559 /*-------------------------------------------------------------------------- 560 | domLineColumn 561 | 562 \-------------------------------------------------------------------------*/ 563 typedef struct domLineColumn { 564 565 int line; 566 int column; 567 568 } domLineColumn; 569 570 571 /*-------------------------------------------------------------------------- 572 | domNode 573 | 574 \-------------------------------------------------------------------------*/ 575 typedef struct domNode { 576 577 domNodeType nodeType : 8; 578 domNodeFlags nodeFlags : 8; 579 #ifdef TDOM_LESS_NS 580 domNameSpaceIndex namespace : 8; 581 unsigned int info : 8; 582 #else 583 unsigned int dummy : 8; 584 unsigned int info : 8; 585 #endif 586 unsigned int nodeNumber; 587 domDocument *ownerDocument; 588 struct domNode *parentNode; 589 struct domNode *previousSibling; 590 struct domNode *nextSibling; 591 592 domString nodeName; /* now the element node specific fields */ 593 #ifndef TDOM_LESS_NS 594 domNameSpaceIndex namespace; 595 #endif 596 struct domNode *firstChild; 597 struct domNode *lastChild; 598 struct domAttrNode *firstAttr; 599 600 } domNode; 601 602 /*-------------------------------------------------------------------------- 603 | domDeleteInfo 604 | 605 \-------------------------------------------------------------------------*/ 606 607 typedef struct domDeleteInfo { 608 domDocument * document; 609 domNode * node; 610 Tcl_Interp * interp; 611 char * traceVarName; 612 } domDeleteInfo; 613 614 615 /*-------------------------------------------------------------------------- 616 | domTextNode 617 | 618 \-------------------------------------------------------------------------*/ 619 typedef struct domTextNode { 620 621 domNodeType nodeType : 8; 622 domNodeFlags nodeFlags : 8; 623 #ifdef TDOM_LESS_NS 624 domNameSpaceIndex namespace : 8; 625 unsigned int info : 8; 626 #else 627 unsigned int dummy : 8; 628 unsigned int info : 8; 629 #endif 630 unsigned int nodeNumber; 631 domDocument *ownerDocument; 632 struct domNode *parentNode; 633 struct domNode *previousSibling; 634 struct domNode *nextSibling; 635 636 domString nodeValue; /* now the text node specific fields */ 637 int valueLength; 638 639 } domTextNode; 640 641 642 /*-------------------------------------------------------------------------- 643 | domProcessingInstructionNode 644 | 645 \-------------------------------------------------------------------------*/ 646 typedef struct domProcessingInstructionNode { 647 648 domNodeType nodeType : 8; 649 domNodeFlags nodeFlags : 8; 650 #ifdef TDOM_LESS_NS 651 domNameSpaceIndex namespace : 8; 652 unsigned int info : 8; 653 #else 654 unsigned int dummy : 8; 655 unsigned int info : 8; 656 #endif 657 unsigned int nodeNumber; 658 domDocument *ownerDocument; 659 struct domNode *parentNode; 660 struct domNode *previousSibling; 661 struct domNode *nextSibling; 662 663 domString targetValue; /* now the pi specific fields */ 664 int targetLength; 665 #ifndef TDOM_LESS_NS 666 domNameSpaceIndex namespace; 667 #endif 668 domString dataValue; 669 int dataLength; 670 671 } domProcessingInstructionNode; 672 673 674 /*-------------------------------------------------------------------------- 675 | domAttrNode 676 | 677 \-------------------------------------------------------------------------*/ 678 typedef struct domAttrNode { 679 680 domNodeType nodeType : 8; 681 domAttrFlags nodeFlags : 8; 682 #ifdef TDOM_LESS_NS 683 domNameSpaceIndex namespace : 8; 684 unsigned int info : 8; 685 #else 686 unsigned int dummy : 8; 687 unsigned int info : 8; 688 domNameSpaceIndex namespace; 689 #endif 690 domString nodeName; 691 domString nodeValue; 692 int valueLength; 693 struct domNode *parentNode; 694 struct domAttrNode *nextSibling; 695 696 } domAttrNode; 697 698 /*-------------------------------------------------------------------------- 699 | domAddCallback 700 | 701 \-------------------------------------------------------------------------*/ 702 typedef int (*domAddCallback) (domNode * node, void * clientData); 703 typedef void (*domFreeCallback) (domNode * node, void * clientData); 704 705 /*-------------------------------------------------------------------------- 706 | Function prototypes 707 | 708 \-------------------------------------------------------------------------*/ 709 const char * domException2String (domException exception); 710 711 712 void domModuleInitialize (void); 713 domDocument * domCreateDoc (const char *baseURI, int storeLineColumn); 714 domDocument * domCreateDocument (const char *uri, 715 char *documentElementTagName); 716 void domSetDocumentElement (domDocument *doc); 717 718 domDocument * domReadDocument (XML_Parser parser, 719 char *xml, 720 int length, 721 int ignoreWhiteSpaces, 722 int keepCDATA, 723 int storeLineColumn, 724 int ignoreXMLNS, 725 int feedbackAfter, 726 Tcl_Obj *feedbackCmd, 727 Tcl_Channel channel, 728 const char *baseurl, 729 Tcl_Obj *extResolver, 730 int useForeignDTD, 731 int paramEntityParsing, 732 Tcl_Interp *interp, 733 int *status); 734 735 void domFreeDocument (domDocument *doc, 736 domFreeCallback freeCB, 737 void * clientData); 738 739 void domFreeNode (domNode *node, 740 domFreeCallback freeCB, 741 void *clientData, 742 int dontfree); 743 744 domTextNode * domNewTextNode (domDocument *doc, 745 const char *value, 746 int length, 747 domNodeType nodeType); 748 749 domNode * domNewElementNode (domDocument *doc, 750 const char *tagName); 751 752 domNode * domNewElementNodeNS (domDocument *doc, 753 const char *tagName, 754 const char *uri); 755 756 domProcessingInstructionNode * domNewProcessingInstructionNode ( 757 domDocument *doc, 758 const char *targetValue, 759 int targetLength, 760 const char *dataValue, 761 int dataLength); 762 763 domAttrNode * domSetAttribute (domNode *node, const char *attributeName, 764 const char *attributeValue); 765 766 domAttrNode * domSetAttributeNS (domNode *node, const char *attributeName, 767 const char *attributeValue, 768 const char *uri, 769 int createNSIfNeeded); 770 domAttrNode * domGetAttributeNodeNS (domNode *node, const char *uri, 771 const char *localname); 772 773 int domRemoveAttribute (domNode *node, const char *attributeName); 774 int domRemoveAttributeNS (domNode *node, const char *uri, 775 const char *localName); 776 domNode * domPreviousSibling (domNode *attr); 777 domException domDeleteNode (domNode *node, domFreeCallback freeCB, void *clientData); 778 domException domRemoveChild (domNode *node, domNode *childToRemove); 779 domException domAppendChild (domNode *node, domNode *childToAppend); 780 domException domInsertBefore (domNode *node, domNode *childToInsert, domNode *refChild); 781 domException domReplaceChild (domNode *node, domNode *newChild, domNode *oldChild); 782 domException domSetNodeValue (domNode *node, const char *nodeValue, 783 int valueLen); 784 domNode * domCloneNode (domNode *node, int deep); 785 786 domTextNode * domAppendNewTextNode (domNode *parent, char *value, int length, domNodeType nodeType, int disableOutputEscaping); 787 domNode * domAppendNewElementNode (domNode *parent, const char *tagName, 788 const char *uri); 789 domNode * domAppendLiteralNode (domNode *parent, domNode *node); 790 domNS * domAddNSToNode (domNode *node, domNS *nsToAdd); 791 const char * domNamespacePrefix (domNode *node); 792 const char * domNamespaceURI (domNode *node); 793 const char * domGetLocalName (const char *nodeName); 794 int domSplitQName (const char *name, char *prefix, 795 const char **localName); 796 domNS * domLookupNamespace (domDocument *doc, const char *prefix, 797 const char *namespaceURI); 798 domNS * domLookupPrefix (domNode *node, const char *prefix); 799 int domIsNamespaceInScope (domActiveNS *NSstack, int NSstackPos, 800 const char *prefix, const char *namespaceURI); 801 const char * domLookupPrefixWithMappings (domNode *node, const char *prefix, 802 char **prefixMappings); 803 domNS * domLookupURI (domNode *node, char *uri); 804 domNS * domGetNamespaceByIndex (domDocument *doc, int nsIndex); 805 domNS * domNewNamespace (domDocument *doc, const char *prefix, 806 const char *namespaceURI); 807 int domGetLineColumn (domNode *node, int *line, int *column); 808 809 int domXPointerChild (domNode * node, int all, int instance, domNodeType type, 810 char *element, char *attrName, char *attrValue, 811 int attrLen, domAddCallback addCallback, 812 void * clientData); 813 814 int domXPointerDescendant (domNode * node, int all, int instance, 815 int * i, domNodeType type, char *element, 816 char *attrName, char *attrValue, int attrLen, 817 domAddCallback addCallback, void * clientData); 818 819 int domXPointerAncestor (domNode * node, int all, int instance, 820 int * i, domNodeType type, char *element, 821 char *attrName, char *attrValue, int attrLen, 822 domAddCallback addCallback, void * clientData); 823 824 int domXPointerXSibling (domNode * node, int forward_mode, int all, int instance, 825 domNodeType type, char *element, char *attrName, 826 char *attrValue, int attrLen, 827 domAddCallback addCallback, void * clientData); 828 829 const char * findBaseURI (domNode *node); 830 831 void tcldom_tolower (const char *str, char *str_out, int len); 832 int domIsNAME (const char *name); 833 int domIsPINAME (const char *name); 834 int domIsQNAME (const char *name); 835 int domIsNCNAME (const char *name); 836 int domIsChar (const char *str); 837 int domIsBMPChar (const char *str); 838 int domIsComment (const char *str); 839 int domIsCDATA (const char *str); 840 int domIsPIValue (const char *str); 841 void domCopyTo (domNode *node, domNode *parent, int copyNS); 842 void domCopyNS (domNode *from, domNode *to); 843 domAttrNode * domCreateXMLNamespaceNode (domNode *parent); 844 void domRenumberTree (domNode *node); 845 int domPrecedes (domNode *node, domNode *other); 846 void domNormalize (domNode *node, int forXPath, 847 domFreeCallback freeCB, void *clientData); 848 domException domAppendData (domTextNode *node, char *value, int length, 849 int disableOutputEscaping); 850 851 #ifdef TCL_THREADS 852 void domLocksLock(domlock *dl, int how); 853 void domLocksUnlock(domlock *dl); 854 void domLocksAttach(domDocument *doc); 855 void domLocksDetach(domDocument *doc); 856 void domLocksFinalize(ClientData dummy); 857 #endif 858 859 /*--------------------------------------------------------------------------- 860 | coercion routines for calling from C++ 861 | 862 \--------------------------------------------------------------------------*/ 863 domAttrNode * coerceToAttrNode( domNode *n ); 864 domTextNode * coerceToTextNode( domNode *n ); 865 domProcessingInstructionNode * coerceToProcessingInstructionNode( domNode *n ); 866 867 868 #endif 869 870