xml/cxmllibrary/src/tinydom/src/tiny_dom_write.c
branchRCL_3
changeset 21 604ca70b6235
parent 20 889504eac4fb
equal deleted inserted replaced
20:889504eac4fb 21:604ca70b6235
     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