1 module diet.internal..string;
2 
3 import std.ascii : isWhite;
4 
5 pure @safe nothrow:
6 
7 string ctstrip(string s)
8 {
9 	size_t strt = 0, end = s.length;
10 	while (strt < s.length && s[strt].isWhite) strt++;
11 	while (end > 0 && s[end-1].isWhite) end--;
12 	return strt < end ? s[strt .. end] : null;
13 }
14 
15 string ctstripLeft(string s)
16 {
17 	size_t i = 0;
18 	while (i < s.length && s[i].isWhite) i++;
19 	return s[i .. $];
20 }
21 
22 string ctstripRight(string s)
23 {
24 	size_t i = s.length;
25 	while (i > 0 && s[i-1].isWhite) i--;
26 	return s[0 .. i];
27 }
28 
29 string dstringEscape(char ch)
30 {
31 	switch (ch) {
32 		default: return ""~ch;
33 		case '\\': return "\\\\";
34 		case '\r': return "\\r";
35 		case '\n': return "\\n";
36 		case '\t': return "\\t";
37 		case '\"': return "\\\"";
38 	}
39 }
40 
41 string dstringEscape(in ref string str)
42 {
43 	string ret;
44 	foreach( ch; str ) ret ~= dstringEscape(ch);
45 	return ret;
46 }
47 
48 string dstringUnescape(in string str)
49 {
50 	string ret;
51 	size_t i, start = 0;
52 	for( i = 0; i < str.length; i++ )
53 		if( str[i] == '\\' ){
54 			if( i > start ){
55 				if( start > 0 ) ret ~= str[start .. i];
56 				else ret = str[0 .. i];
57 			}
58 			assert(i+1 < str.length, "The string ends with the escape char: " ~ str);
59 			switch(str[i+1]){
60 				default: ret ~= str[i+1]; break;
61 				case 'r': ret ~= '\r'; break;
62 				case 'n': ret ~= '\n'; break;
63 				case 't': ret ~= '\t'; break;
64 			}
65 			i++;
66 			start = i+1;
67 		}
68 
69 	if( i > start ){
70 		if( start == 0 ) return str;
71 		else ret ~= str[start .. i];
72 	}
73 	return ret;
74 }
75 
76 string sanitizeEscaping(string str)
77 {
78 	str = dstringUnescape(str);
79 	return dstringEscape(str);
80 }
81 
82 string stripUTF8BOM(string input)
83 {
84 	if (input.length >= 3 && input[0 .. 3] == [0xEF, 0xBB, 0xBF])
85 		return input[3 .. $];
86 	return input;
87 }