1 /*************************************************************************** 2 * Copyright (C) 2007 by Jesus Arias Fisteus * 3 * jaf@it.uc3m.es * 4 * * 5 * This program is free software; you can redistribute it and/or modify * 6 * it under the terms of the GNU General Public License as published by * 7 * the Free Software Foundation; either version 2 of the License, or * 8 * (at your option) any later version. * 9 * * 10 * This program is distributed in the hope that it will be useful, * 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 * GNU General Public License for more details. * 14 * * 15 * You should have received a copy of the GNU General Public License * 16 * along with this program; if not, write to the * 17 * Free Software Foundation, Inc., * 18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 19 ***************************************************************************/ 20 21 /* 22 * tree.h 23 * 24 * (Jes�s Arias Fisteus) 25 * 26 * tipos de datos y funciones necesarios para construir 27 * y navegar por un �rbol que represente el documento. 28 * 29 * El documento XHTML resultante de la conversi�n se 30 * va almacenando en memoria en forma de �rbol. 31 * Los nodos del �rbol ser�n estructuras de datos que 32 * pueden representar a un elemento, datos textuales 33 * o un comentario. El primer nodo del �rbol ser� 34 * un nodo especial que contiene el tipo de documento 35 * y un puntero al primer nodo (elemento ra�z). 36 * A su vez, los nodos de elemento tendr�n un puntero 37 * a una lista enlazada de nodos de atributo, que contienen 38 * el identificador y el valor de un atributo. 39 * 40 * En este fichero se encuentran las funciones necesarias 41 * para acceder a este �rbol (prototipos) y todos los 42 * tipos de datos que representan los nodos del �rbol. 43 * 44 */ 45 46 47 #ifndef TREE_H 48 #define TREE_H 49 50 #include "xchar.h" 51 52 53 54 typedef int buff_index_t; 55 56 57 58 /* 59 * un nodo para la lista de 60 * atributos de un elemento 61 * 62 */ 63 struct att_node_{ 64 int att_id; 65 int es_valido; 66 struct att_node_ *sig; 67 buff_index_t valor; 68 }; 69 70 typedef struct att_node_ att_node_t; 71 72 73 74 75 /* 76 * datos espec�ficos para un elemento 77 * en tree_node_t 78 * 79 */ 80 typedef struct { 81 int elm_id; 82 att_node_t *attlist; 83 struct tree_node_ *hijo; 84 } node_element_t; 85 86 87 88 89 90 /* 91 * datos espec�ficos para datos 92 * de caracteres en tree_node_t 93 * 94 */ 95 typedef struct { 96 int data_len; 97 int is_cdata_sec; 98 buff_index_t data; 99 } node_chardata_t; 100 101 102 103 /* 104 * tipos de nodo 105 * 106 */ 107 typedef enum { 108 Node_element, 109 Node_chardata, 110 Node_cdata_sec, 111 Node_comment 112 } node_type_t; 113 114 115 /* 116 * un nodo del �rbol 117 * 118 */ 119 struct tree_node_{ 120 121 node_type_t tipo; 122 struct tree_node_ *padre; 123 struct tree_node_ *sig; /* siguiente hermano */ 124 125 union { 126 node_element_t elemento; 127 node_chardata_t chardata; 128 } cont; 129 }; 130 131 typedef struct tree_node_ tree_node_t; 132 133 134 135 136 /* 137 * ra�z para todo elemento 138 * 139 */ 140 typedef struct { 141 142 int xhtml_doctype; 143 int html_version; 144 /* char encoding[32]; */ 145 146 147 tree_node_t *inicio; /* puntero al primer nodo del doc */ 148 149 } document_t; 150 151 152 153 154 155 156 157 158 /* 159 * ======================================================== 160 * funciones asociadas 161 * ======================================================== 162 * 163 */ 164 165 166 167 /* 168 * inicializa las estructuras de datos 169 * 170 * �hay que ejecutarlo antes que cualquier 171 * otra funci�n de este m�dulo! 172 * 173 */ 174 void tree_init(void); 175 176 177 178 179 /* 180 * crea un nuevo �rbol y devuelve su puntero 181 * 182 */ 183 document_t *new_tree_document(int xhtml_type, int html_vers); 184 185 186 187 188 /* 189 * crea un nuevo nodo para el �rbol, pero NO LO ENLAZA 190 * 191 * tipo: 192 * - node_element 193 * - node_chardata 194 * 195 */ 196 tree_node_t *new_tree_node(node_type_t tipo); 197 198 199 200 /* 201 * establece el elemento padre del documento 202 * 203 * si el documento ya tiene algo, no lo enlaza 204 * 205 */ 206 void link_root_node(document_t *doc, tree_node_t *nodo); 207 208 209 210 211 /* 212 * enlaza 'nodo' en el �rbol sobre 'to': 213 * 214 * mode: 215 * - LINK_MODE_CHILD: enlaza como (�ltimo) hijo de 'to' 216 * - LINK_MODE_BROTHER: enlaza como (siguiente) hermano de 'to' 217 * - LINK_NODE_FIRST_CHILD: enlaza como (primer) hijo de 'to' 218 * 219 */ 220 #define LINK_MODE_CHILD 1 221 #define LINK_MODE_BROTHER 2 222 #define LINK_MODE_FIRST_CHILD 3 223 void link_node( tree_node_t *nodo, tree_node_t *to, int mode); 224 225 /* 226 * crea y enlaza uno o m�s nodos de datos o comentario consecutivos. 227 * si es necesario, se parte el nodo de datos en varios bloques. 228 * Todos aquellos nodos con tama�o posiblemente superior 229 * al tama�o de bloque DATA_BUFFER_SIZE deben ser creados y enlazados 230 * mediante esta funci�n. 231 */ 232 void tree_link_data_node(node_type_t tipo, tree_node_t *actual_element, 233 const xchar *data, int len_data); 234 235 /** 236 * desenlaza el nodo del �rbol (no puede ser el nodo ra�z) 237 * 238 * si tiene hijos, se mantienen unidos a �l 239 * 240 */ 241 void tree_unlink_node(tree_node_t *node); 242 243 /* 244 * enlaza un nuevo nodo de atributos en un nodo de elemento 245 * 246 */ 247 void tree_set_node_att(tree_node_t *nodo, int att_id, const xchar *value, 248 int is_valid); 249 /* 250 * establece los datos de un nodo de datos (Node_chardata) 251 * 252 */ 253 void tree_set_node_data(tree_node_t *nodo, const xchar *data, int len_data); 254 255 /* 256 * busca el elemento con id elm_id desde el nodo src 257 * subiendo sucesivamente al padre 258 * 259 * devuelve el elemento o NULL si se alcanza el root 260 * del documento 261 * 262 */ 263 tree_node_t *tree_search_elm_up(tree_node_t *src, int elm_id); 264 265 /* 266 * busca el elemento con id elm_id hijo del nodo src 267 * 268 * devuelve el elemento o NULL si no se encuentra 269 * 270 */ 271 tree_node_t *tree_search_elm_child(tree_node_t *padre, int elm_id); 272 273 274 275 276 #define NODE_NONE 0 /* fin de �rbol */ 277 #define NODE_CHILD 1 /* hijo */ 278 #define NODE_BROTHER 2 /* hermano */ 279 #define NODE_FATHER 3 /* padre */ 280 /* 281 * recorre el �rbol desde src hacia abajo 282 * 283 * devuelve: 284 * 285 * NODE_NONE fin de �rbol 286 * NODE_CHILD hijo 287 * NODE_BROTHER hermano 288 * NODE_FATHER retorno al padre 289 * 290 * y actualiza el puntero al nuevo nodo 291 * 292 * (si *src==NULL, devuelve NODE_NONE) 293 * 294 * va hacia (hasta que uno sea no nulo 295 * - src->hijo si (allow_child==1) 296 * - src->sig 297 * - src->father 298 * - NULL 299 * 300 */ 301 int tree_walk(tree_node_t **src, int allow_child); 302 303 /* 304 * devuelve un puntero a la zona de datos 305 * apuntada por el �ndice 'index' en el 306 * buffer de datos 307 * 308 */ 309 void *tree_index_to_ptr(buff_index_t index); 310 311 /* 312 * busca en la lista de atributos de un nodo de elemento 313 * aquel cuyo id sea att_id 314 * 315 * devuelve un puntero al nodo o NULL si no se encuentra 316 * 317 */ 318 att_node_t *tree_node_search_att(tree_node_t *node, int att_id); 319 320 /* 321 * Sustituto para malloc(size_t size) 322 * 323 */ 324 void *tree_malloc(size_t size); 325 326 /* 327 * Sustituto para strdup(char *str) 328 * "str" debe acabar en 0. 329 * invoca a tree_malloc: no debe ser liberado con free() 330 * 331 */ 332 char *tree_strdup(const char *str); 333 334 /* 335 * Sustituto para strdup(char *str) 336 * "str" puede no acabar en 0 (se reservan size + 1 chars). 337 * invoca a tree_malloc: no debe ser liberado con free() 338 * 339 */ 340 char *tree_strdup_n(const char *str, size_t size); 341 342 /* 343 * devuelve el n�mero de bytes de memoria utilizados a trav�s 344 * de este m�dulo. 345 * 346 */ 347 unsigned int tree_allocated_memory(); 348 349 /* 350 * libera la memoria reservada 351 * 352 */ 353 void tree_free(void); 354 355 /* 356 * macros 357 * 358 */ 359 360 #define ELM_ID(tree_node) (tree_node->cont.elemento.elm_id) 361 #define ELM_PTR(tree_node) (elm_list[tree_node->cont.elemento.elm_id]) 362 363 #define ATT_PTR(att_node) (att_list[att_node]->att_id]) 364 365 366 367 368 369 370 371 372 /* 373 * ============================================================= 374 * variables 375 * ============================================================= 376 * 377 */ 378 379 380 381 #endif 382