1 module more.parse; 2 3 // returns: ubyte.max on error 4 ubyte hexValue(char c) 5 { 6 if(c <= '9') { 7 return (c >= '0') ? cast(ubyte)(c - '0') : ubyte.max; 8 } 9 if(c >= 'a') { 10 return (c <= 'f') ? cast(ubyte)(c + 10 - 'a') : ubyte.max; 11 } 12 if(c >= 'A' && c <= 'F') { 13 return cast(ubyte)(c + 10 - 'A'); 14 } 15 return ubyte.max; 16 } 17 unittest 18 { 19 assert(ubyte.max == hexValue('/')); 20 assert(0 == hexValue('0')); 21 assert(9 == hexValue('9')); 22 assert(ubyte.max == hexValue(':')); 23 24 assert(ubyte.max == hexValue('@')); 25 assert(10 == hexValue('A')); 26 assert(15 == hexValue('F')); 27 assert(ubyte.max == hexValue('G')); 28 29 assert(ubyte.max == hexValue('`')); 30 assert(10 == hexValue('a')); 31 assert(15 == hexValue('f')); 32 assert(ubyte.max == hexValue('g')); 33 34 for(int cAsInt = char.min; cAsInt <= char.max; cAsInt++) { 35 char c = cast(char)cAsInt; 36 if(c >= '0' && c <= '9') { 37 assert(c - '0' == hexValue(c)); 38 } else if(c >= 'a' && c <= 'f') { 39 assert(c + 10 - 'a' == hexValue(c)); 40 } else if(c >= 'A' && c <= 'F') { 41 assert(c + 10 - 'A' == hexValue(c)); 42 } else { 43 assert(ubyte.max == hexValue(c)); 44 } 45 } 46 } 47 48 bool hasCharSet(string charSet)(const(char)* str, const(char)* limit) 49 { 50 for(;; str++) 51 { 52 if (str >= limit) 53 return false; 54 auto c = *str; 55 foreach(charSetChar; charSet) { 56 if(c == charSetChar) { 57 return true; 58 } 59 } 60 } 61 } 62 pragma(inline) 63 bool hasCharSet(string charSet)(const(char)[] str) 64 { 65 return hasCharSet!charSet(str.ptr, str.ptr + str.length); 66 } 67 68 /** 69 Iterates over the given string and returns a pointer to the first character that 70 is not in the given $(D charSet). 71 */ 72 inout(char)* skipCharSet(string charSet)(inout(char)* str) 73 { 74 STR_LOOP: 75 for(;;) 76 { 77 auto c = *str; 78 foreach(charSetChar; charSet) { 79 if(c == charSetChar) { 80 str++; 81 continue STR_LOOP; 82 } 83 } 84 break; 85 } 86 return str; 87 } 88 /// ditto 89 inout(char)* skipCharSet(string charSet)(inout(char)* str, const(char)* limit) 90 { 91 STR_LOOP: 92 for(;str < limit;) 93 { 94 auto c = *str; 95 foreach(charSetChar; charSet) { 96 if(c == charSetChar) { 97 str++; 98 continue STR_LOOP; 99 } 100 } 101 break; 102 } 103 return str; 104 } 105 /** 106 Iterates over the given string and returns a pointer to the first character that 107 is not a space. 108 */ 109 pragma(inline) inout(char)* skipSpace(inout(char)* str) 110 { 111 return skipCharSet!" "(str); 112 } 113 pragma(inline) inout(char)* skipSpace(inout(char)* str, const(char)* limit) 114 { 115 return skipCharSet!" "(str, limit); 116 } 117 118 // TODO: create more overloads 119 bool startsWith(const(char)* str, const(char)* limit, const(char)[] needle) 120 { 121 auto size = limit - str; 122 if(size < needle.length) 123 { 124 return false; 125 } 126 return str[0..needle.length] == needle[]; 127 } 128 129 /** Returns a pointer to the first occurence of $(D c) or $(D sentinal). 130 */ 131 inout(char)* findCharPtr(char sentinal = '\0')(inout(char)* str, char c) 132 { 133 for(;;str++) { 134 if(*str == c || *str == sentinal) { 135 return str; 136 } 137 } 138 } 139 /** Returns a pointer to the first occurence of $(D c). If no $(D c) is found 140 then the limit is returned. 141 */ 142 inout(char)* findCharPtr(inout(char)* str, const(char)* limit, char c) 143 { 144 for(;;str++) { 145 if(str >= limit || *str == c) { 146 return str; 147 } 148 } 149 } 150 /// ditto 151 pragma(inline) 152 inout(char)* findCharPtr(inout(char)[] str, char c) 153 { 154 return findCharPtr(str.ptr, str.ptr + str.length, c); 155 } 156 157 /** Returns the index of the first occurence of $(D c). If no $(D c) is found 158 then the length of the string is returned. 159 */ 160 size_t findCharIndex(char sentinal = '\0')(const(char)* str, char c) 161 { 162 auto saveStart = str; 163 for(;;str++) { 164 if(*str == c || *str == sentinal) { 165 return str - saveStart; 166 } 167 } 168 } 169 size_t findCharIndex(const(char)* str, const(char)* limit, char c) 170 { 171 auto saveStart = str; 172 for(;;str++) { 173 if(str >= limit || *str == c) { 174 return str - saveStart; 175 } 176 } 177 } 178 size_t findCharIndex(const(char)[] str, char c) 179 { 180 foreach(i, strChar; str) { 181 if(c == strChar) { 182 return i; 183 } 184 } 185 return str.length; 186 }