Parsing an URI

I recently promised, that if I couldn’t find a valid URI-parser in ActionScript 2, I would create and release my own.

I’ve thus created my own built on simple string parsing functions (as opposed to using some regexp implementation, which is still not natively supported until AS3). It does not properly handle invalid chars of an URI (like spaces, special characters and more), but assumes an URL-encoded URI of some sort.

Well, here it is:

class org.barklund.utils.URI {
	/**
	 * parts of uri
	 */
	public var host:String;
	public var scheme:String;
	public var user:String;
	public var password:String;
	public var query:String;
	public var fragment:String;
	public var port:String;
	public var resource:String;
	/** 
	 * complete uri
	 */
	public var uri:String;
	/**
	 * private constructor initiating parse
	 */
	private function URI(u:String) {
		uri = u;
		parse();
	}
	/**
	 * parse uri into scheme, host and resource - if these exist
	 */
	private function parse():Void {
		// if no slash - we only have resource
		var first_slash:Number = uri.indexOf("/");
		if (first_slash == -1) {
			resource = uri;
			parseResource();
			return;
		}
		// if :// (before first slash) we have scheme first
		var working:String = uri;
		var scheme_end:Number = uri.indexOf("://");
		if (scheme_end != -1 && scheme_end < first_slash) {
			scheme = uri.substr(0, scheme_end);
			working = working.substr(scheme_end+3);
		}
		// split working into host and resource
		first_slash = working.indexOf("/");
		if (first_slash == -1) {
			// no resource
			host = working;
			parseHost();
		} else {
			host = working.substr(0, first_slash);
			resource = working.substr(first_slash);
			parseResource();
			parseHost();
		}
	}
	/**
	 * parse resource into resource, fragment and query if exists
	 */
	private function parseResource():Void {
		// split fragment from resource - including #
		var fragment_part:Number = resource.indexOf("#");
		if (fragment_part != -1) {
			fragment = resource.substr(fragment_part);
			resource = resource.substr(0, fragment_part);
		}
		// split query from resource - including ?
		var query_part:Number = resource.indexOf("?");
		if (query_part != -1) {
			query = resource.substr(query_part);
			resource = resource.substr(0, query_part);
		}
	}
	/**
	 * parse host into host, port, user and password if exists
	 */
	private function parseHost():Void {
		// split host into user:pass and host:port over @
		var at:Number = host.indexOf("@");
		var colon:Number;
		if (at != -1) {
			user = host.substr(0, at);
			host = host.substr(at + 1);
			// split pass from user
			colon = user.indexOf(":");
			if (colon != -1) {
				password = user.substr(colon + 1);
				user = user.substr(0, colon);
 
			}
		}
		// split port from host
		colon = host.indexOf(":");
		if (colon != -1) {
			port = host.substr(colon + 1);
			host = host.substr(0, colon);
 
		}
	}
	/**
	 * static constructor. it looks nice and adds the possibility to return null.
	 */
	public static function parseString(uri:String):URI {
		if (uri) {
			return new URI(uri);
		} else {
			return null
		}
	}
}

It is used via the static constructor like:

import org.barklund.utils.URI;
class org.barklund.somewhere.Something {
	...
	var my_ftp:URI = URI.parseString("ftp://myuser:mypassword@myhost:21/some/ressource");
	if (my_ftp.scheme === "ftp") {
		...
}

No related posts.

Category: AS2 Comment »


Leave a Reply



Back to top

     

Get Adobe Flash playerPlugin by wpburn.com wordpress themes