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

📄 jsxml.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
        cx->xmlSettingFlags &= ~flag;    return JS_TRUE;}static JSPropertySpec xml_static_props[] = {    {js_ignoreComments_str,     XML_IGNORE_COMMENTS,   JSPROP_PERMANENT,                                xml_setting_getter, xml_setting_setter},    {js_ignoreProcessingInstructions_str,                   XML_IGNORE_PROCESSING_INSTRUCTIONS, JSPROP_PERMANENT,                                xml_setting_getter, xml_setting_setter},    {js_ignoreWhitespace_str,   XML_IGNORE_WHITESPACE, JSPROP_PERMANENT,                                xml_setting_getter, xml_setting_setter},    {js_prettyPrinting_str,     XML_PRETTY_PRINTING,   JSPROP_PERMANENT,                                xml_setting_getter, xml_setting_setter},    {js_prettyIndent_str,       XML_PRETTY_INDENT,     JSPROP_PERMANENT,                                xml_setting_getter, NULL},    {0,0,0,0,0}};/* Derive cx->xmlSettingFlags bits from xml_static_props tinyids. */#define XSF_IGNORE_COMMENTS     JS_BIT(XML_IGNORE_COMMENTS)#define XSF_IGNORE_PROCESSING_INSTRUCTIONS                                    \                                JS_BIT(XML_IGNORE_PROCESSING_INSTRUCTIONS)#define XSF_IGNORE_WHITESPACE   JS_BIT(XML_IGNORE_WHITESPACE)#define XSF_PRETTY_PRINTING     JS_BIT(XML_PRETTY_PRINTING)#define XSF_CACHE_VALID         JS_BIT(XML_PRETTY_INDENT)/* * Extra, unrelated but necessarily disjoint flag used by ParseNodeToXML. * This flag means a couple of things: * * - The top JSXML created for a parse tree must have an object owning it. * * - That the default namespace normally inherited from the temporary *   <parent xmlns='...'> tag that wraps a runtime-concatenated XML source *   string must, in the case of a precompiled XML object tree, inherit via *   ad-hoc code in ParseNodeToXML. * * Because of the second purpose, we name this flag XSF_PRECOMPILED_ROOT. */#define XSF_PRECOMPILED_ROOT    (XSF_CACHE_VALID << 1)/* Macros for special-casing xml:, xmlns= and xmlns:foo= in ParseNodeToQName. */#define IS_XML(str)                                                           \    (JSSTRING_LENGTH(str) == 3 && IS_XML_CHARS(JSSTRING_CHARS(str)))#define IS_XMLNS(str)                                                         \    (JSSTRING_LENGTH(str) == 5 && IS_XMLNS_CHARS(JSSTRING_CHARS(str)))#define IS_XML_CHARS(chars)                                                   \    (JS_TOLOWER((chars)[0]) == 'x' &&                                         \     JS_TOLOWER((chars)[1]) == 'm' &&                                         \     JS_TOLOWER((chars)[2]) == 'l')#define HAS_NS_AFTER_XML(chars)                                               \    (JS_TOLOWER((chars)[3]) == 'n' &&                                         \     JS_TOLOWER((chars)[4]) == 's')#define IS_XMLNS_CHARS(chars)                                                 \    (IS_XML_CHARS(chars) && HAS_NS_AFTER_XML(chars))#define STARTS_WITH_XML(chars,length)                                         \    (length >= 3 && IS_XML_CHARS(chars))static const char xml_namespace_str[] = "http://www.w3.org/XML/1998/namespace";static const char xmlns_namespace_str[] = "http://www.w3.org/2000/xmlns/";static JSXMLQName *ParseNodeToQName(JSContext *cx, JSParseNode *pn, JSXMLArray *inScopeNSes,                 JSBool isAttributeName){    JSString *str, *uri, *prefix, *localName;    size_t length, offset;    const jschar *start, *limit, *colon;    uint32 n;    JSXMLNamespace *ns;    JS_ASSERT(pn->pn_arity == PN_NULLARY);    str = ATOM_TO_STRING(pn->pn_atom);    length = JSSTRING_LENGTH(str);    start = JSSTRING_CHARS(str);    JS_ASSERT(length != 0 && *start != '@');    JS_ASSERT(length != 1 || *start != '*');    uri = cx->runtime->emptyString;    limit = start + length;    colon = js_strchr_limit(start, ':', limit);    if (colon) {        offset = PTRDIFF(colon, start, jschar);        prefix = js_NewDependentString(cx, str, 0, offset, 0);        if (!prefix)            return NULL;        if (STARTS_WITH_XML(start, offset)) {            if (offset == 3) {                uri = JS_InternString(cx, xml_namespace_str);                if (!uri)                    return NULL;            } else if (offset == 5 && HAS_NS_AFTER_XML(start)) {                uri = JS_InternString(cx, xmlns_namespace_str);                if (!uri)                    return NULL;            } else {                uri = NULL;            }        } else {            uri = NULL;            n = inScopeNSes->length;            while (n != 0) {                --n;                ns = XMLARRAY_MEMBER(inScopeNSes, n, JSXMLNamespace);                if (ns->prefix && js_EqualStrings(ns->prefix, prefix)) {                    uri = ns->uri;                    break;                }            }        }        if (!uri) {            js_ReportCompileErrorNumber(cx, pn,                                        JSREPORT_PN | JSREPORT_ERROR,                                        JSMSG_BAD_XML_NAMESPACE,                                        js_ValueToPrintableString(cx,                                            STRING_TO_JSVAL(prefix)));            return NULL;        }        localName = js_NewStringCopyN(cx, colon + 1, length - (offset + 1), 0);        if (!localName)            return NULL;    } else {        if (isAttributeName) {            /*             * An unprefixed attribute is not in any namespace, so set prefix             * as well as uri to the empty string.             */            prefix = uri;        } else {            /*             * Loop from back to front looking for the closest declared default             * namespace.             */            n = inScopeNSes->length;            while (n != 0) {                --n;                ns = XMLARRAY_MEMBER(inScopeNSes, n, JSXMLNamespace);                if (!ns->prefix || IS_EMPTY(ns->prefix)) {                    uri = ns->uri;                    break;                }            }            prefix = IS_EMPTY(uri) ? cx->runtime->emptyString : NULL;        }        localName = str;    }    return js_NewXMLQName(cx, uri, prefix, localName);}static JSString *ChompXMLWhitespace(JSContext *cx, JSString *str){    size_t length, newlength, offset;    const jschar *cp, *start, *end;    jschar c;    length = JSSTRING_LENGTH(str);    for (cp = start = JSSTRING_CHARS(str), end = cp + length; cp < end; cp++) {        c = *cp;        if (!JS_ISXMLSPACE(c))            break;    }    while (end > cp) {        c = end[-1];        if (!JS_ISXMLSPACE(c))            break;        --end;    }    newlength = PTRDIFF(end, cp, jschar);    if (newlength == length)        return str;    offset = PTRDIFF(cp, start, jschar);    return js_NewDependentString(cx, str, offset, newlength, 0);}static JSXML *ParseNodeToXML(JSContext *cx, JSParseNode *pn, JSXMLArray *inScopeNSes,               uintN flags){    JSXML *xml, *kid, *attr, *attrj;    JSString *str;    uint32 length, n, i, j;    JSParseNode *pn2, *pn3, *head, **pnp;    JSXMLNamespace *ns;    JSXMLQName *qn, *attrjqn;    JSXMLClass xml_class;    int stackDummy;    if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {        js_ReportCompileErrorNumber(cx, pn, JSREPORT_PN | JSREPORT_ERROR,                                    JSMSG_OVER_RECURSED);        return NULL;    }#define PN2X_SKIP_CHILD ((JSXML *) 1)    /*     * Cases return early to avoid common code that gets an outermost xml's     * object, which protects GC-things owned by xml and its descendants from     * garbage collection.     */    xml = NULL;    if (!js_EnterLocalRootScope(cx))        return NULL;    switch (pn->pn_type) {      case TOK_XMLELEM:        length = inScopeNSes->length;        pn2 = pn->pn_head;        xml = ParseNodeToXML(cx, pn2, inScopeNSes, flags);        if (!xml)            goto fail;        flags &= ~XSF_PRECOMPILED_ROOT;        n = pn->pn_count;        JS_ASSERT(n >= 2);        n -= 2;        if (!XMLArraySetCapacity(cx, &xml->xml_kids, n))            goto fail;        i = 0;        while ((pn2 = pn2->pn_next) != NULL) {            if (!pn2->pn_next) {                /* Don't append the end tag! */                JS_ASSERT(pn2->pn_type == TOK_XMLETAGO);                break;            }            if ((flags & XSF_IGNORE_WHITESPACE) &&                n > 1 && pn2->pn_type == TOK_XMLSPACE) {                --n;                continue;            }            kid = ParseNodeToXML(cx, pn2, inScopeNSes, flags);            if (kid == PN2X_SKIP_CHILD) {                --n;                continue;            }            if (!kid)                goto fail;            /* Store kid in xml right away, to protect it from GC. */            XMLARRAY_SET_MEMBER(&xml->xml_kids, i, kid);            kid->parent = xml;            ++i;            /* XXX where is this documented in an XML spec, or in E4X? */            if ((flags & XSF_IGNORE_WHITESPACE) &&                n > 1 && kid->xml_class == JSXML_CLASS_TEXT) {                str = ChompXMLWhitespace(cx, kid->xml_value);                if (!str)                    goto fail;                kid->xml_value = str;            }        }        JS_ASSERT(i == n);        if (n < pn->pn_count - 2)            XMLArrayTrim(&xml->xml_kids);        XMLARRAY_TRUNCATE(cx, inScopeNSes, length);        break;      case TOK_XMLLIST:        xml = js_NewXML(cx, JSXML_CLASS_LIST);        if (!xml)            goto fail;        n = pn->pn_count;        if (!XMLArraySetCapacity(cx, &xml->xml_kids, n))            goto fail;        i = 0;        for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {            /*             * Always ignore insignificant whitespace in lists -- we shouldn't             * condition this on an XML.ignoreWhitespace setting when the list             * constructor is XMLList (note XML/XMLList unification hazard).             */            if (pn2->pn_type == TOK_XMLSPACE) {                --n;                continue;            }            kid = ParseNodeToXML(cx, pn2, inScopeNSes, flags);            if (kid == PN2X_SKIP_CHILD) {                --n;                continue;            }            if (!kid)                goto fail;            XMLARRAY_SET_MEMBER(&xml->xml_kids, i, kid);            ++i;        }        if (n < pn->pn_count)            XMLArrayTrim(&xml->xml_kids);        break;      case TOK_XMLSTAGO:      case TOK_XMLPTAGC:        length = inScopeNSes->length;        pn2 = pn->pn_head;        JS_ASSERT(pn2->pn_type == TOK_XMLNAME);        if (pn2->pn_arity == PN_LIST)            goto syntax;        xml = js_NewXML(cx, JSXML_CLASS_ELEMENT);        if (!xml)            goto fail;        /* First pass: check syntax and process namespace declarations. */        JS_ASSERT(pn->pn_count >= 1);        n = pn->pn_count - 1;        pnp = &pn2->pn_next;        head = *pnp;        while ((pn2 = *pnp) != NULL) {            size_t length;            const jschar *chars;            if (pn2->pn_type != TOK_XMLNAME || pn2->pn_arity != PN_NULLARY)                goto syntax;            /* Enforce "Well-formedness constraint: Unique Att Spec". */            for (pn3 = head; pn3 != pn2; pn3 = pn3->pn_next->pn_next) {                if (pn3->pn_atom == pn2->pn_atom) {                    js_ReportCompileErrorNumber(cx, pn2,                                                JSREPORT_PN | JSREPORT_ERROR,                                                JSMSG_DUPLICATE_XML_ATTR,                                                js_ValueToPrintableString(cx,                                                    ATOM_KEY(pn2->pn_atom)));                    goto fail;                }            }            str = ATOM_TO_STRING(pn2->pn_atom);            pn2 = pn2->pn_next;            JS_ASSERT(pn2);            if (pn2->pn_type != TOK_XMLATTR)                goto syntax;            length = JSSTRING_LENGTH(str);            chars = JSSTRING_CHARS(str);            if (length >= 5 &&                IS_XMLNS_CHARS(chars) &&                (length == 5 || chars[5] == ':')) {                JSString *uri, *prefix;                uri = ATOM_TO_STRING(pn2->pn_atom);                if (length == 5) {                    /* 10.3.2.1. Step 6(h)(i)(1)(a). */                    prefix = cx->runtime->emptyString;                } else {                    prefix = js_NewStringCopyN(cx, chars + 6, length - 6, 0);                    if (!prefix)                        goto fail;                }                /*                 * Once the new ns is appended to xml->xml_namespaces, it is                 * protected from GC by the object that owns xml -- which is                 * either xml->object if outermost, or the object owning xml's                 * oldest ancestor if !outermost.                 */                ns = js_NewXMLNamespace(cx, prefix, uri, JS_TRUE);                if (!ns)                    goto fail;                /*                 * Don't add a namespace that's already in scope.  If someone                 * extracts a child property from its parent via [[Get]], then                 * we enforce the invariant, noted many times in ECMA-357, that                 * the child's namespaces form a possibly-improper superset of                 * its ancestors' namespaces.                 */                if (!XMLARRAY_HAS_MEMBER(inScopeNSes, ns, namespace_identity)) {                    if (!XMLARRAY_APPEND(cx, inScopeNSes, ns) ||                        !XMLARRAY_APPEND(cx, &xml->xml_namespaces, ns)) {                        goto fail;                    }                }                JS_ASSERT(n >= 2);                n -= 2;                *pnp = pn2->pn_next;                /* XXXbe recycle pn2 */                continue;            }            pnp = &pn2->pn_next;        }        /*         * If called from js_ParseNodeToXMLObject, emulate the effect of the         * <parent xmlns='%s'>...</parent> wrapping done by "ToXML Applied to         * the String Type" (ECMA-357 10.3.1).         */        if (flags & XSF_PRECOMPILED_ROOT) {            JS_ASSERT(length >= 1);            ns = XMLARRAY_MEMBER(inScopeNSes, 0, JSXMLNamespace);            JS_ASSERT(!XMLARRAY_HAS_MEMBER(&xml->xml_namespaces, ns,                                           namespace_identity));            ns = js_NewXMLNamespace(cx, ns->prefix, ns->uri, JS_FALSE);            if (!ns)                goto fail;            if (!XMLARRAY_APPEND(cx, &xml->xml_namespaces, ns))                goto fail;        }        XMLArrayTrim(&xml->xml_namespaces);        /* Second pass: process tag name and attributes, using namespaces. */        pn2 = pn->pn_head;        qn = ParseNodeToQName(cx, pn2, inScopeNSes, JS_FALSE);        if (!qn)            goto fail;        xml->name = qn;        JS_ASSERT((n & 1) == 0);        n >>= 1;        if (!XMLArraySetCapacity(cx, &xml->xml_attrs, n))            goto fail;        for (i = 0; (pn2 = pn2->pn_next) != NULL; i++) {            qn = ParseNodeToQName(cx, pn2, inScopeNSes, JS_TRUE);            if (!qn) {                xml->xml_attrs.length = i;

⌨️ 快捷键说明

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