<libroxml  version="3.0.1" />
contact: tristan.lelong@libroxml.net
roxml_content.c
Go to the documentation of this file.
1 
12 #include <string.h>
13 #include <stdlib.h>
14 #include "roxml_mem.h"
15 #include "roxml_file.h"
16 #include "roxml_buff.h"
17 
28 ROXML_STATIC ROXML_INT inline int roxml_read(int pos, int size, char *buffer, node_t *node)
29 {
30  int len = 0;
31 
32  if (size > 0 && buffer) {
33  if (node->type & ROXML_FILE)
34  len = roxml_read_file(pos, size, buffer, node);
35  else
36  len = roxml_read_buff(pos, size, buffer, node);
37  }
38 
39  return len;
40 }
41 
42 ROXML_STATIC ROXML_INT inline int roxml_content_size(node_t *n, int *offset)
43 {
44  int total = 0;
45 
46  *offset = 0;
47 
48  if (!n)
49  return 0;
50 
51  if (n->type & ROXML_ELM_NODE) {
52  node_t *ptr = n->chld;
53  while (ptr) {
54  if ((ptr->type & ROXML_NODE_TYPES) == ROXML_TXT_NODE)
55  total += ptr->end - ptr->pos;
56  ptr = ptr->sibl;
57  }
58  } else if (n->type & ROXML_ATTR_NODE) {
59  if (n->chld) {
60  total = n->chld->end - n->chld->pos;
61  *offset = n->chld->pos;
62  }
63  } else {
64  int name_len = 0;
65 
66  ROXML_GET_BASE_BUFFER(name);
67 
69  name_len = strlen(name);
70 
71  ROXML_PUT_BASE_BUFFER(name);
72 
73  if (n->type & ROXML_DOCTYPE_NODE)
74  name_len += 2;
75  else if (n->type & ROXML_TXT_NODE)
76  name_len = 0;
77  else if (n->type & ROXML_CMT_NODE)
78  name_len = 4;
79  else if (n->type & ROXML_PI_NODE)
80  name_len += 3;
81 
82  total = n->end - n->pos - name_len;
83  *offset = n->pos + name_len;
84  }
85  return total;
86 }
87 
88 ROXML_STATIC ROXML_INT inline char *roxml_prepare_buffer(node_t *n, char *buffer, int contentsize, int size)
89 {
90  if (n == NULL) {
91  if (buffer)
92  memset(buffer, 0, size);
93  return NULL;
94  }
95  if (buffer == NULL)
96  buffer = roxml_malloc(sizeof(char), contentsize + 1, PTR_CHAR);
97  memset(buffer, 0, size);
98 
99  return buffer;
100 }
101 
102 ROXML_API char *roxml_get_content(node_t *n, char *buffer, int bufsize, int *size)
103 {
104  int total = 0;
105  int content_offset;
106  int content_size;
107  char *content;
108 
109  if (n == ROXML_INVALID_DOC)
110  return NULL;
111 
112  content_size = roxml_content_size(n, &content_offset);
113  content = roxml_prepare_buffer(n, buffer, content_size, bufsize);
114 
115  if (buffer != content)
116  bufsize = content_size + 1;
117  if (content_size > bufsize - 1)
118  content_size = bufsize - 1;
119  if (content == NULL) {
120  if (size)
121  *size = 0;
122  return buffer;
123  }
124 
125  if (n->type & ROXML_ELM_NODE) {
126  node_t *ptr = n->chld;
127 
128  while (ptr) {
129  if (ptr->type & ROXML_TXT_NODE) {
130  int len = 0;
131  int read_size = ptr->end - ptr->pos;
132 
133  if (total + read_size > bufsize - 1)
134  read_size = bufsize - total - 1;
135  len += roxml_read(ptr->pos, read_size, content + total, ptr);
136 
137  total += len;
138  }
139  ptr = ptr->sibl;
140  }
141  } else {
142  node_t *target = n;
143  if (n->type & ROXML_ATTR_NODE)
144  target = n->chld;
145  total = roxml_read(content_offset, content_size, content, target);
146  }
147 
148  content[total] = '\0';
149  if (size)
150  *size = total + 1;
151  return content;
152 }
153 
154 ROXML_STATIC ROXML_INT inline int roxml_name_size(node_t *n, int size, int *offset)
155 {
156  int total = 0;
157 
158  *offset = 0;
159 
160  if (!n)
161  return 0;
162 
163  if ((n->type & ROXML_TXT_NODE) || (n->type & ROXML_CMT_NODE)) {
164  total = 0;
165  } else {
166  *offset = n->pos;
167 
168  if (n->type & ROXML_PI_NODE)
169  *offset += 2;
170  else if (n->type & ROXML_DOCTYPE_NODE)
171  *offset += 1;
172 
173  total = ROXML_BASE_LEN;
174  }
175 
176  return total;
177 }
178 
179 ROXML_API char *roxml_get_name(node_t *n, char *buffer, int size)
180 {
181  int content_offset;
182  int content_size;
183  char *content;
184 
185  if (n == ROXML_INVALID_DOC)
186  return NULL;
187 
188  content_size = roxml_name_size(n, size, &content_offset);
189  content = roxml_prepare_buffer(n, buffer, content_size, size);
190 
191  if (buffer != content)
192  size = content_size + 1;
193  if (content_size > size - 1)
194  content_size = size - 1;
195  if (content == NULL)
196  return buffer;
197  if (content_size == 0)
198  return content;
199 
200  memset(content, 0, content_size);
201 
202  if (n->prnt == NULL) {
203  strcpy(content, "documentRoot");
204  } else if (n->type & ROXML_NS_NODE) {
205  roxml_ns_t *ns = (roxml_ns_t *)n->priv;
206  if (ns)
207  strncpy(content, ns->alias, size);
208  else
209  content[0] = '\0';
210  } else {
211  int total = 0;
212  int count = 0;
213  char *begin = content;
214 
215  total = roxml_read(content_offset, content_size, content, n);
216 
217  while (ROXML_WHITE(begin[0]) || begin[0] == '<')
218  begin++;
219 
220  if (n->type & ROXML_PI_NODE) {
221  for (; count < total; count++) {
222  if (ROXML_WHITE(begin[count]))
223  break;
224  else if ((begin[count] == '?') && (begin[count + 1] == '>'))
225  break;
226  }
227  } else if (n->type & ROXML_ELM_NODE) {
228  for (; count < total; count++) {
229  if (ROXML_WHITE(begin[count]))
230  break;
231  else if ((begin[count] == '/') && (begin[count + 1] == '>'))
232  break;
233  else if (begin[count] == '>')
234  break;
235  }
236  } else if (n->type & ROXML_ATTR_NODE) {
237  for (; count < total; count++) {
238  if (ROXML_WHITE(begin[count]))
239  break;
240  else if (begin[count] == '=')
241  break;
242  else if (begin[count] == '>')
243  break;
244  else if ((begin[count] == '/') && (begin[count + 1] == '>'))
245  break;
246  }
247  } else if (n->type & ROXML_DOCTYPE_NODE) {
248  for (; count < total; count++) {
249  if (ROXML_WHITE(begin[count]))
250  break;
251  else if (begin[count] == '>')
252  break;
253  }
254  }
255  begin[count++] = '\0';
256  memmove(content, begin, count);
257  }
258 
259  return content;
260 }
261 
263 {
264  node_t *ptr = n;
265  int nb;
266 
267  if (n == ROXML_INVALID_DOC)
268  return -1;
269 
270  nb = 0;
271  if (ptr->chld) {
272  ptr = ptr->chld;
273  do {
274  if (ptr->type & type)
275  nb++;
276  ptr = ptr->sibl;
277  } while (ptr);
278  }
279 
280  if (type & ROXML_ATTR_NODE) {
281  ptr = n->attr;
282  while (ptr) {
283  nb++;
284  ptr = ptr->sibl;
285  }
286  }
287  return nb;
288 }
289 
290 ROXML_STATIC ROXML_INT inline node_t *roxml_get_nodes_by_name(node_t *n, int type, char *name)
291 {
292  node_t *ptr;
293 
294  if (n->attr && (type & ROXML_ATTR_NODE))
295  ptr = n->attr;
296  else
297  ptr = n->chld;
298 
299  while (ptr) {
300  if ((ptr->type & ROXML_NODE_TYPES) & type) {
301  int ans = strcmp(roxml_get_name(ptr, NULL, 0), name);
303  if (ans == 0)
304  return ptr;
305  }
306  ptr = ptr->sibl;
307  }
308  return NULL;
309 }
310 
311 ROXML_STATIC ROXML_INT inline node_t *roxml_get_nodes_by_nth(node_t *n, int type, int nth)
312 {
313  node_t *ptr;
314  int count = 0;
315 
316  if (n->ns && (type & ROXML_NS_NODE)) {
317  ptr = n->ns;
318  if (nth == 0)
319  return ptr;
320  } else if (n->attr && (type & ROXML_ATTR_NODE)) {
321  ptr = n->attr;
322  if (nth == 0)
323  return ptr;
324  while ((ptr->sibl) && (nth > count)) {
325  ptr = ptr->sibl;
326  count++;
327  }
328  } else {
329  ptr = n->chld;
330  while (ptr && !((ptr->type & ROXML_NODE_TYPES) & type))
331  ptr = ptr->sibl;
332  }
333  if (nth > count) {
334  ptr = n->chld;
335  while (ptr && !((ptr->type & ROXML_NODE_TYPES) & type))
336  ptr = ptr->sibl;
337  while (ptr && (ptr->sibl) && (nth > count)) {
338  ptr = ptr->sibl;
339  if ((ptr->type & ROXML_NODE_TYPES) & type)
340  count++;
341  }
342  }
343  if (nth > count)
344  return NULL;
345  return ptr;
346 }
347 
348 ROXML_API node_t *roxml_get_nodes(node_t *n, int type, char *name, int nth)
349 {
350  if (n == ROXML_INVALID_DOC)
351  return ROXML_INVALID_DOC;
352  else if (name == NULL)
353  return roxml_get_nodes_by_nth(n, type, nth);
354  else
355  return roxml_get_nodes_by_name(n, type, name);
356 }
357 
359 {
360  return roxml_get_nodes(n, ROXML_NS_NODE, NULL, 0);
361 }
362 
364 {
366 }
367 
368 ROXML_API inline node_t *roxml_get_pi(node_t *n, int nth)
369 {
370  return roxml_get_nodes(n, ROXML_PI_NODE, NULL, nth);
371 }
372 
374 {
376 }
377 
378 ROXML_API inline node_t *roxml_get_cmt(node_t *n, int nth)
379 {
380  return roxml_get_nodes(n, ROXML_CMT_NODE, NULL, nth);
381 }
382 
384 {
386 }
387 
388 ROXML_API inline node_t *roxml_get_txt(node_t *n, int nth)
389 {
390  return roxml_get_nodes(n, ROXML_TXT_NODE, NULL, nth);
391 }
392 
394 {
396 }
397 
398 ROXML_API inline node_t *roxml_get_attr(node_t *n, char *name, int nth)
399 {
400  return roxml_get_nodes(n, ROXML_ATTR_NODE, name, nth);
401 }
402 
404 {
406 }
407 
408 ROXML_API inline node_t *roxml_get_chld(node_t *n, char *name, int nth)
409 {
410  return roxml_get_nodes(n, ROXML_ELM_NODE, name, nth);
411 }
412 
414 {
415  if (n == ROXML_INVALID_DOC)
416  return ROXML_INVALID_NODE;
417  return (n->type & ROXML_NODE_TYPES);
418 }
419 
421 {
422  int idx = 1;
423  char name[256];
424  node_t *prnt;
425  node_t *first;
426 
427  if (n == ROXML_INVALID_DOC)
428  return 0;
429 
430  roxml_get_name(n, name, 256);
431 
432  prnt = n->prnt;
433  if (!prnt)
434  return 1;
435  first = prnt->chld;
436 
437  while ((first) && (first != n)) {
438  char twin[256];
439 
440  roxml_get_name(first, twin, 256);
441  if (strcmp(name, twin) == 0)
442  idx++;
443  first = first->sibl;
444  }
445 
446  return idx;
447 }
#define ROXML_FILE
ROXML_API node_t * roxml_get_ns(node_t *n)
namespace getter function
#define ROXML_INVALID_DOC
Definition: roxml.h:195
ROXML_API int roxml_get_cmt_nb(node_t *n)
comments number getter function
#define ROXML_NS_NODE
Definition: roxml.h:102
ROXML_API node_t * roxml_get_txt(node_t *n, int nth)
text node getter function
node_t structure
Definition: roxml_types.h:133
ROXML_API int roxml_get_nodes_nb(node_t *n, int type)
number of nodes getter function
ROXML_API int roxml_get_chld_nb(node_t *n)
chlds number getter function
ROXML_API void roxml_release(void *data)
memory cleanning function
Definition: roxml_mem.c:109
struct node * attr
Definition: roxml_types.h:145
ROXML_INT int roxml_read_buff(int pos, int size, char *buffer, node_t *node)
read xml doc function
Definition: roxml_buff.c:16
#define ROXML_ATTR_NODE
Definition: roxml.h:51
#define RELEASE_LAST
Definition: roxml.h:188
roxml_pos_t end
Definition: roxml_types.h:141
#define ROXML_INVALID_NODE
Definition: roxml.h:43
ROXML_API node_t * roxml_get_attr(node_t *n, char *name, int nth)
attribute getter function
#define ROXML_PI_NODE
Definition: roxml.h:94
struct node * chld
Definition: roxml_types.h:143
ROXML_API int roxml_get_txt_nb(node_t *n)
text node number getter function
ROXML_STATIC ROXML_INT int roxml_read(int pos, int size, char *buffer, node_t *node)
read xml doc function
Definition: roxml_content.c:28
char * alias
Definition: roxml_types.h:122
#define ROXML_API
Definition: roxml.h:24
#define ROXML_DOCTYPE_NODE
Definition: roxml.h:126
ROXML_INT int roxml_read_file(int pos, int size, char *buffer, node_t *node)
read xml doc function
Definition: roxml_file.c:18
struct node * sibl
Definition: roxml_types.h:142
File XML document backend.
#define ROXML_CMT_NODE
Definition: roxml.h:86
ROXML_API node_t * roxml_get_cmt(node_t *n, int nth)
comment getter function
roxml_pos_t pos
Definition: roxml_types.h:140
ROXML_API node_t * roxml_get_nodes(node_t *n, int type, char *name, int nth)
nodes getter function
struct node * ns
Definition: roxml_types.h:147
namespace structure
Definition: roxml_types.h:119
ROXML_API char * roxml_get_content(node_t *n, char *buffer, int bufsize, int *size)
content getter function
#define ROXML_ELM_NODE
Definition: roxml.h:70
XML internal memory management module.
ROXML_API int roxml_get_type(node_t *n)
node type function
ROXML_API node_t * roxml_get_chld(node_t *n, char *name, int nth)
chld getter function
void * priv
Definition: roxml_types.h:148
struct node * prnt
Definition: roxml_types.h:144
#define ROXML_WHITE(n)
#define ROXML_BASE_LEN
Definition: roxml_defines.h:91
ROXML_API node_t * roxml_get_pi(node_t *n, int nth)
process-instruction getter function
#define ROXML_NODE_TYPES
Definition: roxml.h:150
ROXML_API int roxml_get_pi_nb(node_t *n)
process-instruction number getter function
#define ROXML_TXT_NODE
Definition: roxml.h:78
unsigned short type
Definition: roxml_types.h:134
#define PTR_CHAR
ROXML_API char * roxml_get_name(node_t *n, char *buffer, int size)
name getter function
buffer XML document backend
ROXML_INT void * roxml_malloc(int size, int num, int type)
alloc memory function
Definition: roxml_mem.c:124
ROXML_API int roxml_get_attr_nb(node_t *n)
number of attribute getter function
ROXML_API int roxml_get_node_position(node_t *n)
node get position function