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. "&amp;" -> "&", "&#38;" -> "&", "&#x26;" -> "&"
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 // &lt; ...
957 // &#1234;
958 // &#x12AF;
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){