// E4X 10.4, pg 36 Atom XMLListClass::ToXMLList(Atom arg) { AvmCore* core = this->core(); if (AvmCore::isNullOrUndefined(arg)) { toplevel()->throwTypeError( (arg == undefinedAtom) ? kConvertUndefinedToObjectError : kConvertNullToObjectError); return arg; } if (AvmCore::isXMLList(arg)) { return arg; } else if (AvmCore::isXML(arg)) { XMLObject *x = AvmCore::atomToXMLObject(arg); Multiname m; bool bFound = x->getQName (&m); Atom parent = x->parent(); if (parent == undefinedAtom) parent = nullObjectAtom; XMLListObject *xl = XMLListObject::create(core->GetGC(), toplevel()->xmlListClass(), parent, bFound ? &m : 0); xl->_append (arg); return xl->atom(); } else { Toplevel* toplevel = this->toplevel(); Stringp s = core->string(arg); if (s->matchesLatin1("<>", 2, 0) && s->matchesLatin1("</>", 3, s->length()-3)) s = s->substr(2, s->length() - 5); Namespace *defaultNamespace = toplevel->getDefaultNamespace(); // We handle this step in the XMLObject constructor to avoid concatenation huge strings together // parentString = <parent xnlns=defaultNamespace> s </parent> // 3. Parse parentString as a W3C element information info e // 4. If the parse fails, throw a SyntaxError exception // 5. x = toXML(e); //StringBuffer parentString (core); //parentString << "<parent xmlns=\""; //parentString << defaultNamespace->getURI(); //parentString << "\">"; //parentString << s; //parentString << "</parent>"; XMLObject *x = XMLObject::create(core->GetGC(), toplevel->xmlClass(), s, defaultNamespace); XMLListObject *xl = XMLListObject::create(core->GetGC(), toplevel->xmlListClass()); for (uint32_t i = 0; i < x->getNode()->_length(); i++) { E4XNode *c = x->getNode()->_getAt (i); c->setParent (NULL); // !!@ trying to emulate rhino behavior here // Add the default namespace to our top element. Namespace *ns = toplevel->getDefaultNamespace(); c->_addInScopeNamespace (core, ns, core->findPublicNamespace()); xl->_appendNode (c); } return xl->atom(); } }
// E4X 10.3, page 32 Atom XMLClass::ToXML(Atom arg) { Toplevel* toplevel = this->toplevel(); AvmCore* core = this->core(); if (AvmCore::isNullOrUndefined(arg)) { toplevel->throwTypeError( (arg == undefinedAtom) ? kConvertUndefinedToObjectError : kConvertNullToObjectError); return arg; } else if (AvmCore::isXML(arg)) { return arg; } else if (AvmCore::isXMLList(arg)) { XMLListObject *xl = AvmCore::atomToXMLList(arg); if (xl->_length() == 1) { return xl->_getAt(0)->atom(); } else { toplevel->throwTypeError(kXMLMarkupMustBeWellFormed); return 0;//notreached } } else { Namespace *defaultNamespace = toplevel->getDefaultNamespace(); // 2. Parse parentString as a W3C element information info e // 3. If the parse fails, throw a SyntaxError exception XMLObject *x = new (core->GetGC()) XMLObject(toplevel->xmlClass(), core->string(arg), defaultNamespace); // 4. x = toXML(e); // 5. if x.length == 0 // return new xml object if (!x->getNode()->_length()) { x->setNode( new (core->GetGC()) TextE4XNode(0, core->kEmptyString) ); } // 6. else if x.length == 1 // x[0].parent = null // return x[0] else if (x->getNode()->_length() == 1) { x->setNode( x->getNode()->_getAt (0)); // discard parent node x->getNode()->setParent (0); } // 7. else throw a syntaxError else { // check for multiple nodes where the first n-1 are PI/comment nodes and the // last one is an element node. Just ignore the PI/comment nodes and return // the element node. (bug 148526). // Will also now ignore any text nodes that just contain whitespace (leading // or trailing) the one valid element node. If multiple element nodes are found, // that is a failing case as well. (bug 192355) E4XNode *node = x->getNode(); E4XNode *validNode = NULL; for (uint32 i = 0; i < node->_length(); i++) { E4XNode *n = node->_getAt (i); if (n->getClass() == E4XNode::kElement) { if (validNode != NULL) toplevel->throwTypeError(kXMLMarkupMustBeWellFormed); validNode = n; } else if (n->getClass() == E4XNode::kText) { if (!n->getValue()->isWhitespace()) { toplevel->throwTypeError(kXMLMarkupMustBeWellFormed); } } } // No valid nodes found if (!validNode) toplevel->throwTypeError(kXMLMarkupMustBeWellFormed); x->setNode( validNode ); // discard parent node validNode->setParent (0); } return x->atom(); } }