1 module yu..string; 2 3 import std.array; 4 import std.string; 5 import std.traits; 6 import std.range; 7 import std.experimental.allocator.common; 8 9 void splitNameValue(TChar, Char, bool caseSensitive = true)(TChar[] data, 10 in Char pDelim, in Char vDelim, scope bool delegate(TChar[], TChar[]) callback) if ( 11 isSomeChar!(Unqual!TChar) && isSomeChar!(Unqual!Char)) { 12 enum size_t blen = 1; 13 enum size_t elen = 1; 14 const dchar pairDelim = pDelim; 15 const dchar valueDelim = vDelim; 16 17 mixin(TSplitNameValue!()); 18 } 19 20 void splitNameValue(TChar, Char, bool caseSensitive = true)(TChar[] data, 21 const(Char)[] pairDelim, const(Char)[] valueDelim, scope bool delegate(TChar[], 22 TChar[]) callback) if (isSomeChar!(Unqual!TChar) && isSomeChar!(Unqual!Char)) { 23 const size_t blen = pairDelim.length; 24 const size_t elen = valueDelim.length; 25 26 mixin(TSplitNameValue!()); 27 28 } 29 30 bool isSameIngnoreLowUp(TChar)(TChar[] s1, TChar[] s2) if (isSomeChar!(Unqual!TChar)) { 31 import std.uni; 32 33 if (s1.length != s2.length) 34 return false; 35 for (size_t i = 0; i < s1.length; ++i) { 36 dchar c1 = toLower(s1[i]); 37 dchar c2 = toLower(s2[i]); 38 if (c1 != c2) 39 return false; 40 } 41 return true; 42 } 43 44 @trusted struct CStr(Alloc) { 45 enum isStaticAlloc = (stateSize!Alloc == 0); 46 @disable this(); 47 @disable this(this); 48 49 static if (isStaticAlloc) { 50 this(string str) { 51 setString(str); 52 } 53 } else { 54 this(string str, Alloc alloc) { 55 _alloc = alloc; 56 setString(str); 57 } 58 } 59 60 ~this() { 61 if (_data.ptr !is null) 62 _alloc.deallocate(_data); 63 } 64 65 @property const(char*) ptr() const nothrow{ 66 return _data.ptr; 67 } 68 69 @property length() const nothrow { 70 return _data.length; 71 } 72 73 private: 74 void setString(string str) { 75 import core.stdc.string; 76 77 if (str.length == 0) 78 return; 79 size_t size = str.length + 1; 80 _data = cast(char[]) _alloc.allocate(size); 81 if (_data.length == 0) 82 return; 83 memcpy(_data.ptr, str.ptr, str.length); 84 _data[str.length] = '\0'; 85 } 86 87 static if (isStaticAlloc) 88 alias _alloc = Alloc.instance; 89 else 90 Alloc _alloc; 91 char[] _data; 92 } 93 94 @safe ubyte formHex(in char[2] chs) { 95 import std.uri; 96 97 ubyte charToByte(dchar ch) { 98 switch (ch) { 99 case '0': 100 return 0x00; 101 case '1': 102 return 0x01; 103 case '2': 104 return 0x02; 105 case '3': 106 return 0x03; 107 case '4': 108 return 0x04; 109 case '5': 110 return 0x05; 111 case '6': 112 return 0x06; 113 case '7': 114 return 0x07; 115 case '8': 116 return 0x08; 117 case '9': 118 return 0x09; 119 case 'A': 120 return 0x0A; // 10 121 case 'B': 122 return 0x0B; // 11 123 case 'C': 124 return 0x0C; // 12 125 case 'D': 126 return 0x0D; // 13 127 case 'E': 128 return 0x0E; // 14 129 case 'F': 130 return 0x0F; // 15 131 default: 132 throw new StringException("Hex char is inVaild!"); 133 } 134 } 135 136 import std.uni; 137 138 dchar ch = toUpper(chs[0]); 139 ubyte frist = charToByte(ch); 140 ch = toUpper(chs[1]); 141 ubyte seced = charToByte(ch); 142 return cast(ubyte)((frist << 4) | seced); 143 } 144 145 146 private template TSplitNameValue() { 147 enum TSplitNameValue = q{ 148 static if(caseSensitive) 149 enum thecaseSensitive = CaseSensitive.yes; 150 else 151 enum thecaseSensitive = CaseSensitive.no; 152 while(data.length > 0) 153 { 154 auto index = data.indexOf(pairDelim,thecaseSensitive); 155 string keyValue; 156 if(index < 0){ 157 keyValue = data; 158 data.length = 0; 159 } else { 160 keyValue = data[0..index]; 161 data = data[(index + blen) .. $]; 162 } 163 if(keyValue.length == 0) 164 continue; 165 auto valueDelimPos = keyValue.indexOf(valueDelim,thecaseSensitive); 166 if(valueDelimPos < 0){ 167 if(!callback(keyValue,string.init)) 168 return; 169 } else { 170 auto name = keyValue[0..valueDelimPos]; 171 auto value = keyValue[(valueDelimPos + elen)..$]; 172 if(!callback(name,value)) 173 return; 174 } 175 } 176 }; 177 } 178 179 unittest { 180 import std.stdio; 181 182 string hh = "ggujg=wee&ggg=ytgy&ggg0HH&hjkhk=00"; 183 string hh2 = "ggujg$=wee&$ggg=ytgy&$ggg0HH&hjkhk$=00"; 184 185 splitNameValue!(immutable char, char)(hh, '&', '=', (string key, string value) { 186 writeln("1. ", key, " ", value); 187 return true; 188 }); 189 190 splitNameValue!(immutable char, char)(hh2, "&$", "$=", (string key, string value) { 191 writeln("2. ", key, " ", value); 192 return true; 193 }); 194 195 writeln(isSameIngnoreLowUp("AAA12345", "aaa12345")); 196 }