Mercurial > projects > ldc
view tango/tango/net/http/HttpStack.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
line wrap: on
line source
/******************************************************************************* copyright: Copyright (c) 2004 Kris Bell. All rights reserved license: BSD style: $(LICENSE) version: Initial release: April 2004 author: Kris, John Reimer *******************************************************************************/ module tango.net.http.HttpStack; private import tango.core.Exception; /****************************************************************************** Unix doesn't appear to have a memicmp() ... JJR notes that the strncasecmp() is available instead. ******************************************************************************/ version (Win32) { extern (C) int memicmp (char *, char *, uint); } version (Posix) { extern (C) int strncasecmp (char *, char*, uint); } extern (C) void* memmove (void* dst, void* src, int n); /****************************************************************************** Internal representation of a token ******************************************************************************/ class Token { private char[] value; Token set (char[] value) { this.value = value; return this; } char[] toString () { return value; } } /****************************************************************************** A stack of Tokens, used for capturing http headers. The tokens themselves are typically mapped onto the content of a Buffer, or some other external content, so there's minimal allocation involved (typically zero). ******************************************************************************/ class HttpStack { private int depth; private Token[] tokens; private static const int MaxHttpStackSize = 256; /********************************************************************** Construct a HttpStack with the specified initial size. The stack will later be resized as necessary. **********************************************************************/ this (int size = 10) { tokens = new Token[0]; resize (tokens, size); } /********************************************************************** Clone this stack of tokens **********************************************************************/ HttpStack clone () { // setup a new HttpStack of the same depth HttpStack clone = new HttpStack(depth); clone.depth = depth; // duplicate the content of each original token for (int i=0; i < depth; ++i) clone.tokens[i].set (tokens[i].toString().dup); return clone; } /********************************************************************** Iterate over all tokens in stack **********************************************************************/ int opApply (int delegate(inout Token) dg) { int result = 0; for (int i=0; i < depth; ++i) if ((result = dg (tokens[i])) != 0) break; return result; } /********************************************************************** Pop the stack all the way back to zero **********************************************************************/ final void reset () { depth = 0; } /********************************************************************** Scan the tokens looking for the first one with a matching name. Returns the matching Token, or null if there is no such match. **********************************************************************/ final Token findToken (char[] match) { Token tok; for (int i=0; i < depth; ++i) { tok = tokens[i]; if (isMatch (tok, match)) return tok; } return null; } /********************************************************************** Scan the tokens looking for the first one with a matching name, and remove it. Returns true if a match was found, or false if not. **********************************************************************/ final bool removeToken (char[] match) { for (int i=0; i < depth; ++i) if (isMatch (tokens[i], match)) { tokens[i].value = null; return true; } return false; } /********************************************************************** Return the current stack depth **********************************************************************/ final int size () { return depth; } /********************************************************************** Push a new token onto the stack, and set it content to that provided. Returns the new Token. **********************************************************************/ final Token push (char[] content) { return push().set (content); } /********************************************************************** Push a new token onto the stack, and set it content to be that of the specified token. Returns the new Token. **********************************************************************/ final Token push (inout Token token) { return push (token.toString()); } /********************************************************************** Push a new token onto the stack, and return it. **********************************************************************/ final Token push () { if (depth == tokens.length) resize (tokens, depth * 2); return tokens[depth++]; } /********************************************************************** Pop the stack by one. **********************************************************************/ final void pop () { if (depth) --depth; else throw new IOException ("illegal attempt to pop Token stack"); } /********************************************************************** See if the given token matches the specified text. The two must match the minimal extent exactly. **********************************************************************/ final static bool isMatch (inout Token token, char[] match) { char[] target = token.toString(); int length = target.length; if (length > match.length) length = match.length; if (length is 0) return false; version (Win32) return memicmp (target.ptr, match.ptr, length) is 0; version (Posix) return strncasecmp (target.ptr, match.ptr, length) is 0; } /********************************************************************** Resize this stack by extending the array. **********************************************************************/ final static void resize (inout Token[] tokens, int size) { int i = tokens.length; // this should *never* realistically happen if (size > MaxHttpStackSize) throw new IOException ("Token stack exceeds maximum depth"); for (tokens.length=size; i < tokens.length; ++i) tokens[i] = new Token(); } }