229 lines
6.2 KiB
C++
229 lines
6.2 KiB
C++
/* ***** 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 ***** */
|
|
|
|
|
|
#include "avmplus.h"
|
|
|
|
namespace avmplus
|
|
{
|
|
Multiname::Multiname(NamespaceSet* nsset)
|
|
{
|
|
this->flags = 0;
|
|
setNsset(nsset);
|
|
this->name = NULL;
|
|
}
|
|
|
|
Multiname::Multiname()
|
|
{
|
|
this->flags = 0;
|
|
this->name = NULL;
|
|
this->ns = NULL;
|
|
}
|
|
|
|
Multiname::Multiname(Namespace* ns, Stringp name, bool qualified)
|
|
{
|
|
this->flags = 0;
|
|
setNamespace(ns);
|
|
setName(name);
|
|
if (qualified)
|
|
setQName();
|
|
}
|
|
|
|
Namespace* Multiname::getNamespace(int i) const
|
|
{
|
|
AvmAssert(!isRtns() && !isAnyNamespace());
|
|
if (flags&NSSET)
|
|
{
|
|
AvmAssert(i >= 0 && i < namespaceCount());
|
|
return nsset ? nsset->namespaces[i] : NULL;
|
|
}
|
|
else
|
|
{
|
|
AvmAssert(i == 0);
|
|
return ns;
|
|
}
|
|
}
|
|
|
|
bool Multiname::contains(Namespace* ns) const
|
|
{
|
|
if (flags & NSSET)
|
|
{
|
|
if( !nsset ) return false;
|
|
for (int i=0; i < nsset->size; i++)
|
|
if (nsset->namespaces[i] == ns)
|
|
return true;
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return this->ns == ns;
|
|
}
|
|
}
|
|
|
|
bool Multiname::matches(const Multiname* qname) const
|
|
{
|
|
// For attributes (XML::getprop page 12)
|
|
//if (((n.[[Name]].localName == "*") || (n.[[Name]].localName == a.[[Name]].localName)) &&
|
|
// ((n.[[Name]].uri == nulll) || (n.[[Name]].uri == a.[[Name]].uri)))
|
|
|
|
// For regular element props (XML::getprop page 12)
|
|
// if (n.localName = "*" OR m2 and (m2.localName == n.localName)
|
|
// and (!n.uri) or (m2) and (n.uri == m2.uri)))
|
|
|
|
//Stringp n1 = core->string(this->name);
|
|
|
|
if (qname)
|
|
{
|
|
//Stringp n2 = core->string(m2->name);
|
|
|
|
if (this->isAttr() != qname->isAttr())
|
|
return false;
|
|
}
|
|
|
|
// An anyName that is not qualified matches all properties
|
|
if (this->isAnyName() && !this->isQName())
|
|
return true;
|
|
|
|
// Not an anyName, if m2 is valid, verify names are identical
|
|
if (!this->isAnyName() && qname && (this->name != qname->getName()))
|
|
return false;
|
|
|
|
if (!qname)
|
|
return false;
|
|
|
|
if (this->isAnyNamespace())
|
|
return true;
|
|
|
|
// find a matching namespace between m2 and this
|
|
// if no match return false
|
|
Stringp u2 = qname->getNamespace()->getURI();
|
|
uint8 type2 = (uint8)(qname->getNamespace()->getType());
|
|
//Stringp s2 = core->string(u2);
|
|
for (int i = 0; i < this->namespaceCount(); i++)
|
|
{
|
|
// We'd like to just compare namespace objects but we need
|
|
// to check URIs since two namespaces with different prefixes
|
|
// are considered a match
|
|
Stringp u1 = getNamespace(i)->getURI();
|
|
uint8 type1 = (uint8)(getNamespace(i)->getType());
|
|
//Stringp s1 = core->string(u1);
|
|
if (u1 == u2 && type1 == type2)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/* static */
|
|
Stringp Multiname::format(AvmCore *core, Namespace* ns, Stringp name, bool attr)
|
|
{
|
|
if (ns == core->publicNamespace)
|
|
{
|
|
return name;
|
|
}
|
|
else
|
|
{
|
|
if (attr)
|
|
{
|
|
return core->concatStrings(core->newString("@"), core->concatStrings(ns->getURI(),
|
|
core->concatStrings(core->newString("::"), name)));
|
|
}
|
|
else
|
|
{
|
|
return core->concatStrings(ns->getURI(),
|
|
core->concatStrings(core->newString("::"), name));
|
|
}
|
|
}
|
|
}
|
|
|
|
//#ifdef AVMPLUS_VERBOSE
|
|
// Made available in non-AVMPLUS_VERBOSE builds for describeType
|
|
Stringp Multiname::format(AvmCore* core , MultiFormat form) const
|
|
{
|
|
Stringp attr = this->isAttr() ? core->newString("@") : (Stringp)core->kEmptyString;
|
|
Stringp name = this->isAnyName()
|
|
? core->newString("*")
|
|
: (this->isRtname()
|
|
? core->newString("[]")
|
|
: getName());
|
|
|
|
if (isAnyNamespace())
|
|
{
|
|
return core->concatStrings(attr, core->concatStrings(core->newString("*::"), name));
|
|
}
|
|
else if (isRtns())
|
|
{
|
|
return core->concatStrings(attr, core->concatStrings(core->newString("[]::"), name));
|
|
}
|
|
else if (namespaceCount() == 1 && isQName())
|
|
{
|
|
return format(core, getNamespace(), core->concatStrings(attr,name));
|
|
}
|
|
else
|
|
{
|
|
// various switches
|
|
bool showNs = (form == MULTI_FORMAT_FULL) || (form == MULTI_FORMAT_NS_ONLY);
|
|
bool showName = (form == MULTI_FORMAT_FULL) || (form == MULTI_FORMAT_NAME_ONLY);
|
|
bool showBrackets = (form == MULTI_FORMAT_FULL);
|
|
Stringp s = attr;
|
|
if (showNs)
|
|
{
|
|
if (showBrackets)
|
|
s = core->concatStrings(s, core->newString("{"));
|
|
|
|
for (int i=0,n=namespaceCount(); i < n; i++)
|
|
{
|
|
if (getNamespace(i)==core->publicNamespace)
|
|
s = core->concatStrings(s, core->newString("public"));
|
|
else
|
|
s = core->concatStrings(s, getNamespace(i)->getURI());
|
|
if (i+1 < n)
|
|
s = core->concatStrings(s, core->newString(","));
|
|
}
|
|
|
|
if (showBrackets)
|
|
s = core->concatStrings(s, core->newString("}::"));
|
|
}
|
|
|
|
if (showName)
|
|
s = core->concatStrings(s, name);
|
|
return s;
|
|
}
|
|
}
|
|
//#endif
|
|
}
|