Mercurial > projects > dwt-linux
comparison dwt/dwthelper/utils.d @ 223:d0081b1505da
dwt.dwthelper restructure
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 10 Apr 2008 08:58:40 +0200 |
parents | ba054b4a1c55 |
children | 5366f8db1eda |
comparison
equal
deleted
inserted
replaced
222:79bb10c082fb | 223:d0081b1505da |
---|---|
30 // alias tango.util.collection.ArraySeq.ArraySeq!(Object) ArrayList; | 30 // alias tango.util.collection.ArraySeq.ArraySeq!(Object) ArrayList; |
31 // alias tango.util.collection.LinkSeq.LinkSeq!(Object) LinkList; | 31 // alias tango.util.collection.LinkSeq.LinkSeq!(Object) LinkList; |
32 // alias tango.util.collection.model.Map.Map!(Object,Object) Map; | 32 // alias tango.util.collection.model.Map.Map!(Object,Object) Map; |
33 // alias tango.util.collection.HashMap.HashMap!(Object,Object) HashMap; | 33 // alias tango.util.collection.HashMap.HashMap!(Object,Object) HashMap; |
34 | 34 |
35 public import dwt.dwthelper.Integer; | |
36 | |
37 alias char[] String; | 35 alias char[] String; |
38 alias tango.text.Text.Text!(char) StringBuffer; | 36 alias tango.text.Text.Text!(char) StringBuffer; |
39 | 37 |
40 void implMissing( char[] file, uint line ){ | 38 void implMissing( char[] file, uint line ){ |
41 Stderr.formatln( "implementation missing in file {} line {}", file, line ); | 39 Stderr.formatln( "implementation missing in file {} line {}", file, line ); |
740 GCStats s;// = gc_stats(); | 738 GCStats s;// = gc_stats(); |
741 return s.poolsize; | 739 return s.poolsize; |
742 } | 740 } |
743 | 741 |
744 | 742 |
745 | |
746 | |
747 // import tango.core.Runtime; | |
748 private uint calcKey( void* key ){ | |
749 uint k = cast(uint)cast(void*)key; | |
750 k ^= 0x8000_0000; | |
751 return k; | |
752 } | |
753 | |
754 // private bool collectHandler(Object o){ | |
755 // uint key = calcKey( cast(void*)o ); | |
756 // if( auto p = key in mKeyCollectedNotifiers ){ | |
757 // (*p)( key ); | |
758 // mKeyCollectedNotifiers.remove( key ); | |
759 // } | |
760 // ClassInfo ci = o.classinfo; | |
761 // while(ci !is null ){ | |
762 // foreach( i; ci.interfaces ){ | |
763 // uint key = calcKey( cast(void*)o + i.offset ); | |
764 // if( auto p = key in mKeyCollectedNotifiers ){ | |
765 // (*p)( key ); | |
766 // mKeyCollectedNotifiers.remove( key ); | |
767 // } | |
768 // } | |
769 // ci = ci.base; | |
770 // } | |
771 // return true; | |
772 // } | |
773 // | |
774 // static this(){ | |
775 // Runtime.collectHandler( & collectHandler ); | |
776 // } | |
777 // | |
778 // void delegate( uint k ) KeyCollectedNotifier; | |
779 // KeyCollectedNotifier[ uint ] mKeyCollectedNotifiers; | |
780 // | |
781 // private synchronized void addKeyCollectedNotifier( uint key, KeyCollectedNotifier del ){ | |
782 // mKeyCollectedNotifiers[ key ] = del; | |
783 // } | |
784 | |
785 class WeakHashMap(K,T) { | |
786 static assert( is(K==class) || is(K==interface) ); | |
787 T[uint] data; | |
788 | |
789 private void removeInternalKey( uint key ){ | |
790 data.remove( key ); | |
791 } | |
792 | |
793 public void add (K key, T element){ | |
794 data[ calcKey(cast(void*)key) ] = element; | |
795 // addKeyCollectedNotifier( calcKey(key), &removeInternalKey ); | |
796 } | |
797 public void removeKey (K key){ | |
798 data.remove( calcKey(cast(void*)key) ); | |
799 } | |
800 public T get(K key){ | |
801 if( auto p = calcKey(cast(void*)key) in data ){ | |
802 return *p; | |
803 } | |
804 return null; | |
805 } | |
806 } | |
807 /+++ | |
808 | |
809 import dwt.dwthelper.InputStream; | |
810 InputStream ClassInfoGetResourceAsStream( ClassInfo ci, char[] aName ){ | |
811 implMissing( __FILE__, __LINE__ ); | |
812 return null; | |
813 } | |
814 +++/ | |
815 void ExceptionPrintStackTrace( Exception e ){ | 743 void ExceptionPrintStackTrace( Exception e ){ |
816 ExceptionPrintStackTrace( e, Stderr ); | 744 ExceptionPrintStackTrace( e, Stderr ); |
817 } | 745 } |
818 void ExceptionPrintStackTrace( Exception e, Print!(char) print ){ | 746 void ExceptionPrintStackTrace( Exception e, Print!(char) print ){ |
819 print.formatln( "Exception in {}({}): {}", e.file, e.line, e.msg ); | 747 print.formatln( "Exception in {}({}): {}", e.file, e.line, e.msg ); |
820 } | 748 } |
749 | |
750 interface Reader{ | |
751 } | |
752 interface Writer{ | |
753 } | |
754 | |
755 | |
756 class Collator : Comparator { | |
757 public static Collator getInstance(){ | |
758 implMissing( __FILE__, __LINE__ ); | |
759 return null; | |
760 } | |
761 private this(){ | |
762 } | |
763 int compare(Object o1, Object o2){ | |
764 implMissing( __FILE__, __LINE__ ); | |
765 return 0; | |
766 } | |
767 } | |
768 | |
769 interface Enumeration { | |
770 public bool hasMoreElements(); | |
771 public Object nextElement(); | |
772 } | |
773 | |
774 | |
775 template arraycast(T) { | |
776 T[] arraycast(U) (U[] u) { | |
777 static if ( | |
778 (is (T == interface ) && is (U == interface )) || | |
779 (is (T == class ) && is (U == class ))) { | |
780 return(cast(T[])u); | |
781 } | |
782 else { | |
783 int l = u.length; | |
784 T[] res; | |
785 res.length = l; | |
786 for (int i = 0; i < l; i++) { | |
787 res[i] = cast(T)u[i]; | |
788 } | |
789 return(res); | |
790 } | |
791 } | |
792 } | |
793 | |
794 char[] stringcast( Object o ){ | |
795 if( auto str = cast(ArrayWrapperString) o ){ | |
796 return str.array; | |
797 } | |
798 return null; | |
799 } | |
800 char[][] stringcast( Object[] objs ){ | |
801 char[][] res = new char[][](objs.length); | |
802 foreach( idx, obj; objs ){ | |
803 res[idx] = stringcast(obj); | |
804 } | |
805 return res; | |
806 } | |
807 ArrayWrapperString stringcast( char[] str ){ | |
808 return new ArrayWrapperString( str ); | |
809 } | |
810 ArrayWrapperString[] stringcast( char[][] strs ){ | |
811 ArrayWrapperString[] res = new ArrayWrapperString[ strs.length ]; | |
812 foreach( idx, str; strs ){ | |
813 res[idx] = stringcast(str); | |
814 } | |
815 return res; | |
816 } | |
817 | |
821 | 818 |
822 bool ArrayEquals(T)( T[] a, T[] b ){ | 819 bool ArrayEquals(T)( T[] a, T[] b ){ |
823 if( a.length !is b.length ){ | 820 if( a.length !is b.length ){ |
824 return false; | 821 return false; |
825 } | 822 } |
842 } | 839 } |
843 } | 840 } |
844 } | 841 } |
845 } | 842 } |
846 | 843 |
847 interface Reader{ | |
848 } | |
849 interface Writer{ | |
850 } | |
851 | |
852 | |
853 class Collator : Comparator { | |
854 public static Collator getInstance(){ | |
855 implMissing( __FILE__, __LINE__ ); | |
856 return null; | |
857 } | |
858 private this(){ | |
859 } | |
860 int compare(Object o1, Object o2){ | |
861 implMissing( __FILE__, __LINE__ ); | |
862 return 0; | |
863 } | |
864 } | |
865 | |
866 interface Enumeration { | |
867 public bool hasMoreElements(); | |
868 public Object nextElement(); | |
869 } | |
870 | |
871 | |
872 template arraycast(T) { | |
873 T[] arraycast(U) (U[] u) { | |
874 static if ( | |
875 (is (T == interface ) && is (U == interface )) || | |
876 (is (T == class ) && is (U == class ))) { | |
877 return(cast(T[])u); | |
878 } | |
879 else { | |
880 int l = u.length; | |
881 T[] res; | |
882 res.length = l; | |
883 for (int i = 0; i < l; i++) { | |
884 res[i] = cast(T)u[i]; | |
885 } | |
886 return(res); | |
887 } | |
888 } | |
889 } | |
890 | |
891 char[] stringcast( Object o ){ | |
892 if( auto str = cast(ArrayWrapperString) o ){ | |
893 return str.array; | |
894 } | |
895 return null; | |
896 } | |
897 char[][] stringcast( Object[] objs ){ | |
898 char[][] res = new char[][](objs.length); | |
899 foreach( idx, obj; objs ){ | |
900 res[idx] = stringcast(obj); | |
901 } | |
902 return res; | |
903 } | |
904 ArrayWrapperString stringcast( char[] str ){ | |
905 return new ArrayWrapperString( str ); | |
906 } | |
907 ArrayWrapperString[] stringcast( char[][] strs ){ | |
908 ArrayWrapperString[] res = new ArrayWrapperString[ strs.length ]; | |
909 foreach( idx, str; strs ){ | |
910 res[idx] = stringcast(str); | |
911 } | |
912 return res; | |
913 } | |
914 | |
915 | |
916 class Arrays{ | 844 class Arrays{ |
917 public static bool equals(Object[] a, Object[] b){ | 845 public static bool equals(Object[] a, Object[] b){ |
918 if( a.length !is b.length ){ | 846 if( a.length !is b.length ){ |
919 return false; | 847 return false; |
920 } | 848 } |
939 } | 867 } |
940 idx++; | 868 idx++; |
941 } | 869 } |
942 return -1; | 870 return -1; |
943 } | 871 } |
944 | |
945 /++ | |
946 + Decode XML entities into UTF8 string. | |
947 + Eg. "&" -> "&", "&" -> "&", "&" -> "&" | |
948 + Throws TextException on failure | |
949 + The given string is modified. | |
950 +/ | |
951 char[] xmlUnescape( char[] str ){ | |
952 | |
953 void error(){ | |
954 throw new TextException( "xmlUnescape" ); | |
955 } | |
956 // < ... | |
957 // Ӓ | |
958 // ኯ | |
959 char[] src = str; | |
960 char[] trg = str; | |
961 while( src.length ){ | |
962 if( src[0] !is '&' ){ | |
963 trg[0] = src[0]; | |
964 trg = trg[1..$]; | |
965 src = src[1..$]; | |
966 } | |
967 else{ | |
968 src = src[1..$]; // go past '&' | |
969 if( src.length < 2 ) error(); | |
970 | |
971 // search semi | |
972 int len = Math.min( src.length, 10 ); // limit semi search to possible longest entityname | |
973 int semi = tango.text.Util.locate( src[0 .. len ], ';' ); | |
974 if( semi is len ) error(); // no semi found | |
975 | |
976 char[] entityName = src[ 0 .. semi ]; // name without semi | |
977 dchar entityValue = 0; | |
978 switch( entityName ){ | |
979 case "lt": entityValue = '<'; break; | |
980 case "gt": entityValue = '>'; break; | |
981 case "amp": entityValue = '&'; break; | |
982 case "quot": entityValue = '\"'; break; | |
983 case "apos": entityValue = '\''; break; | |
984 default: | |
985 if( entityName[0] is 'x' ){ | |
986 if( semi < 2 ) error(); | |
987 if( semi > 9 ) error(); | |
988 foreach( hex; entityName[1..$] ){ | |
989 entityValue <<= 4; | |
990 if( hex >= '0' && hex <= '9' ){ | |
991 entityValue |= ( hex - '0' ); | |
992 } | |
993 else if( hex >= 'a' && hex <= 'f' ){ | |
994 entityValue |= ( hex - 'a' ); | |
995 } | |
996 else if( hex >= 'A' && hex <= 'F' ){ | |
997 entityValue |= ( hex - 'A' ); | |
998 } | |
999 else{ | |
1000 error(); | |
1001 } | |
1002 } | |
1003 } | |
1004 else{ | |
1005 if( semi < 1 ) error(); | |
1006 if( semi > 9 ) error(); | |
1007 foreach( dec; entityName[1..$] ){ | |
1008 if( dec >= '0' && dec <= '9' ){ | |
1009 entityValue *= 10; | |
1010 entityValue += ( dec - '0' ); | |
1011 } | |
1012 else{ | |
1013 error(); | |
1014 } | |
1015 } | |
1016 } | |
1017 } | |
1018 dchar[1] arr; | |
1019 arr[0] = entityValue; | |
1020 uint ate = 0; | |
1021 char[] res = tango.text.convert.Utf.toString( arr, trg, &ate ); | |
1022 trg = trg[ res.length .. $ ]; | |
1023 src = src[ semi +1 .. $ ]; // go past semi | |
1024 } | |
1025 } | |
1026 return str[ 0 .. trg.ptr-str.ptr ]; | |
1027 } | |
1028 | |
1029 | |
1030 /++ | |
1031 + Encode XML entities into UTF8 string. | |
1032 + First checks if processing is needed. | |
1033 + If not, the original string is returned. | |
1034 + If processing is needed, a new string is allocated. | |
1035 +/ | |
1036 char[] xmlEscape( char[] xml ){ | |
1037 bool needsReplacement( dchar c ){ | |
1038 switch( c ){ | |
1039 case '<': | |
1040 case '>': | |
1041 case '&': | |
1042 case '\"': | |
1043 case '\'': | |
1044 case '\r': | |
1045 case '\n': | |
1046 case '\u0009': | |
1047 return true; | |
1048 default: | |
1049 return c > 0x7F; | |
1050 } | |
1051 } | |
1052 | |
1053 // Check if processing is needed | |
1054 foreach( char c; xml ){ | |
1055 if( needsReplacement( c )){ | |
1056 goto Lprocess; | |
1057 } | |
1058 } | |
1059 return xml; | |
1060 Lprocess: | |
1061 | |
1062 // yes, do a new string, start with +20 chars | |
1063 char[] res = new char[ xml.length + 20 ]; | |
1064 res.length = 0; | |
1065 | |
1066 foreach( dchar c; xml ){ | |
1067 | |
1068 if( !needsReplacement( c )){ | |
1069 res ~= c; | |
1070 } | |
1071 else{ | |
1072 res ~= '&'; | |
1073 switch( c ){ | |
1074 case '<': res ~= "lt"; break; | |
1075 case '>': res ~= "gt"; break; | |
1076 case '&': res ~= "amp"; break; | |
1077 case '\"': res ~= "quot"; break; | |
1078 case '\'': res ~= "apos"; break; | |
1079 case '\r': case '\n': case '\u0009': | |
1080 default: | |
1081 char toHexDigit( int i ){ | |
1082 if( i < 10 ) return '0'+i; | |
1083 return 'A'+i-10; | |
1084 } | |
1085 res ~= "#x"; | |
1086 if( c <= 0xFF ){ | |
1087 res ~= toHexDigit(( c >> 4 ) & 0x0F ); | |
1088 res ~= toHexDigit(( c >> 0 ) & 0x0F ); | |
1089 } | |
1090 else if( c <= 0xFFFF ){ | |
1091 res ~= toHexDigit(( c >> 12 ) & 0x0F ); | |
1092 res ~= toHexDigit(( c >> 8 ) & 0x0F ); | |
1093 res ~= toHexDigit(( c >> 4 ) & 0x0F ); | |
1094 res ~= toHexDigit(( c >> 0 ) & 0x0F ); | |
1095 } | |
1096 else if( c <= 0xFFFFFF ){ | |
1097 res ~= toHexDigit(( c >> 20 ) & 0x0F ); | |
1098 res ~= toHexDigit(( c >> 16 ) & 0x0F ); | |
1099 res ~= toHexDigit(( c >> 12 ) & 0x0F ); | |
1100 res ~= toHexDigit(( c >> 8 ) & 0x0F ); | |
1101 res ~= toHexDigit(( c >> 4 ) & 0x0F ); | |
1102 res ~= toHexDigit(( c >> 0 ) & 0x0F ); | |
1103 } | |
1104 else { | |
1105 res ~= toHexDigit(( c >> 28 ) & 0x0F ); | |
1106 res ~= toHexDigit(( c >> 24 ) & 0x0F ); | |
1107 res ~= toHexDigit(( c >> 20 ) & 0x0F ); | |
1108 res ~= toHexDigit(( c >> 16 ) & 0x0F ); | |
1109 res ~= toHexDigit(( c >> 12 ) & 0x0F ); | |
1110 res ~= toHexDigit(( c >> 8 ) & 0x0F ); | |
1111 res ~= toHexDigit(( c >> 4 ) & 0x0F ); | |
1112 res ~= toHexDigit(( c >> 0 ) & 0x0F ); | |
1113 } | |
1114 break; | |
1115 } | |
1116 res ~= ';'; | |
1117 } | |
1118 } | |
1119 } | |
1120 | |
1121 int arrayIndexOf(T)( T[] arr, T v ){ | 872 int arrayIndexOf(T)( T[] arr, T v ){ |
1122 int res = -1; | 873 int res = -1; |
1123 int idx = 0; | 874 int idx = 0; |
1124 foreach( p; arr ){ | 875 foreach( p; arr ){ |
1125 if( p == v){ | 876 if( p == v){ |