Example #1
0
    // 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();
        }
    }
Example #2
0
	// 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();
		}
	}