00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 module mango.utils.Text;
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 struct TextTemplate(T)
00054 {
00055
00056
00057
00058
00059
00060
00061 deprecated final static T[] replace (T[] source, T match, T replacement)
00062 {
00063 T* p;
00064 T* scan = source;
00065 int length = source.length;
00066
00067 while ((p = locate (scan, match, length)) != null)
00068 {
00069 *p = replacement;
00070 length -= (p - scan);
00071 scan = p;
00072 }
00073 return source;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083 deprecated final static int indexOf (T[] source, T match, int start=0)
00084 {
00085 if (start < source.length)
00086 {
00087 T *p = locate (&source[start], match, source.length - start);
00088 if (p)
00089 return start + (p - &source[start]);
00090 }
00091 return -1;
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101 deprecated final static int indexOf (T[] source, T[] match, int start=0)
00102 {
00103 int length = match.length;
00104 int extent = source.length - length + 1;
00105
00106 if (length)
00107 {
00108 T* p;
00109 T c = match[0];
00110
00111 for (; start < extent; ++start)
00112 if ((p = locate (&source[start], c, extent-start)) != null)
00113 if (equal (p, match, length))
00114 start = p - source.ptr;
00115 else
00116 return start;
00117 }
00118 return -1;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127 deprecated final static bool isSpace (T c)
00128 {
00129 return cast(bool) (c is ' ' || c is '\t' || c is '\r' || c is '\n');
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139 deprecated final static T[] trim (T[] source)
00140 {
00141 if (source.length)
00142 {
00143 int front,
00144 back = source.length;
00145
00146 while (front < back && isSpace(source[front]))
00147 ++front;
00148
00149 while (back > front && isSpace(source[back-1]))
00150 --back;
00151
00152 if (front > 0 || back < source.length)
00153 return source[front..back];
00154 }
00155 return source;
00156 }
00157
00158
00159
00160
00161
00162
00163 deprecated final static T[][] split (T[] src, T[] delim)
00164 {
00165 int pos,
00166 mark;
00167 T[][] ret;
00168
00169 assert (delim.length);
00170 while ((pos = indexOf (src, delim, pos)) >= 0)
00171 {
00172 ret ~= src [mark..pos];
00173 pos += delim.length;
00174 mark = pos;
00175 }
00176
00177 if (mark < src.length)
00178 ret ~= src [mark..src.length];
00179 return ret;
00180 }
00181
00182
00183
00184
00185
00186 version (X86)
00187 {
00188 static if (is(T == char))
00189 {
00190 static char* locate (char* s, char match, int length)
00191 {
00192 asm
00193 {
00194 mov EDI, s;
00195 mov ECX, length;
00196 movzx EAX, match;
00197
00198 cld;
00199 repnz;
00200 scasb;
00201 jz ok;
00202 xor EAX, EAX;
00203 jmp fail;
00204 ok:
00205 lea EAX, [EDI-1];
00206 fail:;
00207 }
00208 }
00209
00210 static bool equal (char* s, char* d, int length)
00211 {
00212 asm
00213 {
00214 mov EDI, s;
00215 mov ESI, d;
00216 mov ECX, length;
00217 xor EAX, EAX;
00218
00219 cld;
00220 repz;
00221 cmpsb;
00222 jnz fail;
00223 inc EAX;
00224 fail:;
00225 }
00226 }
00227 }
00228
00229 static if (is(T == wchar))
00230 {
00231 static wchar* locate (wchar* s, wchar match, int length)
00232 {
00233 asm
00234 {
00235 mov EDI, s;
00236 mov ECX, length;
00237 movzx EAX, match;
00238
00239 cld;
00240 repnz;
00241 scasw;
00242 jz ok;
00243 xor EAX, EAX;
00244 jmp fail;
00245 ok:
00246 lea EAX, [EDI-2];
00247 fail:;
00248 }
00249 }
00250
00251 static bool equal (wchar* s, wchar* d, int length)
00252 {
00253 asm
00254 {
00255 mov EDI, s;
00256 mov ESI, d;
00257 mov ECX, length;
00258 xor EAX, EAX;
00259
00260 cld;
00261 repz;
00262 cmpsw;
00263 jnz fail;
00264 inc EAX;
00265 fail:;
00266 }
00267 }
00268 }
00269
00270 static if (is(T == dchar))
00271 {
00272 static dchar* locate (dchar* s, dchar match, int length)
00273 {
00274 asm
00275 {
00276 mov EDI, s;
00277 mov ECX, length;
00278 mov EAX, match;
00279
00280 cld;
00281 repnz;
00282 scasd;
00283 jz ok;
00284 xor EAX, EAX;
00285 jmp fail;
00286 ok:
00287 lea EAX, [EDI-4];
00288 fail:;
00289 }
00290 }
00291
00292 static bool equal (dchar* s, dchar* d, int length)
00293 {
00294 asm
00295 {
00296 mov EDI, s;
00297 mov ESI, d;
00298 mov ECX, length;
00299 xor EAX, EAX;
00300
00301 cld;
00302 repz;
00303 cmpsd;
00304 jnz fail;
00305 inc EAX;
00306 fail:;
00307 }
00308 }
00309 }
00310 }
00311 else
00312 {
00313 static T* locate (T* s, T match, int len)
00314 {
00315 while (len--)
00316 if (*s++ == match)
00317 return s-1;
00318 return null;
00319 }
00320
00321 static bool equal (T* s, T* d, int len)
00322 {
00323 while (len--)
00324 if (*s++ != *d++)
00325 return false;
00326 return true;
00327 }
00328
00329 }
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 alias TextTemplate!(char) Text;
00343
00344
00345
00346
00347
00348
00349
00350 unittest
00351 {
00352 try
00353 {
00354 char[] test = "123456789";
00355 assert (Text.locate (test, 'a', test.length) == null);
00356 assert (Text.locate (test, '3', test.length) == &test[2]);
00357 assert (Text.locate (test, '1', test.length) == &test[0]);
00358
00359 assert (Text.equal (test, test, test.length));
00360 assert (!Text.equal (test, "qwe", 3));
00361 } catch (Object o)
00362 Cout (o.toString() ~ "\n");
00363 }