1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 /* ************************************************************************/ |
|
18 #include "cxml_internal.h" |
|
19 #include <xml/cxml/nw_wbxml_parse.h> |
|
20 #include <xml/cxml/nw_wbxml_document.h> |
|
21 #include <xml/cxml/nw_encoder_wbxmlwriter.h> |
|
22 #include "nw_encoder_tinydom2wbxml.h" |
|
23 #include <xml/cxml/nw_tinytree.h> |
|
24 #include <xml/cxml/nw_tinydom.h> |
|
25 |
|
26 |
|
27 /* Create an empty tree */ |
|
28 |
|
29 NW_Status_t |
|
30 NW_TinyDom_Tree_create(NW_TinyDom_Tree_t *dom_tree, |
|
31 NW_TinyDom_Parser_t *dom_parser, |
|
32 NW_WBXML_Document_t *doc, |
|
33 NW_WBXML_Parser_t *parser, |
|
34 NW_WBXML_Writer_t* writer, |
|
35 NW_Uint16 init_node_count, |
|
36 NW_Bool enableStringTable) |
|
37 { |
|
38 NW_WBXML_Dictionary_t* dictionary = NULL; |
|
39 |
|
40 /* First get the dictionary */ |
|
41 |
|
42 if (doc->publicid != 0) { |
|
43 dictionary = NW_WBXML_Dictionary_getByPublicId (doc->publicid); |
|
44 parser->dictionary = NW_WBXML_Dictionary_getIndexByPublicId(doc->publicid); |
|
45 } |
|
46 else if (doc->doc_type != NULL) { |
|
47 dictionary = NW_WBXML_Dictionary_getByDocType (doc->doc_type, doc->charset); |
|
48 parser->dictionary = NW_WBXML_Dictionary_getIndexByDocType(doc->doc_type, doc->charset); |
|
49 } |
|
50 |
|
51 if (dictionary == NULL) { |
|
52 return NW_STAT_FAILURE; |
|
53 } |
|
54 |
|
55 /* TODO: make dictionary a member of dom_parser ?? */ |
|
56 |
|
57 /* Initialize the writer */ |
|
58 |
|
59 NW_WBXML_Writer_Initialize(writer, |
|
60 0, NULL, |
|
61 NULL, |
|
62 dictionary, |
|
63 dictionary, |
|
64 ((enableStringTable == NW_TRUE) ? |
|
65 NW_Encoder_StringTable_getStringTableOffset : |
|
66 NULL), |
|
67 ((enableStringTable == NW_TRUE) ? |
|
68 NW_Encoder_StringTable_addToStringTable : |
|
69 NULL), |
|
70 ((enableStringTable == NW_TRUE) ? |
|
71 doc->strtbl_extension : |
|
72 NULL), |
|
73 ((enableStringTable == NW_TRUE) ? |
|
74 NW_Encoder_StringTable_StringTableIterateInit : |
|
75 NULL), |
|
76 ((enableStringTable == NW_TRUE) ? |
|
77 NW_Encoder_StringTable_StringTableIterateNext : |
|
78 NULL), |
|
79 NW_TRUE); |
|
80 |
|
81 /* Construct the dom tree object */ |
|
82 NW_TinyDom_Tree_construct(dom_tree, parser, doc, writer); |
|
83 |
|
84 /* Construct the dom parser object */ |
|
85 NW_TinyDom_Parser_construct(dom_parser, dom_tree); |
|
86 |
|
87 /* Construct the tiny tree object, passing the dom parser as the |
|
88 context argument */ |
|
89 |
|
90 |
|
91 if( (NW_TinyTree_construct(&(dom_tree->tree), |
|
92 (CXML_Vector_Metric_t)(init_node_count + 1), |
|
93 0, |
|
94 0, |
|
95 dom_parser, |
|
96 NW_TRUE) ) == NW_STAT_FAILURE) |
|
97 { |
|
98 return NW_STAT_OUT_OF_MEMORY; |
|
99 } |
|
100 |
|
101 /* The root node we create here actually has no valid buffer storage yet */ |
|
102 NW_TinyTree_setRoot(&(dom_tree->tree), 0); |
|
103 |
|
104 /* TODO: Why does dom_tree need a doc member if parser has one too ???? */ |
|
105 parser->doc = doc; |
|
106 |
|
107 dom_tree->root_node = NW_TinyTree_getRoot(&(dom_tree->tree)); |
|
108 |
|
109 /* Write the doc header block. This will fill in the root node storage */ |
|
110 dom_tree->root_node = NW_TinyDom_writeDocHeader(dom_tree, |
|
111 doc->version, |
|
112 doc->publicid, |
|
113 doc->charset); |
|
114 if (dom_tree->root_node == NULL) { |
|
115 return NW_STAT_FAILURE; |
|
116 } |
|
117 /* Mark the root node as the doc node */ |
|
118 NW_TinyTree_Node_setUserFlags(dom_tree->root_node, T_DOM_NODE_DOC); |
|
119 return NW_STAT_SUCCESS; |
|
120 } |
|
121 |
|
122 NW_TinyTree_Node_t * |
|
123 NW_TinyDom_writeDocHeader(NW_TinyDom_Tree_t *dom_tree, |
|
124 NW_Uint8 version, |
|
125 NW_Uint32 publicid, |
|
126 NW_Uint32 encoding) |
|
127 { |
|
128 NW_Status_t status; |
|
129 NW_TinyTree_Offset_t offset; |
|
130 NW_TinyTree_Node_t * node = dom_tree->root_node; |
|
131 CXML_Vector_Metric_t size; |
|
132 |
|
133 /* If the root node isn't set, the tree wasn't properly inited */ |
|
134 if (node != NULL) { |
|
135 NW_Uint8* buffer; |
|
136 /* Set up the writer for a sizing pass */ |
|
137 NW_WBXML_Writer_SetToSizing(dom_tree->writer); |
|
138 /* Call the writer to run the sizing pass */ |
|
139 status = NW_WBXML_Writer_Header(dom_tree->writer, |
|
140 version, |
|
141 publicid, |
|
142 encoding, |
|
143 0); |
|
144 |
|
145 |
|
146 if (status != NW_STAT_SUCCESS) { |
|
147 return NULL; |
|
148 } |
|
149 /* Allocate a buffer of the correct size */ |
|
150 size = (CXML_Vector_Metric_t)NW_WBXML_Writer_GetSize(dom_tree->writer); |
|
151 buffer = NW_TinyTree_GetWritableBlock(&(dom_tree->tree), size, &offset); |
|
152 |
|
153 if(buffer == NULL) |
|
154 { |
|
155 return NULL; |
|
156 } |
|
157 |
|
158 /* Set up the writer for actual writing */ |
|
159 NW_WBXML_Writer_SetToWrite(dom_tree->writer, size, buffer); |
|
160 /* Do the write */ |
|
161 status = NW_WBXML_Writer_Header(dom_tree->writer, |
|
162 version, |
|
163 publicid, |
|
164 encoding, |
|
165 0); |
|
166 |
|
167 if (status != NW_STAT_SUCCESS) { |
|
168 return NULL; |
|
169 } |
|
170 /* Point the root node source offset at the new block */ |
|
171 node->source_offset = offset; |
|
172 } |
|
173 return node; |
|
174 } |
|
175 |
|
176 |
|
177 NW_TinyTree_Node_t * |
|
178 NW_TinyDom_createAttributeByToken(NW_TinyDom_Tree_t *dom_tree, |
|
179 NW_Uint16 token, |
|
180 NW_TinyDom_AttrVal_t *value) |
|
181 { |
|
182 NW_Status_t status; |
|
183 NW_TinyTree_Offset_t offset; |
|
184 |
|
185 NW_TinyTree_Node_t * node = NW_TinyTree_createNode(&(dom_tree->tree),0); |
|
186 |
|
187 if (node != NULL) { |
|
188 NW_Uint8* buffer; |
|
189 CXML_Vector_Metric_t size; |
|
190 |
|
191 /* Set up the writer for a sizing pass */ |
|
192 NW_WBXML_Writer_SetToSizing(dom_tree->writer); |
|
193 /* Call the writer to run the sizing pass */ |
|
194 status = NW_Encoder_writeAttributeByToken(dom_tree->writer, token, value, |
|
195 dom_tree->doc->charset); |
|
196 |
|
197 if (status != NW_STAT_SUCCESS) { |
|
198 return NULL; |
|
199 } |
|
200 /* Allocate a buffer of the correct size */ |
|
201 size = (CXML_Vector_Metric_t)NW_WBXML_Writer_GetSize(dom_tree->writer); |
|
202 buffer = NW_TinyTree_GetWritableBlock(&(dom_tree->tree), size, &offset); |
|
203 if (buffer == NULL) |
|
204 { |
|
205 return NULL; |
|
206 } |
|
207 |
|
208 /* Set up the writer for actual writing */ |
|
209 NW_WBXML_Writer_SetToWrite(dom_tree->writer, size, buffer); |
|
210 /* Do the write */ |
|
211 status = NW_Encoder_writeAttributeByToken(dom_tree->writer, token, value, |
|
212 dom_tree->doc->charset); |
|
213 if (status != NW_STAT_SUCCESS) { |
|
214 return NULL; |
|
215 } |
|
216 /* Point the node source offset at the new block */ |
|
217 node->source_offset = offset; |
|
218 /* Mark node as attribute node */ |
|
219 NW_TinyTree_Node_setUserFlags(node, T_DOM_NODE_ATTR); |
|
220 return node; |
|
221 } |
|
222 return NULL; |
|
223 } |
|
224 |
|
225 NW_TinyTree_Node_t * |
|
226 NW_TinyDom_createAttributeByName(NW_TinyDom_Tree_t *dom_tree, |
|
227 NW_String_t *name, |
|
228 NW_TinyDom_AttrVal_t *value) |
|
229 { |
|
230 NW_Status_t status; |
|
231 NW_TinyTree_Offset_t offset; |
|
232 |
|
233 NW_TinyTree_Node_t * node = NW_TinyTree_createNode(&(dom_tree->tree),0); |
|
234 |
|
235 if (node != NULL) { |
|
236 NW_Uint8* buffer; |
|
237 CXML_Vector_Metric_t size; |
|
238 |
|
239 /* Set up the writer for a sizing pass */ |
|
240 NW_WBXML_Writer_SetToSizing(dom_tree->writer); |
|
241 /* Call the writer to run the sizing pass */ |
|
242 status = NW_Encoder_writeAttributeByName(dom_tree->writer, name, value, |
|
243 dom_tree->doc->charset); |
|
244 |
|
245 if (status != NW_STAT_SUCCESS) { |
|
246 return NULL; |
|
247 } |
|
248 /* Allocate a buffer of the correct size */ |
|
249 size = (CXML_Vector_Metric_t)NW_WBXML_Writer_GetSize(dom_tree->writer); |
|
250 buffer = NW_TinyTree_GetWritableBlock(&(dom_tree->tree), size, &offset); |
|
251 if (buffer == NULL) |
|
252 { |
|
253 return NULL; |
|
254 } |
|
255 |
|
256 /* Set up the writer for actual writing */ |
|
257 NW_WBXML_Writer_SetToWrite(dom_tree->writer, size, buffer); |
|
258 /* Do the write */ |
|
259 status = NW_Encoder_writeAttributeByName(dom_tree->writer, name, value, |
|
260 dom_tree->doc->charset); |
|
261 if (status != NW_STAT_SUCCESS) { |
|
262 return NULL; |
|
263 } |
|
264 /* Point the node source offset at the new block */ |
|
265 node->source_offset = offset; |
|
266 /* Mark node as attribute node */ |
|
267 NW_TinyTree_Node_setUserFlags(node, T_DOM_NODE_ATTR); |
|
268 return node; |
|
269 } |
|
270 return NULL; |
|
271 } |
|
272 |
|
273 NW_Status_t |
|
274 NW_TinyDom_AttributeHandle_initWithStartToken(NW_TinyDom_AttributeHandle_t* tinyHandle, |
|
275 NW_TinyTree_Node_t** ppNode, |
|
276 NW_TinyDom_Parser_t* parser, |
|
277 NW_Uint16 fqToken) |
|
278 { |
|
279 NW_Status_t status; |
|
280 NW_TinyTree_Offset_t offset; |
|
281 NW_Uint8* buffer; |
|
282 CXML_Vector_Metric_t size; |
|
283 NW_TinyDom_Tree_t* dom_tree = parser->dom_tree; |
|
284 |
|
285 /* Set up the writer for a sizing pass */ |
|
286 NW_WBXML_Writer_SetToSizing(dom_tree->writer); |
|
287 /* Call the writer to run the sizing pass */ |
|
288 status = NW_WBXML_Writer_AttributeToken(dom_tree->writer, fqToken); |
|
289 if (status != NW_STAT_SUCCESS) { |
|
290 return status; |
|
291 } |
|
292 status = NW_WBXML_Writer_End(dom_tree->writer); |
|
293 if (status != NW_STAT_SUCCESS) { |
|
294 return status; |
|
295 } |
|
296 /* Allocate a buffer of the correct size */ |
|
297 size = (CXML_Vector_Metric_t)NW_WBXML_Writer_GetSize(dom_tree->writer); |
|
298 buffer = NW_TinyTree_GetWritableBlock(&(dom_tree->tree), size, &offset); |
|
299 if (buffer == NULL) |
|
300 { |
|
301 return NW_STAT_OUT_OF_MEMORY; |
|
302 } |
|
303 |
|
304 *ppNode = NW_TinyTree_createNode(&(dom_tree->tree), offset); |
|
305 if (*ppNode == NULL) { |
|
306 NW_Mem_Free(buffer); |
|
307 return NW_STAT_OUT_OF_MEMORY; |
|
308 } |
|
309 NW_TinyTree_Node_setUserFlags(*ppNode, T_DOM_NODE_ATTR); |
|
310 |
|
311 /* Set up the writer for actual writing */ |
|
312 NW_WBXML_Writer_SetToWrite(dom_tree->writer, size, buffer); |
|
313 /* Do the write */ |
|
314 status = NW_WBXML_Writer_AttributeToken(dom_tree->writer, fqToken); |
|
315 if (status != NW_STAT_SUCCESS) { |
|
316 return status; |
|
317 } |
|
318 status = NW_WBXML_Writer_End(dom_tree->writer); |
|
319 if (status != NW_STAT_SUCCESS) { |
|
320 return status; |
|
321 } |
|
322 /* initialize the attribute handle */ |
|
323 NW_TinyDom_AttributeHandle_init(tinyHandle, parser, offset); |
|
324 |
|
325 return NW_STAT_SUCCESS; |
|
326 } |
|
327 |
|
328 NW_Status_t |
|
329 NW_TinyDom_AttributeHandle_addVal(NW_TinyDom_AttributeHandle_t* tinyHandle, |
|
330 NW_TinyTree_Node_t* node, |
|
331 NW_TinyDom_AttrVal_t* val) |
|
332 { |
|
333 NW_TinyDom_AttrVal_t av; |
|
334 NW_TinyTree_t* tinyTree = &(tinyHandle->tlit.tiny_parser->dom_tree->tree); |
|
335 NW_TinyDom_Tree_t* tinyDomTree = tinyHandle->tlit.tiny_parser->dom_tree; |
|
336 NW_Uint32 encoding; |
|
337 void* existingBuffer; |
|
338 NW_Uint8* buffer; |
|
339 CXML_Vector_Metric_t start = 0; |
|
340 CXML_Vector_Metric_t valSize; |
|
341 CXML_Vector_Metric_t existingSize; |
|
342 CXML_Vector_Metric_t offset; |
|
343 NW_Status_t status = NW_STAT_FAILURE; |
|
344 |
|
345 encoding = NW_TinyDom_getDocHeader(tinyTree)->charset; |
|
346 |
|
347 switch (val->type) { |
|
348 case NW_WBXML_ATTR_COMPONENT_TOKEN: |
|
349 case NW_WBXML_ATTR_COMPONENT_STRING: |
|
350 case NW_WBXML_ATTR_COMPONENT_EXT: |
|
351 case NW_WBXML_ATTR_COMPONENT_ENTITY: |
|
352 case NW_WBXML_ATTR_COMPONENT_OPAQUE: |
|
353 NW_WBXML_Writer_SetToSizing(tinyDomTree->writer); |
|
354 start |
|
355 = (CXML_Vector_Metric_t)NW_WBXML_Writer_GetSize(tinyDomTree->writer); |
|
356 status = NW_Encoder_writeAttrVal(tinyDomTree->writer, val, |
|
357 encoding); |
|
358 if (status != NW_STAT_SUCCESS) { |
|
359 return status; |
|
360 } |
|
361 status = NW_WBXML_Writer_End(tinyDomTree->writer); |
|
362 break; |
|
363 } |
|
364 if (status != NW_STAT_SUCCESS) { |
|
365 return status; |
|
366 } |
|
367 valSize |
|
368 = (CXML_Vector_Metric_t)(NW_WBXML_Writer_GetSize(tinyDomTree->writer) |
|
369 - start); |
|
370 |
|
371 /* existing content size */ |
|
372 start = node->source_offset; |
|
373 NW_TinyDom_AttributeHandle_init(tinyHandle, tinyHandle->tlit.tiny_parser, |
|
374 node->source_offset); |
|
375 tinyHandle->value = &av; /* required to hold value results */ |
|
376 while (NW_TinyDom_AttributeHandle_valsIterate(&(tinyHandle->tlit)) != 0) { |
|
377 /* empty loop body: we just want parser to advance */ |
|
378 } |
|
379 existingSize = (CXML_Vector_Metric_t)(tinyHandle->tlit.offset - start); |
|
380 existingBuffer = NW_TinyTree_Node_getSourceAddress(tinyTree, node); |
|
381 |
|
382 buffer = NW_TinyTree_GetWritableBlock(tinyTree, |
|
383 ((CXML_Vector_Metric_t) |
|
384 (valSize + existingSize)), |
|
385 &offset); |
|
386 if (buffer == NULL) { |
|
387 return NW_STAT_OUT_OF_MEMORY; |
|
388 } |
|
389 NW_Mem_memcpy(buffer, existingBuffer, existingSize); |
|
390 NW_WBXML_Writer_SetToWrite(tinyDomTree->writer, |
|
391 valSize, |
|
392 buffer + existingSize); |
|
393 (void)NW_Encoder_writeAttrVal(tinyDomTree->writer, val, encoding); |
|
394 (void)NW_WBXML_Writer_End(tinyDomTree->writer); |
|
395 |
|
396 /* TBD there is no way to "free" the old storage */ |
|
397 node->source_offset = offset; |
|
398 return NW_STAT_SUCCESS; |
|
399 } |
|
400 |
|
401 |
|
402 NW_TinyTree_Node_t * |
|
403 NW_TinyDom_createElementByToken(NW_TinyDom_Tree_t *dom_tree, NW_Uint16 token) { |
|
404 |
|
405 NW_Status_t status; |
|
406 NW_TinyTree_Offset_t offset; |
|
407 |
|
408 NW_TinyTree_Node_t * node = NW_TinyTree_createNode(&(dom_tree->tree),0); |
|
409 |
|
410 if (node != NULL) { |
|
411 NW_Uint8* buffer; |
|
412 CXML_Vector_Metric_t size; |
|
413 |
|
414 /* Set up the writer for a sizing pass */ |
|
415 NW_WBXML_Writer_SetToSizing(dom_tree->writer); |
|
416 /* Call the writer to run the sizing pass */ |
|
417 status = NW_Encoder_writeElementByToken(dom_tree->writer, token); |
|
418 |
|
419 if (status != NW_STAT_SUCCESS) { |
|
420 return NULL; |
|
421 } |
|
422 /* Allocate a buffer of the correct size */ |
|
423 size = (CXML_Vector_Metric_t)NW_WBXML_Writer_GetSize(dom_tree->writer); |
|
424 buffer = NW_TinyTree_GetWritableBlock(&(dom_tree->tree), size, &offset); |
|
425 if (buffer == NULL) |
|
426 { |
|
427 return NULL; |
|
428 } |
|
429 |
|
430 /* Set up the writer for actual writing */ |
|
431 NW_WBXML_Writer_SetToWrite(dom_tree->writer, size, buffer); |
|
432 /* Do the write */ |
|
433 status = NW_Encoder_writeElementByToken(dom_tree->writer, token); |
|
434 if (status != NW_STAT_SUCCESS) { |
|
435 return NULL; |
|
436 } |
|
437 |
|
438 /* Point the node source offset at the new block */ |
|
439 node->source_offset = offset; |
|
440 /* Mark node as attribute node */ |
|
441 NW_TinyTree_Node_setUserFlags(node, T_DOM_NODE_TAG); |
|
442 return node; |
|
443 } |
|
444 return NULL; |
|
445 } |
|
446 |
|
447 |
|
448 NW_TinyTree_Node_t * |
|
449 NW_TinyDom_createElementByName(NW_TinyDom_Tree_t *dom_tree, NW_String_t *name) |
|
450 { |
|
451 NW_Status_t status; |
|
452 NW_TinyTree_Offset_t offset; |
|
453 |
|
454 NW_TinyTree_Node_t * node = NW_TinyTree_createNode(&(dom_tree->tree),0); |
|
455 |
|
456 if (node != NULL) { |
|
457 NW_Uint8* buffer; |
|
458 CXML_Vector_Metric_t size; |
|
459 |
|
460 /* Set up the writer for a sizing pass */ |
|
461 NW_WBXML_Writer_SetToSizing(dom_tree->writer); |
|
462 /* Call the writer to run the sizing pass */ |
|
463 status = NW_Encoder_writeElementByName(dom_tree->writer, name, |
|
464 dom_tree->doc->charset); |
|
465 if (status != NW_STAT_SUCCESS) { |
|
466 return NULL; |
|
467 } |
|
468 /* Allocate a buffer of the correct size */ |
|
469 size = (CXML_Vector_Metric_t)NW_WBXML_Writer_GetSize(dom_tree->writer); |
|
470 buffer = NW_TinyTree_GetWritableBlock(&(dom_tree->tree), size, &offset); |
|
471 if (buffer == NULL) |
|
472 { |
|
473 return NULL; |
|
474 } |
|
475 |
|
476 /* Set up the writer for actual writing */ |
|
477 NW_WBXML_Writer_SetToWrite(dom_tree->writer, size, buffer); |
|
478 /* Do the write */ |
|
479 status = NW_Encoder_writeElementByName(dom_tree->writer, name, |
|
480 dom_tree->doc->charset); |
|
481 if (status != NW_STAT_SUCCESS) { |
|
482 return NULL; |
|
483 } |
|
484 |
|
485 /* Point the node source offset at the new block */ |
|
486 node->source_offset = offset; |
|
487 /* Mark node as attribute node */ |
|
488 NW_TinyTree_Node_setUserFlags(node, T_DOM_NODE_TAG); |
|
489 return node; |
|
490 } |
|
491 return NULL; |
|
492 } |
|
493 |
|
494 NW_TinyTree_Node_t * |
|
495 NW_TinyDom_createTextNode(NW_TinyDom_Tree_t *dom_tree, |
|
496 NW_TinyDom_Text_t *text) |
|
497 { |
|
498 NW_Status_t status; |
|
499 NW_TinyTree_Offset_t offset; |
|
500 |
|
501 NW_TinyTree_Node_t * node = NW_TinyTree_createNode(&(dom_tree->tree),0); |
|
502 |
|
503 if (node != NULL) { |
|
504 NW_Uint8* buffer; |
|
505 CXML_Vector_Metric_t size; |
|
506 |
|
507 /* Set up the writer for a sizing pass */ |
|
508 NW_WBXML_Writer_SetToSizing(dom_tree->writer); |
|
509 /* Call the writer to run the sizing pass */ |
|
510 status = NW_Encoder_writeText(dom_tree->writer, text, |
|
511 dom_tree->doc->charset); |
|
512 if (status != NW_STAT_SUCCESS) { |
|
513 return NULL; |
|
514 } |
|
515 /* Allocate a buffer of the correct size */ |
|
516 size = (CXML_Vector_Metric_t)NW_WBXML_Writer_GetSize(dom_tree->writer); |
|
517 buffer = NW_TinyTree_GetWritableBlock(&(dom_tree->tree), size, &offset); |
|
518 if (buffer == NULL) |
|
519 { |
|
520 return NULL; |
|
521 } |
|
522 |
|
523 /* Set up the writer for actual writing */ |
|
524 NW_WBXML_Writer_SetToWrite(dom_tree->writer, size, buffer); |
|
525 /* Do the write */ |
|
526 status = NW_Encoder_writeText(dom_tree->writer, text, |
|
527 dom_tree->doc->charset); |
|
528 if (status != NW_STAT_SUCCESS) { |
|
529 return NULL; |
|
530 } |
|
531 /* Point the node source offset at the new block */ |
|
532 node->source_offset = offset; |
|
533 /* Mark node as attribute node */ |
|
534 NW_TinyTree_Node_setUserFlags(node, T_DOM_NODE_TEXT); |
|
535 return node; |
|
536 } |
|
537 return NULL; |
|
538 } |
|
539 |
|
540 NW_Status_t |
|
541 NW_TinyDom_addDataFromTextItem(NW_TinyTree_t* tinyTree, |
|
542 NW_TinyDom_Tree_t* tinyDomTree, |
|
543 NW_DOM_TextNode_t* node, |
|
544 NW_TinyDom_AttrVal_t* val, |
|
545 NW_Uint32 encoding) |
|
546 { |
|
547 void* existingBuffer; |
|
548 NW_Uint8* buffer; |
|
549 NW_TinyDom_TextHandle_t iterator; |
|
550 NW_TinyDom_Text_t textItem; |
|
551 CXML_Vector_Metric_t start = 0; |
|
552 CXML_Vector_Metric_t valSize; |
|
553 CXML_Vector_Metric_t existingSize; |
|
554 CXML_Vector_Metric_t offset; |
|
555 NW_Status_t status = NW_STAT_FAILURE; |
|
556 |
|
557 switch (val->type) { |
|
558 case NW_WBXML_ATTR_COMPONENT_STRING: |
|
559 case NW_WBXML_ATTR_COMPONENT_EXT: |
|
560 case NW_WBXML_ATTR_COMPONENT_ENTITY: |
|
561 case NW_WBXML_ATTR_COMPONENT_OPAQUE: |
|
562 NW_WBXML_Writer_SetToSizing(tinyDomTree->writer); |
|
563 start |
|
564 = (CXML_Vector_Metric_t)NW_WBXML_Writer_GetSize(tinyDomTree->writer); |
|
565 status = NW_Encoder_writeAttrVal(tinyDomTree->writer, val, |
|
566 encoding); |
|
567 if (status != NW_STAT_SUCCESS) { |
|
568 return status; |
|
569 } |
|
570 status = NW_WBXML_Writer_End(tinyDomTree->writer); |
|
571 break; |
|
572 } |
|
573 if (status != NW_STAT_SUCCESS) { |
|
574 return status; |
|
575 } |
|
576 valSize |
|
577 = (CXML_Vector_Metric_t)(NW_WBXML_Writer_GetSize(tinyDomTree->writer) |
|
578 - start); |
|
579 |
|
580 /* existing content size */ |
|
581 NW_TinyDom_TextHandle_init(&iterator, |
|
582 NW_TinyDom_getParser(tinyTree), |
|
583 NW_TinyTree_Node_getSourceOffset(node)); |
|
584 start = (CXML_Vector_Metric_t)iterator.tlit.offset; |
|
585 while (NW_TinyDom_TextHandle_iterate(&iterator, &textItem) != 0) { |
|
586 /* empty loop body: we just want parser to advance */ |
|
587 } |
|
588 existingSize = (CXML_Vector_Metric_t)(iterator.tlit.offset - start); |
|
589 existingBuffer = NW_TinyTree_Node_getSourceAddress(tinyTree, node); |
|
590 |
|
591 buffer = NW_TinyTree_GetWritableBlock(tinyTree, |
|
592 ((CXML_Vector_Metric_t) |
|
593 (valSize + existingSize)), |
|
594 &offset); |
|
595 if (buffer == NULL) { |
|
596 return NW_STAT_OUT_OF_MEMORY; |
|
597 } |
|
598 NW_Mem_memcpy(buffer, existingBuffer, existingSize); |
|
599 NW_WBXML_Writer_SetToWrite(tinyDomTree->writer, |
|
600 valSize, |
|
601 buffer + existingSize); |
|
602 (void)NW_Encoder_writeAttrVal(tinyDomTree->writer, val, encoding); |
|
603 (void)NW_WBXML_Writer_End(tinyDomTree->writer); |
|
604 |
|
605 /* TBD there is no way to "free" the old storage */ |
|
606 node->source_offset = offset; |
|
607 return NW_STAT_SUCCESS; |
|
608 } |
|
609 |
|
610 NW_Status_t |
|
611 NW_TinyDom_removeAttrFromListNode(NW_TinyDom_AttrListHandle_t *it, NW_Uint32 length) |
|
612 { |
|
613 NW_Uint16 len = 0; |
|
614 NW_Byte* p = NULL; |
|
615 NW_Byte *moveTo = NULL; |
|
616 NW_Byte *moveFrom = NULL; |
|
617 |
|
618 p = (NW_Byte*)((NW_Byte*)it->segment + it->offset); |
|
619 moveTo = (NW_Byte*)(p - length); |
|
620 moveFrom = p; |
|
621 while (*p != 0x01) |
|
622 { |
|
623 len++; |
|
624 p++; |
|
625 } |
|
626 NW_Mem_memset(moveTo, 0, length); |
|
627 NW_Mem_memmove(moveTo, moveFrom, (len+1)); |
|
628 return NW_STAT_SUCCESS; |
|
629 } |
|
630 |
|
631 |
|
632 |
|
633 |
|
634 |
|
635 |
|
636 |
|