📄 ixmlparser.c
字号:
return -1;
}
/*==============================================================================*
* Parser_copyToken
* copy string in src into xml parser token buffer
* Internal to parser only.
*
*===============================================================================*/
static int
Parser_copyToken( IN Parser * xmlParser,
IN char *src,
IN int len )
{
int i,
c,
cl;
char *psrc,
*pend;
utf8char uch;
if( !src || len <= 0 ) {
return IXML_FAILED;
}
psrc = src;
pend = src + len;
while( psrc < pend ) {
if( ( c = Parser_getChar( psrc, &cl ) ) <= 0 ) {
return IXML_FAILED;
}
if( cl == 1 ) {
Parser_appendTokBufChar( xmlParser, ( char )c );
psrc++;
} else {
i = Parser_intToUTF8( c, uch );
if( i == 0 ) {
return IXML_FAILED;
}
Parser_appendTokBufStr( xmlParser, uch );
psrc += cl;
}
}
if( psrc > pend ) {
return IXML_FAILED;
} else {
return IXML_SUCCESS; // success
}
}
/*==============================================================================*
*
* Parser_skipString
* Skips all characters in the string until it finds the skip key.
* Then it skips the skip key and returns.
* Internal to parser only
*
*===============================================================================*/
static int
Parser_skipString( INOUT char **pstrSrc,
IN const char *strSkipKey )
{
if( !( *pstrSrc ) || !strSkipKey ) {
return IXML_FAILED;
}
while( ( **pstrSrc )
&& strncmp( *pstrSrc, strSkipKey,
strlen( strSkipKey ) ) != 0 ) {
( *pstrSrc )++;
}
if( **pstrSrc == '\0' ) {
return IXML_SYNTAX_ERR;
}
*pstrSrc = *pstrSrc + strlen( strSkipKey );
return IXML_SUCCESS; //success
}
/*==============================================================================*
*
* Function:
* Returns:
*
*
*===============================================================================*/
static int
Parser_skipPI( INOUT char **pSrc )
{
char *pEnd = NULL;
assert( *pSrc );
if( *pSrc == NULL ) {
return IXML_FAILED;
}
if( ( strncasecmp( *pSrc, ( char * )XMLDECL, strlen( XMLDECL ) ) == 0 ) || ( strncasecmp( *pSrc, ( char * )XMLDECL2, strlen( XMLDECL2 ) ) == 0 ) ) { // not allowed
return IXML_SYNTAX_ERR;
}
if( strncasecmp( *pSrc, ( char * )BEGIN_PI, strlen( BEGIN_PI ) ) == 0 ) {
pEnd = strstr( *pSrc, END_PI );
if( ( pEnd != NULL ) && ( pEnd != *pSrc ) ) {
*pSrc = pEnd + strlen( BEGIN_PI );
} else {
return IXML_SYNTAX_ERR;
}
}
return IXML_SUCCESS;
}
/*==============================================================================*
* Parser_skipXMLDecl:
* skips XML declarations.
* Internal only to parser.
*
*===============================================================================*/
static int
Parser_skipXMLDecl( INOUT Parser * xmlParser )
{
int rc = IXML_FAILED;
assert( xmlParser );
if( xmlParser == NULL ) {
return rc;
}
rc = Parser_skipString( &( xmlParser->curPtr ), END_PI );
Parser_skipWhiteSpaces( xmlParser );
return rc;
}
/*==============================================================================*
* Parser_skipProlog
* skip prolog
* Internal to parser only.
*
*===============================================================================*/
static int
Parser_skipProlog( INOUT Parser * xmlParser )
{
int rc = IXML_SUCCESS;
assert( xmlParser != NULL );
if( xmlParser == NULL ) {
return IXML_FAILED;
}
Parser_skipWhiteSpaces( xmlParser );
if( strncmp( xmlParser->curPtr, ( char * )XMLDECL, strlen( XMLDECL ) ) == 0 ) { // <?xml
rc = Parser_skipXMLDecl( xmlParser );
if( rc != IXML_SUCCESS ) {
return rc;
}
}
rc = Parser_skipMisc( xmlParser );
if( ( rc == IXML_SUCCESS ) && strncmp( xmlParser->curPtr, ( char * )BEGIN_DOCTYPE, strlen( BEGIN_DOCTYPE ) ) == 0 ) { // <! DOCTYPE
xmlParser->curPtr++;
rc = Parser_skipDocType( &( xmlParser->curPtr ) );
}
if( rc == IXML_SUCCESS ) {
rc = Parser_skipMisc( xmlParser );
}
return rc;
}
/*==============================================================================*
*
* Function:
* Returns:
* Skips all characters in the string until it finds the skip key.
* Then it skips the skip key and returns.
*
*===============================================================================*/
static int
Parser_skipComment( INOUT char **pstrSrc )
{
char *pStrFound = NULL;
assert( ( *pstrSrc ) != NULL );
if( *pstrSrc == NULL ) {
return IXML_FAILED;
}
pStrFound = strstr( *pstrSrc, END_COMMENT );
if( ( pStrFound != NULL ) && ( pStrFound != *pstrSrc ) &&
( *( pStrFound - 1 ) != '-' ) ) {
*pstrSrc = pStrFound + strlen( END_COMMENT );
} else {
return IXML_SYNTAX_ERR;
}
return IXML_SUCCESS;
}
/*==============================================================================*
* Parser_skipDocType
* skips document type declaration
*
*===============================================================================*/
static int
Parser_skipDocType( INOUT char **pstr )
{
char *pCur = *pstr;
char *pNext = NULL; // default there is no nested <
int num = 1;
assert( ( *pstr ) != NULL );
if( *pstr == NULL ) {
return IXML_FAILED;
}
while( ( pCur != NULL ) && ( num != 0 ) && ( *pCur != 0 ) ) {
if( *pCur == '<' ) {
num++;
} else if( *pCur == '>' ) {
num--;
} else if( *pCur == '"' ) {
pNext = strchr( pCur + 1, '"' );
if( pNext == NULL ) {
return IXML_SYNTAX_ERR;
}
pCur = pNext;
}
pCur++;
}
if( num == 0 ) {
*pstr = pCur;
return IXML_SUCCESS;
} else {
return IXML_SYNTAX_ERR;
}
}
/*==============================================================================*
*
* Parser_skipMisc:
* skip comment, PI and white space
*
*
*===============================================================================*/
static int
Parser_skipMisc( IN Parser * xmlParser )
{
int rc = IXML_SUCCESS;
int done = FALSE;
while( ( done == FALSE ) && ( rc == IXML_SUCCESS ) ) {
if( strncasecmp( xmlParser->curPtr, ( char * )BEGIN_COMMENT, strlen( BEGIN_COMMENT ) ) == 0 ) { // <!--
rc = Parser_skipComment( &( xmlParser->curPtr ) );
} else if( ( strncasecmp( xmlParser->curPtr, ( char * )XMLDECL, strlen( XMLDECL ) ) == 0 ) || ( strncasecmp( xmlParser->curPtr, ( char * )XMLDECL2, strlen( XMLDECL2 ) ) == 0 ) ) { // <?xml or <?xml?
rc = IXML_SYNTAX_ERR;
} else if( strncasecmp( xmlParser->curPtr, ( char * )BEGIN_PI, strlen( BEGIN_PI ) ) == 0 ) { // <?
rc = Parser_skipString( &( xmlParser->curPtr ), END_PI );
} else {
done = TRUE;
}
Parser_skipWhiteSpaces( xmlParser );
}
return rc;
}
/*==============================================================================*
*
* Parser_getNextToken
* return the length of next token in tokenBuff
*
*
*===============================================================================*/
static int
Parser_getNextToken( IN Parser * xmlParser )
{
int tokenLength = 0;
int temp,
tlen;
int rc;
Parser_clearTokenBuf( xmlParser );
if( *( xmlParser->curPtr ) == '\0' ) {
return 0;
}
// skip XML instructions
rc = Parser_skipMisc( xmlParser );
if( rc != IXML_SUCCESS ) {
return 0;
}
// Attribute value logic must come first, since all text untokenized until end-quote
if( *( xmlParser->curPtr ) == QUOTE ) {
tokenLength = 1;
} else if( *( xmlParser->curPtr ) == SINGLEQUOTE ) {
tokenLength = 1;
} else if( *( xmlParser->curPtr ) == LESSTHAN ) { // Check for start tags
temp = Parser_UTF8ToInt( xmlParser->curPtr + 1, &tlen );
if( temp == '/' ) {
tokenLength = 2; // token is '</' end tag
} else if( Parser_isNameChar( temp, FALSE ) == TRUE ) {
tokenLength = 1; // '<' found, so return '<' token
} else {
return 0; //error
}
} else if( *( xmlParser->curPtr ) == EQUALS ) { // Check for '=' token, return it as a token
tokenLength = 1;
} else if( *( xmlParser->curPtr ) == SLASH ) {
if( *( xmlParser->curPtr + 1 ) == GREATERTHAN ) { // token '/>' found
tokenLength = 2;
xmlParser->savePtr = xmlParser->curPtr; // fix
}
} else if( *( xmlParser->curPtr ) == GREATERTHAN ) { // > found, so return it as a token
tokenLength = 1;
} else if( Parser_isNameChar( Parser_UTF8ToInt( xmlParser->curPtr, &tlen ), FALSE ) ) { // Check for name tokens, name found, so find out how long it is
int iIndex = tlen;
while( Parser_isNameChar
( Parser_UTF8ToInt( xmlParser->curPtr + iIndex, &tlen ),
TRUE ) ) {
iIndex += tlen;
}
tokenLength = iIndex;
} else {
return 0;
}
// Copy the token to the return string
if( Parser_copyToken( xmlParser, xmlParser->curPtr, tokenLength ) !=
IXML_SUCCESS ) {
return 0;
}
xmlParser->curPtr += tokenLength;
return tokenLength;
}
/*==============================================================================*
*
* Parser_getNameSpace
* return the namespce as defined as prefix.
* Internal to parser only
*
*===============================================================================*/
static char *
Parser_getNameSpace( IN Parser * xmlParser,
IN char *prefix )
{
IXML_ElementStack *pCur;
IXML_NamespaceURI *pNsUri;
pCur = xmlParser->pCurElement;
if( strcmp( pCur->prefix, prefix ) != 0 ) {
pNsUri = pCur->pNsURI;
while( pNsUri != NULL ) {
if( strcmp( pNsUri->prefix, prefix ) == 0 ) {
return pNsUri->nsURI;
}
pNsUri = pNsUri->nextNsURI;
}
} else {
return pCur->namespaceUri;
}
return NULL;
}
/*==============================================================================*
*
* Parser_addNamespace
* Add a namespace definition
* Internal to parser only
*
*===============================================================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -