📄 wbxmldec.c
字号:
/*
* Copyright (C) Ericsson Mobile Communications AB, 2000.
* Licensed to AU-System AB.
* All rights reserved.
*
* This software is covered by the license agreement between
* the end user and AU-System AB, and may be used and copied
* only in accordance with the terms of the said agreement.
*
* Neither Ericsson Mobile Communications AB nor AU-System AB
* assumes any responsibility or liability for any errors or inaccuracies in
* this software, or any consequential, incidental or indirect damage arising
* out of the use of the Generic WAP Client software.
*/
/* ==================================================================
FILE: wbxmldec.c
General WBXML-decoder.
Rev history:
990302 JPR Created
990322 JPR Modified
990323 JPR WAP 1.1
990326 JPR Corrections in Prolog-decoding
990330 JPR Common string-decoding functions used
990406 JPR Corrections
990427 JPR Supports new CLNTa_error functions
990610 JPR Removal of unreferenced variables
990812 JPR Updated to support channel decoding
990827 JPR Extended WML-parsing
991109 JPR TR 173. Correction in WBXML_ParseElement
991116 JPR Updated to support PUSH Content-types
991124 JPR Redesign of Element Handling, Text Handling,
and Error Handling (Consult separate document).
Updates for WAP 1.2 are also included.
991126 JPR Application specific parts and calls to
CLNTa_error removed
991208 JPR ViewId removed
991222 JPR Charset handling changed
000104 JPR Change in DTD_CreateElement
000211 JPR Correction in function WBXML_DecodeContent
and WBXML_DecodeAttributeValue (OPAQUE)
000303 JPR Function WBXML_GetContentType added
000510 JPR Call stack reduction implemented
000526 JPR Function WBXML_CheckPublicID modified
000808 JPR Correction in code page handling
000814 JPR Functions WBXML_StepPastAllPIs and
WBXML_StepPastOnePI added
000925 JPR Correction in WBXML_DecodeProlog (WBXML 1.3 added)
001220 NKE Added missing public id WBXML 1.3 codes
010105 NKE WBXML decoder rewritten to avoid recursion and
enable scheduled execution. Replaced WBXML_DecodeElement
WBXML_DecodeContent with WBXML_Decode and WBXML_InitDedcode.
Added helpfunctions WBXML_DeleteCurrentElement and
WBXML_AddElement. Updated several other functions.
010126 NKE Activated scheduled excecution. Improved several functions.
010210 NKE Minor bugfixes.
010319 IPN TR 342, Memory optimizing in WBXML_DecodeAttributeValue
and WBXML_DecodeAttributes
010330 KEOL Added some functionality for handling provisoning
010502 ASPN WTA-WML support modified.
================================================================== */
#include "wbxmldec.h"
#include "wbxmlelm.h"
#include "trnscode.h"
#include "prov_dec.h"
#include "hdrutil.h"
#define MORE_DATA (decodeStruct->pbCurByte < decodeStruct->pbEnd)
#define WBXML_STATE_0 0
#define WBXML_STATE_1 1
#define WBXML_STATE_2 2
/*========================================================================
WBXML_GetStrTabVal
==========================================================================*/
WCHAR* WBXML_GetStrTabVal (pWBXMLDECODESTR decodeStruct, UINT32 offset)
{
pSTRINGTABSTR tabElem;
for (tabElem = decodeStruct->pStrTab; tabElem != NULL; tabElem = tabElem->pNext)
if (tabElem->iOffset == offset)
return tabElem->pwchString;
decodeStruct->iDecodeResult |= WBXML_Error_StringTable;
return NULL;
}
/*========================================================================
WBXML_CreateWBXMLDecStr
==========================================================================*/
pWBXMLDECODESTR WBXML_CreateWBXMLDecStr (void)
{
pWBXMLDECODESTR pDecStr=NULL;
/* Allocate memory */
pDecStr=NEWSTRUCT(WBXMLDECODESTR);
if (pDecStr!=NULL)
{
pDecStr->pbCurByte=NULL;
pDecStr->pbEnd=NULL;
pDecStr->iCharset=IANA_CHARSET_INVALID;
pDecStr->iContentLevel=0;
pDecStr->bContentType=0;
pDecStr->iVersion=0;
pDecStr->iAttrCodePage=0;
pDecStr->iTagCodePage=0;
pDecStr->iDecodeResult=0;
pDecStr->pStrTab=NULL;
pDecStr->pAppSpec=NULL;
}
return pDecStr;
}
void WBXML_DelStrTab (pWBXMLDECODESTR pDecStr)
{
pSTRINGTABSTR pStrTemp=NULL;
while (pDecStr->pStrTab!=NULL)
{
DEALLOC(&(pDecStr->pStrTab->pwchString));
pStrTemp=pDecStr->pStrTab;
pDecStr->pStrTab=pDecStr->pStrTab->pNext;
DEALLOC(&pStrTemp);
}
}
/*========================================================================
WBXML_DeleteWBXMLDecStr
==========================================================================*/
void WBXML_DeleteWBXMLDecStr (pWBXMLDECODESTR *ppDecStr)
{
if (*ppDecStr!=NULL)
{
WBXML_DelStrTab (*ppDecStr);
DEALLOC(ppDecStr);
}
}
/*========================================================================
WBXML_CopyCharToWChar
==========================================================================*/
WCHAR* WBXML_CopyCharToWChar (pWBXMLDECODESTR pDecStr, CHAR* src)
{
WCHAR *pchTempValue=NULL;
/* ASSERT: pDecStr!=NULL
src!=NULL
*/
pchTempValue=w_cstr2wstr(src);
pDecStr=pDecStr;
#ifndef HAS_SETJMP
if (pchTempValue==NULL)
{
/* Could not create copy - out of memory. */
pDecStr->iDecodeResult|=WBXML_Error_OutOfMemory;
}
#endif
return pchTempValue;
}
/*========================================================================
WBXML_GetSTR_I
==========================================================================*/
WCHAR *WBXML_GetSTR_I (pWBXMLDECODESTR pDecStr)
{
INT16 iCharset=pDecStr->iCharset;
INT32 iLength=0;
UINT32 iBytes=0;
WCHAR *pchResult=NULL;
if ( pDecStr->pbCurByte < pDecStr->pbEnd )
{
/* Calculate length */
iLength=Iana2Unicode_calcLen (pDecStr->pbCurByte, iCharset, TRUE,
pDecStr->pbEnd-pDecStr->pbCurByte, &iBytes);
/* Check result */
if (iLength<0)
{
/* Not OK. Interpret as iso-latin-1 */
pDecStr->iDecodeResult|=WBXML_Warning_UnknownCharset;
iCharset=IANA_CHARSET_LATIN1;
Iana2Unicode_calcLen (pDecStr->pbCurByte, iCharset, TRUE,
pDecStr->pbEnd-pDecStr->pbCurByte, &iBytes);
iLength=iBytes;
}
/* Create result buffer */
pchResult=NEWARRAY(WCHAR,iLength+1);
/* Convert string */
if (pchResult!=NULL)
{
/* Set termination character */
pchResult[iLength]=0;
if (Iana2Unicode_convert(pDecStr->pbCurByte, iCharset, iBytes,
pchResult, iLength))
{
/* Step past string */
pDecStr->pbCurByte+=iBytes+Iana2Unicode_getNullTermByteLen(iCharset);
}
else
{
/* Error */
DEALLOC(&pchResult);
/* Charset error */
pDecStr->iDecodeResult|=WBXML_Error_CharsetEncoding;
}
}
else
{
/* Out of memory */
pDecStr->iDecodeResult|=WBXML_Error_OutOfMemory;
}
}
else
{
/* Data stream error */
pDecStr->iDecodeResult|=WBXML_Error_DataStream;
}
/* Return string */
return pchResult;
}
/*========================================================================
WBXML_GetMBUINT32
==========================================================================*/
UINT32 WBXML_GetMBUINT32 (pWBXMLDECODESTR pDecStr)
{
UINT32 iPos=0;
UINT32 iResult=0;
if ( pDecStr->pbCurByte < pDecStr->pbEnd )
{
if (ReadMBUInt32(&iResult,pDecStr->pbCurByte,
pDecStr->pbEnd-pDecStr->pbCurByte,&iPos))
{
/* Step forward */
pDecStr->pbCurByte+=iPos;
}
else
{
/* Fatal error. Error in encoding of MBUINT32. */
pDecStr->iDecodeResult|=WBXML_Error_MbuintEncoding;
}
}
else
{
/* Instream error */
pDecStr->iDecodeResult|=WBXML_Error_DataStream;
}
return iResult;
}
/*========================================================================
WBXML_CheckIfGlobalText
==========================================================================*/
BOOL WBXML_CheckIfGlobalText (BYTE bToken)
{
/* Check if ( string | extension | entity ) */
switch (bToken)
{
case GLOBAL_ENTITY:
case GLOBAL_STR_I:
case GLOBAL_EXT_I_0:
case GLOBAL_EXT_I_1:
case GLOBAL_EXT_I_2:
case GLOBAL_EXT_T_0:
case GLOBAL_EXT_T_1:
case GLOBAL_EXT_T_2:
case GLOBAL_STR_T:
case GLOBAL_EXT_0:
case GLOBAL_EXT_1:
case GLOBAL_EXT_2:
return TRUE;
}
return FALSE;
}
/*========================================================================
WBXML_DecodeGlobalText
==========================================================================*/
pELEMENTTYPE WBXML_DecodeGlobalText (pWBXMLDECODESTR pDecStr)
{
pELEMENTTYPE pElement=NULL;
WCHAR *pwchString=NULL;
BYTE bToken=0;
UINT32 iMBUINT32=0;
if ( pDecStr->pbCurByte < pDecStr->pbEnd )
{
bToken=*pDecStr->pbCurByte++;
switch (bToken)
{
/* Entity */
case GLOBAL_ENTITY:
/* Get mbuint32 */
iMBUINT32=WBXML_GetMBUINT32 (pDecStr);
/* Create element */
pElement=XML_CreateEntity (iMBUINT32);
break;
/* Inline string */
case GLOBAL_STR_I:
/* Get inline string */
pwchString=WBXML_GetSTR_I(pDecStr);
/* Create inline text element */
pElement=XML_CreateInlineText(&pwchString);
break;
/* Extension with inline string */
case GLOBAL_EXT_I_0:
case GLOBAL_EXT_I_1:
case GLOBAL_EXT_I_2:
/* Get inline string */
pwchString=WBXML_GetSTR_I(pDecStr);
/* Create extension element */
pElement=XML_CreateExt(&pwchString, bToken);
break;
case GLOBAL_STR_T:
/* Get mbuint32 */
iMBUINT32=WBXML_GetMBUINT32 (pDecStr);
/* Create string table text element */
pElement=XML_CreateTableText(iMBUINT32);
break;
case GLOBAL_EXT_T_0:
case GLOBAL_EXT_T_1:
case GLOBAL_EXT_T_2:
/* Get mbuint32 */
iMBUINT32=WBXML_GetMBUINT32 (pDecStr);
/* Get copy of string table element */
pwchString=CreateStringCopy(WBXML_GetStrTabVal(pDecStr,iMBUINT32));
/* Create extension element */
pElement=XML_CreateExt(&pwchString, bToken);
break;
case GLOBAL_EXT_0:
case GLOBAL_EXT_1:
case GLOBAL_EXT_2:
pwchString=NULL;
/* Create extension element */
pElement=XML_CreateExt(&pwchString, bToken);
break;
}
}
else
{
/* Instream error */
pDecStr->iDecodeResult|=WBXML_Error_DataStream;
}
return pElement;
}
/*========================================================================
WBXML_DecodeAttributeValue
==========================================================================*/
pELEMENTTYPE WBXML_DecodeAttributeValue (pWBXMLDECODESTR pDecStr)
{
BOOL fCont=TRUE;
BYTE bToken=NULL;
pELEMENTTYPE pAttrVal=NULL;
pELEMENTTYPE pAttrPart=NULL;
/* Get all attribute value parts */
while ( (pDecStr->pbCurByte < pDecStr->pbEnd ) && (fCont) && pDecStr->iDecodeResult < WBXML_FatalError )
{
pAttrPart=NULL;
bToken=*pDecStr->pbCurByte;
/* Switch page */
if (bToken==GLOBAL_SWITCH_PAGE)
{
pDecStr->pbCurByte++;
/* Switch Attribute Code Page */
if ( pDecStr->pbCurByte < pDecStr->pbEnd )
{
pDecStr->iAttrCodePage=*pDecStr->pbCurByte;
pDecStr->pbCurByte++;
}
}
/* End */
else if (bToken==GLOBAL_END)
{
fCont=FALSE;
}
/* ( string | extension | entity ) */
else if (WBXML_CheckIfGlobalText(bToken))
{
/* Get Text-element */
pAttrPart=WBXML_DecodeGlobalText (pDecStr);
}
/* OPAQUE */
else if (bToken==GLOBAL_OPAQUE)
{
UINT32 iLength=0;
pDecStr->pbCurByte++;
/* Get length (mbuint32) */
iLength=WBXML_GetMBUINT32 (pDecStr);
/* Copy data */
if ( pDecStr->pbCurByte+iLength < pDecStr->pbEnd )
{
BYTE* pbData=NEWARRAY (BYTE,iLength);
#ifndef HAS_SETJMP
if (pbData!=NULL)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -