/* [<][>][^][v][top][bottom][index][help] */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is [Open Source Virtual Machine.].
*
* The Initial Developer of the Original Code is
* Adobe System Incorporated.
* Portions created by the Initial Developer are Copyright (C) 2004-2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Adobe AS3 Team
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __avmplus_E4XNode__
#define __avmplus_E4XNode__
// E4X 9.1.1 Internal Properties and Methods
// Name
// Parent
// Attributes
// InScopeNamespaces
// Length
// Delete (overrides Object version)
// Get (overrides Object version)
// HasProperty (overrides Object version)
// Put (overrides Object version)
// DeleteByIndex (PropertyName)
// DeepCopy
// ResolveValue
// Descendants (PropertyName)
// Equals (Value)
// Insert (PropertyName, Value)
// Replace (PropertyName, Value)
// AddInScopeNamespace (Namespace)
// These are static objects on the XML type
// E4X: The XML constructor has the following properties
// XML.ignoreComments
// XML.ignoreProcessingInstructions
// XML.ignoreWhitespace
// XML.prettyPrinting
// XML.prettyIndent
// XML.settings
// XML.setSettings ([settings])
// XML.defaultSettings()
// XML.prototype.constructor ??
// XML.prototype.addNamespace
// XML.prototype.appendChild
// XML.prototype.attribute
// XML.prototype.attributes
// XML.prototype.child
// XML.prototype.childIndex
// XML.prototype.children
// XML.prototype.comments
// XML.prototype.contains
// XML.prototype.copy
// XML.prototype.descendants
// XML.prototype.elements
// XML.prototype.hasOwnProperty
// XML.prototype.hasComplexContent
// XML.prototype.hasSimpleContent
// XML.prototype.inScopeNamespaces
// XML.prototype.insertChildAfter
// XML.prototype.insertChildBefore
// XML.prototype.length
// XML.prototype.localName
// XML.prototype.name
// XML.prototype.namespace
// XML.prototype.namespaceDeclarations
// XML.prototype.nodeKind
// XML.prototype.normalize
// XML.prototype.parent
// XML.prototype.processingInstructions
// XML.prototype.prependChild
// XML.prototype.propertyIsEnumerable
// XML.prototype.removeNamespace
// XML.prototype.replace
// XML.prototype.setChildren
// XML.prototype.setLocalName
// XML.prototype.setName
// XML.prototype.setNamespace
// XML.prototype.text
// XML.prototype.toString
// XML.prototype.toXMLString
// XML.prototype.valueOf
namespace avmplus
{
class E4XNodeAux : public MMgc::GCObject
{
DRCWB(Stringp) m_name;
DRCWB(Namespace*) m_ns;
/** callback on changes to children, attribute, name or namespace */
DRCWB(FunctionObject*) m_notification;
friend class E4XNode;
friend class ElementE4XNode;
public:
E4XNodeAux(Stringp s, Namespace* ns, FunctionObject* notify = NULL);
};
///////////////////////////////////////////////////
///////////////////////////////////////////////////
/**
* E4XNode is the C++ implementation of the XML class
* in the E4X Specification.
*/
// Currently this is 12-bytes in size (4 bytes wasted by GC)
// Element nodes are 24 bytes
// All other nodes are 16 bytes
class E4XNode : public MMgc::GCObject
{
protected:
/** Either null or an E4XNode, valid for all node types */
DWB(E4XNode*) m_parent;
// If this is a simple name with no namespace or notification function,
// we just have a string pointer. Otherwise, we're a E4XNodeAux value
// containing a name + namespace as well as a notification function.
// E4XNodeAux *
// String *
uintptr m_nameOrAux;
#define AUXBIT 0x1
public:
E4XNode(E4XNode* parent) : m_parent(parent), m_nameOrAux(0) { }
// we have virtual functions, so we probably need a virtual dtor
virtual ~E4XNode() {}
bool getQName (Multiname *mn, Namespacep publicNS) const;
void setQName (AvmCore *core, Stringp name, Namespace *ns = 0);
void setQName (AvmCore *core, const Multiname *mn);
virtual Stringp getValue() const = 0;
virtual void setValue (String *s) = 0;
E4XNode* getParent() const { return m_parent; };
void setParent(E4XNode* n) { m_parent = n; }
// Not used as bit fields (only one bit at a time can be set) but
// used for fast multi-type compares.
enum NodeTypes
{
kUnknown = 0x0001,
kAttribute = 0x0002,
kText = 0x0004,
kCDATA = 0x0008, // same as text but no string conversion on output
kComment = 0x0010,
kProcessingInstruction = 0x0020,
kElement = 0x0040
};
virtual int getClass() const = 0;
virtual uint32 numAttributes() const { return 0; };
virtual AtomArray *getAttributes() const { return 0; };
virtual E4XNode *getAttribute(uint32 /*index*/) const { return NULL; };
virtual uint32 numNamespaces() const { return 0; };
virtual AtomArray *getNamespaces() const { return 0; };
virtual uint32 numChildren() const { return 0; };
virtual E4XNode *_getAt(uint32 /*i*/) const { return 0; };
virtual void clearChildren() {};
virtual void setChildAt (uint32 /*i*/, E4XNode* /*x*/) {};
virtual void insertChild (uint32 /*i*/, E4XNode* /*x*/) {};
virtual void removeChild (uint32 /*i*/) {};
virtual void convertToAtomArray() {};
bool hasSimpleContent() const;
bool hasComplexContent() const;
int32 childIndex() const;
String* nodeKind(Toplevel* toplevel) const;
virtual void addAttribute (E4XNode *x);
// Should this silently fail or assert?
virtual void setNotification(AvmCore* /*core*/, FunctionObject* /*f*/, Namespacep /*publicNS*/) { return; }
virtual FunctionObject* getNotification() const { return NULL; }
// The following routines are E4X support routines
// Private functions not exposed to AS
// DeleteByIndex (PropertyName)
// DeepCopy
// ResolveValue
// Descendants (PropertyName)
// Equals (Value)
// Insert (PropertyName, Value)
// Replace (PropertyName, Value)
// AddInScopeNamespace (Namespace)
// Corresponds to [[Length]] in the docs
virtual uint32 _length() const { return 0; };
bool _equals(Toplevel* toplevel, AvmCore *core, E4XNode *value) const;
void _deleteByIndex (uint32 entry);
E4XNode *_deepCopy (AvmCore *core, Toplevel *toplevel, Namespacep publicNS) const;
virtual void _insert (AvmCore *core, Toplevel *toplevel, uint32 entry, Atom value);
virtual E4XNode* _replace (AvmCore *core, Toplevel *toplevel, uint32 entry, Atom value, Atom pastValue = 0);
virtual void _addInScopeNamespace (AvmCore *core, Namespace *ns, Namespacep publicNS);
virtual void _append (E4XNode* /*childNode*/) { AvmAssert(0); };
// Extract a namespace from a tag name, and return the new tag name in tagName
Namespace *FindNamespace(AvmCore *core, Toplevel *toplevel, Stringp& tagName, bool bAttribute);
int FindMatchingNamespace(AvmCore *core, Namespace *ns);
void BuildInScopeNamespaceList(AvmCore *core, AtomArray *list) const;
void dispose();
MMgc::GC *gc() const { return MMgc::GC::GetGC(this); }
};
class TextE4XNode : public E4XNode
{
DRCWB(Stringp) m_value;
public:
TextE4XNode (E4XNode *parent, String *value);
int getClass() const { return kText; };
Stringp getValue() const { return m_value; };
void setValue (String *s) { m_value = s; }
};
class CommentE4XNode : public E4XNode
{
DRCWB(Stringp) m_value;
public:
CommentE4XNode (E4XNode *parent, String *value);
int getClass() const { return kComment; };
Stringp getValue() const { return m_value; };
void setValue (String *s) { m_value = s; }
};
class AttributeE4XNode : public E4XNode
{
DRCWB(Stringp) m_value;
public:
AttributeE4XNode (E4XNode *parent, String *value);
int getClass() const { return kAttribute; };
Stringp getValue() const { return m_value; };
void setValue (String *s) { m_value = s; }
};
class CDATAE4XNode : public E4XNode
{
DRCWB(Stringp) m_value;
public:
CDATAE4XNode (E4XNode *parent, String *value);
int getClass() const { return kCDATA; };
Stringp getValue() const { return m_value; };
void setValue (String *s) { m_value = s; }
};
class PIE4XNode : public E4XNode
{
/** only when m_class != kElement */
DRCWB(Stringp) m_value;
public:
PIE4XNode (E4XNode *parent, String *value);
int getClass() const { return kProcessingInstruction; };
Stringp getValue() const { return m_value; };
void setValue (String *s) { m_value = s; }
};
// Currently this is 24-bytes in size
class ElementE4XNode : public E4XNode
{
// This stores E4XNode pointers and NOT Atoms
DWB(AtomArray *) m_attributes;
// This stores Atoms (atom-ized Namespace pointers)
DWB(AtomArray *) m_namespaces;
// If the low bit of this integer is set, this value points directly
// to a single child (one E4XNode *). If there are multiple children,
// this points to an AtomArray containing E4XNode pointers (NOT Atoms)
DWB(uintptr) m_children;
#define SINGLECHILDBIT 0x1
friend class E4XNode;
public:
ElementE4XNode (E4XNode *parent);
int getClass() const { return kElement; };
uint32 numAttributes() const { return (m_attributes ? m_attributes->getLength() : 0); };
AtomArray *getAttributes() const { return m_attributes; };
E4XNode *getAttribute(uint32 index) const { return (E4XNode *)AvmCore::atomToGenericObject(m_attributes->getAt(index)); };
void addAttribute (E4XNode *x);
uint32 numNamespaces() const { return (m_namespaces ? m_namespaces->getLength() : 0); };
AtomArray *getNamespaces() const { return m_namespaces; };
uint32 numChildren() const;// { return (m_children ? m_children->getLength() : 0); };
void clearChildren();
void setChildAt (uint32 i, E4XNode *x);
#define SINGLECHILDBIT 0x1
void insertChild (uint32 i, E4XNode *x);
void removeChild (uint32 i);
void convertToAtomArray();
Stringp getValue() const { return 0; };
void setValue (String *s) { (void)s; AvmAssert(s == 0); }
void setNotification(AvmCore* core, FunctionObject* f, Namespacep publicNS);
FunctionObject* getNotification() const;
// E4X support routines below
uint32 _length() const { return numChildren(); };
E4XNode *_getAt(uint32 i) const;
void _append (E4XNode *childNode);
void _addInScopeNamespace (AvmCore *core, Namespace *ns, Namespacep publicNS);
void _insert (AvmCore *core, Toplevel *toplevel, uint32 entry, Atom value);
E4XNode* _replace (AvmCore *core, Toplevel *toplevel, uint32 entry, Atom value, Atom pastValue = 0);
void CopyAttributesAndNamespaces(AvmCore *core, Toplevel *toplevel, XMLTag& tag, Namespacep publicNS);
};
}
#endif /* __avmplus_E4XNode__ */