changeset 198:be4ce760802a

Add: missing files
author Frank Benoit <benoit@tionex.de>
date Thu, 10 Apr 2008 11:20:26 +0200
parents 184ab53b7785
children 3d5dbb27dec2
files dwt/dwthelper/WeakHashMap.d dwt/dwthelper/WeakRef.d dwt/dwthelper/XmlTranscode.d
diffstat 3 files changed, 302 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/dwthelper/WeakHashMap.d	Thu Apr 10 11:20:26 2008 +0200
@@ -0,0 +1,33 @@
+module dwt.dwthelper.WeakHashMap;
+
+
+/+
+    Is not yet 'weak'
++/
+class WeakHashMap {
+
+    static class Ref {
+        size_t ptr;
+        this(Object k){
+            ptr = cast(size_t)cast(void*)k;
+        }
+    }
+
+    Object[ Ref ] data;
+
+    public void add (Object key, Object element){
+        auto k = new Ref(key);
+        data[ k ] = element;
+    }
+    public void removeKey (Object key){
+        scope k = new Ref(key);
+        data.remove( k );
+    }
+    public Object get(Object key){
+        scope k = new Ref(key);
+        if( auto p = k in data ){
+            return *p;
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/dwthelper/WeakRef.d	Thu Apr 10 11:20:26 2008 +0200
@@ -0,0 +1,88 @@
+/*==========================================================================
+ * weakref.d
+ *    Written in the D Programming Language (http://www.digitalmars.com/d)
+ */
+/***************************************************************************
+ * Creates a weak reference to a class instance.
+ *
+ * A weak reference lets you hold onto a pointer to an object without
+ * preventing the garbage collector from collecting it.
+ * If the garbage collector collects the object then the weak pointer will
+ * become 'null'.  Thus one should always check a weak pointer for null
+ * before doing anything that depends upon it having a value.
+ *
+ * Tested with:
+ *    DMD 1.025 / Phobos 1.025
+ *    DMD 1.025 / Tango 0.99.4
+ *
+ * Usage example:
+---
+ class Something {}
+
+ auto a = new Something();
+ auto wa = new WeakRef!(Something)(a);
+ std.gc.fullCollect();
+
+ // Reference 'a' prevents collection so wa.ptr is non-null
+ assert(wa.ptr is a);
+
+ delete a;
+
+ // 'a' is gone now, so wa.ptr magically becomes null
+ assert(wa.ptr is null);
+---
+ *
+ *
+ * Author:  William V. Baxter III
+ * Contributors:
+ * Date: 21 Jan 2008
+ * Copyright: (C) 2008  William Baxter
+ * License: Public Domain where allowed by law, ZLIB/PNG otherwise.
+ */
+//===========================================================================
+
+module dwt.dwthelper.WeakRef;
+
+private {
+    alias void delegate(Object) DisposeEvt;
+    extern (C) void  rt_attachDisposeEvent( Object obj, DisposeEvt evt );
+    extern (C) void  rt_detachDisposeEvent( Object obj, DisposeEvt evt );
+}
+
+class WeakRef(T : Object) {
+private:
+    size_t cast_ptr_;
+    void unhook(Object o) {
+        if (cast(size_t)cast(void*)o == cast_ptr_) {
+            rt_detachDisposeEvent(o, &unhook);
+            cast_ptr_ = 0;
+        }
+    }
+public:
+
+    this(T tptr) {
+        cast_ptr_ = cast(size_t)cast(void*)tptr;
+        rt_attachDisposeEvent(tptr, &unhook);
+    }
+    ~this() {
+        T p = ptr();
+        if (p) {
+            rt_detachDisposeEvent(p, &unhook);
+        }
+    }
+    T ptr() {
+        return cast(T)cast(void*)cast_ptr_;
+    }
+    WeakRef dup() {
+        return new WeakRef(ptr());
+    }
+    int opEquals( Object o ){
+        if( auto other = cast( WeakRef!(T) )o ){
+            return other.cast_ptr_ is cast_ptr_;
+        }
+        return false;
+    }
+    hash_t toHash(){
+        return cast_ptr_;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/dwthelper/XmlTranscode.d	Thu Apr 10 11:20:26 2008 +0200
@@ -0,0 +1,181 @@
+module dwt.dwthelper.XmlTranscode;
+
+import dwt.dwthelper.utils;
+import tango.core.Exception;
+
+/++
+ + Decode XML entities into UTF8 string.
+ + Eg. "&amp;" -> "&", "&#38;" -> "&", "&#x26;" -> "&"
+ + Throws TextException on failure
+ + The given string is modified.
+ +/
+char[] xmlUnescape( char[] str ){
+
+    void error(){
+        throw new TextException( "xmlUnescape" );
+    }
+    // &lt; ...
+    // &#1234;
+    // &#x12AF;
+    char[] src = str;
+    char[] trg = str;
+    while( src.length ){
+        if( src[0] !is '&' ){
+            trg[0] = src[0];
+            trg = trg[1..$];
+            src = src[1..$];
+        }
+        else{
+            src = src[1..$]; //  go past '&'
+            if( src.length < 2 ) error();
+
+            // search semi
+            int len = Math.min( src.length, 10 ); // limit semi search to possible longest entityname
+            int semi = tango.text.Util.locate( src[0 .. len ], ';' );
+            if( semi is len ) error(); // no semi found
+
+            char[] entityName = src[ 0 .. semi ]; // name without semi
+            dchar entityValue = 0;
+            switch( entityName ){
+                case "lt":   entityValue = '<'; break;
+                case "gt":   entityValue = '>'; break;
+                case "amp":  entityValue = '&'; break;
+                case "quot": entityValue = '\"'; break;
+                case "apos": entityValue = '\''; break;
+                default:
+                    if( entityName[0] is 'x' ){
+                        if( semi < 2 ) error();
+                        if( semi > 9 ) error();
+                        foreach( hex; entityName[1..$] ){
+                            entityValue <<= 4;
+                            if( hex >= '0' && hex <= '9' ){
+                                entityValue |= ( hex - '0' );
+                            }
+                            else if( hex >= 'a' && hex <= 'f' ){
+                                entityValue |= ( hex - 'a' );
+                            }
+                            else if( hex >= 'A' && hex <= 'F' ){
+                                entityValue |= ( hex - 'A' );
+                            }
+                            else{
+                                error();
+                            }
+                        }
+                    }
+                    else{
+                        if( semi < 1 ) error();
+                        if( semi > 9 ) error();
+                        foreach( dec; entityName[1..$] ){
+                            if( dec >= '0' && dec <= '9' ){
+                                entityValue *= 10;
+                                entityValue += ( dec - '0' );
+                            }
+                            else{
+                                error();
+                            }
+                        }
+                    }
+            }
+            dchar[1] arr;
+            arr[0] = entityValue;
+            uint ate = 0;
+            char[] res = tango.text.convert.Utf.toString( arr, trg, &ate );
+            trg = trg[ res.length .. $ ];
+            src = src[ semi +1 .. $ ]; // go past semi
+        }
+    }
+    return str[ 0 .. trg.ptr-str.ptr ];
+}
+
+
+/++
+ + Encode XML entities into UTF8 string.
+ + First checks if processing is needed.
+ + If not, the original string is returned.
+ + If processing is needed, a new string is allocated.
+ +/
+char[] xmlEscape( char[] xml ){
+    bool needsReplacement( dchar c ){
+        switch( c ){
+            case '<':
+            case '>':
+            case '&':
+            case '\"':
+            case '\'':
+            case '\r':
+            case '\n':
+            case '\u0009':
+                return true;
+            default:
+                return c > 0x7F;
+        }
+    }
+
+    // Check if processing is needed
+    foreach( char c; xml ){
+        if( needsReplacement( c )){
+            goto Lprocess;
+        }
+    }
+    return xml;
+Lprocess:
+
+    // yes, do a new string, start with +20 chars
+    char[] res = new char[ xml.length + 20 ];
+    res.length = 0;
+
+    foreach( dchar c; xml ){
+
+        if( !needsReplacement( c )){
+            res ~= c;
+        }
+        else{
+            res ~= '&';
+            switch( c ){
+                case '<': res ~= "lt"; break;
+                case '>': res ~= "gt"; break;
+                case '&': res ~= "amp"; break;
+                case '\"': res ~= "quot"; break;
+                case '\'': res ~= "apos"; break;
+                case '\r': case '\n': case '\u0009':
+                default:
+                    char toHexDigit( int i ){
+                        if( i < 10 ) return '0'+i;
+                        return 'A'+i-10;
+                    }
+                    res ~= "#x";
+                    if( c <= 0xFF ){
+                        res ~= toHexDigit(( c >> 4 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 0 ) & 0x0F );
+                    }
+                    else if( c <= 0xFFFF ){
+                        res ~= toHexDigit(( c >> 12 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 8 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 4 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 0 ) & 0x0F );
+                    }
+                    else if( c <= 0xFFFFFF ){
+                        res ~= toHexDigit(( c >> 20 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 16 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 12 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 8 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 4 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 0 ) & 0x0F );
+                    }
+                    else {
+                        res ~= toHexDigit(( c >> 28 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 24 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 20 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 16 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 12 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 8 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 4 ) & 0x0F );
+                        res ~= toHexDigit(( c >> 0 ) & 0x0F );
+                    }
+                    break;
+            }
+            res ~= ';';
+        }
+    }
+}
+