| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 | /******************************************************************************* copyright: Copyright (c) 2006 Kris Bell. All rights reserved license: BSD style: $(LICENSE) version: Dec 2006: Initial release author: Kris Placeholder for a selection of ASCII utilities. These generally will not work with utf8, and cannot be easily extended to utf16 or utf32 *******************************************************************************/ module tango.text.Ascii; version (Win32) { private extern (C) int memicmp (in char *, in char *, uint); private extern (C) int memcmp (in char *, in char *, uint); } version (Posix) { private extern (C) int memcmp (in char *, in char *, uint); private extern (C) int strncasecmp (in char *, in char*, uint); private alias strncasecmp memicmp; } /****************************************************************************** Convert to lowercase in-place. ******************************************************************************/ char[] toLower (char[] src) { foreach (ref c; src) if (c>= 'A' && c <= 'Z') c = cast(char)(c + 32); return src; } /****************************************************************************** Convert to lowercase. Returns the converted content in dst. ******************************************************************************/ char[] toLower (const(char[]) src, char[] dst) { assert (dst.length >= src.length); dst[0 .. src.length] = src [0 .. $]; return toLower(dst [0 .. src.length]); } /****************************************************************************** Convert to uppercase in-place. ******************************************************************************/ char[] toUpper (char[] src) { foreach (ref c; src) if (c>= 'a' && c <= 'z') c = cast(char)(c - 32); return src; } /****************************************************************************** Convert to uppercase. Returns the converted content in dst. ******************************************************************************/ char[] toUpper (const(char[]) src, char[] dst) { assert (dst.length >= src.length); dst[0 .. src.length] = src [0 .. $]; return toUpper(dst [0 .. src.length]); } /****************************************************************************** Compare two char[] ignoring case. Returns 0 if equal ******************************************************************************/ int icompare (const(char[]) s1, const(char[]) s2) { auto len = s1.length; if (s2.length < len) len = s2.length; auto result = memicmp (s1.ptr, s2.ptr, cast(int)len); if (result is 0) result = cast(int)s1.length - cast(int)s2.length; return result; } /****************************************************************************** Compare two char[] with case. Returns 0 if equal ******************************************************************************/ int compare (const(char[]) s1, const(char[]) s2) { auto len = s1.length; if (s2.length < len) len = s2.length; auto result = memcmp (s1.ptr, s2.ptr, cast(int)len); if (result is 0) result = cast(int)s1.length - cast(int)s2.length; return result; } /****************************************************************************** Return the index position of a text pattern within src, or src.length upon failure. This is a case-insensitive search (with thanks to Nietsnie) ******************************************************************************/ size_t isearch (in char[] src, in char[] pattern) { enum char[] _caseMap = [ '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', '\020','\021','\022','\023','\024','\025','\026','\027', '\030','\031','\032','\033','\034','\035','\036','\037', '\040','\041','\042','\043','\044','\045','\046','\047', '\050','\051','\052','\053','\054','\055','\056','\057', '\060','\061','\062','\063','\064','\065','\066','\067', '\070','\071','\072','\073','\074','\075','\076','\077', '\100','\141','\142','\143','\144','\145','\146','\147', '\150','\151','\152','\153','\154','\155','\156','\157', '\160','\161','\162','\163','\164','\165','\166','\167', '\170','\171','\172','\133','\134','\135','\136','\137', '\140','\141','\142','\143','\144','\145','\146','\147', '\150','\151','\152','\153','\154','\155','\156','\157', '\160','\161','\162','\163','\164','\165','\166','\167', '\170','\171','\172','\173','\174','\175','\176','\177', '\200','\201','\202','\203','\204','\205','\206','\207', '\210','\211','\212','\213','\214','\215','\216','\217', '\220','\221','\222','\223','\224','\225','\226','\227', '\230','\231','\232','\233','\234','\235','\236','\237', '\240','\241','\242','\243','\244','\245','\246','\247', '\250','\251','\252','\253','\254','\255','\256','\257', '\260','\261','\262','\263','\264','\265','\266','\267', '\270','\271','\272','\273','\274','\275','\276','\277', '\300','\341','\342','\343','\344','\345','\346','\347', '\350','\351','\352','\353','\354','\355','\356','\357', '\360','\361','\362','\363','\364','\365','\366','\367', '\370','\371','\372','\333','\334','\335','\336','\337', '\340','\341','\342','\343','\344','\345','\346','\347', '\350','\351','\352','\353','\354','\355','\356','\357', '\360','\361','\362','\363','\364','\365','\366','\367', '\370','\371','\372','\373','\374','\375','\376','\377', ]; assert(src.ptr); assert(pattern.ptr); for (int i1=0, i2; i1 <= cast(int)(src.length - pattern.length); ++i1) { for (i2=0; i2 < pattern.length; ++i2) if (_caseMap[src[i1 + i2]] != _caseMap[pattern[i2]]) break; if (i2 is pattern.length) return i1; } return src.length; } /****************************************************************************** ******************************************************************************/ debug (UnitTest) { unittest { char[20] tmp; assert (toLower("1bac", tmp) == "1bac"); assert (toLower("1BAC", tmp) == "1bac"); assert (toUpper("1bac", tmp) == "1BAC"); assert (toUpper("1BAC", tmp) == "1BAC"); assert (icompare ("ABC", "abc") is 0); assert (icompare ("abc", "abc") is 0); assert (icompare ("abcd", "abc") > 0); assert (icompare ("abc", "abcd") < 0); assert (icompare ("ACC", "abc") > 0); assert (isearch ("ACC", "abc") is 3); assert (isearch ("ACC", "acc") is 0); assert (isearch ("aACC", "acc") is 1); } } debug (Ascii) { void main() {} } |