xml/cxmllibrary/src/xmlp/src/Xmlp2Wbxml.c
branchRCL_3
changeset 32 889504eac4fb
equal deleted inserted replaced
31:6bcc0aa4be39 32:889504eac4fb
       
     1 /*
       
     2 * Copyright (c) 2000 - 2001 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 <string.h>
       
    19 #include "cxml_internal.h"
       
    20 #include <xml/cxml/nw_encoder_wbxmlwriter.h>
       
    21 #include <xml/cxml/nw_xmlp_xmlparser.h>
       
    22 #include <xml/cxml/nw_xmlp_xmlp2wbxml.h>
       
    23 #include <xml/cxml/nw_encoder_stringtable.h>
       
    24 #include "cxml_xmlp_entity.h"
       
    25 
       
    26 
       
    27 typedef struct CXML_Encoding_String_s {
       
    28    NW_Int8* charSetStr;
       
    29    NW_Uint32   encodingVal;
       
    30 }CXML_Encoding_String_t;
       
    31 
       
    32 /* Number of encoding string supported */
       
    33 
       
    34 #define CXML_Encoding_Str_Num 5
       
    35 
       
    36 static
       
    37 const CXML_Encoding_String_t CXML_EncodingStr_Array[] = 
       
    38 {
       
    39  {(NW_Int8*) "utf-8", HTTP_utf_8 },
       
    40  {(NW_Int8*) "us-ascii", HTTP_us_ascii  },
       
    41  {(NW_Int8*) "iso-10646-ucs-2", HTTP_iso_10646_ucs_2 },
       
    42  {(NW_Int8*) "iso-8859-1", HTTP_iso_8859_1 },
       
    43  {(NW_Int8*) "utf-8", HTTP_utf_16}
       
    44 };
       
    45 
       
    46 typedef struct NW_XML_XmlpWbxmlEncoder_s
       
    47 {
       
    48     NW_WBXML_Writer_t* pE;
       
    49     /*
       
    50     need access to last tag token to backpatch attribute and content flags
       
    51     */
       
    52     NW_Uint32 lastTagTokenIndex;
       
    53     NW_Uint32 publicID; /* needed to pass to start callback */
       
    54     NW_Uint32 encoding; /* needed to pass to start callback */
       
    55 
       
    56 } NW_XML_XmlpWbxmlEncoder_t;
       
    57 
       
    58 /* The following function finds the encoding in the XML declaration statement (if any). 
       
    59  * This function is called only when there is no BOM present and encoding is assumed 
       
    60  * ASCII/Latine-1.
       
    61  * e.g. <?xml version="1.0" encoding="iso-8859-1"?>, here XML Declaration has the encoding
       
    62  * of "iso-8859-1"
       
    63  */
       
    64 
       
    65 static NW_Bool NW_XML_FindEncoding(NW_Uint32 length, const unsigned char* pBuf, NW_Uint32* encodingVal)
       
    66 {
       
    67 
       
    68  NW_Bool s = NW_FALSE;
       
    69  NW_Uint8* sourceWalker     = NULL;
       
    70  NW_Uint8* encodingStart    = NULL;
       
    71  NW_Uint8* encodingValStart = NULL;
       
    72  NW_Uint8* endXMLDecl       = NULL;
       
    73  NW_Uint32  xmlDeclLen       = 0;
       
    74  NW_Uint32  encodingValLen   = 0;
       
    75  NW_Uint32 i = 0;
       
    76 
       
    77  /* Look for end of the XML Declration statement */
       
    78 
       
    79  endXMLDecl = (NW_Uint8*) strstr((char*) pBuf+2, "?>");
       
    80 
       
    81  if(endXMLDecl)
       
    82  {
       
    83   xmlDeclLen =  endXMLDecl -  pBuf;
       
    84 
       
    85 
       
    86      if(xmlDeclLen < length)
       
    87      {
       
    88       encodingStart = (NW_Uint8*) strstr(( (char*)(pBuf+2) ),"encoding");
       
    89 
       
    90       /*Move the pointer after the encoding */
       
    91 
       
    92 
       
    93        if(encodingStart)
       
    94        {
       
    95         sourceWalker = encodingStart + 8;
       
    96 
       
    97         /*Skip any space */
       
    98         while(CXML_Str_Isspace((NW_Ucs2)(*sourceWalker & 0xffff) ) ) 
       
    99         {
       
   100             sourceWalker++;
       
   101         }
       
   102 
       
   103         if(*sourceWalker == '=')
       
   104         {
       
   105             sourceWalker++;
       
   106             while(CXML_Str_Isspace((NW_Ucs2)(*sourceWalker & 0xffff) ) )
       
   107             {
       
   108                 sourceWalker++;
       
   109             }
       
   110         }
       
   111 
       
   112         if( (*sourceWalker == '\'') || (*sourceWalker == '\"') )
       
   113         {
       
   114          sourceWalker++;
       
   115         }
       
   116 
       
   117 		 encodingValStart = sourceWalker;
       
   118 
       
   119 		/* End the Encoding value consume if one of following condition is reached:
       
   120 		 * 1) Closing quote has encounted.
       
   121 		 * 2) '>' closing tag has encountered
       
   122 		 * 3) Space had encounted
       
   123 		 * 4) '?' has encounded.
       
   124 		 * There is possibilty of some arguments after encoding like following:
       
   125 		 * <?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
       
   126 		 */
       
   127 
       
   128 		while( (*sourceWalker != '\'') && (*sourceWalker != '\"') &&
       
   129 			   (*sourceWalker != '>') && (*sourceWalker != '?') )
       
   130 		{
       
   131 		 encodingValLen++;
       
   132 		 sourceWalker++;
       
   133 		}
       
   134 
       
   135         for(i=0; i < CXML_Encoding_Str_Num; i++)
       
   136 	    {
       
   137          if(!strncmp((char*) encodingValStart, (char*) CXML_EncodingStr_Array[i].charSetStr,encodingValLen))
       
   138          {
       
   139           *encodingVal = CXML_EncodingStr_Array[i].encodingVal;
       
   140           s = NW_TRUE;
       
   141           break;
       
   142          }
       
   143         }/*end for() */
       
   144        }/*end if(encodingStart)*/
       
   145      }/*end if(xmlDeclLen < length)*/
       
   146  }/*end if(endXMLDecl)*/
       
   147 
       
   148  return s;
       
   149 }/*end NW_XML_FindEncoding()*/
       
   150 
       
   151 NW_Status_t
       
   152 EXPORT_C
       
   153 NW_XML_ComputeEncoding(NW_Uint32 length, const unsigned char* pBuf,
       
   154                              NW_Uint32* pEncoding, NW_Endianness_t* pEndianness)
       
   155 {
       
   156     NW_Uint32 c0, c1, c2, c3;
       
   157     if (length < 4)
       
   158     {
       
   159         return NW_STAT_FAILURE;
       
   160     }
       
   161     c0 = pBuf[0];
       
   162     c1 = pBuf[1];
       
   163     c2 = pBuf[2];
       
   164     c3 = pBuf[3];
       
   165     if (c0 == 0 && c1 == 0 && c2 == 0xfe && c3 == 0xff)
       
   166     {
       
   167         *pEncoding = 1001; /* ISO-10646-UCS-4 IANA MIBenum */
       
   168         *pEndianness = NW_BIG_ENDIAN;
       
   169     }
       
   170     else if (c0 == 0 && c1 == 0 && c2 == 0 && c3 == 0x3c)
       
   171     {
       
   172         *pEncoding = 1001; /* ISO-10646-UCS-4 IANA MIBenum */
       
   173         *pEndianness = NW_BIG_ENDIAN;
       
   174     }
       
   175     else if (c0 == 0xff && c1 == 0xfe && c2 == 0 && c3 == 0)
       
   176     {
       
   177         *pEncoding = 1001; /* ISO-10646-UCS-4 IANA MIBenum */
       
   178         *pEndianness = NW_LITTLE_ENDIAN;
       
   179     }
       
   180     else if (c0 == 0x3c && c1 == 0 && c2 == 0 && c3 == 0)
       
   181     {
       
   182         *pEncoding = 1001; /* ISO-10646-UCS-4 IANA MIBenum */
       
   183         *pEndianness = NW_LITTLE_ENDIAN;
       
   184     }
       
   185     else if (c0 == 0xfe && c1 == 0xff && !(c2 == 0 && c3 == 0))
       
   186     {
       
   187         /* call it UCS-2 instead of UTF-16 IANA MIBenum, favor over
       
   188            UTF-16BE 1013 */
       
   189         *pEncoding = 1000;
       
   190         *pEndianness = NW_BIG_ENDIAN;
       
   191     }
       
   192     else if (c0 == 0 && c1 == 0x3c && c2 == 0 && c3 == 0x3f)
       
   193     {
       
   194         /* could be UTF-16 but must read xml encoding decl to tell */
       
   195         *pEncoding = 1000; /* UCS-2 IANA MIBenum */
       
   196         *pEndianness = NW_BIG_ENDIAN;
       
   197     }
       
   198     else if (c0 == 0xff && c1 == 0xfe && !(c2 == 0 && c3 == 0))
       
   199     {
       
   200          /* call it UCS-2 instead of UTF-16 IANA MIBenum, favor over
       
   201             UTF-16LE 1014 */
       
   202         *pEncoding = 1000;
       
   203         *pEndianness = NW_LITTLE_ENDIAN;
       
   204     }
       
   205     else if (c0 == 0x3c && c1 == 0 && c2 == 0x3f && c3 == 0)
       
   206     {
       
   207         /* could be UTF-16 but must read xml encoding decl to tell */
       
   208         *pEncoding = 1000; /* UCS-2 IANA MIBenum */
       
   209         *pEndianness = NW_LITTLE_ENDIAN;
       
   210     }
       
   211     else if (c0 == 0x3c && c1 == 0x3f && c2 == 0x78 && c3 == 0x6d)
       
   212     {
       
   213         /* could be anything with anything with an ASCII subset,
       
   214         must read xml encoding decl to tell */
       
   215         if( !NW_XML_FindEncoding (length,pBuf, pEncoding) )
       
   216         {
       
   217         /*If encoding is not in the XML Declaration */
       
   218         *pEncoding = 106; /* UTF-8 IANA MIBenum, no endianness */
       
   219         }
       
   220         *pEndianness = NW_NATIVE_ENDIAN; 
       
   221     }
       
   222     else if (c0 == 0xef && c1 == 0xbb && c2 == 0xbf) /* c3 ignored */
       
   223     {
       
   224         *pEncoding = 106; /* UTF-8 IANA MIBenum, no endianness */
       
   225         *pEndianness = NW_NATIVE_ENDIAN; /* Ha! */
       
   226     }
       
   227     else
       
   228     {
       
   229         /* default to UTF-8 and let the parser barf if it isn't */
       
   230         *pEncoding = 106; /* UTF-8 IANA MIBenum, no endianness */
       
   231         *pEndianness = NW_NATIVE_ENDIAN; /* Ha! */
       
   232     }
       
   233     return NW_STAT_SUCCESS;
       
   234 }
       
   235 
       
   236 
       
   237 
       
   238 /* When encoding is UCS-2, the parser has changed the byte order to
       
   239 native, however, the WBXML should be written in network (i.e., big
       
   240 endian) order.  The way this is done is to change the byte order
       
   241 in-place to network order, write the WBXML, and then put the byte
       
   242 order back to native in-place. */
       
   243 static
       
   244 void
       
   245 NW_XML_XmlpWbxmlEncoder_Ucs2NativeToNetworkByteOrder(NW_Uint32 byteCount,
       
   246                                                      NW_Uint8* pBuf)
       
   247 {
       
   248   NW_Uint32 i;
       
   249   NW_Uint16 c_ucs2 = 1;
       
   250 
       
   251   if (((NW_Uint8*)&c_ucs2)[0] == 1) { /* test for little endian host */
       
   252     for (i = 0; i < byteCount; i += 2) {
       
   253       (void)NW_Mem_memcpy(&c_ucs2, pBuf + i, sizeof(NW_Uint16));
       
   254       pBuf[i] = (NW_Uint8)((c_ucs2 >> 8) & 0xff);
       
   255       pBuf[i+1] = (NW_Uint8)(c_ucs2 & 0xff);
       
   256     }
       
   257   }
       
   258 }
       
   259 
       
   260 static
       
   261 void
       
   262 NW_XML_XmlpWbxmlEncoder_Ucs2NetworkToNativeByteOrder(NW_Uint32 byteCount,
       
   263                                                      NW_Uint8* pBuf)
       
   264 {
       
   265   NW_Uint32 i;
       
   266   NW_Uint16 c_ucs2 = 1;
       
   267 
       
   268   if (((NW_Uint8*)&c_ucs2)[0] == 1) { /* test for little endian host */
       
   269     for (i = 0; i < byteCount; i += 2) {
       
   270       /* this is a clever trick: pick up bytes in big endian order,
       
   271          force the result to memory via taking address of result which
       
   272          will put the 16-bits into native byte order, then copy the
       
   273          result over the original bytes */
       
   274       c_ucs2 = (NW_Uint16)((pBuf[i] << 8) | pBuf[i+1]);
       
   275       (void)NW_Mem_memcpy(pBuf + i, &c_ucs2, sizeof(NW_Uint16));
       
   276     }
       
   277   }
       
   278 }
       
   279 
       
   280 /* end of line normalization replaces DOS or Mac style end of line
       
   281 with Unix style end of line.  If no normalization is needed, then on
       
   282 return *ppTextOut == pTextIn (i.e., no malloc was done), otherwise you
       
   283 need to call NW_Mem_Free(*ppTextOut) when you are done with the output
       
   284 NOTE: only works for native byte order!
       
   285 */
       
   286 static
       
   287 NW_Status_t
       
   288 NW_XML_XmlpWbxmlEncoder_EndOfLineNormalization(NW_Uint32 encoding,
       
   289                                                NW_Uint32* pCharCount,
       
   290                                                NW_Uint32* pByteCount,
       
   291                                                const NW_Uint8* pTextIn,
       
   292                                                NW_Uint8** ppTextOut)
       
   293 {
       
   294   NW_Uint32 i;
       
   295   NW_Uint32 j;
       
   296   NW_Uint32 elideCharCount;
       
   297   NW_Uint32 elideByteCount;
       
   298   NW_Int32 byteCount;
       
   299   NW_Ucs2 cUCS2;
       
   300   NW_Uint8 crHit;
       
   301   NW_Uint8 needsNormalization = 0;
       
   302 
       
   303   /* the output is the input unless it must be normalized */
       
   304   *ppTextOut = (NW_Uint8*)pTextIn;
       
   305 
       
   306   /* scan to count #xD's that need translating */
       
   307   elideCharCount = 0;
       
   308   elideByteCount = 0;
       
   309   crHit = 0;
       
   310   for (i = 0; i < *pByteCount; i += (NW_Uint32)byteCount) {
       
   311     byteCount = NW_String_readChar((NW_Uint8*)&(pTextIn[i]), &cUCS2, encoding);
       
   312     if (byteCount < 0) {
       
   313       return NW_STAT_FAILURE;
       
   314     }
       
   315     /* catch DOS 0xd 0xa eol */
       
   316     if (crHit && (cUCS2 == 0xa)) {
       
   317       elideCharCount++;
       
   318       elideByteCount += (NW_Uint32)byteCount;
       
   319     }
       
   320     if (cUCS2 == 0xd) {
       
   321       needsNormalization = 1;
       
   322       crHit = 1;
       
   323     } else {
       
   324       crHit = 0;
       
   325     }
       
   326   }
       
   327   if (needsNormalization) {
       
   328     /* alloc a new string */
       
   329     *ppTextOut = (NW_Uint8*) NW_Mem_Malloc(*pByteCount - elideByteCount);
       
   330     if (*ppTextOut == NULL) {
       
   331       *ppTextOut = (NW_Uint8*)pTextIn;
       
   332       return NW_STAT_OUT_OF_MEMORY;
       
   333     }
       
   334 
       
   335     /* make a normalized copy of input */
       
   336     crHit = 0;
       
   337     j = 0;
       
   338     for (i = 0; i < *pByteCount; i += (NW_Uint32)byteCount) {
       
   339       byteCount = NW_String_readChar((NW_Uint8*)&(pTextIn[i]), &cUCS2, encoding);
       
   340       if (byteCount < 0) {
       
   341         NW_Mem_Free(*ppTextOut);
       
   342         *ppTextOut = (NW_Uint8*)pTextIn;
       
   343         return NW_STAT_FAILURE;
       
   344       }
       
   345       /* check that readChar isn't trying to read off end of buffer */
       
   346       NW_ASSERT((i + byteCount - 1) < *pByteCount);
       
   347       if (cUCS2 == 0xd) {
       
   348         crHit = 1;
       
   349         if (byteCount == 1) {
       
   350           (*ppTextOut)[j++] = 0xa;
       
   351         } else if (byteCount == 2) {
       
   352           /* this looks odd but takes into account either endianess */
       
   353           if (pTextIn[i] == 0xd) {
       
   354             (*ppTextOut)[j++] = (NW_Uint8)0xa;
       
   355             (*ppTextOut)[j++] = 0;
       
   356           } else {
       
   357             (*ppTextOut)[j++] = 0;
       
   358             (*ppTextOut)[j++] = (NW_Uint8)0xa;
       
   359           }
       
   360         } else {
       
   361           NW_ASSERT(byteCount <= 2); /* code bug, force debug stop here */
       
   362           NW_Mem_Free(*ppTextOut);
       
   363           *ppTextOut = (NW_Uint8*)pTextIn;
       
   364           return NW_STAT_FAILURE;
       
   365         }
       
   366       } else {
       
   367         if (!(crHit && (cUCS2 == 0xa))) {
       
   368           (void)NW_Mem_memcpy(&((*ppTextOut)[j]), &(pTextIn[i]), (NW_Uint32)byteCount);
       
   369           j += (NW_Uint32)byteCount;
       
   370         }
       
   371         crHit = 0;
       
   372       }
       
   373     }
       
   374     *pByteCount -= elideByteCount;
       
   375     *pCharCount -= elideCharCount;
       
   376   }
       
   377   return NW_STAT_SUCCESS;
       
   378 }
       
   379 
       
   380 static
       
   381 NW_Status_t
       
   382 NW_XML_XmlpWbxmlEncoder_New(NW_Uint32 publicID, NW_Uint32 encoding, void** ppV)
       
   383 {
       
   384     NW_WBXML_Dictionary_t* pDictionary;
       
   385     NW_XML_XmlpWbxmlEncoder_t** ppTE = (NW_XML_XmlpWbxmlEncoder_t**)ppV;
       
   386     *ppTE = (NW_XML_XmlpWbxmlEncoder_t*) NW_Mem_Malloc(sizeof(NW_XML_XmlpWbxmlEncoder_t));
       
   387     if (!*ppTE) {
       
   388         return NW_STAT_OUT_OF_MEMORY;
       
   389     }
       
   390     (*ppTE)->lastTagTokenIndex = 0;
       
   391     (*ppTE)->publicID = publicID;
       
   392     (*ppTE)->encoding = encoding;
       
   393     (*ppTE)->pE = (NW_WBXML_Writer_t*) NW_Mem_Malloc(sizeof(NW_WBXML_Writer_t));
       
   394     if (!((*ppTE)->pE)) {
       
   395         return NW_STAT_OUT_OF_MEMORY;
       
   396     }
       
   397     /* Note that we only have access to one dictionary and we
       
   398     should really have two: one for tags and one for attributes. */
       
   399     pDictionary = NW_WBXML_Dictionary_getByPublicId((*ppTE)->publicID);
       
   400 
       
   401     if(  ( CXML_Additional_Feature_Supprted() & CXML_DTD_SUPPORT_ON) )
       
   402     {
       
   403      NW_Encoder_StringTable_t* strTable = NW_Encoder_StringTable_new();
       
   404    
       
   405 
       
   406      NW_WBXML_Writer_Initialize((*ppTE)->pE,
       
   407                              0, NULL, NULL, /* no mem needed for sizing */
       
   408                              pDictionary,
       
   409 							 pDictionary,
       
   410                              NW_Encoder_StringTable_getStringTableOffset,
       
   411 							 NW_Encoder_StringTable_addToStringTable,
       
   412                              strTable, 
       
   413 							 NW_Encoder_StringTable_StringTableIterateInit,
       
   414 							 NW_Encoder_StringTable_StringTableIterateNext,
       
   415                              1 /* do sizing only */);
       
   416     }
       
   417     else
       
   418     {
       
   419 
       
   420     NW_WBXML_Writer_Initialize((*ppTE)->pE,
       
   421                                0, NULL, NULL, /* no mem needed for sizing */
       
   422                                pDictionary, pDictionary,
       
   423                                NULL, NULL, NULL, NULL, NULL, /* string table stuff */
       
   424                                1 /* do sizing only */);
       
   425     }
       
   426     return NW_STAT_SUCCESS;
       
   427 }
       
   428 
       
   429 static
       
   430 void
       
   431 NW_XML_XmlpWbxmlEncoder_SetToWrite(NW_XML_XmlpWbxmlEncoder_t* pTE,
       
   432                                    NW_Uint32 byteLength, NW_Uint8* pBuf,
       
   433                                    NW_WBXML_Writer_GrowBuf_t growBufCallback)
       
   434 {
       
   435 
       
   436     if( ( CXML_Additional_Feature_Supprted() & CXML_DTD_SUPPORT_ON) )
       
   437     {
       
   438         NW_Encoder_StringTable_t* strTable = NW_Encoder_StringTable_new();
       
   439    
       
   440 
       
   441         NW_WBXML_Writer_Initialize(pTE->pE,
       
   442                              byteLength, pBuf,
       
   443                              growBufCallback,
       
   444                              pTE->pE->pTagDictionary,
       
   445 							 pTE->pE->pAttributeDictionary,
       
   446                              NW_Encoder_StringTable_getStringTableOffset,
       
   447 							 NW_Encoder_StringTable_addToStringTable,
       
   448                              strTable, 
       
   449 							 NW_Encoder_StringTable_StringTableIterateInit,
       
   450 							 NW_Encoder_StringTable_StringTableIterateNext,
       
   451                              0 /* don't do sizing, write */);
       
   452     }
       
   453    else
       
   454     {
       
   455     NW_WBXML_Writer_Initialize(pTE->pE,
       
   456                                byteLength, pBuf,
       
   457                                growBufCallback,
       
   458                                pTE->pE->pTagDictionary,
       
   459                                pTE->pE->pAttributeDictionary,
       
   460                                NULL, NULL, NULL, NULL, NULL,  /* string table stuff */
       
   461                                0 /* don't do sizing, write */);
       
   462     }
       
   463 }
       
   464 
       
   465 void
       
   466 NW_XML_XmlpWbxmlEncoder_Delete(void* pV)
       
   467 {
       
   468     NW_XML_XmlpWbxmlEncoder_t* pTE = (NW_XML_XmlpWbxmlEncoder_t*)pV;
       
   469     NW_WBXML_Writer_t* pE = pTE->pE;
       
   470     NW_Mem_Free(pE); /* note that this doesn't free WBXML buf and string table. */
       
   471     NW_Mem_Free(pTE);
       
   472 }
       
   473 
       
   474 static
       
   475 NW_Status_t
       
   476 NW_XML_XmlpWbxmlEncoder_StartDocument_CB(NW_XML_Reader_t* pT, void* pV)
       
   477 {
       
   478     NW_XML_XmlpWbxmlEncoder_t* pTE = (NW_XML_XmlpWbxmlEncoder_t*)pV;
       
   479     NW_WBXML_Writer_t* pE = pTE->pE;
       
   480 
       
   481     NW_REQUIRED_PARAM(pT);
       
   482 
       
   483     /* Note: We do not build a string table because it isn't clear if
       
   484     it is worthwhile. */
       
   485 
       
   486     return NW_WBXML_Writer_Header(pE, 3, pTE->publicID, pTE->encoding, 0);
       
   487 }
       
   488 
       
   489 static
       
   490 NW_Status_t
       
   491 NW_XML_XmlpWbxmlEncoder_Tag_Start_CB(NW_XML_Reader_t* pT,
       
   492                                      const NW_XML_Reader_Interval_t* pI_name,
       
   493                                      void* pV)
       
   494 {
       
   495     NW_XML_XmlpWbxmlEncoder_t* pTE = (NW_XML_XmlpWbxmlEncoder_t*)pV;
       
   496     NW_WBXML_Writer_t* pE = pTE->pE;
       
   497     NW_Uint32 length;
       
   498     NW_Uint32 nameByteLength;
       
   499     NW_Uint8* pName;
       
   500     NW_Status_t s;
       
   501     if (!NW_XML_Reader_Interval_IsWellFormed(pI_name)) {
       
   502         return NW_STAT_FAILURE;
       
   503     }
       
   504     length = pI_name->stop - pI_name->start;
       
   505     nameByteLength = length;
       
   506     s = NW_XML_Reader_DataAddressFromBuffer(pT, pI_name->start,
       
   507                                          &nameByteLength,
       
   508                                          &pName);
       
   509     if (NW_STAT_IS_FAILURE(s)) {
       
   510         return s;
       
   511     }
       
   512     if (nameByteLength != length) {
       
   513         return NW_STAT_FAILURE;
       
   514     }
       
   515     length = pI_name->charStop - pI_name->charStart;
       
   516     s = NW_WBXML_Writer_TagString(pE, pTE->encoding, length, nameByteLength,
       
   517                             pName, &(pTE->lastTagTokenIndex));
       
   518     if (NW_STAT_IS_FAILURE(s)) {
       
   519         return s;
       
   520     }
       
   521     /* default to content but erase if see empty tag end */
       
   522     return NW_WBXML_Writer_TagSetContentFlag(pE, pTE->lastTagTokenIndex);
       
   523 }
       
   524 
       
   525 static
       
   526 NW_Status_t
       
   527 NW_XML_XmlpWbxmlEncoder_Attr_Start_CB(NW_XML_Reader_t* pT,
       
   528                                       const NW_XML_Reader_Interval_t* pI_name,
       
   529                                       void* pV)
       
   530 {
       
   531     NW_XML_XmlpWbxmlEncoder_t* pTE = (NW_XML_XmlpWbxmlEncoder_t*)pV;
       
   532     NW_WBXML_Writer_t* pE = pTE->pE;
       
   533     NW_REQUIRED_PARAM(pT);
       
   534     NW_REQUIRED_PARAM(pI_name);
       
   535     return NW_WBXML_Writer_TagSetAttributesFlag(pE, pTE->lastTagTokenIndex);
       
   536 }
       
   537 
       
   538 static
       
   539 NW_Status_t
       
   540 NW_XML_XmlpWbxmlEncoder_Attr_VarVal_CB(NW_XML_Reader_t* pT,
       
   541                                         const NW_XML_Reader_Interval_t* pI_name,
       
   542                                         const NW_XML_Reader_Interval_t* pI_value,
       
   543                                         void* pV)
       
   544 {
       
   545     NW_XML_XmlpWbxmlEncoder_t* pTE = (NW_XML_XmlpWbxmlEncoder_t*)pV;
       
   546     NW_WBXML_Writer_t* pE = pTE->pE;
       
   547     NW_Uint32 length;
       
   548     NW_Uint32 nameLength;
       
   549     NW_Uint8* pName;
       
   550     NW_Uint32 valueByteLength;
       
   551     NW_Uint32 valueCharCount;
       
   552     NW_Uint8* pValue;
       
   553     NW_Status_t s;
       
   554 
       
   555     if (!NW_XML_Reader_Interval_IsWellFormed(pI_name)) {
       
   556         return NW_STAT_FAILURE;
       
   557     }
       
   558 
       
   559     /* var name setup */
       
   560     length = pI_name->stop - pI_name->start;
       
   561     nameLength = length; /* byte length */
       
   562     s = NW_XML_Reader_DataAddressFromBuffer(pT, pI_name->start,
       
   563                                          &nameLength, &pName);
       
   564     if (NW_STAT_IS_FAILURE(s)) {
       
   565         return s;
       
   566     }
       
   567     if (nameLength != length) {
       
   568         return NW_STAT_FAILURE;
       
   569     }
       
   570     nameLength = pI_name->charStop - pI_name->charStart; /* char count */
       
   571 
       
   572     /* value setup */
       
   573     length = pI_value->stop - pI_value->start;
       
   574     valueByteLength = length;
       
   575     s = NW_XML_Reader_DataAddressFromBuffer(pT, pI_value->start,
       
   576                                          &valueByteLength, &pValue);
       
   577     if (NW_STAT_IS_FAILURE(s)) {
       
   578         return s;
       
   579     }
       
   580     if (valueByteLength != length) {
       
   581         return NW_STAT_FAILURE;
       
   582     }
       
   583     valueCharCount = pI_value->charStop - pI_value->charStart;
       
   584 
       
   585     if (pT->encoding == HTTP_iso_10646_ucs_2) {
       
   586       NW_XML_XmlpWbxmlEncoder_Ucs2NativeToNetworkByteOrder(valueByteLength,
       
   587                                                            pValue);
       
   588     }
       
   589     s = NW_WBXML_Writer_AttributeAndValue(pE, pTE->encoding, nameLength,
       
   590                                           pName, valueCharCount,
       
   591                                           valueByteLength, pValue);
       
   592     if (NW_STAT_IS_FAILURE(s)) {
       
   593         return s;
       
   594     }
       
   595     if (pT->encoding == HTTP_iso_10646_ucs_2) {
       
   596       NW_XML_XmlpWbxmlEncoder_Ucs2NetworkToNativeByteOrder(valueByteLength,
       
   597                                                            pValue);
       
   598     }
       
   599     return NW_STAT_SUCCESS;
       
   600 }
       
   601 
       
   602 static
       
   603 NW_Status_t
       
   604 NW_XML_XmlpWbxmlEncoder_Attributes_End_CB(NW_XML_Reader_t* pT,
       
   605                                           NW_Uint32 attributeCount, void* pV)
       
   606 {
       
   607     NW_XML_XmlpWbxmlEncoder_t* pTE = (NW_XML_XmlpWbxmlEncoder_t*)pV;
       
   608     NW_WBXML_Writer_t* pE = pTE->pE;
       
   609     NW_Status_t s;
       
   610     NW_REQUIRED_PARAM(pT);
       
   611     /* if there were any attributes, then must write end token */
       
   612     if (attributeCount) {
       
   613         s = NW_WBXML_Writer_End(pE);
       
   614         if (NW_STAT_IS_FAILURE(s)) {
       
   615             return s;
       
   616         }
       
   617     }
       
   618     return NW_STAT_SUCCESS;
       
   619 }
       
   620 
       
   621 static
       
   622 NW_Status_t
       
   623 NW_XML_XmlpWbxmlEncoder_CoreTextHandler(NW_Uint32 encoding,
       
   624                                         NW_Uint32 charCount,
       
   625                                         NW_Uint32 byteLength,
       
   626                                         NW_Uint8* pText,
       
   627                                         NW_WBXML_Writer_t* pE)
       
   628 {
       
   629     NW_Uint8* pNormalizedText;
       
   630     NW_Status_t s;
       
   631 
       
   632     s = NW_XML_XmlpWbxmlEncoder_EndOfLineNormalization(encoding,
       
   633                                                        &charCount,
       
   634                                                        &byteLength,
       
   635                                                        pText,
       
   636                                                        &pNormalizedText);
       
   637     if (NW_STAT_IS_FAILURE(s)) {
       
   638       return s;
       
   639     }
       
   640     if (encoding == HTTP_iso_10646_ucs_2) {
       
   641       NW_XML_XmlpWbxmlEncoder_Ucs2NativeToNetworkByteOrder(byteLength,
       
   642                                                            pNormalizedText);
       
   643     }
       
   644     s = NW_WBXML_Writer_Text(pE, encoding, byteLength, pNormalizedText);
       
   645     if (NW_STAT_IS_FAILURE(s)) {
       
   646       return s;
       
   647     }
       
   648     if (pText == pNormalizedText) {
       
   649       if (encoding == HTTP_iso_10646_ucs_2) {
       
   650         NW_XML_XmlpWbxmlEncoder_Ucs2NetworkToNativeByteOrder(byteLength,
       
   651                                                              pNormalizedText);
       
   652       }
       
   653     } else {
       
   654       NW_Mem_Free(pNormalizedText);
       
   655     }
       
   656     return NW_STAT_SUCCESS;
       
   657 }
       
   658 
       
   659 
       
   660 static
       
   661 NW_Status_t
       
   662 NW_XML_XmlpWbxmlEncoder_Content_CB(NW_XML_Reader_t* pT,
       
   663                                    const NW_XML_Reader_Interval_t* pI_content,
       
   664                                    void* pV)
       
   665 {
       
   666     NW_XML_XmlpWbxmlEncoder_t* pTE = (NW_XML_XmlpWbxmlEncoder_t*)pV;
       
   667     NW_WBXML_Writer_t* pE = pTE->pE;
       
   668     NW_Status_t s;
       
   669     NW_Uint32 length;
       
   670     NW_Uint32 byteLength;
       
   671     NW_Uint32 charCount;
       
   672     NW_Uint8* pContent;
       
   673     NW_Uint8* pNormalizedContent;
       
   674 
       
   675     if (!NW_XML_Reader_Interval_IsWellFormed(pI_content)) {
       
   676         return NW_STAT_FAILURE;
       
   677     }
       
   678     length = pI_content->stop - pI_content->start;
       
   679     byteLength = length;
       
   680     s = NW_XML_Reader_DataAddressFromBuffer(pT, pI_content->start,
       
   681                                             &byteLength,
       
   682                                             &pContent);
       
   683     if (NW_STAT_IS_FAILURE(s)) {
       
   684         return s;
       
   685     }
       
   686     if (byteLength != length) {
       
   687         return NW_STAT_FAILURE;
       
   688     }
       
   689     charCount = pI_content->charStop - pI_content->charStart;
       
   690     s = NW_XML_XmlpWbxmlEncoder_EndOfLineNormalization(pT->encoding,
       
   691                                                        &charCount,
       
   692                                                        &byteLength,
       
   693                                                        pContent,
       
   694                                                        &pNormalizedContent);
       
   695     if (NW_STAT_IS_FAILURE(s)) {
       
   696         return s;
       
   697     }
       
   698     if (pT->encoding == HTTP_iso_10646_ucs_2) {
       
   699       NW_XML_XmlpWbxmlEncoder_Ucs2NativeToNetworkByteOrder(byteLength,
       
   700                                                            pNormalizedContent);
       
   701     }
       
   702     s = NW_WBXML_Writer_Text(pE, pT->encoding, byteLength, pNormalizedContent);
       
   703     if (NW_STAT_IS_FAILURE(s)) {
       
   704         return s;
       
   705     }
       
   706     if (pContent == pNormalizedContent) {
       
   707       if (pT->encoding == HTTP_iso_10646_ucs_2) {
       
   708         NW_XML_XmlpWbxmlEncoder_Ucs2NetworkToNativeByteOrder(byteLength,
       
   709                                                              pNormalizedContent);
       
   710       }
       
   711     } else {
       
   712       NW_Mem_Free(pNormalizedContent);
       
   713     }
       
   714     return NW_STAT_SUCCESS;
       
   715 }
       
   716 
       
   717 static
       
   718 NW_Status_t
       
   719 NW_XML_XmlpWbxmlEncoder_Tag_End_CB(NW_XML_Reader_t* pT,
       
   720                                    const NW_XML_Reader_Interval_t* pI_name,
       
   721                                    NW_Uint32 emptyTagFlag, void* pV)
       
   722 {
       
   723     NW_XML_XmlpWbxmlEncoder_t* pTE = (NW_XML_XmlpWbxmlEncoder_t*)pV;
       
   724     NW_WBXML_Writer_t* pE = pTE->pE;
       
   725     NW_Status_t s;
       
   726     NW_REQUIRED_PARAM(pT);
       
   727     NW_REQUIRED_PARAM(pI_name);
       
   728     if (emptyTagFlag) {
       
   729         s = NW_WBXML_Writer_TagClearContentFlag(pE, pTE->lastTagTokenIndex);
       
   730     } else {
       
   731         s = NW_WBXML_Writer_End(pE);
       
   732     }
       
   733     if (NW_STAT_IS_FAILURE(s)) {
       
   734         return s;
       
   735     }
       
   736     return s;
       
   737 }
       
   738 
       
   739 static
       
   740 NW_Status_t
       
   741 NW_XML_XmlpWbxmlEncoder_Cdata_CB(NW_XML_Reader_t* pT,
       
   742                                  const NW_XML_Reader_Interval_t* pI_cdata,
       
   743                                  void* pV)
       
   744 {
       
   745     NW_XML_XmlpWbxmlEncoder_t* pTE = (NW_XML_XmlpWbxmlEncoder_t*)pV;
       
   746     NW_WBXML_Writer_t* pE = pTE->pE;
       
   747     NW_Uint8* pText;
       
   748     NW_Uint8* pQuotedText;
       
   749     NW_Uint8* pSrc;
       
   750     NW_Uint8* pDest;
       
   751     NW_Uint32 encoding = pT->encoding;
       
   752     NW_Uint32 length;
       
   753     NW_Uint32 byteLength;
       
   754     NW_Uint32 charCount;
       
   755     NW_Uint32 ampCount;
       
   756     NW_Uint32 i, j;
       
   757     NW_Ucs2 cUCS2;
       
   758     NW_Status_t s;
       
   759 
       
   760     /* code only supports the following charset values */
       
   761     NW_ASSERT((encoding == HTTP_us_ascii)
       
   762               || (encoding == HTTP_iso_8859_1)
       
   763               || (encoding == HTTP_utf_8)
       
   764               || (encoding == HTTP_iso_10646_ucs_2));
       
   765     
       
   766     charCount = pI_cdata->charStop - pI_cdata->charStart;
       
   767     length = pI_cdata->stop - pI_cdata->start;
       
   768     if (length < 1) {
       
   769       return NW_STAT_SUCCESS;
       
   770     }
       
   771     byteLength = length;
       
   772     s = NW_XML_Reader_DataAddressFromBuffer(pT, pI_cdata->start,
       
   773                                             &byteLength,
       
   774                                             &pText);
       
   775     if (NW_STAT_IS_FAILURE(s)) {
       
   776       return s;
       
   777     }
       
   778     if (byteLength != length) {
       
   779       return NW_STAT_FAILURE;
       
   780     }
       
   781 
       
   782     /* Cdata is not supposed to have any entity expansion done on it.
       
   783        Since we don't alter the original document text in general, we
       
   784        have done the entity expansion outside of cXML.  Therefore, we
       
   785        must quote any ampersands in the Cdata to prevent later entity
       
   786        expansion. */
       
   787 
       
   788     /* count ampersands */
       
   789     pSrc = pText;
       
   790     ampCount = 0;
       
   791     for (i = 0; i < charCount; i++) {
       
   792       j = NW_String_readChar(pSrc, &cUCS2, pT->encoding);
       
   793       pSrc += j;
       
   794       /* don't need to check j < 1, text has already been validated */
       
   795       if (cUCS2 == '&') {
       
   796         ampCount++;
       
   797       }
       
   798     }
       
   799 
       
   800     pQuotedText = pText;
       
   801     if (ampCount) {
       
   802       /* allocate a new buffer
       
   803 
       
   804       need incremental length for: & => &amp;
       
   805       start with single byte charset value */
       
   806       ampCount *= 4;
       
   807       /* double for ucs2 */
       
   808       if (pT->encoding == HTTP_iso_10646_ucs_2) {
       
   809         ampCount *= 2;
       
   810       }
       
   811       pQuotedText = (NW_Uint8*)NW_Mem_Malloc(byteLength + ampCount);
       
   812       if (pQuotedText == NULL) {
       
   813         return NW_STAT_OUT_OF_MEMORY;
       
   814       }
       
   815 
       
   816       /* copy and quote ampersands */
       
   817       pSrc = pText;
       
   818       pDest = pQuotedText;
       
   819       for (i = 0; i < charCount; i++) {
       
   820         j = NW_String_readChar(pSrc, &cUCS2, encoding);
       
   821         /* don't need to check for byteCount < 1, text has already been
       
   822            validated */
       
   823         NW_Mem_memcpy(pDest, pSrc, j);
       
   824         pSrc += j;
       
   825         pDest += j;
       
   826         if (cUCS2 == '&') {
       
   827           if (encoding == HTTP_iso_10646_ucs_2) {
       
   828             /* double byte */
       
   829             *((NW_Uint16*)pDest) = 'a';
       
   830             *((NW_Uint16*)(pDest + 2)) = 'm';
       
   831             *((NW_Uint16*)(pDest + 4)) = 'p';
       
   832             *((NW_Uint16*)(pDest + 6)) = ';';
       
   833             pDest += 8;
       
   834           } else {
       
   835             /* single byte encodings */
       
   836             NW_Mem_memcpy(pDest, "amp;", 4);
       
   837             pDest += 4;
       
   838           }
       
   839         }
       
   840       }
       
   841       byteLength += ampCount;
       
   842       if (pT->encoding == HTTP_iso_10646_ucs_2) {
       
   843         charCount += (ampCount / 2);
       
   844       } else {
       
   845         charCount = byteLength;
       
   846       }
       
   847     }
       
   848 
       
   849     /* output the text */
       
   850     s = NW_XML_XmlpWbxmlEncoder_CoreTextHandler(pT->encoding,
       
   851                                                 charCount,
       
   852                                                 byteLength,
       
   853                                                 pQuotedText,
       
   854                                                 pE);
       
   855     if (pQuotedText != pText) {
       
   856       NW_Mem_Free(pQuotedText);
       
   857     }
       
   858     return s;
       
   859 }
       
   860 
       
   861 static
       
   862 NW_Status_t
       
   863 NW_XML_XmlpWbxmlEncoder_EndDocument_CB(NW_XML_Reader_t* pT, void* pV)
       
   864 {
       
   865     /* When debugging, this func provides a place to capture the final WBXML. */
       
   866     NW_REQUIRED_PARAM(pT);
       
   867     NW_REQUIRED_PARAM(pV);
       
   868     return NW_STAT_SUCCESS;
       
   869 }
       
   870 
       
   871 
       
   872 /* Function to check the string table of encoder process. If the string table is
       
   873  * found and supported then keep a copy of this so that WBXML parser can populate 
       
   874  * its string table from this.
       
   875  */
       
   876 static 
       
   877 void NW_XML_StrTbl(struct NW_XML_Parser_EventCallbacks_s* eventCBs,
       
   878                                                            void** WBXMLEncStrTbl)
       
   879 {
       
   880   //Keep the copy of the WBXML string table, so that it can be added to the
       
   881   //DOM later. 
       
   882    if( (NW_Bool) (CXML_Additional_Feature_Supprted() & CXML_DTD_SUPPORT_ON) ) 
       
   883    {
       
   884      NW_Uint32 stringTableByteCount = 0;
       
   885      NW_Encoder_StringTable_t* strTable = (NW_Encoder_StringTable_t*)
       
   886            ((NW_XML_XmlpWbxmlEncoder_t*)eventCBs->pClientPointer)->pE->pStringTableObject;
       
   887      if(strTable)
       
   888      {
       
   889        stringTableByteCount = NW_Encoder_StringTable_getTotalBytes(strTable);
       
   890        if( (stringTableByteCount == 0) || (WBXMLEncStrTbl == NULL) )
       
   891        {
       
   892         //Empty Table
       
   893         NW_Encoder_StringTable_delete(strTable);
       
   894         if(WBXMLEncStrTbl)
       
   895         {
       
   896          *WBXMLEncStrTbl = NULL;
       
   897         }
       
   898        }
       
   899        else
       
   900        {
       
   901         if(WBXMLEncStrTbl)
       
   902         {
       
   903         *WBXMLEncStrTbl = (void*) strTable;
       
   904         }
       
   905        }//end else
       
   906     }//end if(strTable)
       
   907      else
       
   908      {
       
   909       if(WBXMLEncStrTbl)
       
   910         {
       
   911          *WBXMLEncStrTbl = NULL;
       
   912         }
       
   913      }
       
   914    }//end if((NW_Bool) CXML_Additional_Feature_Supprted() ) 
       
   915    else
       
   916    {
       
   917     if(WBXMLEncStrTbl)
       
   918     {
       
   919      *WBXMLEncStrTbl = NULL;
       
   920     }
       
   921    }
       
   922  return;
       
   923 }/*NW_XML_StrTbl()*/
       
   924 
       
   925 
       
   926 //Write the entity content now. There are two possibilities for
       
   927 //entities.
       
   928 //
       
   929 // 1) If it is character or decimal or predefined entities. 
       
   930 //    In this case, intEntityValStr = NULL.
       
   931 //
       
   932 // 2) If it is "Internal Entity" then intEntityValStr != NULL.
       
   933 //     So, this is directly written to WBXML encoder as inline string.
       
   934 //    In this case, entityVal = 0;
       
   935 
       
   936 static
       
   937 NW_Status_t
       
   938 NW_XML_XmlpWbxmlEncoder_Entity_CB(NW_XML_Reader_t* pT,NW_Uint32 numEntity,
       
   939                                    void* pV, CXML_Uint8* intEntityValStr)
       
   940 {
       
   941     NW_XML_XmlpWbxmlEncoder_t* pTE = (NW_XML_XmlpWbxmlEncoder_t*)pV;
       
   942     NW_WBXML_Writer_t* pW = pTE->pE;
       
   943     NW_Status_t s = NW_STAT_FAILURE;
       
   944 
       
   945     NW_REQUIRED_PARAM(pT);
       
   946     NW_REQUIRED_PARAM(pV);
       
   947 
       
   948     if(intEntityValStr == NULL)
       
   949     {
       
   950 	 s = NW_WBXML_Writer_Entity(pW,numEntity);
       
   951     }
       
   952     else if( (intEntityValStr != NULL) && (numEntity == 0) )
       
   953     {
       
   954      NW_Uint32 valBufByteCnt = 0;
       
   955      NW_Int32 valBufLen = NW_String_charBuffGetLength( (void*)intEntityValStr,
       
   956                                                  pT->encoding,
       
   957                                                  &valBufByteCnt);
       
   958 
       
   959       /* Write internal entity as Inline string */
       
   960 
       
   961       s = NW_WBXML_Writer_Text( pW, pT->encoding, valBufByteCnt, intEntityValStr);
       
   962      
       
   963     }/*end else if*/
       
   964 
       
   965     return s;
       
   966 }/*end NW_XML_XmlpWbxmlEncoder_Entity_CB() */
       
   967 
       
   968 /* This is used for if Entity is there in the Attribute value */
       
   969 
       
   970 static
       
   971 NW_Status_t
       
   972 NW_XML_XmlpWbxmlEncoder_Entity_Attr_VarVal_CB(NW_XML_Reader_t* pT,
       
   973                                         const NW_XML_Reader_Interval_t* pI_name,
       
   974                                         NW_Uint8* pValue,
       
   975 										NW_Uint32 valueByteLength,
       
   976                                         void* pV)
       
   977 {
       
   978 NW_XML_XmlpWbxmlEncoder_t* pTE = (NW_XML_XmlpWbxmlEncoder_t*)pV;
       
   979     NW_WBXML_Writer_t* pE = pTE->pE;
       
   980     NW_Uint32 length;
       
   981     NW_Uint32 nameLength;
       
   982 	NW_Uint32 valueCharCount;
       
   983     NW_Uint8* pName;
       
   984     NW_Status_t s;
       
   985 
       
   986     if (!NW_XML_Reader_Interval_IsWellFormed(pI_name)) {
       
   987         return NW_STAT_FAILURE;
       
   988     }
       
   989 
       
   990     /* var name setup */
       
   991     length = pI_name->stop - pI_name->start;
       
   992     nameLength = length; /* byte length */
       
   993     s = NW_XML_Reader_DataAddressFromBuffer(pT, pI_name->start,
       
   994                                          &nameLength, &pName);
       
   995     if (NW_STAT_IS_FAILURE(s)) {
       
   996         return s;
       
   997     }
       
   998     if (nameLength != length) {
       
   999         return NW_STAT_FAILURE;
       
  1000     }
       
  1001     nameLength = pI_name->charStop - pI_name->charStart; /* char count */
       
  1002 
       
  1003     /* value setup */
       
  1004     valueCharCount = valueByteLength;
       
  1005     
       
  1006 
       
  1007     if (pT->encoding == HTTP_iso_10646_ucs_2) {
       
  1008       NW_XML_XmlpWbxmlEncoder_Ucs2NativeToNetworkByteOrder(valueByteLength,
       
  1009                                                            pValue);
       
  1010     }
       
  1011     s = NW_WBXML_Writer_AttributeAndValue(pE, pTE->encoding, nameLength,
       
  1012                                           pName, valueCharCount,
       
  1013                                           valueByteLength, pValue);
       
  1014     if (NW_STAT_IS_FAILURE(s)) {
       
  1015         return s;
       
  1016     }
       
  1017     if (pT->encoding == HTTP_iso_10646_ucs_2) {
       
  1018       NW_XML_XmlpWbxmlEncoder_Ucs2NetworkToNativeByteOrder(valueByteLength,
       
  1019                                                            pValue);
       
  1020     }
       
  1021     return NW_STAT_SUCCESS;
       
  1022 }/*end NW_XML_XmlpWbxmlEncoder_Entity_Attr_VarVal_CB(..)*/
       
  1023 
       
  1024 
       
  1025 
       
  1026 
       
  1027 
       
  1028 NW_Status_t
       
  1029 NW_XML_XmlToWbxml(NW_Buffer_t* pInBuf, NW_Uint32 encoding, 
       
  1030                   NW_Buffer_t** ppOutBuf, NW_Uint32* line, 
       
  1031                   NW_Uint32 publicID, void** WBXMLEncStrTbl)
       
  1032 {
       
  1033     NW_Status_t s;
       
  1034     NW_XML_Reader_t t;
       
  1035     NW_Uint8* pWbxmlBuf;
       
  1036     NW_Uint8* docStartAddress;
       
  1037     NW_Uint32 docByteLength;
       
  1038     NW_Uint32 wbxmlBufLength;
       
  1039     struct NW_XML_Parser_EventCallbacks_s wbxmlEncodeCallbacks;
       
  1040     NW_XML_XmlpWbxmlEncoder_t* ppTE = NULL;
       
  1041     NW_WBXML_Writer_t* pW = NULL;
       
  1042 
       
  1043     NW_ASSERT( pInBuf != NULL );
       
  1044     NW_ASSERT( ppOutBuf != NULL );
       
  1045     NW_ASSERT( line != NULL );
       
  1046 
       
  1047     *line = 0;
       
  1048     if (pInBuf->length == 0 || pInBuf->data == NULL) {
       
  1049       return NW_STAT_FAILURE;
       
  1050     }
       
  1051     /* For UTF-8 and UCS-2 handle BOM (byte order mark).  Also, for
       
  1052        UCS-2 handle network (big) to native byte order conversion. */
       
  1053     docByteLength = pInBuf->length;
       
  1054     docStartAddress = pInBuf->data;
       
  1055     if (encoding == HTTP_utf_8) {
       
  1056       /* look for BOM and remove if found */
       
  1057       if (docByteLength >= 3) {
       
  1058         if ((docStartAddress[0] == 0xef)
       
  1059             && (docStartAddress[1] == 0xbb)
       
  1060             && (docStartAddress[2] == 0xbf)) {
       
  1061           docByteLength -= 3;
       
  1062           docStartAddress += 3;
       
  1063         }
       
  1064       }
       
  1065     }
       
  1066     if (encoding == HTTP_iso_10646_ucs_2) {
       
  1067       /* WARNING: we are assuming network byte order (i.e., big) for
       
  1068          the input document */
       
  1069       /* verify the doc has an even number of bytes, check LSB != 1 */
       
  1070       if ((docByteLength & 1) == 1) {
       
  1071         return NW_STAT_FAILURE;
       
  1072       }
       
  1073 
       
  1074       /* make a pass over the doc, forcing byte order to native byte order */
       
  1075       NW_XML_XmlpWbxmlEncoder_Ucs2NetworkToNativeByteOrder(docByteLength,
       
  1076                                                            docStartAddress);
       
  1077       /* now look for BOM and remove if found */
       
  1078       if (docByteLength >= 2) {
       
  1079         if (((docStartAddress[0] == 0xfe) && (docStartAddress[1] == 0xff))
       
  1080             || ((docStartAddress[0] == 0xff) && (docStartAddress[1] == 0xfe))) {
       
  1081           docByteLength -= 2;
       
  1082           docStartAddress += 2;
       
  1083         }
       
  1084       }
       
  1085     }
       
  1086     /* verify there is some doc remaining after BOM processing */
       
  1087     if (docByteLength == 0) {
       
  1088       return NW_STAT_FAILURE;
       
  1089     }
       
  1090 
       
  1091     /* malloc the output buffer */
       
  1092     *ppOutBuf = (NW_Buffer_t*) NW_Mem_Malloc(sizeof(NW_Buffer_t));
       
  1093     if (!*ppOutBuf) {
       
  1094         return NW_STAT_OUT_OF_MEMORY;
       
  1095     }
       
  1096     (*ppOutBuf)->length = 0;
       
  1097     (*ppOutBuf)->allocatedLength = 0;
       
  1098     (*ppOutBuf)->data = NULL;
       
  1099 
       
  1100     /* Null out all WBXML generation callback addresses. */
       
  1101     NW_Mem_memset(&wbxmlEncodeCallbacks, 0,
       
  1102                   sizeof(struct NW_XML_Parser_EventCallbacks_s));
       
  1103     /* Add in-use WBXML generation callbacks. */
       
  1104     wbxmlEncodeCallbacks.StartDocument_CB = NW_XML_XmlpWbxmlEncoder_StartDocument_CB;
       
  1105     wbxmlEncodeCallbacks.Tag_Start_CB = NW_XML_XmlpWbxmlEncoder_Tag_Start_CB;
       
  1106     wbxmlEncodeCallbacks.Attr_Start_CB = NW_XML_XmlpWbxmlEncoder_Attr_Start_CB;
       
  1107     wbxmlEncodeCallbacks.Attr_VarVal_CB = NW_XML_XmlpWbxmlEncoder_Attr_VarVal_CB;
       
  1108     wbxmlEncodeCallbacks.Attributes_End_CB = NW_XML_XmlpWbxmlEncoder_Attributes_End_CB;
       
  1109     wbxmlEncodeCallbacks.Tag_End_CB = NW_XML_XmlpWbxmlEncoder_Tag_End_CB;
       
  1110     wbxmlEncodeCallbacks.Content_CB = NW_XML_XmlpWbxmlEncoder_Content_CB;
       
  1111     wbxmlEncodeCallbacks.Cdata_CB = NW_XML_XmlpWbxmlEncoder_Cdata_CB;
       
  1112     wbxmlEncodeCallbacks.EndDocument_CB = NW_XML_XmlpWbxmlEncoder_EndDocument_CB;
       
  1113 
       
  1114     wbxmlEncodeCallbacks.Entity_CB = NW_XML_XmlpWbxmlEncoder_Entity_CB;
       
  1115     wbxmlEncodeCallbacks.Attr_Entity_VarVal_CB = NW_XML_XmlpWbxmlEncoder_Entity_Attr_VarVal_CB;
       
  1116 
       
  1117 
       
  1118     /* The encoder contains a WBXML_Writer that defaults to a sizing pass. */
       
  1119     s = NW_XML_XmlpWbxmlEncoder_New(publicID, encoding,
       
  1120                                     &(wbxmlEncodeCallbacks.pClientPointer));
       
  1121     if (NW_STAT_IS_FAILURE(s)) {
       
  1122         return s;
       
  1123     }
       
  1124 
       
  1125     ppTE = (NW_XML_XmlpWbxmlEncoder_t*)wbxmlEncodeCallbacks.pClientPointer;
       
  1126     pW   = (NW_WBXML_Writer_t*) ppTE->pE;
       
  1127 
       
  1128     /* Hand the document text to the Reader in preparation for parsing. */
       
  1129     s = NW_XML_Reader_InitFromBuffer(&t, docByteLength, docStartAddress);
       
  1130     if (NW_STAT_IS_FAILURE(s)) {
       
  1131         NW_XML_XmlpWbxmlEncoder_Delete(wbxmlEncodeCallbacks.pClientPointer);
       
  1132         if(pW->pStringTableObject)
       
  1133         {
       
  1134          NW_Encoder_StringTable_delete(pW->pStringTableObject);
       
  1135         }
       
  1136         return s;
       
  1137     }
       
  1138     NW_XML_Reader_SetEncoding(&t, encoding);
       
  1139 
       
  1140     /* Parse and do a sizing pass for the WBXML. */
       
  1141     s = NW_XML_Parse(&t, &wbxmlEncodeCallbacks);
       
  1142     if (NW_STAT_IS_FAILURE(s)) {
       
  1143         NW_Uint32 column;
       
  1144         NW_XML_Reader_GetLineColumn(&t, line, &column);
       
  1145         if(pW->pStringTableObject)
       
  1146         {
       
  1147          NW_Encoder_StringTable_delete(pW->pStringTableObject);
       
  1148         }
       
  1149         NW_XML_XmlpWbxmlEncoder_Delete(wbxmlEncodeCallbacks.pClientPointer);
       
  1150         return s;
       
  1151     }
       
  1152 
       
  1153     /* If there is any string table data then free it after PASS-1 as
       
  1154      * PASS-2 will again store the data in this. The PASS-1 only calulate
       
  1155      * size of the WBXML buffer.
       
  1156      */
       
  1157 
       
  1158     NW_Encoder_StringTable_delete((NW_Encoder_StringTable_t*)
       
  1159            ((NW_XML_XmlpWbxmlEncoder_t*)wbxmlEncodeCallbacks.pClientPointer)->pE->pStringTableObject);
       
  1160 
       
  1161 
       
  1162     /* Allocate buffer and reinitialize writer to write to buf. */
       
  1163     wbxmlBufLength = (((NW_XML_XmlpWbxmlEncoder_t*)
       
  1164                        wbxmlEncodeCallbacks.pClientPointer)->pE->index);
       
  1165     pWbxmlBuf = (NW_Uint8*) NW_Mem_Malloc(wbxmlBufLength);
       
  1166     if (!pWbxmlBuf) {
       
  1167         if(pW->pStringTableObject)
       
  1168         {
       
  1169          NW_Encoder_StringTable_delete(pW->pStringTableObject);
       
  1170         }
       
  1171         NW_XML_XmlpWbxmlEncoder_Delete(wbxmlEncodeCallbacks.pClientPointer);
       
  1172         return NW_STAT_OUT_OF_MEMORY;
       
  1173     }
       
  1174     NW_XML_XmlpWbxmlEncoder_SetToWrite((NW_XML_XmlpWbxmlEncoder_t*)
       
  1175                                        wbxmlEncodeCallbacks.pClientPointer,
       
  1176                                        wbxmlBufLength, pWbxmlBuf,
       
  1177                                        NULL /* no growth callback */);
       
  1178     /* Reregister the document text with the Reader in preparation for parsing. */
       
  1179     s = NW_XML_Reader_InitFromBuffer(&t, docByteLength, docStartAddress);
       
  1180     if (NW_STAT_IS_FAILURE(s)) {
       
  1181         if(pW->pStringTableObject)
       
  1182         {
       
  1183          NW_Encoder_StringTable_delete(pW->pStringTableObject);
       
  1184         }
       
  1185         NW_XML_XmlpWbxmlEncoder_Delete(wbxmlEncodeCallbacks.pClientPointer);
       
  1186         return s;
       
  1187     }
       
  1188     NW_XML_Reader_SetEncoding(&t, encoding);
       
  1189 
       
  1190     /* Parse and generate WBXML. */
       
  1191     s = NW_XML_Parse(&t, &wbxmlEncodeCallbacks);
       
  1192     if (NW_STAT_IS_FAILURE(s)) {
       
  1193         NW_Uint32 column;
       
  1194         NW_XML_Reader_GetLineColumn(&t, line, &column);
       
  1195         if(pW->pStringTableObject)
       
  1196         {
       
  1197          NW_Encoder_StringTable_delete(pW->pStringTableObject);
       
  1198         }
       
  1199         NW_XML_XmlpWbxmlEncoder_Delete(wbxmlEncodeCallbacks.pClientPointer);
       
  1200         return s;
       
  1201     }
       
  1202 
       
  1203     /* The string table  support check and initialize parameter accordingly. */
       
  1204      
       
  1205 
       
  1206     NW_XML_StrTbl(&wbxmlEncodeCallbacks,WBXMLEncStrTbl);
       
  1207 
       
  1208     NW_XML_XmlpWbxmlEncoder_Delete(wbxmlEncodeCallbacks.pClientPointer);
       
  1209     (*ppOutBuf)->length = wbxmlBufLength;
       
  1210     (*ppOutBuf)->allocatedLength = wbxmlBufLength;
       
  1211     (*ppOutBuf)->data = pWbxmlBuf;
       
  1212     return NW_STAT_SUCCESS;
       
  1213 }
       
  1214 
       
  1215