# HG changeset patch # User Frank Benoit # Date 1207810720 -7200 # Node ID d0081b1505da6726ac73477eb16cf534a593cbee # Parent 79bb10c082fbe3f32e30a136fd035ef185e0bfae dwt.dwthelper restructure diff -r 79bb10c082fb -r d0081b1505da dwt/accessibility/AccessibleObject.d --- a/dwt/accessibility/AccessibleObject.d Wed Apr 09 17:39:05 2008 +0200 +++ b/dwt/accessibility/AccessibleObject.d Thu Apr 10 08:58:40 2008 +0200 @@ -24,7 +24,6 @@ import dwt.accessibility.ACC; import dwt.accessibility.AccessibleFactory; import dwt.widgets.Display; -import dwt.dwthelper.Integer; import dwt.dwthelper.utils; import tango.io.Stdout; import tango.stdc.stringz; diff -r 79bb10c082fb -r d0081b1505da dwt/custom/BusyIndicator.d --- a/dwt/custom/BusyIndicator.d Wed Apr 09 17:39:05 2008 +0200 +++ b/dwt/custom/BusyIndicator.d Thu Apr 10 08:58:40 2008 +0200 @@ -18,7 +18,6 @@ import dwt.graphics.Cursor; import dwt.widgets.Display; import dwt.widgets.Shell; -import dwt.dwthelper.Integer; import dwt.dwthelper.Runnable; import dwt.dwthelper.utils; diff -r 79bb10c082fb -r d0081b1505da dwt/custom/CTabFolder.d --- a/dwt/custom/CTabFolder.d Wed Apr 09 17:39:05 2008 +0200 +++ b/dwt/custom/CTabFolder.d Thu Apr 10 08:58:40 2008 +0200 @@ -49,7 +49,6 @@ import dwt.custom.CTabFolderEvent; import dwt.dwthelper.utils; -import dwt.dwthelper.Integer; import tango.util.Convert; static import tango.text.convert.Utf; diff -r 79bb10c082fb -r d0081b1505da dwt/dwthelper/Integer.d --- a/dwt/dwthelper/Integer.d Wed Apr 09 17:39:05 2008 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -/** - * Authors: Frank Benoit - */ - -module dwt.dwthelper.Integer; - -import dwt.dwthelper.utils; - -static import tango.text.convert.Integer; -private import tango.core.Exception; - - - diff -r 79bb10c082fb -r d0081b1505da dwt/dwthelper/WeakHashMap.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/dwthelper/WeakHashMap.d Thu Apr 10 08:58:40 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; + } +} diff -r 79bb10c082fb -r d0081b1505da dwt/dwthelper/WeakRef.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/dwthelper/WeakRef.d Thu Apr 10 08:58:40 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_; + } +} diff -r 79bb10c082fb -r d0081b1505da dwt/dwthelper/XmlTranscode.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/dwthelper/XmlTranscode.d Thu Apr 10 08:58:40 2008 +0200 @@ -0,0 +1,178 @@ +module dwt.dwthelper.XmlTranscode; + +/++ + + Decode XML entities into UTF8 string. + + Eg. "&" -> "&", "&" -> "&", "&" -> "&" + + Throws TextException on failure + + The given string is modified. + +/ +char[] xmlUnescape( char[] str ){ + + void error(){ + throw new TextException( "xmlUnescape" ); + } + // < ... + // Ӓ + // ኯ + 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 ~= ';'; + } + } +} + diff -r 79bb10c082fb -r d0081b1505da dwt/dwthelper/utils.d --- a/dwt/dwthelper/utils.d Wed Apr 09 17:39:05 2008 +0200 +++ b/dwt/dwthelper/utils.d Thu Apr 10 08:58:40 2008 +0200 @@ -32,8 +32,6 @@ // 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; @@ -742,76 +740,6 @@ } - - -// 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 ); } @@ -819,31 +747,6 @@ 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{ @@ -913,6 +816,31 @@ } +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; + } + } + } +} + class Arrays{ public static bool equals(Object[] a, Object[] b){ if( a.length !is b.length ){ @@ -941,183 +869,6 @@ } return -1; } - -/++ - + Decode XML entities into UTF8 string. - + Eg. "&" -> "&", "&" -> "&", "&" -> "&" - + Throws TextException on failure - + The given string is modified. - +/ -char[] xmlUnescape( char[] str ){ - - void error(){ - throw new TextException( "xmlUnescape" ); - } - // < ... - // Ӓ - // ኯ - 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; diff -r 79bb10c082fb -r d0081b1505da dwt/internal/image/TIFFDirectory.d --- a/dwt/internal/image/TIFFDirectory.d Wed Apr 09 17:39:05 2008 +0200 +++ b/dwt/internal/image/TIFFDirectory.d Thu Apr 10 08:58:40 2008 +0200 @@ -21,7 +21,6 @@ import dwt.graphics.PaletteData; import dwt.graphics.RGB; import dwt.DWT; -import dwt.dwthelper.Integer; import dwt.dwthelper.utils; final class TIFFDirectory { diff -r 79bb10c082fb -r d0081b1505da dwt/layout/GridLayout.d --- a/dwt/layout/GridLayout.d Wed Apr 09 17:39:05 2008 +0200 +++ b/dwt/layout/GridLayout.d Thu Apr 10 08:58:40 2008 +0200 @@ -22,7 +22,6 @@ import dwt.widgets.Scrollable; import dwt.dwthelper.System; -import dwt.dwthelper.Integer; import tango.text.Util; import tango.util.Convert;