diff options
Diffstat (limited to 'media/libdrm/mobile1/src/xml/xml_tinyparser.c')
-rw-r--r-- | media/libdrm/mobile1/src/xml/xml_tinyparser.c | 834 |
1 files changed, 834 insertions, 0 deletions
diff --git a/media/libdrm/mobile1/src/xml/xml_tinyparser.c b/media/libdrm/mobile1/src/xml/xml_tinyparser.c new file mode 100644 index 000000000000..7580312d9e8f --- /dev/null +++ b/media/libdrm/mobile1/src/xml/xml_tinyparser.c @@ -0,0 +1,834 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <xml/xml_tinyParser.h> + +int32_t xml_errno; + +#ifdef XML_DOM_PARSER + +#define XML_IS_WHITESPACE(x) ((x) == '\t' || (x) == '\n' || (x) == ' ' || (x) == '\r') +#define XML_IS_NAMECHAR(ch) (isalpha(ch) || isdigit(ch) || ch ==':' || \ + ch == '_' || ch == '-' || ch =='.') + +static uint8_t *xml_ignore_blank(uint8_t *buffer) +{ + if (NULL == buffer) + return NULL; + + while (XML_IS_WHITESPACE(*buffer)) + buffer++; + + return buffer; +} + +static uint8_t *xml_goto_tagend(uint8_t *buffer) +{ + int32_t nameLen, valueLen; + uint8_t *name, *value; + + if (NULL == buffer) + return NULL; + + /* Ignore the start-tag */ + if (*buffer == '<') { + buffer++; + while (buffer != NULL && XML_IS_NAMECHAR(*buffer)) + buffer++; + if (NULL == buffer) + return NULL; + } + + do { + if (NULL == (buffer = xml_ignore_blank(buffer))) + return NULL; + + if (*buffer == '>' || (*buffer == '/' && *(buffer + 1) == '>')) + return buffer; + + if (NULL == + XML_DOM_getAttr(buffer, &name, &nameLen, &value, &valueLen)) + return NULL; + + buffer = value + valueLen + 1; + } while (*buffer != '\0'); + + return NULL; +} + +static uint8_t *xml_match_tag(uint8_t *buffer) +{ + int32_t tagLen, tagType, bal; + + if (NULL == buffer) + return NULL; + + bal = 0; + do { + if (NULL == (buffer = XML_DOM_getTag(buffer, &tagLen, &tagType))) + return NULL; + + switch (tagType) { + case XML_TAG_SELF: + case XML_TAG_START: + if (NULL == (buffer = xml_goto_tagend(buffer + tagLen + 1))) + return NULL; + if (strncmp((char *)buffer, "/>", 2) == 0) { + buffer += 2; + } else { + bal++; + } + break; + + case XML_TAG_END: + if (bal <= 0) + return NULL; + buffer = buffer + tagLen + 2; + bal--; + break; + } + } while (bal != 0); + + return buffer; +} + +uint8_t *XML_DOM_getAttr(uint8_t *buffer, uint8_t **pName, int32_t *nameLen, + uint8_t **pValue, int32_t *valueLen) +{ + uint8_t charQuoted; + + if (NULL == buffer) { + XML_ERROR(XML_ERROR_BUFFER_NULL); + return NULL; + } + + /* Ignore the tag */ + if (*buffer == '<') { + buffer++; + /* Ignore the STag */ + while (buffer != NULL && XML_IS_NAMECHAR(*buffer)) + buffer++; + if (NULL == buffer) + return NULL; + } + + if (NULL == (buffer = xml_ignore_blank(buffer))) { + XML_ERROR(XML_ERROR_BUFFER_NULL); + return NULL; + } + + /* Name */ + *pName = buffer; + while (buffer != NULL && XML_IS_NAMECHAR(*buffer)) + buffer++; + if (NULL == buffer) { + XML_ERROR(XML_ERROR_ATTR_NAME); + return NULL; + } + *nameLen = buffer - *pName; + if (*nameLen <= 0) { + XML_ERROR(XML_ERROR_ATTR_NAME); + return NULL; + } + + /* '=' */ + buffer = xml_ignore_blank(buffer); + if (NULL == buffer || *buffer != '=') { + XML_ERROR(XML_ERROR_ATTR_MISSED_EQUAL); + return NULL; + } + + /* Value */ + buffer++; + buffer = xml_ignore_blank(buffer); + if (NULL == buffer || (*buffer != '"' && *buffer != '\'')) { + XML_ERROR(XML_ERROR_ATTR_VALUE); + return NULL; + } + charQuoted = *buffer++; + *pValue = buffer; + while (*buffer != '\0' && *buffer != charQuoted) + buffer++; + if (*buffer != charQuoted) { + XML_ERROR(XML_ERROR_ATTR_VALUE); + return NULL; + } + *valueLen = buffer - *pValue; + + XML_ERROR(XML_ERROR_OK); + + return buffer + 1; +} + +uint8_t *XML_DOM_getValue(uint8_t *buffer, uint8_t **pValue, int32_t *valueLen) +{ + uint8_t *pEnd; + + if (NULL == buffer) { + XML_ERROR(XML_ERROR_BUFFER_NULL); + return NULL; + } + + /* Ignore the STag */ + if (*buffer == '<') { + buffer++; + /* If it's an end_tag, no value should be returned */ + if (*buffer == '/') { + *valueLen = 0; + XML_ERROR(XML_ERROR_NOVALUE); + return NULL; + } + + while (buffer != NULL && XML_IS_NAMECHAR(*buffer)) + buffer++; + if (NULL == buffer) { + XML_ERROR(XML_ERROR_BUFFER_NULL); + return NULL; + } + + if (NULL == (buffer = xml_goto_tagend(buffer))) { + XML_ERROR(XML_ERROR_PROPERTY_END); + return NULL; + } + } + + /* <test/> node found */ + if (*buffer == '/') { + if (*(buffer + 1) != '>') { + XML_ERROR(XML_ERROR_PROPERTY_END); + return NULL; + } + XML_ERROR(XML_ERROR_OK); + *valueLen = 0; + return buffer; + } + + if (*buffer == '>') + buffer++; + + if (NULL == (buffer = xml_ignore_blank(buffer))) { + XML_ERROR(XML_ERROR_BUFFER_NULL); + return NULL; + } + + /* the following is a tag instead of the value */ + if (*buffer == '<') { /* nono value, such as <test></test> */ + buffer++; + if (*buffer != '/') { + XML_ERROR(XML_ERROR_ENDTAG); + return NULL; + } + *valueLen = 0; + XML_ERROR(XML_ERROR_OK); + return NULL; + } + + *pValue = buffer; + pEnd = NULL; + while (*buffer != '\0' && *buffer != '<') { + if (!XML_IS_WHITESPACE(*buffer)) + pEnd = buffer; + buffer++; + } + if (*buffer != '<' || pEnd == NULL) { + XML_ERROR(XML_ERROR_VALUE); + return NULL; + } + + *valueLen = pEnd - *pValue + 1; + + buffer++; + if (*buffer != '/') { + XML_ERROR(XML_ERROR_ENDTAG); + return NULL; + } + + XML_ERROR(XML_ERROR_OK); + + return buffer - 1; +} + +uint8_t *XML_DOM_getTag(uint8_t *buffer, int32_t *tagLen, int32_t *tagType) +{ + uint8_t *pStart; + + /* WARNING: <!-- --> comment is not supported in this verison */ + if (NULL == buffer) { + XML_ERROR(XML_ERROR_BUFFER_NULL); + return NULL; + } + + do { + while (*buffer != '<') { + if (*buffer == '\0') { + XML_ERROR(XML_ERROR_BUFFER_NULL); + return NULL; + } + + if (*buffer == '\"' || *buffer == '\'') { + uint8_t charQuoted = *buffer; + buffer++; + while (*buffer != '\0' && *buffer != charQuoted) + buffer++; + if (*buffer == '\0') { + XML_ERROR(XML_ERROR_BUFFER_NULL); + return NULL; + } + } + buffer++; + } + buffer++; + } while (*buffer == '!' || *buffer == '?'); + + pStart = buffer - 1; + + if (*buffer == '/') { + buffer++; + *tagType = XML_TAG_END; + } else { + /* check here if it is self-end-tag */ + uint8_t *pCheck = xml_goto_tagend(pStart); + if (pCheck == NULL) { + XML_ERROR(XML_ERROR_PROPERTY_END); + return NULL; + } + + if (*pCheck == '>') + *tagType = XML_TAG_START; + else if (strncmp((char *)pCheck, "/>", 2) == 0) + *tagType = XML_TAG_SELF; + else { + XML_ERROR(XML_ERROR_PROPERTY_END); + return NULL; + } + } + + while (buffer != NULL && XML_IS_NAMECHAR(*buffer)) + buffer++; + if (NULL == buffer) { + XML_ERROR(XML_ERROR_BUFFER_NULL); + return NULL; + } + + if (*tagType == XML_TAG_END) + *tagLen = buffer - pStart - 2; + else + *tagLen = buffer - pStart - 1; + + XML_ERROR(XML_ERROR_OK); + + return pStart; +} + +uint8_t *XML_DOM_getNode(uint8_t *buffer, const uint8_t *const node) +{ + uint8_t *pStart; + uint8_t buf[XML_MAX_PROPERTY_LEN + 2]; + uint8_t *nodeStr = buf; + uint8_t *retPtr = NULL; + int32_t tagLen, tagType; + uint8_t *lastNode = (uint8_t *)""; + + if (NULL == buffer) { + XML_ERROR(XML_ERROR_BUFFER_NULL); + return NULL; + } + + strncpy((char *)nodeStr, (char *)node, XML_MAX_PROPERTY_LEN); + strcat((char *)nodeStr, "\\"); + pStart = (uint8_t *)strchr((char *)nodeStr, '\\'); + + while (pStart != NULL) { + *pStart = '\0'; + + /* get the first start_tag from buffer */ + if (NULL == (buffer = XML_DOM_getTag(buffer, &tagLen, &tagType))) { + XML_ERROR(XML_ERROR_NO_SUCH_NODE); + return NULL; + } + + if (tagType == XML_TAG_END) { + if (0 == + strncmp((char *)lastNode, (char *)(buffer + 2), strlen((char *)lastNode))) + XML_ERROR(XML_ERROR_NO_SUCH_NODE); + else + XML_ERROR(XML_ERROR_NO_START_TAG); + return NULL; + } + + /* wrong node, contiue to fetch the next node */ + if ((int32_t) strlen((char *)nodeStr) != tagLen + || strncmp((char *)nodeStr, (char *)(buffer + 1), tagLen) != 0) { + /* we should ignore all the middle code */ + buffer = xml_match_tag(buffer); + continue; + } + + retPtr = buffer; /* retPtr starts with '<xxx>' */ + buffer += (tagLen + 1); + + if (tagType == XML_TAG_SELF) { + nodeStr = pStart + 1; + break; + } + + lastNode = nodeStr; + nodeStr = pStart + 1; + pStart = (uint8_t *)strchr((char *)nodeStr, '\\'); + } + + /* Check 5: nodeStr should be empty here */ + if (*nodeStr != '\0') { + XML_ERROR(XML_ERROR_NO_SUCH_NODE); + return NULL; + } + + XML_ERROR(XML_ERROR_OK); + + return retPtr; +} + +uint8_t *XML_DOM_getNodeValue(uint8_t *buffer, uint8_t *node, + uint8_t **value, int32_t *valueLen) +{ + uint8_t *pStart; + uint8_t *lastTag; + + if (NULL == node || NULL == buffer) { + XML_ERROR(XML_ERROR_BUFFER_NULL); + return NULL; + } + + lastTag = node + strlen((char *)node) - 1; + while (lastTag >= node && *lastTag != '\\') + lastTag--; + lastTag++; + + if (NULL == (pStart = XML_DOM_getNode(buffer, node))) + return NULL; + + pStart += (strlen((char *)lastTag) + 1); + + if (NULL == (pStart = xml_goto_tagend(pStart))) { + XML_ERROR(XML_ERROR_PROPERTY_END); + return NULL; + } + + if (NULL == (pStart = XML_DOM_getValue(pStart, value, valueLen))) + return NULL; + + /* Check the end tag */ +#ifdef XML_DOM_CHECK_ENDTAG + if (strncmp((char *)pStart, "/>", 2) == 0) { + + } else if (strncmp((char *)lastTag, (char *)(pStart + 2), strlen((char *)lastTag)) != + 0) { + XML_ERROR(XML_ERROR_ENDTAG); + return NULL; + } +#endif + + XML_ERROR(XML_ERROR_OK); + + return *value; +} + +uint8_t *XML_DOM_getNextNode(uint8_t *buffer, uint8_t **pNodeName, int32_t *nodenameLen) +{ + int32_t tagType; + + if (NULL == buffer) + return NULL; + + do { + if (NULL == + (buffer = XML_DOM_getTag(buffer + 1, nodenameLen, &tagType))) { + XML_ERROR(XML_ERROR_NO_SUCH_NODE); + return NULL; + } + } while (tagType == XML_TAG_END); + + *pNodeName = buffer + 1; + + XML_ERROR(XML_ERROR_OK); + + return buffer; +} + +#endif /* XML_DOM_PARSER */ + +#ifdef WBXML_DOM_PARSER + +#ifdef WBXML_OLD_VERSION +uint8_t *WBXML_DOM_getNode(uint8_t *buffer, int32_t bufferLen, + uint8_t *node) +{ + int32_t i = 0, j = 0; + + if (NULL == buffer || node == NULL) { + XML_ERROR(XML_ERROR_BUFFER_NULL); + return NULL; + } + + while (i < bufferLen) { + if (WBXML_GET_TAG(buffer[i]) == WBXML_GET_TAG(node[j])) { + j++; + if (node[j] == '\0') + break; + + /* Check if there is the content(it should have content) */ + if (!WBXML_HAS_CONTENT(buffer[i])) { + /*XML_ERROR(WBXML_ERROR_MISSED_CONTENT); */ + XML_ERROR(XML_ERROR_NO_SUCH_NODE); + return NULL; + } + + /* Ignore the attrib filed */ + if (WBXML_HAS_ATTR(buffer[i])) { + while (i < bufferLen && buffer[i] != WBXML_ATTR_END) + i++; + if (i >= bufferLen) + break; + } + } + i++; + + /* Ignore the content filed */ + if (buffer[i] == WBXML_STR_I) { + while (i < bufferLen && buffer[i] != WBXML_END) + i++; + if (i >= bufferLen) + break; + i++; + } + } + + if (i >= bufferLen) { + XML_ERROR(XML_ERROR_NO_SUCH_NODE); + return NULL; + } + + XML_ERROR(XML_ERROR_OK); + + return buffer + i + 1; +} + +uint8_t *WBXML_DOM_getNodeValue(uint8_t *buffer, int32_t bufferLen, + uint8_t *node, + uint8_t **value, int32_t *valueLen) +{ + int32_t i; + uint8_t *pEnd; + + *value = NULL; + *valueLen = 0; + + pEnd = buffer + bufferLen; + buffer = WBXML_DOM_getNode(buffer, bufferLen, node); + if (NULL == buffer) { + XML_ERROR(XML_ERROR_NO_SUCH_NODE); + return NULL; + } + + if (*buffer == WBXML_OPAUE) { + buffer++; + *valueLen = WBXML_GetUintVar(buffer, &i); + if (*valueLen < 0) { + XML_ERROR(WBXML_ERROR_MBUINT32); + return NULL; + } + buffer += i; + *value = buffer; + return *value; + } + + if (*buffer != WBXML_STR_I) { + XML_ERROR(WBXML_ERROR_MISSED_STARTTAG); + return NULL; + } + + buffer++; + + i = 0; + while ((buffer + i) < pEnd && buffer[i] != WBXML_END) + i++; + + if (buffer[i] != WBXML_END) { + XML_ERROR(WBXML_ERROR_MISSED_ENDTAG); + return NULL; + } + + *value = buffer; + *valueLen = i; + XML_ERROR(XML_ERROR_OK); + + return *value; +} +#endif /* WBXML_OLD_VERSION */ + +#define MAX_UINT_VAR_BYTE 4 +#define UINTVAR_INVALID -1 +int32_t WBXML_GetUintVar(const uint8_t *const buffer, int32_t *len) +{ + int32_t i, byteLen; + int32_t sum; + + byteLen = 0; + while ((buffer[byteLen] & 0x80) > 0 && byteLen < MAX_UINT_VAR_BYTE) + byteLen++; + + if (byteLen > MAX_UINT_VAR_BYTE) + return UINTVAR_INVALID; + + *len = byteLen + 1; + sum = buffer[byteLen]; + for (i = byteLen - 1; i >= 0; i--) + sum += ((buffer[i] & 0x7F) << 7 * (byteLen - i)); + + return sum; +} + +XML_BOOL WBXML_DOM_Init(WBXML * pWbxml, uint8_t *buffer, + int32_t bufferLen) +{ + int32_t num, len; + + pWbxml->End = buffer + bufferLen; + pWbxml->version = *buffer++; + if (UINTVAR_INVALID == (num = WBXML_GetUintVar(buffer, &len))) + return XML_FALSE; + buffer += len; + pWbxml->publicid = num; + if (UINTVAR_INVALID == (num = WBXML_GetUintVar(buffer, &len))) + return XML_FALSE; + buffer += len; + pWbxml->charset = num; + if (UINTVAR_INVALID == (num = WBXML_GetUintVar(buffer, &len))) + return XML_FALSE; + buffer += len; + pWbxml->strTable = buffer; + pWbxml->strTableLen = num; + buffer += num; + pWbxml->curPtr = pWbxml->Content = buffer; + pWbxml->depth = 0; + + return XML_TRUE; +} + +void WBXML_DOM_Rewind(WBXML * pWbxml) +{ + pWbxml->curPtr = pWbxml->Content; +} + +XML_BOOL WBXML_DOM_Eof(WBXML * pWbxml) +{ + if (pWbxml->curPtr > pWbxml->End) + return XML_TRUE; + + return XML_FALSE; +} + +uint8_t WBXML_DOM_GetTag(WBXML * pWbxml) +{ + uint8_t tagChar; + + if (pWbxml->curPtr > pWbxml->End) + return XML_EOF; + + tagChar = *pWbxml->curPtr; + pWbxml->curPtr++; + + if (WBXML_GET_TAG(tagChar) == WBXML_CONTENT_END) + pWbxml->depth--; + else + pWbxml->depth++; + + return tagChar; +} + +uint8_t WBXML_DOM_GetChar(WBXML * pWbxml) +{ + return *pWbxml->curPtr++; +} + +void WBXML_DOM_Seek(WBXML * pWbxml, int32_t offset) +{ + pWbxml->curPtr += offset; +} + +uint8_t WBXML_DOM_GetUIntVar(WBXML * pWbxml) +{ + int32_t num, len; + + num = WBXML_GetUintVar(pWbxml->curPtr, &len); + pWbxml->curPtr += len; + + return (uint8_t)num; +} + +#ifdef XML_TREE_STRUCTURE + +#ifdef DEBUG_MODE +static int32_t malloc_times = 0; +static int32_t free_times = 0; +void XML_PrintMallocInfo() +{ + printf("====XML_PrintMallocInfo====\n"); + printf(" Total malloc times:%d\n", malloc_times); + printf(" Total free times:%d\n", free_times); + printf("===========================\n"); +} +#endif + +void *xml_malloc(int32_t size) +{ +#ifdef DEBUG_MODE + malloc_times++; +#endif + return malloc(size); +} + +void xml_free(void *buffer) +{ +#ifdef DEBUG_MODE + free_times++; +#endif + free(buffer); +} + +XML_TREE *xml_tree_fillnode(uint8_t **buf, int32_t tagLen) +{ + XML_TREE *Tree; + uint8_t *pAttr, *pName, *pValue; + int32_t nameLen, valueLen; + uint8_t *buffer = *buf; + + if (NULL == (Tree = (XML_TREE *) xml_malloc(sizeof(XML_TREE)))) + return NULL; + memset(Tree, 0, sizeof(XML_TREE)); + + strncpy((char *)Tree->tag, (char *)++buffer, tagLen); + buffer += tagLen; + pAttr = buffer; + + /* attribute */ + while (NULL != + (pAttr = + XML_DOM_getAttr(pAttr, &pName, &nameLen, &pValue, + &valueLen))) { + XML_TREE_ATTR *attr; + if (NULL == + (attr = (XML_TREE_ATTR *) xml_malloc(sizeof(XML_TREE_ATTR)))) + return NULL; + memset(attr, 0, sizeof(XML_TREE_ATTR)); + strncpy((char *)attr->name, (char *)pName, nameLen); + strncpy((char *)attr->value, (char *)pValue, valueLen); + buffer = pValue + valueLen + 1; + + if (NULL != Tree->attr) // no attribute now + Tree->last_attr->next = attr; + else + Tree->attr = attr; + Tree->last_attr = attr; + } + + /* value */ + pAttr = XML_DOM_getValue(buffer, &pValue, &valueLen); + if (pAttr != NULL && valueLen > 0) { + strncpy((char *)Tree->value, (char *)pValue, valueLen); + buffer = pValue + valueLen; + } + + *buf = buffer; + return Tree; +} + +XML_TREE *XML_makeTree(uint8_t **buf) +{ + uint8_t *pBuf; + int32_t valueLen, tagType; + uint8_t *buffer = *buf; + XML_TREE *TreeHead = NULL; + + if (NULL == (buffer = XML_DOM_getTag(buffer, &valueLen, &tagType))) + return NULL; + if (XML_TAG_END == tagType) + return NULL; + if (NULL == (TreeHead = xml_tree_fillnode(&buffer, valueLen))) + return NULL; + if (XML_TAG_SELF == tagType) { + *buf = buffer; + return TreeHead; + } + + do { + if (NULL == (pBuf = XML_DOM_getTag(buffer, &valueLen, &tagType))) + return NULL; + + switch (tagType) { + case XML_TAG_SELF: + case XML_TAG_START: + if (NULL == TreeHead->child) + TreeHead->child = XML_makeTree(&buffer); + else if (NULL == TreeHead->child->last_brother) { + TreeHead->child->brother = XML_makeTree(&buffer); + TreeHead->child->last_brother = TreeHead->child->brother; + } else { + TreeHead->child->last_brother->brother = + XML_makeTree(&buffer); + TreeHead->child->last_brother = + TreeHead->child->last_brother->brother; + } + break; + case XML_TAG_END: + *buf = pBuf; + return TreeHead; + } + buffer++; + } while (1); +} + +void XML_freeTree(XML_TREE * pTree) +{ + XML_TREE *p, *pNext; + XML_TREE_ATTR *pa, *lastpa; + + if (NULL == pTree) + return; + + p = pTree->brother; + while (NULL != p) { + pNext = p->brother; + p->brother = NULL; + XML_freeTree(p); + p = pNext; + } + + if (NULL != pTree->child) + XML_freeTree(pTree->child); + + pa = pTree->attr; + while (NULL != pa) { + lastpa = pa; + pa = pa->next; + xml_free(lastpa); + } + xml_free(pTree); +} + +#endif /* XML_TREE_STRUCTURE */ + +#endif /* WBXML_DOM_PARSER */ |