changeset 219:9b4e6fc63930

utils updates
author Frank Benoit <benoit@tionex.de>
date Sun, 06 Apr 2008 22:26:22 +0200
parents 0a390aaee2ee
children ba054b4a1c55
files dwt/dwthelper/Integer.d dwt/dwthelper/ResourceBundle.d dwt/dwthelper/System.d dwt/dwthelper/utils.d dwt/internal/CloneableCompatibility.d dwt/internal/DWTEventListener.d dwt/internal/DWTEventObject.d
diffstat 7 files changed, 800 insertions(+), 171 deletions(-) [+]
line wrap: on
line diff
--- a/dwt/dwthelper/Integer.d	Sun Apr 06 22:25:15 2008 +0200
+++ b/dwt/dwthelper/Integer.d	Sun Apr 06 22:26:22 2008 +0200
@@ -1,4 +1,4 @@
-/**
+/**
  * Authors: Frank Benoit <keinfarbton@googlemail.com>
  */
 
@@ -9,135 +9,5 @@
 static import tango.text.convert.Integer;
 private import tango.core.Exception;
 
-public final class Byte {
-    public static byte parseByte( char[] s ){
-        try{
-            int res = tango.text.convert.Integer.parse( s );
-            if( res < byte.min || res > byte.max ){
-                throw new NumberFormatException( "out of range" );
-            }
-            return res;
-        }
-        catch( IllegalArgumentException e ){
-            throw new NumberFormatException( e );
-        }
-    }
-}
-public final class Integer {
-
-    public static int MIN_VALUE = 0x80000000;
-    public static int MAX_VALUE = 0x7fffffff;
-    public static int SIZE = 32;
-
-    public int value;
-    public this ( int value ){
-        this.value = value;
-    }
-
-    public this ( char[] s ){
-    }
-
-    public static char[] toString( int i, int radix ){
-        switch( radix ){
-        case 2:
-            return toBinaryString(i);
-        case 8:
-            return toOctalString(i);
-        case 10:
-            return toString(i);
-        case 16:
-            return toHexString(i);
-        default:
-            implMissing( __FILE__, __LINE__ );
-            return null;
-        }
-    }
-
-    public static char[] toHexString( int i ){
-        return tango.text.convert.Integer.toString(i, tango.text.convert.Integer.Style.Hex );
-    }
-
-    public static char[] toOctalString( int i ){
-        return tango.text.convert.Integer.toString(i, tango.text.convert.Integer.Style.Octal );
-    }
-
-    public static char[] toBinaryString( int i ){
-        return tango.text.convert.Integer.toString(i, tango.text.convert.Integer.Style.Binary );
-    }
-
-    public static char[] toString( int i ){
-        return tango.text.convert.Integer.toString(i);
-    }
-
-    public static int parseInt( char[] s, int radix ){
-        try{
-            return tango.text.convert.Integer.parse( s, cast(uint)radix );
-        }
-        catch( IllegalArgumentException e ){
-            throw new NumberFormatException( e );
-        }
-    }
-
-    public static int parseInt( char[] s ){
-        try{
-            return tango.text.convert.Integer.parse( s );
-        }
-        catch( IllegalArgumentException e ){
-            throw new NumberFormatException( e );
-        }
-    }
-
-    public static Integer valueOf( char[] s, int radix ){
-        implMissing( __FILE__, __LINE__ );
-        return null;
-    }
-
-    public static Integer valueOf( char[] s ){
-        implMissing( __FILE__, __LINE__ );
-        return null;
-    }
-
-    public static Integer valueOf( int i ){
-        implMissing( __FILE__, __LINE__ );
-        return null;
-    }
-
-    public byte byteValue(){
-        return cast(byte)value;
-    }
-
-    public short shortValue(){
-        return cast(short)value;
-    }
-
-    public int intValue(){
-        return value;
-    }
-
-    public long longValue(){
-        return cast(long)value;
-    }
-
-    public float floatValue(){
-        return cast(float)value;
-    }
-
-    public double doubleValue(){
-        return cast(double)value;
-    }
-
-    public override  hash_t toHash(){
-        return intValue();
-    }
-
-    public override int opEquals( Object obj ){
-        implMissing( __FILE__, __LINE__ );
-        return false;
-    }
-
-    public override char[] toString(){
-        return tango.text.convert.Integer.toString( value );
-    }
-}
 
 
--- a/dwt/dwthelper/ResourceBundle.d	Sun Apr 06 22:25:15 2008 +0200
+++ b/dwt/dwthelper/ResourceBundle.d	Sun Apr 06 22:26:22 2008 +0200
@@ -7,6 +7,7 @@
 import tango.io.Stdout;
 
 import dwt.DWT;
+import dwt.dwthelper.utils;
 
 class ResourceBundle {
 
@@ -35,7 +36,7 @@
         while( dataIndex < data.length ){
             //tango.io.Stdout.Stdout.formatln( "properties put {} startline", __LINE__ );
             readLine();
-            line = line.trim();
+            line = dwt.dwthelper.utils.trim(line);
             if( line.length is 0 ){
                 //tango.io.Stdout.Stdout.formatln( "properties put {} was 0 length", __LINE__ );
                 continue;
@@ -95,8 +96,8 @@
                 DWT.error( __FILE__, __LINE__, DWT.ERROR_INVALID_ARGUMENT );
                 continue;
             }
-            key = key.trim();
-            value = value.trim();
+            key = dwt.dwthelper.utils.trim(key);
+            value = dwt.dwthelper.utils.trim(value);
             //tango.io.Stdout.Stdout.formatln( "properties put {}=>{}", key, value );
 
             map[ key.dup ] = value.dup;
@@ -112,7 +113,11 @@
         if( auto v = key in map ){
             return (*v).dup;
         }
-        return key;
+        throw new MissingResourceException( "key not found", this.classinfo.name, key );
+    }
+
+    public char[][] getKeys(){
+        return map.keys;
     }
 
     public static ResourceBundle getBundle( char[] name ){
--- a/dwt/dwthelper/System.d	Sun Apr 06 22:25:15 2008 +0200
+++ b/dwt/dwthelper/System.d	Sun Apr 06 22:26:22 2008 +0200
@@ -128,6 +128,18 @@
     static void exit( int code ){
         .exit(code);
     }
+    public static int identityHashCode(Object x){
+        if( x is null ){
+            return 0;
+        }
+        return (*cast(Object *)&x).toHash();
+    }
 
+    public static char[] getProperty( char[] key ){
+        switch( key ){
+        case "os.name": return "linux";
+        default: return null;
+        }
+    }
 }
 
--- a/dwt/dwthelper/utils.d	Sun Apr 06 22:25:15 2008 +0200
+++ b/dwt/dwthelper/utils.d	Sun Apr 06 22:26:22 2008 +0200
@@ -9,14 +9,33 @@
 public import tango.core.Exception : IllegalArgumentException, IOException;
 
 import tango.io.Stdout;
+import tango.io.Print;
 import tango.stdc.stringz;
 static import tango.text.Util;
+static import tango.text.Text;
 import tango.text.Unicode;
 import tango.text.convert.Utf;
 import tango.core.Exception;
 import tango.stdc.stdlib : exit;
 
 import tango.util.log.Trace;
+import tango.text.UnicodeData;
+static import tango.util.collection.model.Seq;
+// static import tango.util.collection.ArraySeq;
+// static import tango.util.collection.LinkSeq;
+// static import tango.util.collection.model.Map;
+// static import tango.util.collection.HashMap;
+//
+// alias tango.util.collection.model.Seq.Seq!(Object) List;
+// alias tango.util.collection.ArraySeq.ArraySeq!(Object) ArrayList;
+// alias tango.util.collection.LinkSeq.LinkSeq!(Object) LinkList;
+// alias tango.util.collection.model.Map.Map!(Object,Object) Map;
+// alias tango.util.collection.HashMap.HashMap!(Object,Object) HashMap;
+
+public import dwt.dwthelper.Integer;
+
+alias char[] String;
+alias tango.text.Text.Text!(char) StringBuffer;
 
 void implMissing( char[] file, uint line ){
     Stderr.formatln( "implementation missing in file {} line {}", file, line );
@@ -41,11 +60,232 @@
     public this( T data ){
         value = data;
     }
+    public int opEquals( T other ){
+        return value == other;
+    }
+}
+
+class Boolean : ValueWrapperT!(bool) {
+    public static Boolean TRUE;
+    public static Boolean FALSE;
+    public this( bool v ){
+        super(v);
+    }
+
+    alias ValueWrapperT!(bool).opEquals opEquals;
+    public int opEquals( int other ){
+        return value == ( other !is 0 );
+    }
+    public int opEquals( Object other ){
+        if( auto o = cast(Boolean)other ){
+            return value == o.value;
+        }
+        return false;
+    }
+    public bool booleanValue(){
+        return value;
+    }
 }
 
-alias ValueWrapperT!(bool)    ValueWrapperBool;
-alias ValueWrapperT!(int)     ValueWrapperInt;
-alias ValueWrapperT!(long)    ValueWrapperLong;
+alias Boolean    ValueWrapperBool;
+
+
+class Byte : ValueWrapperT!(byte) {
+    public static byte parseByte( char[] s ){
+        try{
+            int res = tango.text.convert.Integer.parse( s );
+            if( res < byte.min || res > byte.max ){
+                throw new NumberFormatException( "out of range" );
+            }
+            return res;
+        }
+        catch( IllegalArgumentException e ){
+            throw new NumberFormatException( e );
+        }
+    }
+    this( byte value ){
+        super( value );
+    }
+}
+alias Byte ValueWrapperByte;
+
+
+class Integer : ValueWrapperT!(int) {
+
+    public static int MIN_VALUE = 0x80000000;
+    public static int MAX_VALUE = 0x7fffffff;
+    public static int SIZE = 32;
+
+    public this ( int value ){
+        super( value );
+    }
+
+    public this ( char[] s ){
+            implMissing( __FILE__, __LINE__ );
+            super(0);
+    }
+
+    public static char[] toString( int i, int radix ){
+        switch( radix ){
+        case 2:
+            return toBinaryString(i);
+        case 8:
+            return toOctalString(i);
+        case 10:
+            return toString(i);
+        case 16:
+            return toHexString(i);
+        default:
+            implMissing( __FILE__, __LINE__ );
+            return null;
+        }
+    }
+
+    public static char[] toHexString( int i ){
+        return tango.text.convert.Integer.toString(i, tango.text.convert.Integer.Style.Hex );
+    }
+
+    public static char[] toOctalString( int i ){
+        return tango.text.convert.Integer.toString(i, tango.text.convert.Integer.Style.Octal );
+    }
+
+    public static char[] toBinaryString( int i ){
+        return tango.text.convert.Integer.toString(i, tango.text.convert.Integer.Style.Binary );
+    }
+
+    public static char[] toString( int i ){
+        return tango.text.convert.Integer.toString(i);
+    }
+
+    public static int parseInt( char[] s, int radix ){
+        try{
+            return tango.text.convert.Integer.parse( s, cast(uint)radix );
+        }
+        catch( IllegalArgumentException e ){
+            throw new NumberFormatException( e );
+        }
+    }
+
+    public static int parseInt( char[] s ){
+        try{
+            return tango.text.convert.Integer.parse( s );
+        }
+        catch( IllegalArgumentException e ){
+            throw new NumberFormatException( e );
+        }
+    }
+
+    public static Integer valueOf( char[] s, int radix ){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public static Integer valueOf( char[] s ){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public static Integer valueOf( int i ){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public byte byteValue(){
+        return cast(byte)value;
+    }
+
+    public short shortValue(){
+        return cast(short)value;
+    }
+
+    public int intValue(){
+        return value;
+    }
+
+    public long longValue(){
+        return cast(long)value;
+    }
+
+    public float floatValue(){
+        return cast(float)value;
+    }
+
+    public double doubleValue(){
+        return cast(double)value;
+    }
+
+    public override  hash_t toHash(){
+        return intValue();
+    }
+
+    public override int opEquals( Object obj ){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+    public override char[] toString(){
+        return tango.text.convert.Integer.toString( value );
+    }
+}
+alias Integer ValueWrapperInt;
+
+class Double : ValueWrapperT!(double) {
+    this( double value ){
+        super(value);
+    }
+    this( char[] str ){
+        implMissing( __FILE__, __LINE__ );
+        super(0.0);
+    }
+    public double doubleValue(){
+        return value;
+    }
+    public static char[] toString( double value ){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+class Float : ValueWrapperT!(float) {
+    this( float value ){
+        super(value);
+    }
+    this( char[] str ){
+        implMissing( __FILE__, __LINE__ );
+        super(0.0);
+    }
+    public float floatValue(){
+        return value;
+    }
+    public static char[] toString( float value ){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+class Long : ValueWrapperT!(long) {
+    this( long value ){
+        super(value);
+    }
+    this( char[] str ){
+        implMissing( __FILE__, __LINE__ );
+        super(0);
+    }
+    public long longValue(){
+        return value;
+    }
+    public static long parseLong(char[] s){
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+    public static char[] toString( double value ){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+alias Long ValueWrapperLong;
+
+
+// alias ValueWrapperT!(int)     ValueWrapperInt;
 
 alias ArrayWrapperT!(byte)    ArrayWrapperByte;
 alias ArrayWrapperT!(int)     ArrayWrapperInt;
@@ -53,6 +293,13 @@
 alias ArrayWrapperT!(char)    ArrayWrapperString;
 alias ArrayWrapperT!(char[])  ArrayWrapperString2;
 
+Object[] StringArrayToObjectArray( String[] strs ){
+    Object[] res = new Object[strs.length];
+    foreach( idx, str; strs ){
+        res[idx] = new ArrayWrapperString(str);
+    }
+    return res;
+}
 int codepointIndexToIndex( char[] str, int cpIndex ){
     int cps = cpIndex;
     int res = 0;
@@ -204,6 +451,9 @@
     return offset;
 }
 
+bool CharacterIsDefined( dchar ch ){
+    return (ch in tango.text.UnicodeData.unicodeData) !is null;
+}
 dchar CharacterFirstToLower( char[] str ){
     int consumed;
     return CharacterFirstToLower( str, consumed );
@@ -229,6 +479,12 @@
 bool CharacterIsDigit( dchar c ){
     return tango.text.Unicode.isDigit( c );
 }
+bool CharacterIsLetter( dchar c ){
+    return tango.text.Unicode.isLetter( c );
+}
+public char[] toUpperCase( char[] str ){
+    return tango.text.Unicode.toUpper( str );
+}
 
 public int indexOf( char[] str, char searched ){
     int res = tango.text.Util.locate( str, searched );
@@ -260,6 +516,14 @@
     if( res is str.length ) res = -1;
     return res;
 }
+public int lastIndexOf(char[] str, char[] ch ){
+    return lastIndexOf( str, ch, str.length );
+}
+public int lastIndexOf(char[] str, char[] ch, int start ){
+    int res = tango.text.Util.locatePatternPrior( str, ch, start );
+    if( res is str.length ) res = -1;
+    return res;
+}
 
 public char[] replace( char[] str, char from, char to ){
     return tango.text.Util.replace( str.dup, from, to );
@@ -326,6 +590,9 @@
 public char[] trim( char[] str ){
     return tango.text.Util.trim( str ).dup;
 }
+public char[] intern( char[] str ){
+    return str;
+}
 
 public char* toStringzValidPtr( char[] src ){
     if( src ){
@@ -348,6 +615,28 @@
             );
 }
 
+class RuntimeException : Exception {
+    this( char[] e = null){
+        super(e);
+    }
+    this( Exception e ){
+        super(e.toString);
+    }
+}
+class IndexOutOfBoundsException : Exception {
+    this( char[] e = null){
+        super(e);
+    }
+}
+
+class UnsupportedOperationException : RuntimeException {
+    this( char[] e = null){
+        super(e);
+    }
+    this( Exception e ){
+        super(e.toString);
+    }
+}
 class NumberFormatException : IllegalArgumentException {
     this( char[] e ){
         super(e);
@@ -356,6 +645,86 @@
         super(e.toString);
     }
 }
+class NullPointerException : Exception {
+    this( char[] e = null ){
+        super(e);
+    }
+    this( Exception e ){
+        super(e.toString);
+    }
+}
+class IllegalStateException : Exception {
+    this( char[] e = null ){
+        super(e);
+    }
+    this( Exception e ){
+        super(e.toString);
+    }
+}
+class InterruptedException : Exception {
+    this( char[] e = null ){
+        super(e);
+    }
+    this( Exception e ){
+        super(e.toString);
+    }
+}
+class InvocationTargetException : Exception {
+    Exception cause;
+    this( Exception e = null, char[] msg = null ){
+        super(msg);
+        cause = e;
+    }
+
+    alias getCause getTargetException;
+    Exception getCause(){
+        return cause;
+    }
+}
+class MissingResourceException : Exception {
+    char[] classname;
+    char[] key;
+    this( char[] msg, char[] classname, char[] key ){
+        super(msg);
+        this.classname = classname;
+        this.key = key;
+    }
+}
+class ParseException : Exception {
+    this( char[] e = null ){
+        super(e);
+    }
+}
+
+interface Cloneable{
+}
+
+interface Comparable {
+    int compareTo(Object o);
+}
+interface Comparator {
+    int compare(Object o1, Object o2);
+}
+interface EventListener{
+}
+
+class EventObject {
+    protected Object source;
+
+    public this(Object source) {
+        if (source is null)
+        throw new IllegalArgumentException( "null arg" );
+        this.source = source;
+    }
+
+    public Object getSource() {
+        return source;
+    }
+
+    public override char[] toString() {
+        return this.classinfo.name ~ "[source=" ~ source.toString() ~ "]";
+    }
+}
 
 private struct GCStats {
     size_t poolsize;        // total size of pool
@@ -374,3 +743,403 @@
 
 
 
+// import tango.core.Runtime;
+private uint calcKey( void* key ){
+    uint k = cast(uint)cast(void*)key;
+    k ^= 0x8000_0000;
+    return k;
+}
+
+// private bool collectHandler(Object o){
+//     uint key = calcKey( cast(void*)o );
+//     if( auto p = key in mKeyCollectedNotifiers ){
+//         (*p)( key );
+//         mKeyCollectedNotifiers.remove( key );
+//     }
+//     ClassInfo ci = o.classinfo;
+//     while(ci !is null ){
+//         foreach( i; ci.interfaces ){
+//             uint key = calcKey( cast(void*)o + i.offset );
+//             if( auto p = key in mKeyCollectedNotifiers ){
+//                 (*p)( key );
+//                 mKeyCollectedNotifiers.remove( key );
+//             }
+//         }
+//         ci = ci.base;
+//     }
+//     return true;
+// }
+//
+// static this(){
+//     Runtime.collectHandler( & collectHandler );
+// }
+//
+// void delegate( uint k ) KeyCollectedNotifier;
+// KeyCollectedNotifier[ uint ] mKeyCollectedNotifiers;
+//
+// private synchronized void addKeyCollectedNotifier( uint key, KeyCollectedNotifier del ){
+//     mKeyCollectedNotifiers[ key ] = del;
+// }
+
+class WeakHashMap(K,T) {
+    static assert( is(K==class) || is(K==interface) );
+    T[uint] data;
+
+    private void removeInternalKey( uint key ){
+        data.remove( key );
+    }
+
+    public void add (K key, T element){
+        data[ calcKey(cast(void*)key) ] = element;
+//         addKeyCollectedNotifier( calcKey(key), &removeInternalKey );
+    }
+    public void removeKey (K key){
+        data.remove( calcKey(cast(void*)key) );
+    }
+    public T get(K key){
+        if( auto p = calcKey(cast(void*)key) in data ){
+            return *p;
+        }
+        return null;
+    }
+}
+
+import dwt.dwthelper.InputStream;
+InputStream ClassInfoGetResourceAsStream( ClassInfo ci, char[] aName ){
+    implMissing( __FILE__, __LINE__ );
+    return null;
+}
+
+void ExceptionPrintStackTrace( Exception e ){
+    ExceptionPrintStackTrace( e, Stderr );
+}
+void ExceptionPrintStackTrace( Exception e, Print!(char) print ){
+    print.formatln( "Exception in {}({}): {}", e.file, e.line, e.msg );
+}
+
+bool ArrayEquals(T)( T[] a, T[] b ){
+    if( a.length !is b.length ){
+        return false;
+    }
+    for( int i = 0; i < a.length; i++ ){
+        static if( is( T==class) || is(T==interface)){
+            if( a[i] !is null && b[i] !is null ){
+                if( a[i] != b[i] ){
+                    return false;
+                }
+            }
+            else if( a[i] is null && b[i] is null ){
+            }
+            else{
+                return false;
+            }
+        }
+        else{
+            if( a[i] != b[i] ){
+                return false;
+            }
+        }
+    }
+}
+
+interface Reader{
+}
+interface Writer{
+}
+
+
+class Collator : Comparator {
+    public static Collator getInstance(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+    private this(){
+    }
+    int compare(Object o1, Object o2){
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+}
+
+interface Enumeration {
+    public bool hasMoreElements();
+    public Object nextElement();
+}
+
+
+template arraycast(T) {
+    T[] arraycast(U) (U[] u) {
+        static if (
+            (is (T == interface ) && is (U == interface )) ||
+            (is (T == class ) && is (U == class ))) {
+            return(cast(T[])u);
+        }
+        else {
+            int l = u.length;
+            T[] res;
+            res.length = l;
+            for (int i = 0; i < l; i++) {
+                res[i] = cast(T)u[i];
+            }
+            return(res);
+        }
+    }
+}
+
+char[] stringcast( Object o ){
+    if( auto str = cast(ArrayWrapperString) o ){
+        return str.array;
+    }
+    return null;
+}
+char[][] stringcast( Object[] objs ){
+    char[][] res = new char[][](objs.length);
+    foreach( idx, obj; objs ){
+        res[idx] = stringcast(obj);
+    }
+    return res;
+}
+ArrayWrapperString stringcast( char[] str ){
+    return new ArrayWrapperString( str );
+}
+ArrayWrapperString[] stringcast( char[][] strs ){
+    ArrayWrapperString[] res = new ArrayWrapperString[ strs.length ];
+    foreach( idx, str; strs ){
+        res[idx] = stringcast(str);
+    }
+    return res;
+}
+
+
+class Arrays{
+    public static bool equals(Object[] a, Object[] b){
+        if( a.length !is b.length ){
+            return false;
+        }
+        for( int i = 0; i < a.length; i++ ){
+            if( a[i] is null && b[i] is null ){
+                continue;
+            }
+            if( a[i] !is null && b[i] !is null && a[i] == b[i] ){
+                continue;
+            }
+            return false;
+        }
+        return true;
+    }
+}
+
+int SeqIndexOf(T)( tango.util.collection.model.Seq.Seq!(T) s, T src ){
+    int idx;
+    foreach( e; s ){
+        if( e == src ){
+            return idx;
+        }
+        idx++;
+    }
+    return -1;
+}
+
+/++
+ + 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 ~= ';';
+        }
+    }
+}
+
+int arrayIndexOf(T)( T[] arr, T v ){
+    int res = -1;
+    int idx = 0;
+    foreach( p; arr ){
+        if( p == v){
+            res = idx;
+            break;
+        }
+        idx++;
+    }
+    return res;
+}
+
+int seqIndexOf( tango.util.collection.model.Seq.Seq!(Object) seq, Object v ){
+    int res = -1;
+    int idx = 0;
+    foreach( p; seq ){
+        if( p == v){
+            res = idx;
+            break;
+        }
+        idx++;
+    }
+    return res;
+}
+
+
--- a/dwt/internal/CloneableCompatibility.d	Sun Apr 06 22:25:15 2008 +0200
+++ b/dwt/internal/CloneableCompatibility.d	Sun Apr 06 22:26:22 2008 +0200
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/*******************************************************************************
  * Copyright (c) 2000, 2003 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -12,8 +12,7 @@
  *******************************************************************************/
 module dwt.internal.CloneableCompatibility;
 
-//PORTING_TYPE
-interface Cloneable{}
+import dwt.dwthelper.utils;
 
 /**
  * This interface is the cross-platform version of the
--- a/dwt/internal/DWTEventListener.d	Sun Apr 06 22:25:15 2008 +0200
+++ b/dwt/internal/DWTEventListener.d	Sun Apr 06 22:26:22 2008 +0200
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/*******************************************************************************
  * Copyright (c) 2000, 2003 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -12,12 +12,8 @@
  *******************************************************************************/
 module dwt.internal.DWTEventListener;
 
-
-//import java.util.EventListener;
+import dwt.dwthelper.utils;
 
-///PORTING_TYPE
-interface EventListener{
-}
 
 /**
  * This interface is the cross-platform version of the
--- a/dwt/internal/DWTEventObject.d	Sun Apr 06 22:25:15 2008 +0200
+++ b/dwt/internal/DWTEventObject.d	Sun Apr 06 22:26:22 2008 +0200
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -13,31 +13,9 @@
 module dwt.internal.DWTEventObject;
 
 
-//import java.util.EventObject;
+import dwt.dwthelper.utils;
 import tango.core.Exception;
 
-///PORTING_TYPE
-class EventObject {
-  protected Object source;
-
-  public this(Object source) {
-    if (source is null)
-      throw new IllegalArgumentException( "null arg" );
-    this.source = source;
-  }
-
-  public Object getSource() {
-    return source;
-  }
-
-  public override char[] toString() {
-    return this.classinfo.name ~ "[source=" ~ source.toString() ~ "]";
-  }
-}
-
-
-
-
 /**
  * This class is the cross-platform version of the
  * java.util.EventObject class.