?? uri.as
字號(hào):
/*
Adobe Systems Incorporated(r) Source Code License Agreement
Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
Please read this Source Code License Agreement carefully before using
the source code.
Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable copyright license, to reproduce,
prepare derivative works of, publicly display, publicly perform, and
distribute this source code and such derivative works in source or
object code form without any attribution requirements.
The name "Adobe Systems Incorporated" must not be used to endorse or promote products
derived from the source code without prior written permission.
You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
against any loss, damage, claims or lawsuits, including attorney's
fees that arise or result from your use or distribution of the source
code.
THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.adobe.net
{
import flash.utils.ByteArray;
/**
* This class implements functions and utilities for working with URI's
* (Universal Resource Identifiers). For technical description of the
* URI syntax, please see RFC 3986 at http://www.ietf.org/rfc/rfc3986.txt
* or do a web search for "rfc 3986".
*
* <p>The most important aspect of URI's to understand is that URI's
* and URL's are not strings. URI's are complex data structures that
* encapsulate many pieces of information. The string version of a
* URI is the serialized representation of that data structure. This
* string serialization is used to provide a human readable
* representation and a means to transport the data over the network
* where it can then be parsed back into its' component parts.</p>
*
* <p>URI's fall into one of three categories:
* <ul>
* <li><scheme>:<scheme-specific-part>#<fragment> (non-hierarchical)</li>
* <li><scheme>:<authority><path>?<query>#<fragment> (hierarchical)</li>
* <li><path>?<query>#<fragment> (relative hierarchical)</li>
* </ul></p>
*
* <p>The query and fragment parts are optional.</p>
*
* <p>This class supports both non-hierarchical and hierarchical URI's</p>
*
* <p>This class is intended to be used "as-is" for the vast majority
* of common URI's. However, if your application requires a custom
* URI syntax (e.g. custom query syntax or special handling of
* non-hierarchical URI's), this class can be fully subclassed. If you
* intended to subclass URI, please see the source code for complete
* documation on protected members and protected fuctions.</p>
*
* @langversion ActionScript 3.0
* @playerversion Flash 9.0
*/
public class URI
{
// Here we define which characters must be escaped for each
// URI part. The characters that must be escaped for each
// part differ depending on what would cause ambiguous parsing.
// RFC 3986 sec. 2.4 states that characters should only be
// encoded when they would conflict with subcomponent delimiters.
// We don't want to over-do the escaping. We only want to escape
// the minimum needed to prevent parsing problems.
// space and % must be escaped in all cases. '%' is the delimiter
// for escaped characters.
public static const URImustEscape:String = " %";
// Baseline of what characters must be escaped
public static const URIbaselineEscape:String = URImustEscape + ":?#/@";
// Characters that must be escaped in the part part.
public static const URIpathEscape:String = URImustEscape + "?#";
// Characters that must be escaped in the query part, if setting
// the query as a whole string. If the query is set by
// name/value, URIqueryPartEscape is used instead.
public static const URIqueryEscape:String = URImustEscape + "#";
// This is what each name/value pair must escape "&=" as well
// so they don't conflict with the "param=value¶m2=value2"
// syntax.
public static const URIqueryPartEscape:String = URImustEscape + "#&=";
// Non-hierarchical URI's can have query and fragment parts, but
// we also want to prevent '/' otherwise it might end up looking
// like a hierarchical URI to the parser.
public static const URInonHierEscape:String = URImustEscape + "?#/";
// Baseline uninitialized setting for the URI scheme.
public static const UNKNOWN_SCHEME:String = "unknown";
// The following bitmaps are used for performance enhanced
// character escaping.
// Baseline characters that need to be escaped. Many parts use
// this.
protected static const URIbaselineExcludedBitmap:URIEncodingBitmap =
new URIEncodingBitmap(URIbaselineEscape);
// Scheme escaping bitmap
protected static const URIschemeExcludedBitmap:URIEncodingBitmap =
URIbaselineExcludedBitmap;
// User/pass escaping bitmap
protected static const URIuserpassExcludedBitmap:URIEncodingBitmap =
URIbaselineExcludedBitmap;
// Authority escaping bitmap
protected static const URIauthorityExcludedBitmap:URIEncodingBitmap =
URIbaselineExcludedBitmap;
// Port escaping bitmap
protected static const URIportExludedBitmap:URIEncodingBitmap =
URIbaselineExcludedBitmap;
// Path escaping bitmap
protected static const URIpathExcludedBitmap:URIEncodingBitmap =
new URIEncodingBitmap(URIpathEscape);
// Query (whole) escaping bitmap
protected static const URIqueryExcludedBitmap:URIEncodingBitmap =
new URIEncodingBitmap(URIqueryEscape);
// Query (individual parts) escaping bitmap
protected static const URIqueryPartExcludedBitmap:URIEncodingBitmap =
new URIEncodingBitmap(URIqueryPartEscape);
// Fragments are the last part in the URI. They only need to
// escape space, '#', and '%'. Turns out that is what query
// uses too.
protected static const URIfragmentExcludedBitmap:URIEncodingBitmap =
URIqueryExcludedBitmap;
// Characters that need to be escaped in the non-hierarchical part
protected static const URInonHierexcludedBitmap:URIEncodingBitmap =
new URIEncodingBitmap(URInonHierEscape);
// Values used by getRelation()
public static const NOT_RELATED:int = 0;
public static const CHILD:int = 1;
public static const EQUAL:int = 2;
public static const PARENT:int = 3;
//-------------------------------------------------------------------
// protected class members
//-------------------------------------------------------------------
protected var _valid:Boolean = false;
protected var _relative:Boolean = false;
protected var _scheme:String = "";
protected var _authority:String = "";
protected var _username:String = "";
protected var _password:String = "";
protected var _port:String = "";
protected var _path:String = "";
protected var _query:String = "";
protected var _fragment:String = "";
protected var _nonHierarchical:String = "";
protected static var _resolver:IURIResolver = null;
/**
* URI Constructor. If no string is given, this will initialize
* this URI object to a blank URI.
*/
public function URI(uri:String = null) : void
{
if (uri == null)
initialize();
else
constructURI(uri);
}
/**
* @private
* Method that loads the URI from the given string.
*/
protected function constructURI(uri:String) : Boolean
{
if (!parseURI(uri))
_valid = false;
return isValid();
}
/**
* @private Private initializiation.
*/
protected function initialize() : void
{
_valid = false;
_relative = false;
_scheme = UNKNOWN_SCHEME;
_authority = "";
_username = "";
_password = "";
_port = "";
_path = "";
_query = "";
_fragment = "";
_nonHierarchical = "";
}
/**
* @private Accessor to explicitly set/get the hierarchical
* state of the URI.
*/
protected function set hierState(state:Boolean) : void
{
if (state)
{
// Clear the non-hierarchical data
_nonHierarchical = "";
// Also set the state vars while we are at it
if (_scheme == "" || _scheme == UNKNOWN_SCHEME)
_relative = true;
else
_relative = false;
if (_authority.length == 0 && _path.length == 0)
_valid = false;
else
_valid = true;
}
else
{
// Clear the hierarchical data
_authority = "";
_username = "";
_password = "";
_port = "";
_path = "";
_relative = false;
if (_scheme == "" || _scheme == UNKNOWN_SCHEME)
_valid = false;
else
_valid = true;
}
}
protected function get hierState() : Boolean
{
return (_nonHierarchical.length == 0);
}
/**
* @private Functions that performs some basic consistency validation.
*/
protected function validateURI() : Boolean
{
// Check the scheme
if (isAbsolute())
{
if (_scheme.length <= 1 || _scheme == UNKNOWN_SCHEME)
{
// we probably parsed a C:\ type path or no scheme
return false;
}
else if (verifyAlpha(_scheme) == false)
return false; // Scheme contains bad characters
}
if (hierState)
{
if (_path.search('\\') != -1)
return false; // local path
else if (isRelative() == false && _scheme == UNKNOWN_SCHEME)
return false; // It's an absolute URI, but it has a bad scheme
}
else
{
if (_nonHierarchical.search('\\') != -1)
return false; // some kind of local path
}
// Looks like it's ok.
return true;
}
/**
* @private
*
* Given a URI in string format, parse that sucker into its basic
* components and assign them to this object. A URI is of the form:
* <scheme>:<authority><path>?<query>#<fragment>
*
* For simplicity, we parse the URI in the following order:
*
* 1. Fragment (anchors)
* 2. Query (CGI stuff)
* 3. Scheme ("http")
* 4. Authority (host name)
* 5. Username/Password (if any)
* 6. Port (server port if any)
* 7. Path (/homepages/mypage.html)
*
* The reason for this order is to minimize any parsing ambiguities.
* Fragments and queries can contain almost anything (they are parts
* that can contain custom data with their own syntax). Parsing
* them out first removes a large chance of parsing errors. This
* method expects well formed URI's, but performing the parse in
* this order makes us a little more tolerant of user error.
*
* REGEXP
* Why doesn't this use regular expressions to parse the URI? We
* have found that in a real world scenario, URI's are not always
* well formed. Sometimes characters that should have been escaped
* are not, and those situations would break a regexp pattern. This
* function attempts to be smart about what it is parsing based on
* location of characters relative to eachother. This function has
* been proven through real-world use to parse the vast majority
* of URI's correctly.
*
* NOTE
* It is assumed that the string in URI form is escaped. This function
* does not escape anything. If you constructed the URI string by
* hand, and used this to parse in the URI and still need it escaped,
* call forceEscape() on your URI object.
*
* Parsing Assumptions
* This routine assumes that the URI being passed is well formed.
* Passing things like local paths, malformed URI's, and the such
* will result in parsing errors. This function can handle
* - absolute hierarchical (e.g. "http://something.com/index.html),
* - relative hierarchical (e.g. "../images/flower.gif"), or
* - non-hierarchical URIs (e.g. "mailto:jsmith@fungoo.com").
*
* Anything else will probably result in a parsing error, or a bogus
* URI object.
*
* Note that non-hierarchical URIs *MUST* have a scheme, otherwise
* they will be mistaken for relative URI's.
*
* If you are not sure what is being passed to you (like manually
* entered text from UI), you can construct a blank URI object and
* call unknownToURI() passing in the unknown string.
*
* @return true if successful, false if there was some kind of
* parsing error
*/
protected function parseURI(uri:String) : Boolean
{
var baseURI:String = uri;
var index:int, index2:int;
// Make sure this object is clean before we start. If it was used
// before and we are now parsing a new URI, we don't want any stale
// info lying around.
initialize();
// Remove any fragments (anchors) from the URI
index = baseURI.indexOf("#");
if (index != -1)
{
// Store the fragment piece if any
if (baseURI.length > (index + 1)) // +1 is to skip the '#'
_fragment = baseURI.substr(index + 1, baseURI.length - (index + 1));
// Trim off the fragment
baseURI = baseURI.substr(0, index);
}
// We need to strip off any CGI parameters (eg '?param=bob')
index = baseURI.indexOf("?");
if (index != -1)
{
if (baseURI.length > (index + 1))
_query = baseURI.substr(index + 1, baseURI.length - (index + 1)); // +1 is to skip the '?'
// Trim off the query
baseURI = baseURI.substr(0, index);
}
// Now try to find the scheme part
index = baseURI.search(':');
index2 = baseURI.search('/');
var containsColon:Boolean = (index != -1);
var containsSlash:Boolean = (index2 != -1);
// This value is indeterminate if "containsColon" is false.
// (if there is no colon, does the slash come before or
// after said non-existing colon?)
var colonBeforeSlash:Boolean = (!containsSlash || index < index2);
// If it has a colon and it's before the first slash, we will treat
// it as a scheme. If a slash is before a colon, there must be a
// stray colon in a path or something. In which case, the colon is
// not the separator for the scheme. Technically, we could consider
// this an error, but since this is not an ambiguous state (we know
// 100% that this has no scheme), we will keep going.
if (containsColon && colonBeforeSlash)
{
// We found a scheme
_scheme = baseURI.substr(0, index);
// Normalize the scheme
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -