xml/cxmllibrary/src/xmlp/src/XMLParser.cpp
branchRCL_3
changeset 21 604ca70b6235
parent 20 889504eac4fb
equal deleted inserted replaced
20:889504eac4fb 21:604ca70b6235
     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 "cxml_internal.h"
       
    19 #include <xml/cxml/nw_xmlp_xmlreader.h>
       
    20 #include <xml/cxml/nw_xmlp_xmlparser.h>
       
    21 #include <xml/cxml/nw_encoder_wbxmlwriter.h>
       
    22 
       
    23 
       
    24 #include "cxml_xmlp_entity.h"
       
    25 #include <xml/cxml/nw_string_string.h>
       
    26 #include "cxml_xmlp_int_entity.h"
       
    27 
       
    28 
       
    29 
       
    30 /* "<?" len 2 */
       
    31 #define NW_XML_String_PiFormStartLength 2
       
    32 static
       
    33 const NW_Uint8 NW_XML_String_PiFormStart[NW_XML_String_PiFormStartLength] =
       
    34 {
       
    35     '<', '?'
       
    36 };
       
    37 
       
    38 /* "?>" len 2 */
       
    39 #define NW_XML_String_PiFormStopLength 2
       
    40 static
       
    41 const NW_Uint8 NW_XML_String_PiFormStop[NW_XML_String_PiFormStopLength] =
       
    42 {
       
    43     '?', '>'
       
    44 };
       
    45 
       
    46 /* "version" len 7 */
       
    47 #define NW_XML_String_VersionLength 7
       
    48 static
       
    49 const NW_Uint8 NW_XML_String_Version[NW_XML_String_VersionLength] =
       
    50 {
       
    51     'v', 'e', 'r', 's', 'i', 'o', 'n'
       
    52 };
       
    53 
       
    54 /* "encoding" len 8 */
       
    55 #define NW_XML_String_EncodingLength 8
       
    56 static
       
    57 const NW_Uint8 NW_XML_String_Encoding[NW_XML_String_EncodingLength] =
       
    58 {
       
    59     'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g'
       
    60 };
       
    61 
       
    62 /* "standalone" len 10 */
       
    63 #define NW_XML_String_StandaloneLength 10
       
    64 static
       
    65 const NW_Uint8 NW_XML_String_Standalone[NW_XML_String_StandaloneLength] =
       
    66 {
       
    67     's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e'
       
    68 };
       
    69 
       
    70 /* "<!DOCTYPE" len 9 */
       
    71 #define NW_XML_String_DoctypeStartLength 9
       
    72 static
       
    73 const NW_Uint8 NW_XML_String_DoctypeStart[NW_XML_String_DoctypeStartLength] =
       
    74 {
       
    75     '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E'
       
    76 };
       
    77 
       
    78 /* "<!ENTITY" len 8 in the DTD */
       
    79 
       
    80 #define NW_XML_String_EntityStartLength 8
       
    81 static
       
    82 const NW_Uint8 NW_XML_String_EntityStart[NW_XML_String_EntityStartLength] =
       
    83 {
       
    84     '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y'
       
    85 };
       
    86 
       
    87 /* "<!--" len 4 comment start */
       
    88 #define NW_XML_String_CommentStartLength 4
       
    89 static
       
    90 const NW_Uint8 NW_XML_String_CommentStart[NW_XML_String_CommentStartLength] =
       
    91 {
       
    92     '<', '!', '-', '-'
       
    93 };
       
    94 
       
    95 /* "-->" len 3 comment end */
       
    96 #define NW_XML_String_CommentStopLength 3
       
    97 static
       
    98 const NW_Uint8 NW_XML_String_CommentStop[NW_XML_String_CommentStopLength] =
       
    99 {
       
   100     '-', '-', '>'
       
   101 };
       
   102 
       
   103 /* "/>" len 2 */
       
   104 #define NW_XML_String_EmptyTagEndLength 2
       
   105 static
       
   106 const NW_Uint8 NW_XML_String_EmptyTagEnd[NW_XML_String_EmptyTagEndLength] =
       
   107 {
       
   108     '/', '>'
       
   109 };
       
   110 
       
   111 /* "</" len 2 */
       
   112 #define NW_XML_String_EndTagStartLength 2
       
   113 static
       
   114 const NW_Uint8 NW_XML_String_EndTagStart[NW_XML_String_EndTagStartLength] =
       
   115 {
       
   116     '<', '/'
       
   117 };
       
   118 
       
   119 /* "<![CDATA[" len 9 */
       
   120 #define NW_XML_String_CdataStartLength 9
       
   121 static
       
   122 const NW_Uint8 NW_XML_String_CdataStart[NW_XML_String_CdataStartLength] =
       
   123 {
       
   124     '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '['
       
   125 };
       
   126 
       
   127 /* "]]>" len 3 */
       
   128 #define NW_XML_String_CdataEndLength 3
       
   129 static
       
   130 const NW_Uint8 NW_XML_String_CdataEnd[NW_XML_String_CdataEndLength] =
       
   131 {
       
   132     ']', ']', '>'
       
   133 };
       
   134 
       
   135 /* All case variations of "xml" */
       
   136 #define NW_XML_String_XmlNameVariationCount 8
       
   137 #define NW_XML_String_XmlLength 3
       
   138 static
       
   139 const NW_Uint8 NW_XML_String_XmlVariations[(NW_XML_String_XmlNameVariationCount
       
   140                                         * NW_XML_String_XmlLength)] =
       
   141 {
       
   142     'x', 'm', 'l', /* all lower case form must be first */
       
   143     'x', 'm', 'L',
       
   144     'x', 'M', 'l',
       
   145     'x', 'M', 'L',
       
   146     'X', 'm', 'l',
       
   147     'X', 'm', 'L',
       
   148     'X', 'M', 'l',
       
   149     'X', 'M', 'L'
       
   150 };
       
   151 
       
   152 
       
   153 /* Assumes position in Reader is at the first character of keyword.
       
   154 returns: *pMatch = 1 if found keyword and advanced over it, 0 if no match
       
   155 NOTE: Keyword match just means the string of keyword chars
       
   156 exists at the read position so it does not mean that the keyword
       
   157 is delimited at the end---it might be followed by more name chars. */
       
   158 static
       
   159 NW_Status_t
       
   160 NW_XML_Parse_KeywordConsume(NW_XML_Reader_t* pT, NW_XML_Reader_Interval_t* pI,
       
   161                             NW_Uint32 l, const NW_Uint8* pKeyword,
       
   162                             NW_Uint32* pMatch)
       
   163 {
       
   164     NW_Status_t s;
       
   165     NW_XML_Reader_Interval_Init(pI);
       
   166     s = NW_XML_Reader_AsciiStringMatch(pT, l, pKeyword, pMatch);
       
   167     if (NW_STAT_IS_SUCCESS(s) && *pMatch) {
       
   168         NW_XML_Reader_Interval_Start(pI, pT);
       
   169         NW_XML_Reader_AdvanceOffset(pT, l);
       
   170         NW_XML_Reader_Interval_Stop(pI, pT);
       
   171     }
       
   172     return s;
       
   173 }
       
   174 
       
   175 /*
       
   176 Parses an XML Name (productions 5, 4) in Reader.
       
   177 If no parse error, then *pI marks the Name.
       
   178 Assumes position in Reader is at the first character of name.
       
   179 returns: *pMatch = 1 if found name and advanced over it, 0 if no match
       
   180 */
       
   181 static
       
   182 NW_Status_t
       
   183 NW_XML_Parse_NameConsume(NW_XML_Reader_t* pT, NW_XML_Reader_Interval_t* pI,
       
   184                          NW_Uint32* pMatch)
       
   185 {
       
   186     /*
       
   187     [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':'
       
   188                      | CombiningChar | Extender
       
   189 
       
   190                      Note: combining and extender ignored here.
       
   191 
       
   192     [5] Name ::= (Letter | '_' | ':') (NameChar)*
       
   193     */
       
   194     NW_Status_t sl;
       
   195     NW_Uint32 isLetter;
       
   196     NW_Status_t su;
       
   197     NW_Uint32 isUnderscore;
       
   198     NW_Status_t sc;
       
   199     NW_Uint32 isColon;
       
   200     NW_Status_t sd = NW_STAT_SUCCESS;
       
   201     NW_Uint32 isDigit = 0;
       
   202     NW_Status_t sp = NW_STAT_SUCCESS;
       
   203     NW_Uint32 isPeriod = 0;
       
   204     NW_Status_t sh = NW_STAT_SUCCESS;
       
   205     NW_Uint32 isHyphen = 0;
       
   206     NW_Status_t s = NW_STAT_SUCCESS;
       
   207 
       
   208     sl = NW_XML_Reader_IsLetter(pT, &isLetter);
       
   209     su = NW_XML_Reader_AsciiCharMatch(pT, '_', &isUnderscore);
       
   210     sc = NW_XML_Reader_AsciiCharMatch(pT, ':', &isColon);
       
   211     *pMatch = 0;
       
   212     NW_XML_Reader_Interval_Init(pI);
       
   213     if (NW_STAT_IS_SUCCESS(sl) && NW_STAT_IS_SUCCESS(su)
       
   214         && NW_STAT_IS_SUCCESS(sc)) {
       
   215         if (isLetter | isUnderscore | isColon) {
       
   216             NW_XML_Reader_Interval_Start(pI, pT);
       
   217             while ((NW_STAT_IS_SUCCESS(sl) && NW_STAT_IS_SUCCESS(su)
       
   218                     && NW_STAT_IS_SUCCESS(sc) && NW_STAT_IS_SUCCESS(sd)
       
   219                     && NW_STAT_IS_SUCCESS(sp) && NW_STAT_IS_SUCCESS(sh)
       
   220                     && NW_STAT_IS_SUCCESS(s))
       
   221                    && (isLetter | isDigit | isPeriod | isHyphen | isUnderscore
       
   222                       | isColon )) {
       
   223                 s = NW_XML_Reader_Advance(pT);
       
   224                 sl = NW_XML_Reader_IsLetter(pT, &isLetter);
       
   225                 sd = NW_XML_Reader_IsDigit(pT, &isDigit);
       
   226                 sp = NW_XML_Reader_AsciiCharMatch(pT, '.', &isPeriod);
       
   227                 sh = NW_XML_Reader_AsciiCharMatch(pT, '-', &isHyphen);
       
   228                 su = NW_XML_Reader_AsciiCharMatch(pT, '_', &isUnderscore);
       
   229                 sc = NW_XML_Reader_AsciiCharMatch(pT, ':', &isColon);
       
   230             }
       
   231             NW_XML_Reader_Interval_Stop(pI, pT);
       
   232             *pMatch = 1;
       
   233         }
       
   234     }
       
   235     if (NW_STAT_IS_SUCCESS(sl) && NW_STAT_IS_SUCCESS(su)
       
   236         && NW_STAT_IS_SUCCESS(sc) && NW_STAT_IS_SUCCESS(sd)
       
   237         && NW_STAT_IS_SUCCESS(sp) && NW_STAT_IS_SUCCESS(sh)
       
   238         && NW_STAT_IS_SUCCESS(s)) {
       
   239         return NW_STAT_SUCCESS;
       
   240     }
       
   241     return NW_STAT_FAILURE;
       
   242 }
       
   243 
       
   244 /* This function reads data from the pT->pBuf and converts this data to
       
   245  * the NW_String_t. The string memory is allocated  here but it is freed
       
   246  * in the calling function.
       
   247  *
       
   248  * pT        --> Parser Structute (IN)
       
   249  * I_attrVal --> Attribute value Interval parameter (IN)
       
   250  * *dataStr   --> Output string (OUT)
       
   251  *
       
   252  * 
       
   253  */
       
   254 
       
   255 static NW_Status_t NW_XML_Data_to_String(NW_XML_Reader_t* pT, NW_XML_Reader_Interval_t* I_attrVal,
       
   256                              NW_String_t* dataStr)
       
   257 {
       
   258  NW_Uint8* pData;
       
   259  NW_Uint32 numbytes = 0;
       
   260  NW_Uint32 totalByteCount = 0;
       
   261  CXML_Uint8* tempAttrValBuf;
       
   262  CXML_Uint32 tempBufLen = 0;
       
   263  NW_Uint32 length;
       
   264  NW_Uint32 i =0;
       
   265  NW_Ucs2 c;
       
   266  NW_Status_t s;
       
   267 
       
   268      length = I_attrVal->stop - I_attrVal->start; 
       
   269      tempBufLen = length; //Desired bytes need to read.
       
   270 
       
   271      s = NW_XML_Reader_DataAddressFromBuffer(pT,I_attrVal->start,
       
   272                                              &tempBufLen,
       
   273                                              &tempAttrValBuf);
       
   274 
       
   275          if (NW_STAT_IS_FAILURE(s))
       
   276          {
       
   277             return s;
       
   278          }
       
   279 
       
   280         if (tempBufLen != length) 
       
   281         {
       
   282             return NW_STAT_FAILURE;
       
   283         }
       
   284 
       
   285 
       
   286  
       
   287     /* pData is not NULL terminated so need to use following method. The num byte
       
   288      * will be used for both pName and pVlaue.
       
   289      */
       
   290 
       
   291 
       
   292     numbytes = NW_String_readChar( (NW_Byte*) tempAttrValBuf,&c,pT->encoding);
       
   293 
       
   294     /* Calculate the length of string. Also add the number of characters 
       
   295      * required for the NULL termination.
       
   296      */
       
   297         
       
   298     totalByteCount = length + numbytes;
       
   299 
       
   300     pData = (NW_Uint8*) NW_Mem_Malloc(totalByteCount);
       
   301 
       
   302     if (pData != NULL) 
       
   303      {
       
   304       (void)NW_Mem_memcpy(pData , tempAttrValBuf, length );
       
   305 
       
   306 
       
   307        for(i=0; i < numbytes; i++)
       
   308        {
       
   309         pData[length+i] = '\0';
       
   310        }
       
   311       } /*end if (pName  != NULL)*/
       
   312      else
       
   313      {
       
   314       return NW_STAT_OUT_OF_MEMORY;
       
   315      }
       
   316 
       
   317      s = NW_String_initialize( dataStr , pData, pT->encoding);
       
   318 
       
   319      if (NW_STAT_IS_FAILURE(s))
       
   320      {
       
   321       return s;
       
   322      }
       
   323 
       
   324      /* This will the storage of the dataStr by the NW_String_delete() */
       
   325 
       
   326      dataStr->length |= 0x80000000;
       
   327 
       
   328  return NW_STAT_SUCCESS;
       
   329 
       
   330 }/*end NW_XML_Data_to_String()*/
       
   331 
       
   332 /* Assumes position in Reader is at the opening quote character for value. 
       
   333 * BUG not yet spec compliant.
       
   334 * The following function is called for Process Instruction and Element
       
   335 * attribute consume. The predefined entities will be handled in 
       
   336 * element attributes only. So, the "entity" parameter is used to 
       
   337 * distinguish between these two cases.
       
   338 * Careful about the "entity" parameter passed. This is used both as 
       
   339 * IN/OUT paramter.
       
   340 
       
   341 *  IN --> if(entity == CXML_TRUE): Then parse attribute value for the
       
   342 *         entities.
       
   343 
       
   344 *  OUT --> (entity=CXML_TRUE): The entity is found in the attribute value.
       
   345 
       
   346 */
       
   347 
       
   348 static
       
   349 NW_Status_t
       
   350 NW_XML_Parse_ValueConsume(NW_XML_Reader_t* pT, NW_XML_Reader_Interval_t* pI,
       
   351 						  CXML_Bool* entityCheck, NW_String_t* attrValStr,
       
   352                           const RPointerArray <CXML_Internal_Entity_t>*  internalEntityList)
       
   353 {
       
   354     /*
       
   355     Literal data is any quoted string not containing the quotation mark
       
   356     used as a delimiter for that string.
       
   357 
       
   358     [10] AttValue ::=   '"' ([^<&"] | Reference)* '"'
       
   359                       | "'" ([^<&'] | Reference)* "'"
       
   360     */
       
   361 
       
   362     /* BUG this only pays attention to the quote chars not the value
       
   363     so it ignores [<&]. */
       
   364     NW_Status_t s;
       
   365     NW_Status_t ssq;
       
   366     NW_Uint32 isOpenSingleQuote;
       
   367     NW_Uint32 isCloseSingleQuote = 0;
       
   368     NW_Status_t sdq;
       
   369     NW_Uint32 isOpenDoubleQuote;
       
   370     NW_Uint32 isCloseDoubleQuote = 0;
       
   371     NW_Status_t slt;
       
   372     NW_Uint32 isLessThan;
       
   373 
       
   374 	NW_Uint32 prevIndex;
       
   375 	NW_Uint32 prevCharIndex;
       
   376 	NW_XML_Reader_LineColumn_t prevLineColumn;
       
   377     CXML_Uint8* intEntityValStr = NULL;
       
   378     CXML_Uint32 tempBufLen = 0;
       
   379 	NW_String_t* tempStr = NULL;
       
   380 	NW_String_t entityValStr;
       
   381     CXML_Bool entityFoundLevel_2 =  NW_FALSE;
       
   382 	CXML_Bool entityFoundOnce = NW_FALSE;
       
   383 	NW_String_initialize (&entityValStr, NULL, 0);
       
   384 	
       
   385 
       
   386 
       
   387 
       
   388     NW_XML_Reader_Interval_Init(pI);
       
   389     ssq = NW_XML_Reader_AsciiCharMatch(pT, '\'', &isOpenSingleQuote);
       
   390     sdq = NW_XML_Reader_AsciiCharMatch(pT, '\"', &isOpenDoubleQuote);
       
   391     if (NW_STAT_IS_FAILURE(sdq) || NW_STAT_IS_FAILURE(ssq)
       
   392         || (!isOpenSingleQuote && !isOpenDoubleQuote)) {
       
   393         return NW_STAT_FAILURE;
       
   394     }
       
   395     /* xor, mutually exclusive */
       
   396     NW_ASSERT(isOpenSingleQuote ^ isOpenDoubleQuote);
       
   397     s = NW_XML_Reader_Advance(pT);
       
   398     if (NW_STAT_IS_FAILURE(s)) {
       
   399         return NW_STAT_FAILURE;
       
   400     }
       
   401     NW_XML_Reader_Interval_Start(pI, pT);
       
   402     for (;;) {
       
   403 
       
   404         /* Check for the closing quotes. If this is empty attribute value 
       
   405          * then no need for the checking the entities.
       
   406          */
       
   407 
       
   408         if (isOpenSingleQuote) {
       
   409             ssq = NW_XML_Reader_AsciiCharMatch(pT, '\'', &isCloseSingleQuote);
       
   410         }
       
   411         if (isOpenDoubleQuote) {
       
   412             sdq = NW_XML_Reader_AsciiCharMatch(pT, '\"', &isCloseDoubleQuote);
       
   413         }
       
   414         slt = NW_XML_Reader_AsciiCharMatch(pT, '<', &isLessThan);
       
   415         if (NW_STAT_IS_FAILURE(ssq) || NW_STAT_IS_FAILURE(sdq)
       
   416             || NW_STAT_IS_FAILURE(slt) || isLessThan) {
       
   417             return NW_STAT_FAILURE;
       
   418         }
       
   419 
       
   420 
       
   421         if( (*entityCheck == CXML_TRUE) && !isCloseSingleQuote && !isCloseDoubleQuote)
       
   422         {
       
   423             NW_Uint32 match;
       
   424 
       
   425             s = NW_XML_Reader_AsciiCharMatch(pT, '&', &match); 
       
   426 
       
   427 		    if (NW_STAT_IS_FAILURE(s))
       
   428 		    {
       
   429                 return NW_STAT_FAILURE;
       
   430             }
       
   431             if (match) 
       
   432 		    {
       
   433               NW_XML_Reader_Interval_t I_entityData;
       
   434 		      NW_Bool entityFoundLevel_1 =  NW_FALSE; //If end of entity (;) found
       
   435 		      NW_Uint32 entityVal = 0;
       
   436 		      NW_XML_Reader_Interval_t* I_attrVal = pI;
       
   437               
       
   438 
       
   439 
       
   440 		      entityFoundLevel_2 =  NW_FALSE;
       
   441               NW_XML_Reader_Interval_Stop(I_attrVal, pT); //Contents before entity
       
   442              
       
   443 			  //Will back if not a valid entity
       
   444 			  NW_XML_Reader_GetPosition(pT,
       
   445                               &prevIndex, &prevCharIndex, &prevLineColumn);
       
   446 
       
   447 		      s = CXML_XML_Parser_Entity(pT,&I_entityData,&entityFoundLevel_1);
       
   448 
       
   449                 if (NW_STAT_IS_FAILURE(s))
       
   450 		        {
       
   451                     return NW_STAT_FAILURE;
       
   452                 }
       
   453                /*
       
   454                 if(entityFoundLevel_1 == NW_FALSE)
       
   455                 {
       
   456                   return NW_STAT_XHTML_BAD_CONTENT;
       
   457                 }
       
   458                 */
       
   459 		      if (entityFoundLevel_1) 
       
   460               {
       
   461 			    // Validate the entity
       
   462                 // The following function checks for the character,
       
   463                 // predefined and Internal Entities.
       
   464 
       
   465                 if( (I_entityData.stop - I_entityData.start) > 0)
       
   466                 {
       
   467 			    s = CXML_XML_Handle_entity(pT,
       
   468                                            &I_entityData,&entityVal,&intEntityValStr,
       
   469                                            &entityFoundLevel_2,
       
   470                                            (void*) internalEntityList);
       
   471                 }
       
   472                 else
       
   473                 {
       
   474                  //Not a valid entity e.g. "&&;" test case
       
   475                  entityFoundLevel_2 = NW_FALSE;
       
   476                 }
       
   477 
       
   478 			    if (NW_STAT_IS_FAILURE(s)) 
       
   479 			    {
       
   480 			     return NW_STAT_FAILURE;
       
   481 			    }
       
   482 
       
   483                 if(entityFoundLevel_2 == CXML_TRUE)
       
   484 			    {
       
   485                  /* Read contents before entity*/
       
   486 
       
   487                    tempBufLen = I_attrVal->stop - I_attrVal->start; 
       
   488 
       
   489 				   if(tempBufLen > 0)
       
   490 				   {
       
   491 
       
   492                     if(tempStr == NULL)
       
   493 					 {
       
   494 					  tempStr = NW_String_new();
       
   495 					  if(tempStr == NULL)
       
   496 					  {
       
   497 					   return NW_STAT_OUT_OF_MEMORY;
       
   498                       }
       
   499 					  
       
   500                     } /*end if(tempStr == NULL)*/
       
   501 
       
   502                     s = NW_XML_Data_to_String (pT,I_attrVal,tempStr);
       
   503                                                           
       
   504                     if (NW_STAT_IS_FAILURE(s))
       
   505                     {
       
   506                      return s;
       
   507                     }
       
   508 
       
   509 					 s = NW_String_concatenate(attrValStr,tempStr,pT->encoding);
       
   510 
       
   511 
       
   512 					 if (NW_STAT_IS_FAILURE(s))
       
   513                      {
       
   514                       return s;
       
   515                      }
       
   516                     
       
   517                     // Do some clean up
       
   518 
       
   519 					if(tempStr != NULL)
       
   520 					{
       
   521 					 NW_String_delete(tempStr);
       
   522 					 tempStr = NULL;
       
   523 					}
       
   524 
       
   525 				   }//end if(tempBufLen > 0)
       
   526 
       
   527                  // Write the entity content now. There are two possibilities for entities.
       
   528                  //
       
   529                  // 1) If it is character or decimal or predefined entities. 
       
   530                  //    In this case, intEntityValStr = NULL.
       
   531                  //
       
   532                  // 2) If it is "Internal Entity" then In this case, entityVal = 0;
       
   533 
       
   534                    if (intEntityValStr == NULL)
       
   535                    {
       
   536 
       
   537                     /* convert contents of the character/predfined entity to string */    
       
   538 
       
   539 				     s = NW_String_entityToString(entityVal,&entityValStr,pT->encoding);
       
   540 
       
   541 					 if (NW_STAT_IS_FAILURE(s))
       
   542                      {
       
   543                       return s;
       
   544                      }
       
   545                    }/*end if (intEntityValStr == NULL)*/
       
   546                    else if(entityVal == 0)
       
   547                    {
       
   548                         /* This is a internal entity string */
       
   549 
       
   550                          s = NW_String_initialize(&entityValStr,intEntityValStr,pT->encoding);
       
   551                          if (NW_STAT_IS_FAILURE(s))
       
   552                          {
       
   553                           return s;
       
   554                          }
       
   555                    } /*end else if(entityVal == 0)*/
       
   556 
       
   557                      /* Add this entity value to the string */
       
   558 			
       
   559 					 s = NW_String_concatenate(attrValStr,&entityValStr,pT->encoding);
       
   560 
       
   561 					 if (NW_STAT_IS_FAILURE(s))
       
   562                      {
       
   563                       return s;
       
   564                      }
       
   565                   
       
   566 
       
   567 				
       
   568 					if(entityValStr.storage != NULL)
       
   569                     {
       
   570                      NW_Mem_Free (entityValStr.storage);
       
   571                     }
       
   572                     // Initialize the entity string for next entity 
       
   573 
       
   574 					NW_String_initialize (&entityValStr, NULL, 0);
       
   575 
       
   576                    //Again start the top level interval
       
   577 
       
   578                     NW_XML_Reader_Interval_Init(pI);
       
   579                     NW_XML_Reader_Interval_Start(pI, pT);
       
   580 
       
   581 					/*Check for the closing quotes after entity parsing */
       
   582 
       
   583 					if (isOpenSingleQuote) {
       
   584 						ssq = NW_XML_Reader_AsciiCharMatch(pT, '\'', &isCloseSingleQuote);
       
   585 					}
       
   586 					if (isOpenDoubleQuote) {
       
   587 						sdq = NW_XML_Reader_AsciiCharMatch(pT, '\"', &isCloseDoubleQuote);
       
   588 					}
       
   589 					slt = NW_XML_Reader_AsciiCharMatch(pT, '<', &isLessThan);
       
   590 					if (NW_STAT_IS_FAILURE(ssq) || NW_STAT_IS_FAILURE(sdq)
       
   591 						|| NW_STAT_IS_FAILURE(slt) || isLessThan) {
       
   592 						return NW_STAT_FAILURE;
       
   593 					}
       
   594 					entityFoundOnce = CXML_TRUE;
       
   595 			    }//endif(entityFoundLevel_2 == CXML_TRUE)
       
   596                 else
       
   597                 {
       
   598                  /* If it is here, the entity is not well formed or a entity is
       
   599                   * not supported. But, it is error for now. 
       
   600                   */
       
   601                 /*
       
   602                    return NW_STAT_XHTML_BAD_CONTENT;*/
       
   603 
       
   604                 //No valid entity found. Parse as the normal string
       
   605                  NW_XML_Reader_SetPosition(pT,
       
   606                                         prevIndex,
       
   607                                         prevCharIndex,
       
   608                                         &prevLineColumn);
       
   609                 }
       
   610                 
       
   611              } //end if (entityFound && inContent)
       
   612 			else
       
   613 			{
       
   614 			 //No valid entity found. Parse as the normal string
       
   615 			  NW_XML_Reader_SetPosition(pT,
       
   616                                         prevIndex,
       
   617                                         prevCharIndex,
       
   618                                         &prevLineColumn);
       
   619 			}//end else
       
   620 		  } //end match
       
   621         } //end if( !isCloseSingleQuote && !isCloseDoubleQuote)
       
   622 
       
   623 
       
   624 
       
   625         if ((isOpenSingleQuote & isCloseSingleQuote)
       
   626             | (isOpenDoubleQuote & isCloseDoubleQuote)) {
       
   627             break;
       
   628         }
       
   629 
       
   630 		if(entityFoundLevel_2 != CXML_TRUE)
       
   631 		{
       
   632          s = NW_XML_Reader_Advance(pT);
       
   633 		}
       
   634 		else
       
   635 		{
       
   636 		 entityFoundLevel_2 = CXML_FALSE;
       
   637 		}
       
   638     }//end for (;;)
       
   639     NW_XML_Reader_Interval_Stop(pI, pT);
       
   640     s = NW_XML_Reader_Advance(pT);
       
   641 
       
   642     
       
   643     if( (*entityCheck == CXML_TRUE) && 
       
   644 		( (entityFoundLevel_2 == CXML_TRUE) || (entityFoundOnce == CXML_TRUE) ) )
       
   645     {
       
   646       /* Get rest of the attribute value contents */
       
   647      
       
   648 		
       
   649        tempBufLen = pI->stop - pI->start; 
       
   650 
       
   651 		if(tempBufLen > 0)
       
   652 		{
       
   653          if(tempStr == NULL)
       
   654 		 {
       
   655 		  tempStr = NW_String_new();
       
   656 		  if(tempStr == NULL)
       
   657 		  {
       
   658 		   return NW_STAT_OUT_OF_MEMORY;
       
   659           }
       
   660 		  
       
   661          } /*end if(tempStr == NULL)*/
       
   662         s = NW_XML_Data_to_String (pT,pI,tempStr);
       
   663 
       
   664         if (NW_STAT_IS_FAILURE(s))
       
   665          {
       
   666           return s;
       
   667          }
       
   668 
       
   669 
       
   670 			s = NW_String_concatenate(attrValStr,tempStr,pT->encoding);
       
   671 
       
   672 			if (NW_STAT_IS_FAILURE(s))
       
   673              {
       
   674               return s;
       
   675              }
       
   676 
       
   677             // Do some clean up
       
   678 
       
   679 			if(tempStr != NULL)
       
   680 			{
       
   681 			 NW_String_delete(tempStr);
       
   682 			 tempStr = NULL;
       
   683 			}
       
   684 
       
   685 		}//endif(tempBufLen > 0)
       
   686 
       
   687     }//end if( (*entityCheck == CXML_TRUE) && (entityFoundLevel_2 == CXML_TRUE) )
       
   688 	else
       
   689 	{
       
   690 	 *entityCheck = CXML_FALSE;
       
   691 	}
       
   692 
       
   693     return s;
       
   694 }
       
   695 
       
   696 /*
       
   697 Parses an XML attribute (production ???) in Reader.
       
   698 If no parse error, then ti_name and ti_attvalue mark the two items.
       
   699 Allows for leading whitespace.  If l is > 0 then p is a "string" of
       
   700 length l that is the name that must match (parse error if doesn't).
       
   701 Assumes position in Reader is at whitespace before or first character
       
   702 of attribute.
       
   703 return: *pMatch = 1 if keyword or attribute name found
       
   704 
       
   705  Careful about the "entity" parameter passed. This is used both as 
       
   706  IN/OUT paramter.
       
   707 
       
   708   IN --> if(entity == CXML_TRUE): Then parse attribute value for the
       
   709          entities.
       
   710 
       
   711   OUT --> (entity=CXML_TRUE): The entity is found in the attribute value.
       
   712 */
       
   713 
       
   714 
       
   715 static
       
   716 NW_Status_t
       
   717 NW_XML_Parse_AttributeValueConsume(NW_XML_Reader_t* pT,
       
   718                                    NW_XML_Reader_Interval_t* pI_name,
       
   719                                    NW_XML_Reader_Interval_t* pI_attvalue,
       
   720                                    NW_Uint32 l, const NW_Uint8* pKeyword,
       
   721                                    NW_Uint32* pMatch,
       
   722 								   CXML_Bool* entity, NW_String_t*  attrValStr,
       
   723                                    const RPointerArray <CXML_Internal_Entity_t>*  internalEntityList)
       
   724 {
       
   725     /*
       
   726     [41] Attribute ::= Name Eq AttValue
       
   727     where Name is possibly a keyword that must match
       
   728     */
       
   729     NW_Status_t s;
       
   730     NW_Uint32 match;
       
   731     NW_Uint32 prevIndex0;
       
   732     NW_Uint32 prevIndex1;
       
   733     NW_Uint32 prevCharIndex0;
       
   734     NW_Uint32 prevCharIndex1;
       
   735     NW_XML_Reader_LineColumn_t prevLineColumn0;
       
   736     NW_XML_Reader_LineColumn_t prevLineColumn1;
       
   737 
       
   738     *pMatch = 0;
       
   739 
       
   740     /* S mandatory */
       
   741     NW_XML_Reader_GetPosition(pT, &prevIndex0, &prevCharIndex0, &prevLineColumn0);
       
   742     s = NW_XML_Reader_SkipSpace(pT);
       
   743     if (NW_STAT_IS_FAILURE(s)) {
       
   744         return s;
       
   745     }
       
   746     NW_XML_Reader_GetPosition(pT, &prevIndex1, &prevCharIndex1, &prevLineColumn1);
       
   747     if (prevIndex0 == prevIndex1) {
       
   748         return NW_STAT_FAILURE;
       
   749     }
       
   750     /* Name */
       
   751     if ((l != 0U) && (pKeyword != NULL)) {
       
   752         s = NW_XML_Parse_KeywordConsume(pT, pI_name, l, pKeyword, pMatch);
       
   753         if (NW_STAT_IS_SUCCESS(s) && !*pMatch) {
       
   754             /* backup so mandatory space not consumed */
       
   755             NW_XML_Reader_SetPosition(pT, prevIndex0, prevCharIndex0, &prevLineColumn0);
       
   756         }
       
   757     } else {
       
   758         s = NW_XML_Parse_NameConsume(pT, pI_name, pMatch);
       
   759     }
       
   760     if (NW_STAT_IS_FAILURE(s) || !*pMatch) {
       
   761         return NW_STAT_FAILURE;
       
   762     }
       
   763     /* S */
       
   764     s = NW_XML_Reader_SkipSpace(pT);
       
   765     if (NW_STAT_IS_FAILURE(s)) {
       
   766         return s;
       
   767     }
       
   768     /* = */
       
   769     s = NW_XML_Reader_AsciiCharMatch(pT, '=', &match);
       
   770     if (NW_STAT_IS_FAILURE(s) || !match) {
       
   771         return NW_STAT_FAILURE;
       
   772     }
       
   773     s = NW_XML_Reader_Advance(pT);
       
   774     if (NW_STAT_IS_FAILURE(s)) {
       
   775         return NW_STAT_FAILURE;
       
   776     }
       
   777     /* S */
       
   778     s = NW_XML_Reader_SkipSpace(pT);
       
   779     if (NW_STAT_IS_FAILURE(s)) {
       
   780         return s;
       
   781     }
       
   782     /* attValue */
       
   783 
       
   784    if(*entity == CXML_FALSE)
       
   785    {
       
   786     return NW_XML_Parse_ValueConsume(pT, pI_attvalue,entity,NULL, internalEntityList);  
       
   787    }
       
   788    else
       
   789    {
       
   790     return NW_XML_Parse_ValueConsume(pT, pI_attvalue,entity,attrValStr, internalEntityList);
       
   791    }
       
   792 }
       
   793 
       
   794 /*
       
   795 Parses an XML Comment (production 15) in Reader.
       
   796 If no parse error, then ti marks the Comment--all chars
       
   797 between the start and end marks including spaces.
       
   798 Assumes position in Reader is the character after "<!--".
       
   799 */
       
   800 static
       
   801 NW_Status_t
       
   802 NW_XML_Parse_CommentConsume(NW_XML_Reader_t* pT, NW_XML_Reader_Interval_t* pI,
       
   803                             const struct NW_XML_Parser_EventCallbacks_s* pE)
       
   804 {
       
   805     /*
       
   806     [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
       
   807 
       
   808     Note: the pattern with (Char - '-') means that the comment cannot
       
   809     end with '--->' although it can begin with '<!--...'.
       
   810 
       
   811     Also, '--' may not appear in a comment.
       
   812     BUG not yet implemented
       
   813     */
       
   814     NW_Status_t s;
       
   815     NW_Uint32 match;
       
   816 
       
   817     NW_XML_Reader_Interval_Start(pI, pT);
       
   818     for (;;) {
       
   819         s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_CommentStopLength,
       
   820                                         NW_XML_String_CommentStop, &match);
       
   821         if (NW_STAT_IS_FAILURE(s)) {
       
   822             return NW_STAT_FAILURE;
       
   823         }
       
   824         if (match) {
       
   825             break;
       
   826         }
       
   827         s = NW_XML_Reader_Advance(pT);
       
   828         if (NW_STAT_IS_FAILURE(s)) {
       
   829             return NW_STAT_FAILURE;
       
   830         }
       
   831     }
       
   832     NW_XML_Reader_Interval_Stop(pI, pT);
       
   833     s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_CommentStopLength);
       
   834     NW_ASSERT(NW_STAT_IS_SUCCESS(s)); /* should never fail */
       
   835     if (pE->Comment_CB != NULL) {
       
   836         s = (*(pE->Comment_CB))(pT, pI, pE->pClientPointer);
       
   837     }
       
   838     return s;
       
   839 }
       
   840 
       
   841 /*
       
   842 Parses things that start with "<?".  These are XMLDecl, TextDecl and
       
   843 the Processing Instruction.  On return the formType distinguishes which one
       
   844 was consumed.  If it was a PI then ti_name marks the PITarget and
       
   845 ti_content marks the text "argument" of the PI.  If it was an XMLDecl
       
   846 (or TextDecl) then examine the booleans to see if various attributes appeared.
       
   847 Note that XMLDecl must have VersionInfo and a TextDecl must not have an SDDecl.
       
   848 Neither XMLDecl or TextDecl should have additional content
       
   849 (i.e., *ti_contentValid should be 0).
       
   850 Assumes position in Reader is the character after "<?".
       
   851 */
       
   852 static
       
   853 NW_Status_t
       
   854 NW_XML_Parse_PiFormConsume(NW_XML_Reader_t* pT, NW_PiFormTypeTag_t* pFormType,
       
   855                            NW_Uint32* pNameValid,
       
   856                            NW_XML_Reader_Interval_t* pI_name,
       
   857                            NW_Uint32* pVersionValid,
       
   858                            NW_XML_Reader_Interval_t* pI_version,
       
   859                            NW_Uint32* pEncodingValid,
       
   860                            NW_XML_Reader_Interval_t* pI_encoding,
       
   861                            NW_Uint32* pStandaloneValid,
       
   862                            NW_XML_Reader_Interval_t* pI_standalone,
       
   863                            NW_Uint32* pContentValid,
       
   864                            NW_XML_Reader_Interval_t* pI_content,
       
   865                            const RPointerArray <CXML_Internal_Entity_t>*  internalEntityList)
       
   866 {
       
   867     /*
       
   868     [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
       
   869 
       
   870     [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
       
   871 
       
   872     when name is an XMLDecl or TextDecl then parse according to
       
   873 
       
   874     [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
       
   875 
       
   876     [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
       
   877 
       
   878     [24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'"
       
   879                          | '"' VersionNum '"')
       
   880 
       
   881     [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
       
   882 
       
   883     [80] EncodingDecl ::= S 'encoding' Eq
       
   884                           ('"' EncName '"' | "'" EncName "'" )
       
   885 
       
   886     [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
       
   887 
       
   888     [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'")
       
   889                     | ('"' ('yes' | 'no') '"'))
       
   890 
       
   891     */
       
   892     NW_Status_t s;
       
   893     NW_XML_Reader_Interval_t I_keyword;
       
   894     NW_Uint32 prevIndex;
       
   895     NW_Uint32 prevCharIndex;
       
   896     NW_XML_Reader_LineColumn_t prevLineColumn;
       
   897     NW_Uint32 match;
       
   898     NW_Uint32 i;
       
   899 	CXML_Bool entity = CXML_FALSE;
       
   900 
       
   901 
       
   902     *pNameValid = *pVersionValid = *pEncodingValid = 0;
       
   903     *pStandaloneValid = *pContentValid = 0;
       
   904     *pFormType = UNKNOWFORM;
       
   905 
       
   906 
       
   907     s = NW_STAT_FAILURE;
       
   908     match = 0;
       
   909     /* Will back up if "xml" is part of a longer name like "xml-stylesheet". */
       
   910     NW_XML_Reader_GetPosition(pT,
       
   911                               &prevIndex, &prevCharIndex, &prevLineColumn);
       
   912     for (i = 0; i < NW_XML_String_XmlNameVariationCount; i++) {
       
   913         s = NW_XML_Parse_KeywordConsume(pT, pI_name,
       
   914                                         NW_XML_String_XmlLength,
       
   915                                         (NW_XML_String_XmlVariations
       
   916                                          + NW_XML_String_XmlLength * i),
       
   917                                         &match);
       
   918         if (NW_STAT_IS_SUCCESS(s) && match) {
       
   919             /* Make sure that the "xml" variant isn't part of a longer name */
       
   920             NW_Uint32 m;
       
   921             /* look for end of piform */
       
   922             s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_PiFormStopLength,
       
   923                                             NW_XML_String_PiFormStop, &m);
       
   924             if (NW_STAT_IS_SUCCESS(s) && m) {
       
   925                 break;
       
   926             }
       
   927             /* look for whitespace */
       
   928             s = NW_XML_Reader_IsSpace(pT, &m);
       
   929             if (NW_STAT_IS_SUCCESS(s) && m) {
       
   930                 break;
       
   931             }
       
   932             /* if get here then "xml" variant is part of a longer name,
       
   933             fail match, back up and shortcut out of loop */
       
   934             match = 0;
       
   935             NW_XML_Reader_SetPosition(pT,
       
   936                                       prevIndex,
       
   937                                       prevCharIndex,
       
   938                                       &prevLineColumn);
       
   939             i = NW_XML_String_XmlNameVariationCount;
       
   940             break;
       
   941         }
       
   942     }
       
   943 
       
   944     if (NW_STAT_IS_SUCCESS(s) && !match) {
       
   945         s = NW_XML_Parse_NameConsume(pT, pI_name, &match);
       
   946     }
       
   947     if (NW_STAT_IS_FAILURE(s) || !match) {
       
   948         return NW_STAT_FAILURE;
       
   949     }
       
   950     *pNameValid = 1;
       
   951 
       
   952     /* Support all the XML declaration starting with any possible combination. */
       
   953 
       
   954     if (i < NW_XML_String_XmlNameVariationCount) 
       
   955     { 
       
   956         /* BUG there is currently no checking of legal values according
       
   957         to productions 26, 81 and 32 */
       
   958         *pFormType = XMLDECL;
       
   959         s = NW_XML_Parse_AttributeValueConsume(pT, &I_keyword, pI_version,
       
   960                                                NW_XML_String_VersionLength,
       
   961                                                NW_XML_String_Version, &match,
       
   962 											   &entity,NULL,
       
   963                                                internalEntityList);
       
   964         if (NW_STAT_IS_FAILURE(s)) {
       
   965             if (match) {
       
   966                 return NW_STAT_FAILURE; /* couldn't parse version value */
       
   967             }
       
   968         } else {
       
   969             if (match) {
       
   970                 *pVersionValid = 1;
       
   971             }
       
   972         }
       
   973         s = NW_XML_Parse_AttributeValueConsume(pT, &I_keyword, pI_encoding,
       
   974                                                NW_XML_String_EncodingLength,
       
   975                                                NW_XML_String_Encoding, &match,
       
   976 											   &entity,NULL,internalEntityList);
       
   977         if (NW_STAT_IS_FAILURE(s)) {
       
   978             if (match) {
       
   979                 return NW_STAT_FAILURE; /* couldn't parse encoding value */
       
   980             }
       
   981         } else {
       
   982             if (match) {
       
   983                 *pEncodingValid = 1;
       
   984             }
       
   985         }
       
   986         s = NW_XML_Parse_AttributeValueConsume(pT, &I_keyword, pI_standalone,
       
   987                                                NW_XML_String_StandaloneLength,
       
   988                                                NW_XML_String_Standalone, &match,
       
   989 											   &entity,NULL,internalEntityList);
       
   990         if (NW_STAT_IS_FAILURE(s)) {
       
   991             if (match) {
       
   992                 return NW_STAT_FAILURE; /* couldn't parse standalone value */
       
   993             }
       
   994         } else {
       
   995             if (match) {
       
   996                 *pStandaloneValid = 1;
       
   997             }
       
   998         }
       
   999     } else {
       
  1000         *pFormType = PI;
       
  1001     }
       
  1002     s = NW_XML_Reader_SkipSpace(pT);
       
  1003     if (NW_STAT_IS_FAILURE(s)) {
       
  1004         return NW_STAT_FAILURE;
       
  1005     }
       
  1006     NW_XML_Reader_Interval_Start(pI_content, pT);
       
  1007     for (;;) {
       
  1008         s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_PiFormStopLength,
       
  1009                                         NW_XML_String_PiFormStop, &match);
       
  1010         if (NW_STAT_IS_FAILURE(s)) {
       
  1011             return NW_STAT_FAILURE;
       
  1012         }
       
  1013         if (match) {
       
  1014             break;
       
  1015         }
       
  1016         s = NW_XML_Reader_Advance(pT);
       
  1017         if (NW_STAT_IS_FAILURE(s)) {
       
  1018             return NW_STAT_FAILURE;
       
  1019         }
       
  1020     }
       
  1021     NW_XML_Reader_Interval_Stop(pI_content, pT);
       
  1022     if (pI_content->start == pI_content->stop) {
       
  1023         *pContentValid = 0;
       
  1024     } else {
       
  1025         *pContentValid = 1;
       
  1026     }
       
  1027     s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_PiFormStopLength);
       
  1028     NW_ASSERT(NW_STAT_IS_SUCCESS(s)); /* should never fail */
       
  1029     return s;
       
  1030 }
       
  1031 
       
  1032 /* Assumes position is either at whitespace or beginning of text. */
       
  1033 static
       
  1034 NW_Status_t
       
  1035 NW_XML_Parse_MiscConsume(NW_XML_Reader_t* pT,
       
  1036                          const struct NW_XML_Parser_EventCallbacks_s* pE,
       
  1037                          const RPointerArray <CXML_Internal_Entity_t>*  internalEntityList)
       
  1038 {
       
  1039     /*
       
  1040     [27] Misc ::= Comment | PI | S
       
  1041 
       
  1042     Note: All invocations of this production take the form "Misc*"
       
  1043     */
       
  1044     NW_Status_t s;
       
  1045     NW_XML_Reader_Interval_t I;
       
  1046     NW_Uint32 match;
       
  1047     NW_Uint32 prevIndex0; /* will do while there is advancement thru Reader */
       
  1048     NW_Uint32 prevIndex1; /* will do while there is advancement thru Reader */
       
  1049     NW_Uint32 prevCharIndex; /* ignored */
       
  1050     NW_XML_Reader_LineColumn_t prevLineColumn; /* ignored */
       
  1051     do {
       
  1052         NW_XML_Reader_GetPosition(pT, &prevIndex0, &prevCharIndex, &prevLineColumn);
       
  1053         s = NW_XML_Reader_SkipSpace(pT);
       
  1054         if (NW_STAT_IS_FAILURE(s)) {
       
  1055             return NW_STAT_FAILURE;
       
  1056         }
       
  1057 
       
  1058         if(pT->end){
       
  1059             break;
       
  1060         }
       
  1061         s = NW_XML_Parse_KeywordConsume(pT, &I,
       
  1062                                         NW_XML_String_CommentStartLength,
       
  1063                                         NW_XML_String_CommentStart, &match);
       
  1064         if (NW_STAT_IS_FAILURE(s)) {
       
  1065             return NW_STAT_FAILURE;
       
  1066         }
       
  1067         if (match) {
       
  1068             s = NW_XML_Parse_CommentConsume(pT, &I, pE);
       
  1069             if (NW_STAT_IS_FAILURE(s)) {
       
  1070                 return NW_STAT_FAILURE;
       
  1071             }
       
  1072         } else {
       
  1073             s = NW_XML_Parse_KeywordConsume(pT, &I,
       
  1074                                             NW_XML_String_PiFormStartLength,
       
  1075                                             NW_XML_String_PiFormStart, &match);
       
  1076             if (NW_STAT_IS_FAILURE(s)) {
       
  1077                 return NW_STAT_FAILURE;
       
  1078             }
       
  1079             if (match) {
       
  1080                 NW_PiFormTypeTag_t pi_type;
       
  1081                 NW_XML_Reader_Interval_t I_name, I_version, I_encoding, I_standalone;
       
  1082                 NW_XML_Reader_Interval_t I_content;
       
  1083                 NW_Uint32 nameValid, versionValid, encodingValid, standaloneValid;
       
  1084                 NW_Uint32 contentValid;
       
  1085                 s = NW_XML_Parse_PiFormConsume(pT, &pi_type,
       
  1086                                                &nameValid,
       
  1087                                                &I_name,
       
  1088                                                &versionValid,
       
  1089                                                &I_version,
       
  1090                                                &encodingValid,
       
  1091                                                &I_encoding,
       
  1092                                                &standaloneValid,
       
  1093                                                &I_standalone,
       
  1094                                                &contentValid,
       
  1095                                                &I_content,
       
  1096                                                internalEntityList);
       
  1097                 if (NW_STAT_IS_FAILURE(s) || !nameValid) {
       
  1098                     return NW_STAT_FAILURE;
       
  1099                 }
       
  1100                 if (pi_type != PI) {
       
  1101                     /* BUG Is this really an illegal case? */
       
  1102                     return NW_STAT_FAILURE;
       
  1103                 }
       
  1104                 if (pE->PiForm_CB != NULL) {
       
  1105                     s = (*(pE->PiForm_CB))(pT, pi_type,
       
  1106                                            (nameValid ? &I_name : NULL),
       
  1107                                            (versionValid ? &I_version : NULL),
       
  1108                                            (encodingValid ? &I_encoding : NULL),
       
  1109                                            (standaloneValid ? &I_standalone : NULL),
       
  1110                                            (contentValid ? &I_content : NULL),
       
  1111                                            pE->pClientPointer);
       
  1112                 }
       
  1113             }
       
  1114         }
       
  1115         NW_XML_Reader_GetPosition(pT, &prevIndex1, &prevCharIndex, &prevLineColumn);
       
  1116     } while (prevIndex0 != prevIndex1); /* do while */
       
  1117     return NW_STAT_SUCCESS;
       
  1118 }
       
  1119 
       
  1120 
       
  1121 /* on entry position should be just after '<!DOCTYPE' */
       
  1122 
       
  1123 static
       
  1124 NW_Status_t
       
  1125 NW_XML_Parse_InternalEntity(NW_XML_Reader_t* pT,
       
  1126                            RPointerArray <CXML_Internal_Entity_t>*  internalEntityList)
       
  1127 {
       
  1128  NW_Status_t s;
       
  1129  NW_XML_Reader_Interval_t I_EntityName;
       
  1130  NW_Uint32 match;
       
  1131  NW_XML_Reader_Interval_t I_EntityValue;
       
  1132  NW_Uint32 quoteChar = 0; /* 0 = double quote, 1 = single quote */
       
  1133  NW_Uint32 matchDoubleQuote;
       
  1134  NW_Uint32 matchSingleQuote;
       
  1135  NW_Uint32 matchPercentSign;
       
  1136  NW_Status_t statusDoubleQuote;
       
  1137  NW_Status_t statusSingleQuote;
       
  1138  
       
  1139 
       
  1140  
       
  1141 
       
  1142     s = NW_XML_Reader_SkipSpace(pT);
       
  1143     if (NW_STAT_IS_FAILURE(s)) 
       
  1144     {
       
  1145         return NW_STAT_FAILURE;
       
  1146     }
       
  1147 
       
  1148 	/* The Internal Parameteric Entities has "%" symbol in the beginning of the entity.
       
  1149 	 * Check for parametric entity has skip the symbol.
       
  1150 	 */
       
  1151 
       
  1152 	s =  NW_XML_Reader_AsciiCharMatch(pT, '%', &matchPercentSign);
       
  1153 
       
  1154     if (NW_STAT_IS_FAILURE(s)) 
       
  1155     {
       
  1156         return NW_STAT_FAILURE;
       
  1157     }
       
  1158 
       
  1159 	if(matchPercentSign)
       
  1160 	{
       
  1161 		/*Advance from '%' sign */
       
  1162 
       
  1163         s = NW_XML_Reader_Advance(pT);
       
  1164         if (NW_STAT_IS_FAILURE(s)) 
       
  1165         {
       
  1166             return NW_STAT_FAILURE;
       
  1167         }
       
  1168       
       
  1169 		s = NW_XML_Reader_SkipSpace(pT);
       
  1170 
       
  1171 		if (NW_STAT_IS_FAILURE(s)) 
       
  1172 		{
       
  1173 			return NW_STAT_FAILURE;
       
  1174 		}
       
  1175 
       
  1176 	} /*end if(matchPercentSign)*/
       
  1177 
       
  1178     /* Name */
       
  1179 
       
  1180     s = NW_XML_Parse_NameConsume(pT, &I_EntityName, &match);
       
  1181     if (NW_STAT_IS_FAILURE(s)) 
       
  1182     {
       
  1183         return NW_STAT_FAILURE;
       
  1184     }
       
  1185 
       
  1186     if (!match) 
       
  1187     {
       
  1188         /* FATAL bad tag */
       
  1189         return NW_STAT_FAILURE;
       
  1190     }
       
  1191 
       
  1192     /* S, space may be there after the Entry Name */
       
  1193 
       
  1194     s = NW_XML_Reader_SkipSpace(pT);
       
  1195     if (NW_STAT_IS_FAILURE(s)) 
       
  1196     {
       
  1197         return NW_STAT_FAILURE;
       
  1198     }
       
  1199 
       
  1200     /* Look for opening single or double quote. Let the closing '>'
       
  1201      * be handled in the DTD function.
       
  1202      */
       
  1203 
       
  1204       statusDoubleQuote = NW_XML_Reader_AsciiCharMatch(pT, '\"', &matchDoubleQuote);
       
  1205       statusSingleQuote = NW_XML_Reader_AsciiCharMatch(pT, '\'', &matchSingleQuote);
       
  1206 
       
  1207       if (NW_STAT_IS_FAILURE(statusDoubleQuote)
       
  1208             || NW_STAT_IS_FAILURE(statusSingleQuote) ) 
       
  1209         {
       
  1210             return NW_STAT_FAILURE;
       
  1211         }
       
  1212         
       
  1213       if(matchDoubleQuote || matchSingleQuote)
       
  1214       {
       
  1215 
       
  1216         if(matchSingleQuote) /* Look for corresponding quote */
       
  1217         {
       
  1218          quoteChar = 1; /* 0 = double quote, 1 = single quote */
       
  1219         }
       
  1220         /*Advance from the Quote */
       
  1221 
       
  1222         s = NW_XML_Reader_Advance(pT);
       
  1223         if (NW_STAT_IS_FAILURE(s)) 
       
  1224         {
       
  1225             return NW_STAT_FAILURE;
       
  1226         }
       
  1227 
       
  1228        /* Start the Internal for the name space */
       
  1229 
       
  1230         NW_XML_Reader_Interval_Start(&I_EntityValue, pT);
       
  1231 
       
  1232        for(; ;)
       
  1233        {
       
  1234         statusDoubleQuote = NW_XML_Reader_AsciiCharMatch(pT, '\"', &matchDoubleQuote);
       
  1235         statusSingleQuote = NW_XML_Reader_AsciiCharMatch(pT, '\'', &matchSingleQuote);
       
  1236 
       
  1237         if(matchDoubleQuote || matchSingleQuote)
       
  1238         {
       
  1239          if(!quoteChar && matchDoubleQuote)
       
  1240          {
       
  1241           NW_XML_Reader_Interval_Stop(&I_EntityValue, pT);
       
  1242           break;
       
  1243          }
       
  1244          else if(quoteChar && matchSingleQuote)
       
  1245          {
       
  1246           NW_XML_Reader_Interval_Stop(&I_EntityValue, pT);
       
  1247           break;
       
  1248          }
       
  1249         }/* if(matchDoubleQuote || matchSingleQuote)*/
       
  1250 
       
  1251         /*Read next character */
       
  1252 
       
  1253         s = NW_XML_Reader_Advance(pT);
       
  1254 
       
  1255         if (NW_STAT_IS_FAILURE(s)) 
       
  1256         {
       
  1257             return NW_STAT_FAILURE;
       
  1258         }
       
  1259 
       
  1260        }/*end for */
       
  1261       }/*end if(statusDoubleQuote || statusSingleQuote)*/
       
  1262 
       
  1263 
       
  1264       s = CXML_XML_Parser_Store_I_Entity(pT,&I_EntityName,&I_EntityValue,internalEntityList);
       
  1265 
       
  1266       if(s != NW_STAT_SUCCESS ) 
       
  1267         {
       
  1268          return s;
       
  1269         }
       
  1270 
       
  1271 
       
  1272  return NW_STAT_SUCCESS;
       
  1273 
       
  1274 }/*end NW_XML_Parse_InternalEntity() */
       
  1275 
       
  1276 /* on entry position should be just after '<!DOCTYPE' */
       
  1277 static
       
  1278 NW_Status_t
       
  1279 NW_XML_Parse_DtdConsume(NW_XML_Reader_t* pT,
       
  1280                         RPointerArray <CXML_Internal_Entity_t>*  internalEntityList)
       
  1281 {
       
  1282     NW_Status_t s;
       
  1283     NW_XML_Reader_Interval_t I_name;
       
  1284     NW_Uint32 match;
       
  1285     NW_XML_Reader_Interval_t I_keyword;
       
  1286     NW_Uint32 inString = 0;
       
  1287     NW_Uint32 quoteChar = 0; /* 0 = double quote, 1 = single quote */
       
  1288     NW_Uint32 balance = 1; /* already read opening greater-than sign */
       
  1289 
       
  1290     /* S */
       
  1291     s = NW_XML_Reader_SkipSpace(pT);
       
  1292     if (NW_STAT_IS_FAILURE(s)) {
       
  1293         return NW_STAT_FAILURE;
       
  1294     }
       
  1295     /* Name */
       
  1296     s = NW_XML_Parse_NameConsume(pT, &I_name, &match);
       
  1297     if (NW_STAT_IS_FAILURE(s)) {
       
  1298         return NW_STAT_FAILURE;
       
  1299     }
       
  1300     if (!match) {
       
  1301         /* FATAL bad tag */
       
  1302         return NW_STAT_FAILURE;
       
  1303     }
       
  1304     /* You can put quoted '<' and '>' in literal value strings which must be ignored. */
       
  1305     while (balance) {
       
  1306         NW_Uint32 matchDoubleQuote;
       
  1307         NW_Uint32 matchSingleQuote;
       
  1308         NW_Uint32 matchGreaterThan;
       
  1309         NW_Uint32 matchLessThan;
       
  1310         NW_Status_t statusDoubleQuote;
       
  1311         NW_Status_t statusSingleQuote;
       
  1312         NW_Status_t statusGreaterThan;
       
  1313         NW_Status_t statusLessThan;
       
  1314 
       
  1315         statusDoubleQuote = NW_XML_Reader_AsciiCharMatch(pT, '\"', &matchDoubleQuote);
       
  1316         statusSingleQuote = NW_XML_Reader_AsciiCharMatch(pT, '\'', &matchSingleQuote);
       
  1317         statusGreaterThan = NW_XML_Reader_AsciiCharMatch(pT, '>', &matchGreaterThan);
       
  1318         statusLessThan    = NW_XML_Reader_AsciiCharMatch(pT, '<', &matchLessThan);
       
  1319 
       
  1320         if (NW_STAT_IS_FAILURE(statusDoubleQuote)
       
  1321             || NW_STAT_IS_FAILURE(statusSingleQuote)
       
  1322             || NW_STAT_IS_FAILURE(statusGreaterThan)
       
  1323             || NW_STAT_IS_FAILURE(statusLessThan)) {
       
  1324             return NW_STAT_FAILURE;
       
  1325         }
       
  1326 
       
  1327         if (inString) {
       
  1328             if (quoteChar) {
       
  1329                 if (matchSingleQuote) {
       
  1330                     inString = 0;
       
  1331                 }
       
  1332             } else if (matchDoubleQuote) {
       
  1333                 inString = 0;
       
  1334             }
       
  1335         } else 
       
  1336             {
       
  1337               if (matchGreaterThan) 
       
  1338               {
       
  1339                 NW_ASSERT(balance);
       
  1340                 balance--;
       
  1341                } else if (matchLessThan) 
       
  1342                 {
       
  1343                     balance++;
       
  1344                      /* '<!ENTITY' */
       
  1345                     s = NW_XML_Parse_KeywordConsume(pT, &I_keyword,
       
  1346                                     NW_XML_String_EntityStartLength,
       
  1347                                     NW_XML_String_EntityStart, &match);
       
  1348                     if (NW_STAT_IS_FAILURE(s)) 
       
  1349                     {
       
  1350                      return NW_STAT_FAILURE;
       
  1351                     }
       
  1352                     if (match) 
       
  1353                     {
       
  1354                         s = NW_XML_Parse_InternalEntity(pT,internalEntityList);
       
  1355                         if (NW_STAT_IS_FAILURE(s))
       
  1356                         {
       
  1357                             return NW_STAT_FAILURE;
       
  1358                         }
       
  1359                     }
       
  1360                 } else if (matchSingleQuote) 
       
  1361                 {
       
  1362                  quoteChar = 1;
       
  1363                  inString = 1;
       
  1364                 }
       
  1365                 else if (matchDoubleQuote) 
       
  1366                 {
       
  1367                  quoteChar = 0;
       
  1368                  inString = 1;
       
  1369                 }
       
  1370             } /*end else */
       
  1371         s = NW_XML_Reader_Advance(pT);
       
  1372         if (NW_STAT_IS_FAILURE(s)) {
       
  1373             return NW_STAT_FAILURE;
       
  1374         }
       
  1375     }
       
  1376     return NW_STAT_SUCCESS;
       
  1377 }
       
  1378 
       
  1379 static
       
  1380 NW_Status_t
       
  1381 NW_XML_Parse_PrologConsume(NW_XML_Reader_t* pT,
       
  1382                            const struct NW_XML_Parser_EventCallbacks_s* pE,
       
  1383                            RPointerArray <CXML_Internal_Entity_t>*  internalEntityList)
       
  1384 {
       
  1385     /*
       
  1386     [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
       
  1387 
       
  1388     [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
       
  1389 
       
  1390     [24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'"
       
  1391                                          | '"' VersionNum '"')
       
  1392 
       
  1393     [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
       
  1394     */
       
  1395 
       
  1396     /* '<?' */
       
  1397     NW_Status_t s;
       
  1398     NW_Uint32 match;
       
  1399     NW_PiFormTypeTag_t pi_type;
       
  1400     NW_Uint32 nameValid;
       
  1401     NW_XML_Reader_Interval_t I_name;
       
  1402     NW_Uint32 versionValid;
       
  1403     NW_XML_Reader_Interval_t I_version;
       
  1404     NW_Uint32 encodingValid;
       
  1405     NW_XML_Reader_Interval_t I_encoding;
       
  1406     NW_Uint32 standaloneValid;
       
  1407     NW_XML_Reader_Interval_t I_standalone;
       
  1408     NW_Uint32 contentValid;
       
  1409     NW_XML_Reader_Interval_t I_content;
       
  1410     NW_XML_Reader_Interval_t I_keyword;
       
  1411     NW_Uint32 prevIndex;
       
  1412     NW_Uint32 prevCharIndex;
       
  1413     NW_XML_Reader_LineColumn_t prevLineColumn;
       
  1414 
       
  1415     /* Might back up if PiForm is from Misc */
       
  1416     NW_XML_Reader_GetPosition(pT, &prevIndex, &prevCharIndex, &prevLineColumn);
       
  1417 
       
  1418     s = NW_XML_Parse_KeywordConsume(pT, &I_keyword,
       
  1419                                     NW_XML_String_PiFormStartLength,
       
  1420                                     NW_XML_String_PiFormStart, &match);
       
  1421     if (NW_STAT_IS_FAILURE(s)) {
       
  1422         return NW_STAT_FAILURE;
       
  1423     }
       
  1424     if (match) {
       
  1425         NW_Uint32 error = 0;
       
  1426         /* XMLDecl */
       
  1427         s = NW_XML_Parse_PiFormConsume(pT, &pi_type,
       
  1428                                        &nameValid,
       
  1429                                        &I_name,
       
  1430                                        &versionValid,
       
  1431                                        &I_version,
       
  1432                                        &encodingValid,
       
  1433                                        &I_encoding,
       
  1434                                        &standaloneValid,
       
  1435                                        &I_standalone,
       
  1436                                        &contentValid,
       
  1437                                        &I_content,
       
  1438                                        internalEntityList);
       
  1439         if (NW_STAT_IS_FAILURE(s) || !nameValid) {
       
  1440             return NW_STAT_FAILURE;
       
  1441         }
       
  1442         switch (pi_type) {
       
  1443         case XMLDECL:
       
  1444             /* BUG not checking for legal values of version,
       
  1445             encoding and standalone */
       
  1446             if (!versionValid) {
       
  1447                 /* version is mandatory */
       
  1448                 error = 1;
       
  1449             }
       
  1450             if (contentValid) {
       
  1451                 /* no other attribute info is legal */
       
  1452                 error = 1;
       
  1453             }
       
  1454             if (!error && (pE->PiForm_CB != NULL)) {
       
  1455                 s = (*(pE->PiForm_CB))(pT, pi_type,
       
  1456                                        (nameValid ? &I_name : NULL),
       
  1457                                        (versionValid ? &I_version : NULL),
       
  1458                                        (encodingValid ? &I_encoding : NULL),
       
  1459                                        (standaloneValid ? &I_standalone : NULL),
       
  1460                                        (contentValid ? &I_content : NULL),
       
  1461                                        pE->pClientPointer);
       
  1462             }
       
  1463             break;
       
  1464         case PI:
       
  1465             /* encountered a PI from Misc, rewind and continue */
       
  1466             NW_XML_Reader_SetPosition(pT, prevIndex, prevCharIndex, &prevLineColumn);
       
  1467             break;
       
  1468         default:
       
  1469             error = 1;
       
  1470             break;
       
  1471         }
       
  1472         if (error) {
       
  1473             if (pE->Exception_CB != NULL) {
       
  1474                 s = (*(pE->Exception_CB))(pT, pE->pClientPointer);
       
  1475             }
       
  1476             return NW_STAT_FAILURE;
       
  1477         }
       
  1478     }
       
  1479     /* MISC */
       
  1480     s = NW_XML_Parse_MiscConsume(pT, pE,internalEntityList);
       
  1481     if (NW_STAT_IS_FAILURE(s)) {
       
  1482         return NW_STAT_FAILURE;
       
  1483     }
       
  1484     /* '<!DOCTYPE' */
       
  1485     s = NW_XML_Parse_KeywordConsume(pT, &I_keyword,
       
  1486                                     NW_XML_String_DoctypeStartLength,
       
  1487                                     NW_XML_String_DoctypeStart, &match);
       
  1488     if (NW_STAT_IS_FAILURE(s)) {
       
  1489         return NW_STAT_FAILURE;
       
  1490     }
       
  1491     if (match) {
       
  1492         s = NW_XML_Parse_DtdConsume(pT,internalEntityList);
       
  1493         if (NW_STAT_IS_FAILURE(s)) {
       
  1494             return NW_STAT_FAILURE;
       
  1495         }
       
  1496     }
       
  1497     /* MISC */
       
  1498     s = NW_XML_Parse_MiscConsume(pT, pE,internalEntityList);
       
  1499     if (NW_STAT_IS_FAILURE(s)) {
       
  1500         return NW_STAT_FAILURE;
       
  1501     }
       
  1502     return NW_STAT_SUCCESS;
       
  1503 }
       
  1504 
       
  1505 /* Assumes read position is at '<' on entry.
       
  1506 return: *pIsEmptyElement = 1 if it is an EmptyElemTag. */
       
  1507 static
       
  1508 NW_Status_t
       
  1509 NW_XML_Parse_ElementOpeningMarkupConsume(NW_XML_Reader_t* pT,
       
  1510                                          NW_Uint32* pIsEmptyElement,
       
  1511                                          const struct
       
  1512                                          NW_XML_Parser_EventCallbacks_s* pE,
       
  1513                                          const RPointerArray <CXML_Internal_Entity_t>*  internalEntityList)
       
  1514 {
       
  1515     /*
       
  1516     [40] STag ::= '<' Name (S Attribute)* S? '>'
       
  1517 
       
  1518     [41] Attribute ::= Name Eq AttValue
       
  1519 
       
  1520     [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
       
  1521     */
       
  1522 
       
  1523     NW_Status_t s;
       
  1524     NW_XML_Reader_Interval_t I_name;
       
  1525     NW_XML_Reader_Interval_t I_attName;
       
  1526     NW_XML_Reader_Interval_t I_attValue;
       
  1527     NW_Uint32 match;
       
  1528     NW_Uint32 attributeCount;
       
  1529 	CXML_Bool entity = CXML_TRUE;
       
  1530 	NW_String_t  attrValStr;
       
  1531 	NW_Byte* finalStr = NULL;
       
  1532 	NW_Uint32 finalStrLen = 0;
       
  1533     NW_String_initialize (&attrValStr, NULL, 0);
       
  1534 
       
  1535 
       
  1536     *pIsEmptyElement = 0;
       
  1537     /* '<' */
       
  1538     s = NW_XML_Reader_AsciiCharMatch(pT, '<', &match);
       
  1539     if (NW_STAT_IS_FAILURE(s) || !match) {
       
  1540         return NW_STAT_FAILURE;
       
  1541     }
       
  1542     s = NW_XML_Reader_Advance(pT);
       
  1543     if (NW_STAT_IS_FAILURE(s)) {
       
  1544         return NW_STAT_FAILURE;
       
  1545     }
       
  1546     /* Name */
       
  1547     s = NW_XML_Parse_NameConsume(pT, &I_name, &match);
       
  1548     if (NW_STAT_IS_FAILURE(s) || !match) {
       
  1549         return NW_STAT_FAILURE;
       
  1550     }
       
  1551     if (pE->Tag_Start_CB != NULL) {
       
  1552         s = (*(pE->Tag_Start_CB))(pT, &I_name, pE->pClientPointer);
       
  1553         if (NW_STAT_IS_FAILURE(s)) {
       
  1554             return NW_STAT_FAILURE;
       
  1555         }
       
  1556     }
       
  1557     /* Do attribute value consume and look for closing markup. */
       
  1558     for (attributeCount = 0;;) {
       
  1559         entity = CXML_TRUE;
       
  1560         s = NW_XML_Parse_AttributeValueConsume(pT, &I_attName, &I_attValue,
       
  1561                                                0, NULL, &match,
       
  1562 											   &entity,&attrValStr,internalEntityList);
       
  1563 
       
  1564         if (NW_STAT_IS_SUCCESS(s) && match && (entity != CXML_TRUE) ) {
       
  1565             attributeCount++;
       
  1566             if (pE->Attr_Start_CB != NULL) {
       
  1567                 s = (*(pE->Attr_Start_CB))(pT, &I_attName, pE->pClientPointer);
       
  1568                 if (NW_STAT_IS_SUCCESS(s)) {
       
  1569                     if (pE->Attr_VarVal_CB != NULL) {
       
  1570                         s = (*(pE->Attr_VarVal_CB))(pT, &I_attName, &I_attValue,
       
  1571                                                     pE->pClientPointer);
       
  1572                     }
       
  1573                 }
       
  1574                 if (NW_STAT_IS_FAILURE(s)) {
       
  1575                     return NW_STAT_FAILURE;
       
  1576                 }
       
  1577                 if(attrValStr.storage != NULL)
       
  1578                 {
       
  1579                  NW_Mem_Free(attrValStr.storage);
       
  1580                 }
       
  1581                 NW_String_initialize (&attrValStr, NULL, 0);
       
  1582             }
       
  1583             continue;
       
  1584         }
       
  1585 		else if(NW_STAT_IS_SUCCESS(s) && match && (entity == CXML_TRUE) )
       
  1586 		{
       
  1587 		    attributeCount++;
       
  1588             if (pE->Attr_Start_CB != NULL) {
       
  1589                 s = (*(pE->Attr_Start_CB))(pT, &I_attName, pE->pClientPointer);
       
  1590                 if (NW_STAT_IS_SUCCESS(s)) {
       
  1591                     if (pE->Attr_Entity_VarVal_CB != NULL) {
       
  1592 						/* The MSB of NW_Byte length if set represents that the 
       
  1593 							string is from storage buffer, so BufferOwns String. So,
       
  1594 						    find exact length.
       
  1595 						*/
       
  1596 						finalStrLen = attrValStr.length & 0x7fffffff;
       
  1597                         
       
  1598                         /* This string is with the NULL terminate character. But,
       
  1599                          * the callback function Attr_Entity_VarVal_CB(..) requires
       
  1600                          * with out this. So, take out NULL termination character 
       
  1601                          * length depending on the Encoding.
       
  1602                          */
       
  1603 
       
  1604                         if ( (pT->encoding == HTTP_iso_10646_ucs_2) &&
       
  1605                              (finalStrLen > 1) &&
       
  1606                              (attrValStr.storage[(finalStrLen-1)] == 0) && 
       
  1607                              (attrValStr.storage[(finalStrLen-2)] == 0) ) 
       
  1608                         {
       
  1609                             finalStrLen--;
       
  1610                             finalStrLen--;
       
  1611                          }
       
  1612                         else if ((pT->encoding == HTTP_utf_8) ||
       
  1613                                 (pT->encoding == HTTP_us_ascii) ||
       
  1614                                 (pT->encoding== HTTP_iso_8859_1)) 
       
  1615                             {
       
  1616                                 if ( (finalStrLen > 0) && (attrValStr.storage[finalStrLen-1] == 0) )
       
  1617                                 {
       
  1618                                  finalStrLen--;
       
  1619                                 }
       
  1620                             }
       
  1621 
       
  1622 						finalStr = (NW_Byte*) NW_Mem_Malloc(finalStrLen);
       
  1623 						if(finalStr == NULL)
       
  1624 						{
       
  1625 						 return NW_STAT_OUT_OF_MEMORY;
       
  1626 						}
       
  1627 
       
  1628 						CXML_Mem_memcpy(finalStr,attrValStr.storage,finalStrLen);
       
  1629 
       
  1630                         s = (*(pE->Attr_Entity_VarVal_CB))(pT, &I_attName,
       
  1631 							   finalStr,finalStrLen,pE->pClientPointer);
       
  1632 						if(finalStr != NULL)
       
  1633 						{
       
  1634 						 NW_Mem_Free(finalStr);
       
  1635 						 finalStr = NULL;
       
  1636 						}
       
  1637                     }
       
  1638                 }
       
  1639                 if (NW_STAT_IS_FAILURE(s)) {
       
  1640                     return NW_STAT_FAILURE;
       
  1641                 }
       
  1642 
       
  1643                 if(attrValStr.storage != NULL)
       
  1644                 {
       
  1645                  NW_Mem_Free(attrValStr.storage);
       
  1646                 }
       
  1647                 NW_String_initialize (&attrValStr, NULL, 0);
       
  1648             }
       
  1649             continue;
       
  1650 		 
       
  1651 		}//end else if(NW_STAT_IS_SUCCESS(s) && match && (entity != CXML_TRUE) )
       
  1652         if (NW_STAT_IS_FAILURE(s) && match) {
       
  1653             return NW_STAT_FAILURE;
       
  1654         }
       
  1655         s = NW_XML_Reader_AsciiCharMatch(pT, '>', &match);
       
  1656         if (NW_STAT_IS_FAILURE(s)) {
       
  1657             return NW_STAT_FAILURE;
       
  1658         }
       
  1659         if (match) {
       
  1660             s = NW_XML_Reader_Advance(pT);
       
  1661             if (NW_STAT_IS_FAILURE(s)) {
       
  1662                 return NW_STAT_FAILURE;
       
  1663             }
       
  1664             if (pE->Attributes_End_CB != NULL) {
       
  1665                 s = (*(pE->Attributes_End_CB))(pT, attributeCount,
       
  1666                                                pE->pClientPointer);
       
  1667                 if (NW_STAT_IS_FAILURE(s)) {
       
  1668                     return NW_STAT_FAILURE;
       
  1669                 }
       
  1670             }
       
  1671             break;
       
  1672         }
       
  1673         s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_EmptyTagEndLength,
       
  1674                                         NW_XML_String_EmptyTagEnd, &match);
       
  1675         if (NW_STAT_IS_FAILURE(s)) {
       
  1676             return NW_STAT_FAILURE;
       
  1677         }
       
  1678         if (match) {
       
  1679             s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_EmptyTagEndLength);
       
  1680             if (NW_STAT_IS_FAILURE(s)) {
       
  1681                 return NW_STAT_FAILURE;
       
  1682             }
       
  1683             if (pE->Attributes_End_CB != NULL) {
       
  1684                 s = (*(pE->Attributes_End_CB))(pT, attributeCount,
       
  1685                                                pE->pClientPointer);
       
  1686                 if (NW_STAT_IS_FAILURE(s)) {
       
  1687                     return NW_STAT_FAILURE;
       
  1688                 }
       
  1689             }
       
  1690             *pIsEmptyElement = 1;
       
  1691             if (pE->Tag_End_CB != NULL) {
       
  1692                 s = (*(pE->Tag_End_CB))(pT, &I_name,
       
  1693                                         1, /* empty tag*/
       
  1694                                         pE->pClientPointer);
       
  1695                 if (NW_STAT_IS_FAILURE(s)) {
       
  1696                     return NW_STAT_FAILURE;
       
  1697                 }
       
  1698             }
       
  1699             break;
       
  1700         }
       
  1701         return NW_STAT_FAILURE;
       
  1702     }
       
  1703     return NW_STAT_SUCCESS;
       
  1704 }
       
  1705 
       
  1706 /* Assumes position is at '<' on entry. */
       
  1707 static
       
  1708 NW_Status_t
       
  1709 NW_XML_Parse_ElementConsume(NW_XML_Reader_t* pT,
       
  1710                             const struct NW_XML_Parser_EventCallbacks_s* pE,
       
  1711                             const RPointerArray <CXML_Internal_Entity_t>*  internalEntityList)
       
  1712 {
       
  1713     /*
       
  1714     [39] element ::= EmptyElemTag | STag content ETag
       
  1715 
       
  1716     [40] STag ::= '<' Name (S Attribute)* S? '>'
       
  1717 
       
  1718     [41] Attribute ::= Name Eq AttValue
       
  1719 
       
  1720     [42] ETag ::= '</' Name S? '>'
       
  1721 
       
  1722     [43] content ::= CharData?
       
  1723                      ((element | Reference | CDSect | PI | Comment)
       
  1724                      CharData?)*
       
  1725 
       
  1726     [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
       
  1727     */
       
  1728     NW_Status_t s;
       
  1729     NW_Uint32 match;
       
  1730     NW_Uint32 isEmptyElement;
       
  1731     NW_Uint32 nestingCount;
       
  1732     NW_Uint32 inContent;
       
  1733     NW_Uint32 prevIndex;
       
  1734 	NW_Uint32 prevCharIndex;
       
  1735     CXML_Uint8* intEntityValStr = NULL;
       
  1736     NW_Uint32 contentLen = 0;
       
  1737 	NW_XML_Reader_LineColumn_t prevLineColumn;
       
  1738 	NW_Bool entityFoundLevel_2 =  NW_FALSE;
       
  1739     NW_XML_Reader_Interval_t I_elementContent;
       
  1740     NW_XML_Reader_Interval_Init(&I_elementContent);	
       
  1741 
       
  1742 
       
  1743     s = NW_XML_Reader_SkipSpace(pT);
       
  1744     if (NW_STAT_IS_FAILURE(s)) 
       
  1745     {
       
  1746         return NW_STAT_FAILURE;
       
  1747     }
       
  1748 
       
  1749     /* Look for initial element markup. */
       
  1750     s = NW_XML_Parse_ElementOpeningMarkupConsume(pT, &isEmptyElement, pE, internalEntityList);
       
  1751     if (NW_STAT_IS_FAILURE(s)) {
       
  1752         return NW_STAT_FAILURE;
       
  1753     }
       
  1754     if (isEmptyElement) {
       
  1755         return NW_STAT_SUCCESS;
       
  1756     }
       
  1757     inContent = 0;
       
  1758     for (nestingCount = 1; nestingCount;) {
       
  1759         /* test for ETag */
       
  1760         s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_EndTagStartLength,
       
  1761                                         NW_XML_String_EndTagStart, &match);
       
  1762         if (NW_STAT_IS_FAILURE(s)) {
       
  1763             return NW_STAT_FAILURE;
       
  1764         }
       
  1765         if (match) 
       
  1766         {
       
  1767             NW_XML_Reader_Interval_t I_name;
       
  1768             if (inContent) 
       
  1769             {
       
  1770                 inContent = 0;
       
  1771                 NW_XML_Reader_Interval_Stop(&I_elementContent, pT);
       
  1772                 
       
  1773                 /*Write the contents only if I_elementContent have some contents*/
       
  1774             
       
  1775                 if(NW_XML_Reader_Interval_IsWellFormed(&I_elementContent) )
       
  1776                 {
       
  1777                   if (pE->Content_CB != NULL) 
       
  1778                   {
       
  1779                     s = (*(pE->Content_CB))(pT, &I_elementContent, pE->pClientPointer);
       
  1780                     if (NW_STAT_IS_FAILURE(s)) {
       
  1781                         return NW_STAT_FAILURE;
       
  1782                     }
       
  1783                   }/*end if (pE->Content_CB != NULL)*/
       
  1784                 }
       
  1785             }/*end if(inContent)*/
       
  1786 
       
  1787             s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_EndTagStartLength);
       
  1788             if (NW_STAT_IS_FAILURE(s)) {
       
  1789                 return NW_STAT_FAILURE;
       
  1790             }
       
  1791             /* Name */
       
  1792             s = NW_XML_Parse_NameConsume(pT, &I_name, &match);
       
  1793             if (NW_STAT_IS_FAILURE(s) || !match) {
       
  1794                 return NW_STAT_FAILURE;
       
  1795             }
       
  1796             /* S */
       
  1797             s = NW_XML_Reader_SkipSpace(pT);
       
  1798             if (NW_STAT_IS_FAILURE(s)) {
       
  1799                 return NW_STAT_FAILURE;
       
  1800             }
       
  1801             /* '>' */
       
  1802             s = NW_XML_Reader_AsciiCharMatch(pT, '>', &match);
       
  1803             if (NW_STAT_IS_FAILURE(s) || !match) {
       
  1804                 return NW_STAT_FAILURE;
       
  1805             }
       
  1806             s = NW_XML_Reader_Advance(pT);
       
  1807             if (NW_STAT_IS_FAILURE(s)) {
       
  1808                 return NW_STAT_FAILURE;
       
  1809             }
       
  1810             /* FUTURE could check that Etag name matches STag name */
       
  1811             nestingCount--;
       
  1812             if (pE->Tag_End_CB != NULL) {
       
  1813                 s = (*(pE->Tag_End_CB))(pT, &I_name,
       
  1814                                         0, /* not empty tag */
       
  1815                                         pE->pClientPointer);
       
  1816                 if (NW_STAT_IS_FAILURE(s)) {
       
  1817                     return NW_STAT_FAILURE;
       
  1818                 }
       
  1819                 /*Just now element (tag) is consumned so contenst will start
       
  1820                  *after this. So, init the content pointer.
       
  1821                  */
       
  1822 
       
  1823                 NW_XML_Reader_Interval_Start(&I_elementContent, pT);
       
  1824             }
       
  1825             continue;
       
  1826         } /*end if(match) */
       
  1827 
       
  1828 
       
  1829         /* test for PI */
       
  1830         s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_PiFormStartLength,
       
  1831                                         NW_XML_String_PiFormStart, &match);
       
  1832         if (NW_STAT_IS_FAILURE(s)) {
       
  1833             return NW_STAT_FAILURE;
       
  1834         }
       
  1835         if (match) {
       
  1836             NW_PiFormTypeTag_t pi_type;
       
  1837             NW_XML_Reader_Interval_t I_name, I_version, I_encoding, I_standalone;
       
  1838             NW_XML_Reader_Interval_t I_content;
       
  1839             NW_Uint32 nameValid, versionValid, encodingValid, standaloneValid;
       
  1840             NW_Uint32 contentValid;
       
  1841             if (inContent) {
       
  1842                 inContent = 0;
       
  1843                 NW_XML_Reader_Interval_Stop(&I_elementContent, pT);
       
  1844                 if (pE->Content_CB != NULL) {
       
  1845                     s = (*(pE->Content_CB))(pT, &I_elementContent, pE->pClientPointer);
       
  1846                     if (NW_STAT_IS_FAILURE(s)) {
       
  1847                         return NW_STAT_FAILURE;
       
  1848                     }
       
  1849                 }
       
  1850             }
       
  1851             s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_PiFormStartLength);
       
  1852             if (NW_STAT_IS_FAILURE(s)) {
       
  1853                 return NW_STAT_FAILURE;
       
  1854             }
       
  1855             s = NW_XML_Parse_PiFormConsume(pT, &pi_type,
       
  1856                                            &nameValid,
       
  1857                                            &I_name,
       
  1858                                            &versionValid,
       
  1859                                            &I_version,
       
  1860                                            &encodingValid,
       
  1861                                            &I_encoding,
       
  1862                                            &standaloneValid,
       
  1863                                            &I_standalone,
       
  1864                                            &contentValid,
       
  1865                                            &I_content,
       
  1866                                            internalEntityList);
       
  1867             if (NW_STAT_IS_FAILURE(s) || !nameValid) {
       
  1868                 return NW_STAT_FAILURE;
       
  1869             }
       
  1870             if (pi_type == PI && (pE->PiForm_CB != NULL)) {
       
  1871                 s = (*(pE->PiForm_CB))(pT, pi_type,
       
  1872                                        (nameValid ? &I_name : NULL),
       
  1873                                        (versionValid ? &I_version : NULL),
       
  1874                                        (encodingValid ? &I_encoding : NULL),
       
  1875                                        (standaloneValid ? &I_standalone : NULL),
       
  1876                                        (contentValid ? &I_content : NULL),
       
  1877                                        pE->pClientPointer);
       
  1878                 if (NW_STAT_IS_FAILURE(s)) {
       
  1879                     return NW_STAT_FAILURE;
       
  1880                 }
       
  1881             }
       
  1882             if (pi_type != PI) {
       
  1883                 /* BUG is this correct? */
       
  1884                 return NW_STAT_FAILURE;
       
  1885             }
       
  1886             continue;
       
  1887         }
       
  1888         /* test for Comment */
       
  1889         s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_CommentStartLength,
       
  1890                                         NW_XML_String_CommentStart, &match);
       
  1891         if (NW_STAT_IS_FAILURE(s)) {
       
  1892             return NW_STAT_FAILURE;
       
  1893         }
       
  1894         if (match) {
       
  1895             NW_XML_Reader_Interval_t I_comment;
       
  1896             if (inContent) {
       
  1897                 inContent = 0;
       
  1898                 NW_XML_Reader_Interval_Stop(&I_elementContent, pT);
       
  1899                 if (pE->Content_CB != NULL) {
       
  1900                     s = (*(pE->Content_CB))(pT, &I_elementContent, pE->pClientPointer);
       
  1901                     if (NW_STAT_IS_FAILURE(s)) {
       
  1902                         return NW_STAT_FAILURE;
       
  1903                     }
       
  1904                 }
       
  1905             }
       
  1906             s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_CommentStartLength);
       
  1907             if (NW_STAT_IS_FAILURE(s)) {
       
  1908                 return NW_STAT_FAILURE;
       
  1909             }
       
  1910             s = NW_XML_Parse_CommentConsume(pT, &I_comment, pE);
       
  1911             if (NW_STAT_IS_FAILURE(s)) {
       
  1912                 return NW_STAT_FAILURE;
       
  1913             }
       
  1914             continue;
       
  1915         }
       
  1916         /* test for CDSect */
       
  1917         s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_CdataStartLength,
       
  1918                                         NW_XML_String_CdataStart, &match);
       
  1919         if (NW_STAT_IS_FAILURE(s)) {
       
  1920             return NW_STAT_FAILURE;
       
  1921         }
       
  1922         if (match) {
       
  1923             NW_XML_Reader_Interval_t I_cdata;
       
  1924             if (inContent) {
       
  1925                 inContent = 0;
       
  1926                 NW_XML_Reader_Interval_Stop(&I_elementContent, pT);
       
  1927                 if (pE->Content_CB != NULL) {
       
  1928                     s = (*(pE->Content_CB))(pT, &I_elementContent, pE->pClientPointer);
       
  1929                     if (NW_STAT_IS_FAILURE(s)) {
       
  1930                         return NW_STAT_FAILURE;
       
  1931                     }
       
  1932                 }
       
  1933             }
       
  1934             s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_CdataStartLength);
       
  1935             if (NW_STAT_IS_FAILURE(s)) {
       
  1936                 return NW_STAT_FAILURE;
       
  1937             }
       
  1938             NW_XML_Reader_Interval_Start(&I_cdata, pT);
       
  1939             for (;;) {
       
  1940                 s = NW_XML_Reader_AsciiStringMatch(pT,
       
  1941                                                 NW_XML_String_CdataEndLength,
       
  1942                                                 NW_XML_String_CdataEnd,
       
  1943                                                 &match);
       
  1944                 if (NW_STAT_IS_FAILURE(s)) {
       
  1945                     NW_XML_Reader_Interval_Stop(&I_cdata, pT);
       
  1946                     return NW_STAT_FAILURE;
       
  1947                 }
       
  1948                 if (match) {
       
  1949                     NW_XML_Reader_Interval_Stop(&I_cdata, pT);
       
  1950                     s = NW_XML_Reader_AdvanceOffset(pT,
       
  1951                                                  NW_XML_String_CdataEndLength);
       
  1952                     if (NW_STAT_IS_FAILURE(s)) {
       
  1953                         return NW_STAT_FAILURE;
       
  1954                     }
       
  1955                     /* BUG Is this spec compliant parsing of CDATA? */
       
  1956                     if (pE->Cdata_CB != NULL) {
       
  1957                         s = (*(pE->Cdata_CB))(pT, &I_cdata, pE->pClientPointer);
       
  1958                         if (NW_STAT_IS_FAILURE(s)) {
       
  1959                             return NW_STAT_FAILURE;
       
  1960                         }
       
  1961                     }
       
  1962                     break;
       
  1963                 }
       
  1964                 s = NW_XML_Reader_Advance(pT);
       
  1965                 if (NW_STAT_IS_FAILURE(s)) {
       
  1966                     NW_XML_Reader_Interval_Stop(&I_cdata, pT);
       
  1967                     return NW_STAT_FAILURE;
       
  1968                 }
       
  1969             }
       
  1970             continue;
       
  1971         }
       
  1972         /* test for illegal '<' or nested element */
       
  1973         s = NW_XML_Reader_AsciiCharMatch(pT, '<', &match);
       
  1974         if (NW_STAT_IS_FAILURE(s)) {
       
  1975             return NW_STAT_FAILURE;
       
  1976         }
       
  1977         if (match) {
       
  1978             if (inContent) {
       
  1979                 inContent = 0;
       
  1980                 NW_XML_Reader_Interval_Stop(&I_elementContent, pT);
       
  1981 
       
  1982                 if (pE->Content_CB != NULL) 
       
  1983                 {
       
  1984                     contentLen = I_elementContent.stop - I_elementContent.start;
       
  1985                     if(contentLen > 0)
       
  1986                     {
       
  1987                      s = (*(pE->Content_CB))(pT, &I_elementContent, pE->pClientPointer);
       
  1988                      if (NW_STAT_IS_FAILURE(s)) 
       
  1989                      {
       
  1990                         return NW_STAT_FAILURE;
       
  1991                      }
       
  1992                     }//end if(contentLen > 0)
       
  1993                 }// end if(pE->Content_CB != NULL)
       
  1994             }
       
  1995             s = NW_XML_Parse_ElementOpeningMarkupConsume(pT, &isEmptyElement,
       
  1996                                                          pE, internalEntityList);
       
  1997             if (NW_STAT_IS_SUCCESS(s)) {
       
  1998                 if (!isEmptyElement) {
       
  1999                     nestingCount++;
       
  2000                 }
       
  2001 
       
  2002                 /*Just now element (tag) is consumned so contenst will start
       
  2003                  *after this. So, init the content pointer.
       
  2004                  */
       
  2005 
       
  2006                 NW_XML_Reader_Interval_Start(&I_elementContent, pT);
       
  2007                  continue;
       
  2008             }
       
  2009             return NW_STAT_FAILURE;
       
  2010         }
       
  2011 
       
  2012 
       
  2013        /* Test for predefined entities and character entries*/
       
  2014 
       
  2015 		s = NW_XML_Reader_AsciiCharMatch(pT, '&', &match); 
       
  2016 
       
  2017 		if (NW_STAT_IS_FAILURE(s))
       
  2018 		{
       
  2019             return NW_STAT_FAILURE;
       
  2020         }
       
  2021 
       
  2022 
       
  2023         if (match) 
       
  2024 		{
       
  2025          NW_XML_Reader_Interval_t I_entityData;
       
  2026 		 NW_Bool entityFoundLevel_1 =  NW_FALSE; //If end of entity (;) found
       
  2027 		 NW_Uint32 entityVal = 0;
       
  2028 		 NW_XML_Reader_Interval_t* I_content = &I_elementContent;
       
  2029 
       
  2030          //Will back off if not a valid entity
       
  2031 
       
  2032 			  NW_XML_Reader_GetPosition(pT,
       
  2033                               &prevIndex, &prevCharIndex, &prevLineColumn);
       
  2034 
       
  2035          /* If it is here then this must in the contents. The entity can appear
       
  2036           * at the beginning of content.
       
  2037           */
       
  2038 
       
  2039          inContent = NW_TRUE;
       
  2040          entityFoundLevel_2 =  NW_FALSE;
       
  2041          NW_XML_Reader_Interval_Stop(I_content, pT); //Contents before entity
       
  2042 
       
  2043 		 s = CXML_XML_Parser_Entity(pT,&I_entityData,&entityFoundLevel_1);
       
  2044 
       
  2045          if (NW_STAT_IS_FAILURE(s))
       
  2046 		 {
       
  2047             return NW_STAT_FAILURE;
       
  2048          }
       
  2049 
       
  2050 		 if (entityFoundLevel_1 && inContent) 
       
  2051 		 {
       
  2052 			 //Validate the entity
       
  2053             
       
  2054              //The following function checks for the character,
       
  2055              //predefined entities and Internal Entities.
       
  2056 
       
  2057             contentLen = I_entityData.stop - I_entityData.start;
       
  2058 
       
  2059             if(contentLen > 0)
       
  2060             {
       
  2061 			s = CXML_XML_Handle_entity(pT,
       
  2062                                        &I_entityData,&entityVal,
       
  2063                                        &intEntityValStr,&entityFoundLevel_2,
       
  2064                                        (void*) internalEntityList);
       
  2065             }
       
  2066             else
       
  2067             {
       
  2068              //Not a valid entity e.g. "&&;" test case
       
  2069              entityFoundLevel_2 = NW_FALSE;
       
  2070             }
       
  2071 
       
  2072 			if (NW_STAT_IS_FAILURE(s)) 
       
  2073 			{
       
  2074 			 return NW_STAT_FAILURE;
       
  2075 			}
       
  2076 
       
  2077             if(entityFoundLevel_2 == CXML_TRUE)
       
  2078 			{
       
  2079                 inContent = NW_FALSE;
       
  2080 
       
  2081 				//Now write content before entity first
       
  2082 
       
  2083 
       
  2084                 if (pE->Content_CB != NULL) {
       
  2085                     contentLen = I_content->stop - I_content->start;
       
  2086                     if(contentLen > 0)
       
  2087                     {
       
  2088                      s = (*(pE->Content_CB))(pT, I_content, pE->pClientPointer);
       
  2089                      if (NW_STAT_IS_FAILURE(s)) {
       
  2090                          return NW_STAT_FAILURE;
       
  2091                      }
       
  2092                     }
       
  2093                 }
       
  2094 			
       
  2095 			    // Write the entity content now. There are two possibilities for
       
  2096                 // entities.
       
  2097                 //
       
  2098                 // 1) If it is character or decimal or predefined entities. 
       
  2099                 //    In this case, intEntityValStr = NULL.
       
  2100                 //
       
  2101                 // 2) If it is "Internal Entity" then intEntityValStr != NULL.
       
  2102                 //     So, this is directly written to WBXML encoder as inline string.
       
  2103                 //    In this case, entityVal = 0;
       
  2104 
       
  2105 
       
  2106              if (pE->Entity_CB != NULL )
       
  2107 				{
       
  2108                     s = (*(pE->Entity_CB))(pT, entityVal, pE->pClientPointer,intEntityValStr);
       
  2109                     
       
  2110   if(intEntityValStr != NULL)
       
  2111                     {
       
  2112                      NW_Mem_Free(intEntityValStr);
       
  2113                     }
       
  2114 if (NW_STAT_IS_FAILURE(s)) 
       
  2115                     {
       
  2116                         return NW_STAT_FAILURE;
       
  2117                     }
       
  2118                   
       
  2119                 }/*end if(pE->Entity_CB != NULL) */
       
  2120 			}//endif(entityFoundLevel_2 == CXML_TRUE)
       
  2121             else
       
  2122             {
       
  2123                 //No valid entity found. Parse as the normal string
       
  2124                  NW_XML_Reader_SetPosition(pT,
       
  2125                                         prevIndex,
       
  2126                                         prevCharIndex,
       
  2127                                         &prevLineColumn);
       
  2128             }
       
  2129          } //end if (entityFoundLevel_1 && inContent)
       
  2130          else
       
  2131          {
       
  2132              //No valid entity found. Parse as the normal string
       
  2133 
       
  2134                  NW_XML_Reader_SetPosition(pT,
       
  2135                                         prevIndex,
       
  2136                                         prevCharIndex,
       
  2137                                         &prevLineColumn);
       
  2138          }
       
  2139 		} //end match
       
  2140 
       
  2141 
       
  2142         /* BUG no reference parsing and also permits illegal char data */
       
  2143         if (!inContent) 
       
  2144 		{
       
  2145             NW_XML_Reader_Interval_Start(&I_elementContent, pT);
       
  2146             inContent = 1;
       
  2147 			if(entityFoundLevel_2 == NW_TRUE)
       
  2148 			{
       
  2149 			 //Don't advance if it is entity as we did already
       
  2150 			 entityFoundLevel_2 = NW_FALSE;
       
  2151 			 continue;
       
  2152 			}
       
  2153         }
       
  2154 
       
  2155         s = NW_XML_Reader_Advance(pT);
       
  2156         if (NW_STAT_IS_FAILURE(s)) {
       
  2157             return NW_STAT_FAILURE;
       
  2158         }
       
  2159     }/*end for(..) */
       
  2160     return NW_STAT_SUCCESS;
       
  2161 }
       
  2162 
       
  2163 EXPORT_C NW_Status_t
       
  2164 NW_XML_Parse(NW_XML_Reader_t* pT, const struct NW_XML_Parser_EventCallbacks_s* pE)
       
  2165 {
       
  2166     /*
       
  2167     [1] document ::= prolog element Misc*
       
  2168     */
       
  2169     NW_Status_t s = NW_STAT_SUCCESS;
       
  2170     RPointerArray <CXML_Internal_Entity_t>  internalEntityList;
       
  2171 
       
  2172     if (pE->StartDocument_CB != NULL) {
       
  2173         s = (*(pE->StartDocument_CB))(pT, pE->pClientPointer);
       
  2174         if (NW_STAT_IS_FAILURE(s)) {
       
  2175             s =  NW_STAT_FAILURE;
       
  2176             goto nw_xml_parser_final;
       
  2177         }
       
  2178     }
       
  2179 
       
  2180     s = NW_XML_Parse_PrologConsume(pT, pE,&internalEntityList);
       
  2181     if (NW_STAT_IS_FAILURE(s)) {
       
  2182         s = NW_STAT_FAILURE;
       
  2183         goto nw_xml_parser_final;
       
  2184     }
       
  2185 
       
  2186     s = NW_XML_Parse_ElementConsume(pT, pE, &internalEntityList);
       
  2187     if (NW_STAT_IS_FAILURE(s)) {
       
  2188         s =  NW_STAT_FAILURE;
       
  2189         goto nw_xml_parser_final;
       
  2190     }
       
  2191 
       
  2192     s = NW_XML_Parse_MiscConsume(pT, pE, &internalEntityList);
       
  2193     if (NW_STAT_IS_FAILURE(s) && !NW_XML_Reader_AtEnd(pT)) {
       
  2194         s = NW_STAT_FAILURE;
       
  2195         goto nw_xml_parser_final;
       
  2196     }
       
  2197 
       
  2198     if (!NW_XML_Reader_AtEnd(pT)) {
       
  2199         s = NW_STAT_FAILURE;
       
  2200         goto nw_xml_parser_final;
       
  2201     }
       
  2202 
       
  2203     if (pE->EndDocument_CB != NULL) {
       
  2204         s = (*(pE->EndDocument_CB))(pT, pE->pClientPointer);
       
  2205         if (NW_STAT_IS_FAILURE(s)) {
       
  2206             goto nw_xml_parser_final;
       
  2207         }
       
  2208     }
       
  2209 
       
  2210 nw_xml_parser_final:
       
  2211 
       
  2212     CXML_XML_Parser_Free_I_Entity_List(internalEntityList);
       
  2213     return s;
       
  2214 }
       
  2215