⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlparse.c

📁 Simple Jabber Client for Symbian Platform
💻 C
📖 第 1 页 / 共 5 页
字号:
                return XML_ERROR_ASYNC_ENTITY;
            }
            return XML_ERROR_NONE;
        case XML_TOK_DATA_CHARS:
            if (characterDataHandler) {
                if (MUST_CONVERT(enc, s)) {
                    for (;;) {
                        ICHAR *dataPtr = (ICHAR *)dataBuf;
                        XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
                        *eventEndPP = s;
                        characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
                        if (s == next)
                            break;
                        *eventPP = s;
                    }
                }
                else
                    characterDataHandler(handlerArg,
                                         (XML_Char *)s,
                                         (XML_Char *)next - (XML_Char *)s);
            }
            else if (defaultHandler)
                reportDefault(parser, enc, s, next);
            break;
        case XML_TOK_PI:
            if (!reportProcessingInstruction(parser, enc, s, next))
                return XML_ERROR_NO_MEMORY;
            break;
        case XML_TOK_COMMENT:
            if (!reportComment(parser, enc, s, next))
                return XML_ERROR_NO_MEMORY;
            break;
        default:
            if (defaultHandler)
                reportDefault(parser, enc, s, next);
            break;
        }
        *eventPP = s = next;
    }
    /* not reached */
}

/* If tagNamePtr is non-null, build a real list of attributes,
otherwise just check the attributes for well-formedness. */

static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
                                const char *s, TAG_NAME *tagNamePtr,
                                BINDING **bindingsPtr)
{
    ELEMENT_TYPE *elementType = 0;
    int nDefaultAtts = 0;
    const XML_Char **appAtts;
    int attIndex = 0;
    int i;
    int n;
    int nPrefixes = 0;
    BINDING *binding;
    const XML_Char *localPart;

    if (tagNamePtr) {
        elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, 0);
        if (!elementType) {
            tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
            if (!tagNamePtr->str)
                return XML_ERROR_NO_MEMORY;
            elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
            if (!elementType)
                return XML_ERROR_NO_MEMORY;
            if (ns && !setElementTypePrefix(parser, elementType))
                return XML_ERROR_NO_MEMORY;
        }
        nDefaultAtts = elementType->nDefaultAtts;
    }
    n = XmlGetAttributes(enc, s, attsSize, atts);
    if (n + nDefaultAtts > attsSize) {
        int oldAttsSize = attsSize;
        attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
        atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
        if (!atts)
            return XML_ERROR_NO_MEMORY;
        if (n > oldAttsSize)
            XmlGetAttributes(enc, s, n, atts);
    }
    appAtts = (const XML_Char **)atts;
    for (i = 0; i < n; i++) {
        ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
                                             atts[i].name
                                             + XmlNameLength(enc, atts[i].name));
        if (!attId)
            return XML_ERROR_NO_MEMORY;
        if ((attId->name)[-1]) {
            if (enc == encoding)
                eventPtr = atts[i].name;
            return XML_ERROR_DUPLICATE_ATTRIBUTE;
        }
        (attId->name)[-1] = 1;
        appAtts[attIndex++] = attId->name;
        if (!atts[i].normalized) {
            enum XML_Error result;
            int isCdata = 1;

            if (attId->maybeTokenized) {
                int j;
                for (j = 0; j < nDefaultAtts; j++) {
                    if (attId == elementType->defaultAtts[j].id) {
                        isCdata = elementType->defaultAtts[j].isCdata;
                        break;
                    }
                }
            }

            result = storeAttributeValue(parser, enc, isCdata,
                                         atts[i].valuePtr, atts[i].valueEnd,
                                         &tempPool);
            if (result)
                return result;
            if (tagNamePtr) {
                appAtts[attIndex] = poolStart(&tempPool);
                poolFinish(&tempPool);
            }
            else
                poolDiscard(&tempPool);
        }
        else if (tagNamePtr) {
            appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
            if (appAtts[attIndex] == 0)
                return XML_ERROR_NO_MEMORY;
            poolFinish(&tempPool);
        }
        if (attId->prefix && tagNamePtr) {
            if (attId->xmlns) {
                if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
                    return XML_ERROR_NO_MEMORY;
                --attIndex;
            }
            else {
                attIndex++;
                nPrefixes++;
                (attId->name)[-1] = 2;
            }
        }
        else
            attIndex++;
    }
    nSpecifiedAtts = attIndex;
    if (tagNamePtr) {
        int j;
        for (j = 0; j < nDefaultAtts; j++) {
            const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
            if (!(da->id->name)[-1] && da->value) {
                if (da->id->prefix) {
                    if (da->id->xmlns) {
                        if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
                            return XML_ERROR_NO_MEMORY;
                    }
                    else {
                        (da->id->name)[-1] = 2;
                        nPrefixes++;
                        appAtts[attIndex++] = da->id->name;
                        appAtts[attIndex++] = da->value;
                    }
                }
                else {
                    (da->id->name)[-1] = 1;
                    appAtts[attIndex++] = da->id->name;
                    appAtts[attIndex++] = da->value;
                }
            }
        }
        appAtts[attIndex] = 0;
    }
    i = 0;
    if (nPrefixes) {
        for (; i < attIndex; i += 2) {
            if (appAtts[i][-1] == 2) {
                ATTRIBUTE_ID *id;
                ((XML_Char *)(appAtts[i]))[-1] = 0;
                id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
                if (id->prefix->binding) {
                    int j;
                    const BINDING *b = id->prefix->binding;
                    const XML_Char *s = appAtts[i];
                    for (j = 0; j < b->uriLen; j++) {
                        if (!poolAppendChar(&tempPool, b->uri[j]))
                            return XML_ERROR_NO_MEMORY;
                    }
                    while (*s++ != ':')
                        ;
                    do {
                        if (!poolAppendChar(&tempPool, *s))
                            return XML_ERROR_NO_MEMORY;
                    } while (*s++);
                    appAtts[i] = poolStart(&tempPool);
                    poolFinish(&tempPool);
                }
                if (!--nPrefixes)
                    break;
            }
            else
                ((XML_Char *)(appAtts[i]))[-1] = 0;
        }
    }
    for (; i < attIndex; i += 2)
        ((XML_Char *)(appAtts[i]))[-1] = 0;
    if (!tagNamePtr)
        return XML_ERROR_NONE;
    for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
        binding->attId->name[-1] = 0;
    if (elementType->prefix) {
        binding = elementType->prefix->binding;
        if (!binding)
            return XML_ERROR_NONE;
        localPart = tagNamePtr->str;
        while (*localPart++ != XML_T(':'))
            ;
    }
    else if (dtd.defaultPrefix.binding) {
        binding = dtd.defaultPrefix.binding;
        localPart = tagNamePtr->str;
    }
    else
        return XML_ERROR_NONE;
    tagNamePtr->localPart = localPart;
    tagNamePtr->uriLen = binding->uriLen;
    i = binding->uriLen;
    do {
        if (i == binding->uriAlloc) {
            binding->uri = realloc(binding->uri, binding->uriAlloc *= 2);
            if (!binding->uri)
                return XML_ERROR_NO_MEMORY;
        }
        binding->uri[i++] = *localPart;
    } while (*localPart++);
    tagNamePtr->str = binding->uri;
    return XML_ERROR_NONE;
}

static
int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
{
    BINDING *b;
    int len;
    for (len = 0; uri[len]; len++)
        ;
    if (namespaceSeparator)
        len++;
    if (freeBindingList) {
        b = freeBindingList;
        if (len > b->uriAlloc) {
            b->uri = realloc(b->uri, len + EXPAND_SPARE);
            if (!b->uri)
                return 0;
            b->uriAlloc = len + EXPAND_SPARE;
        }
        freeBindingList = b->nextTagBinding;
    }
    else {
        b = malloc(sizeof(BINDING));
        if (!b)
            return 0;
        b->uri = malloc(sizeof(XML_Char) * len + EXPAND_SPARE);
        if (!b->uri) {
            free(b);
            return 0;
        }
        b->uriAlloc = len;
    }
    b->uriLen = len;
    memcpy(b->uri, uri, len * sizeof(XML_Char));
    if (namespaceSeparator)
        b->uri[len - 1] = namespaceSeparator;
    b->prefix = prefix;
    b->attId = attId;
    b->prevPrefixBinding = prefix->binding;
    if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
        prefix->binding = 0;
    else
        prefix->binding = b;
    b->nextTagBinding = *bindingsPtr;
    *bindingsPtr = b;
    if (startNamespaceDeclHandler)
        startNamespaceDeclHandler(handlerArg, prefix->name,
                                  prefix->binding ? uri : 0);
    return 1;
}

/* The idea here is to avoid using stack for each CDATA section when
the whole file is parsed with one call. */

static
enum XML_Error cdataSectionProcessor(XML_Parser parser,
                                     const char *start,
                                     const char *end,
                                     const char **endPtr)
{
    enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
    if (start) {
        processor = contentProcessor;
        return contentProcessor(parser, start, end, endPtr);
    }
    return result;
}

/* startPtr gets set to non-null is the section is closed, and to null if
the section is not yet closed. */

static
enum XML_Error doCdataSection(XML_Parser parser,
                              const ENCODING *enc,
                              const char **startPtr,
                              const char *end,
                              const char **nextPtr)
{
    const char *s = *startPtr;
    const char **eventPP;
    const char **eventEndPP;
    if (enc == encoding) {
        eventPP = &eventPtr;
        *eventPP = s;
        eventEndPP = &eventEndPtr;
    }
    else {
        eventPP = &(openInternalEntities->internalEventPtr);
        eventEndPP = &(openInternalEntities->internalEventEndPtr);
    }
    *eventPP = s;
    *startPtr = 0;
    for (;;) {
        const char *next;
        int tok = XmlCdataSectionTok(enc, s, end, &next);
        *eventEndPP = next;
        switch (tok) {
        case XML_TOK_CDATA_SECT_CLOSE:
            if (endCdataSectionHandler)
                endCdataSectionHandler(handlerArg);
#if 0
            /* see comment under XML_TOK_CDATA_SECT_OPEN */
            else if (characterDataHandler)
                characterDataHandler(handlerArg, dataBuf, 0);
#endif
            else if (defaultHandler)
                reportDefault(parser, enc, s, next);
            *startPtr = next;
            return XML_ERROR_NONE;
        case XML_TOK_DATA_NEWLINE:
            if (characterDataHandler) {
                XML_Char c = 0xA;
                characterDataHandler(handlerArg, &c, 1);
            }
            else if (defaultHandler)
                reportDefault(parser, enc, s, next);
            break;
        case XML_TOK_DATA_CHARS:
            if (characterDataHandler) {
                if (MUST_CONVERT(enc, s)) {
                    for (;;) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -