/// <summary> /// Creates an exception object to be thrown from the given error code and arguments. /// </summary> /// <returns>The <see cref="AVM2Exception"/> instance.</returns> /// <param name="code">The error code.</param> /// <param name="arg1">The first argument in the error message.</param> /// <param name="arg2">The second argument in the error message.</param> /// <param name="line">The line number at which the error occurred. If not set, the /// current line number is used.</param> private AVM2Exception _error(ErrorCode code, string?arg1 = null, string?arg2 = null, int line = -1) { if (line == -1) { line = m_curLine; } object?[] args; if (arg2 != null) { args = new object?[] { arg1, arg2, line } } ; else if (arg1 != null) { args = new object?[] { arg1, line } } ; else { args = new object?[] { line } }; return(ErrorHelper.createError(code, args)); } }
/// <summary> /// Converts elements from the source span, and writes the converted objects to the destination span. /// </summary> /// <param name="src">The source span.</param> /// <param name="dst">The destination span. This must have the same length as <paramref name="src"/>.</param> /// /// <exception cref="AVM2Exception">ArgumentError #10061: <paramref name="dst"/> does not have the same /// length as <paramref name="src"/>.</exception> public void convertSpan(ReadOnlySpan <TSource> src, Span <TDest> dst) { if (dst.Length != src.Length) { throw ErrorHelper.createError(ErrorCode.MARIANA__ARGUMENT_OUT_OF_RANGE, nameof(dst)); } convertSpanImpl(src, dst); }
/// <summary> /// Gets the instance of <see cref="GenericComparer{T}"/> for the specified comparison type. /// </summary> /// <param name="type">The kind of comparisons that the returned /// <see cref="GenericComparer{T}"/> instance must perform.</param> /// <returns>The <see cref="GenericComparer{T}"/> instance.</returns> /// /// <exception cref="AVM2Exception"> /// <list type="bullet"> /// <item> /// <description>TypeError #10049: <paramref name="type"/> is /// <see cref="GenericComparerType.DEFAULT" qualifyHint="true"/> and /// <typeparamref name="T"/> is not a supported type.</description> /// </item> /// <item><description>TypeError #10061: <paramref name="type"/> is not a valid value.</description></item> /// </list> /// </exception> /// /// <remarks> /// Only the following type arguments can be used with this method with /// <paramref name="type"/> set to /// <see cref="GenericComparerType.DEFAULT" qualifyHint="true"/>: <see cref="Int32"/>, /// <see cref="UInt32"/>, <see cref="Double"/>, <see cref="String"/>, /// <see cref="Boolean"/>, interface types, the <see cref="ASAny"/> type and any type /// inheriting from the <see cref="ASObject"/> class. For any other type, this method will /// throw an exception if <paramref name="type"/> is set to /// <see cref="GenericComparerType.DEFAULT" qualifyHint="true"/>. When /// <paramref name="type"/> is set to any other value and an unsupported type argument is /// used, an error is not thrown immediately; however, calling any methods on the returned /// comparer may throw invalid conversion errors. /// </remarks> public static GenericComparer <T> getComparer(GenericComparerType type) { return(type switch { GenericComparerType.DEFAULT => defaultComparer, GenericComparerType.NUMERIC => s_lazyComparerSet.value.numericCmp, GenericComparerType.STRING => s_lazyComparerSet.value.stringCmp, GenericComparerType.STRING_IGNORECASE => s_lazyComparerSet.value.stringCmpIgnoreCase, _ => throw ErrorHelper.createError(ErrorCode.MARIANA__ARGUMENT_OUT_OF_RANGE, nameof(type)), });
public static string encodeURIComponent(string uri = "undefined") { if (uri == null) { return("null"); } if (URIUtil.tryEncode(uri, ENCODE_URI_COMPONENT_NO_ENCODE, failOnInvalidSurrogate: false, out string?encoded)) { return(encoded); } throw ErrorHelper.createError(ErrorCode.INVALID_URI, "encodeURIComponent"); }
public static string decodeURI(string uri = "undefined") { if (uri == null) { return("null"); } if (URIUtil.tryDecode(uri, DECODE_URI_NO_DECODE, failOnInvalidSurrogate: false, out string?decoded)) { return(decoded); } throw ErrorHelper.createError(ErrorCode.INVALID_URI, "decodeURI"); }
/// <summary> /// Reads an attribute. /// </summary> private void _readAttribute() { int curLine = m_curLine; if (!_readName(out string?prefix, out string?localName)) { throw _error( ErrorCode.MARIANA__XML_PARSER_INVALID_NAME, (prefix == null) ? localName : prefix + ":" + localName ); } if (m_str.Length - m_pos < 2 || m_str[m_pos] != '=') { throw _error(ErrorCode.XML_PARSER_UNTERMINATED_ATTR); } m_pos++; string attrValue = _readAttributeValue(); if (prefix == null && localName == "xmlns") { _addNamespaceDecl(ASNamespace.unsafeCreate("", attrValue)); } else if (prefix == "xmlns") { if (attrValue.Length == 0) { throw ErrorHelper.createError(ErrorCode.XML_ILLEGAL_PREFIX_PUBLIC_NAMESPACE, localName); } _addNamespaceDecl(ASNamespace.unsafeCreate(localName, attrValue)); } else { // Attribute nodes canot be created at this point; this is because their prefixes // can refer to xmlns declarations after it on the same element tag. So they // must be stored as UnresolvedAttribute until the entire start tag is parsed, // after which their namespace URIs can be resolved and the attribute nodes created. m_unresolvedAttrs.add(new UnresolvedAttribute { lineNumber = curLine, prefix = prefix, localName = localName, value = attrValue, }); } }
/// <summary> /// Creates a new <see cref="ASNamespace"/> with a URI and a prefix. /// </summary> /// /// <param name="prefix">The prefix of the namespace. If this is not a valid XML name, the /// namespace is considered to be prefixless and cannot be used with methods requiring prefixed /// namespaces.</param> /// <param name="uri"> /// The URI of the namespace. If this is the empty string, the prefix must be /// the empty string, otherwise an error is thrown. /// </param> /// /// <exception cref="AVM2Exception"> /// <list type="bullet"> /// <item> /// <description>TypeError #1098: If <paramref name="uri"/> is the empty string, but /// <paramref name="prefix"/> is not the empty string.</description> /// </item> /// </list> /// </exception> public ASNamespace(string prefix, string uri) { prefix = ASString.AS_convertString(prefix); uri = ASString.AS_convertString(uri); if (uri.Length == 0) { if (prefix.Length != 0) { throw ErrorHelper.createError(ErrorCode.XML_ILLEGAL_PREFIX_PUBLIC_NAMESPACE, prefix); } (this.prefix, this.uri) = ("", ""); } else { this.prefix = (prefix.Length == 0 || XMLHelper.isValidName(prefix)) ? prefix : null; this.uri = uri; } }
/// <summary> /// Gets the value of the key-value pair in the tag with the specified key. /// </summary> /// <returns>The value of the key-value pair in the tag with the specified key. If no key-value /// pair with the key exists, returns null. If multiple key-value pairs exist with the given key, /// returns the value of the last such pair.</returns> /// <param name="key">The key. This must not be null.</param> /// <exception cref="AVM2Exception">ArgumentError #10060: <paramref name="key"/> is null.</exception> public string?this[string key] { get { if (key == null) { throw ErrorHelper.createError(ErrorCode.MARIANA__ARGUMENT_NULL, nameof(key)); } var kvs = m_keyvalues; for (int i = kvs.Length - 1; i >= 0; i--) { if (kvs[i].Key == key) { return(kvs[i].Value); } } return(null); } }
/// <summary> /// Returns the metadata tag in this collection with the given name. /// </summary> /// <param name="name">The name of the tag.</param> /// <returns>The metadata tag in this collection with the given name, or null if no /// tag with the name exists. If there is more than one tag with the given name /// in the collection, the first one is returned.</returns> /// <exception cref="AVM2Exception"> /// <list type="bullet"> /// <item><description>ArgumentError #10060: <paramref name="name"/> is null.</description></item> /// </list> /// </exception> public MetadataTag?getTag(string name) { if (name == null) { throw ErrorHelper.createError(ErrorCode.MARIANA__ARGUMENT_NULL, nameof(name)); } var tags = m_tags; for (int i = 0; i < tags.Length; i++) { if (tags[i].name == name) { return(tags[i]); } } return(null); }
/// <summary> /// Gets a Boolean value indicating whether the metadata tag contains a key-value pair with /// the given key. /// </summary> /// <param name="key">The key. This must not be null.</param> /// <returns>True if a key-value pair with the given key exists, false otherwise.</returns> /// <exception cref="AVM2Exception">ArgumentError #10060: <paramref name="key"/> is null.</exception> public bool hasValue(string key) { if (key == null) { throw ErrorHelper.createError(ErrorCode.MARIANA__ARGUMENT_NULL, nameof(key)); } var kvs = m_keyvalues; for (int i = 0; i < kvs.Length; i++) { if (kvs[i].Key == key) { return(true); } } return(false); }
public ASRegExp(RestParam rest) { if (rest.length >= 1 && rest[0].value is ASRegExp otherRegExp) { if (rest.length >= 2 && !rest[1].isUndefined) { throw ErrorHelper.createError(ErrorCode.REGEXP_CONSTRUCT_COPY_FLAGS); } m_internalRegex = otherRegExp.m_internalRegex; m_auxFlags = otherRegExp.m_auxFlags; m_groupNames = otherRegExp.m_groupNames; m_groupCount = otherRegExp.m_groupCount; m_source = otherRegExp.m_source; } else { string pattern = (rest.length >= 1 && !rest[0].isUndefined) ? ASAny.AS_convertString(rest[0]) : ""; string flags = (rest.length >= 2 && !rest[1].isUndefined) ? ASAny.AS_convertString(rest[1]) : ""; _init(pattern, flags); } }
/// <summary> /// Creates a new non-private namespace with the given type and name. /// </summary> /// /// <param name="kind"> /// The kind of namespace to create. This cannot be /// <see cref="NamespaceKind.PRIVATE" qualifyHint="true"/>. (To create a private namespace, use /// the <see cref="Namespace.createPrivate()" qualifyHint="true"/> method), or /// <see cref="NamespaceKind.ANY" qualifyHint="true"/> (which is reserved for the "any" /// namespace). /// </param> /// <param name="uri">The name or URI of the namespace.</param> /// /// <exception cref="AVM2Exception"> /// <list type="bullet"> /// <item> /// <description>ArgumentError #10013: The <paramref name="kind"/> argument is /// <see cref="NamespaceKind.PRIVATE" qualifyHint="true"/>.</description> /// </item> /// <item> /// <description>ArgumentError #10014: The <paramref name="kind"/> argument is /// <see cref="NamespaceKind.ANY" qualifyHint="true"/>.</description> /// </item> /// <item> /// <description>ArgumentError #10016: The <paramref name="kind"/> argument is not a valid value of the /// <see cref="NamespaceKind"/> enumeration.</description> /// </item> /// <item><description>ArgumentError #10017: The <paramref name="uri"/> argument is null.</description></item> /// </list> /// </exception> public Namespace(NamespaceKind kind, string uri) { if (kind == NamespaceKind.PRIVATE) { throw ErrorHelper.createError(ErrorCode.MARIANA__NAMESPACE_CTOR_PRIVATE); } if (kind == NamespaceKind.ANY) { throw ErrorHelper.createError(ErrorCode.MARIANA__NAMESPACE_CTOR_ANY); } if ((uint)kind > (uint)NamespaceKind.PRIVATE) { throw ErrorHelper.createError(ErrorCode.MARIANA__INVALID_NS_CATEGORY, (int)kind); } if (uri == null) { throw ErrorHelper.createError(ErrorCode.MARIANA__NAMESPACE_NULL_NAME); } this.uri = uri; this.m_kindAndId = (uint)kind; }
/// <summary> /// Creates a new <see cref="ASQName"/> object with a prefixed namespace specified by a URI /// and prefix, and a local name. /// </summary> /// /// <param name="prefix">The prefix of the namespace of the XML name.</param> /// <param name="uri">The URI of the namespace of the XML name. If this is null, the QName will /// match XML elements and attributes in any namespace and <paramref name="prefix"/> is ignored.</param> /// <param name="localName">The local name of the XML name. This is the name of the XML /// element or attribute without the namespace. If this is the string "*", the QName /// will match XML elements and attributes with any local name.</param> /// /// <exception cref="AVM2Exception"> /// <list type="bullet"> /// <item> /// <description>TypeError #1098: If <paramref name="uri"/> is the empty string, but /// <paramref name="prefix"/> is not the empty string.</description> /// </item> /// </list> /// </exception> /// /// <remarks> /// If <paramref name="prefix"/> is null, the QName will not have a prefix. This differs from /// the behaviour of the <see cref="ASNamespace(String,String)"/> constructor, which converts /// a null prefix to the string "null". /// </remarks> public ASQName(string?prefix, string?uri, string localName) { if (uri == null) { (this.uri, this.prefix) = (null, null); } else if (uri.Length == 0) { if (prefix != null && prefix.Length != 0) { throw ErrorHelper.createError(ErrorCode.XML_ILLEGAL_PREFIX_PUBLIC_NAMESPACE, prefix); } (this.uri, this.prefix) = ("", ""); } else { bool isValidPrefix = prefix == null || prefix.Length == 0 || XMLHelper.isValidName(prefix); (this.uri, this.prefix) = (uri, isValidPrefix ? prefix : null); } this.localName = ASString.AS_convertString(localName); }
/// <summary> /// Creates an <see cref="AVM2Exception"/> object to throw as an exception when an /// incorrect number of arguments is passed to a method call. /// </summary> /// <param name="methodName">The name of the method to be included in the error message.</param> /// <param name="expected">The number of arguments expected by the method.</param> /// <param name="received">The number of arguments passed to the method call.</param> /// <returns>An <see cref="AVM2Exception"/> object that can be thrown.</returns> /// <remarks> /// Calls to this method are inserted into code generated by the IL compiler; this method /// should not be used in .NET code. /// </remarks> public static AVM2Exception createArgCountMismatchError(string methodName, int expected, int received) => ErrorHelper.createError(ErrorCode.ARG_COUNT_MISMATCH, methodName, expected, received);
/// <summary> /// Creates an <see cref="AVM2Exception"/> to throw when a global memory instruction /// attempts to load or store at an out-of-bounds /// </summary> /// <returns>An <see cref="AVM2Exception"/> object that can be thrown.</returns> /// <remarks> /// Calls to this method are inserted into code generated by the IL compiler; this method /// should not be used in .NET code. /// </remarks> public static AVM2Exception createGlobalMemoryRangeCheckError() => ErrorHelper.createError(ErrorCode.RANGE_INVALID);
/// <summary> /// Creates an <see cref="AVM2Exception"/> object to throw as an exception when a null /// value is dereferenced. /// </summary> /// <returns>An <see cref="AVM2Exception"/> object that can be thrown.</returns> /// <remarks> /// Calls to this method are inserted into code generated by the IL compiler; this method /// should not be used in .NET code. /// </remarks> public static AVM2Exception createNullReferenceError() => ErrorHelper.createError(ErrorCode.NULL_REFERENCE_ERROR);
/// <exclude/> /// <summary> /// This is a special method that is called from the AVM2 runtime and by code compiled by the /// ABC to IL compiler. It must not be called from outside code. /// </summary> internal static new ASAny __AS_INVOKE(ReadOnlySpan <ASAny> args) => throw ErrorHelper.createError(ErrorCode.MATH_NOT_FUNCTION);
/// <exclude/> /// <summary> /// This is a special method that is called from the AVM2 runtime and by code compiled by the /// ABC to IL compiler. It must not be called from outside code. /// </summary> internal static new ASAny __AS_CONSTRUCT(ReadOnlySpan <ASAny> args) => throw ErrorHelper.createError(ErrorCode.MATH_NOT_CONSTRUCTOR);