1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/utils/SkParse.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,295 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include "SkParse.h" 1.14 + 1.15 +static inline bool is_between(int c, int min, int max) 1.16 +{ 1.17 + return (unsigned)(c - min) <= (unsigned)(max - min); 1.18 +} 1.19 + 1.20 +static inline bool is_ws(int c) 1.21 +{ 1.22 + return is_between(c, 1, 32); 1.23 +} 1.24 + 1.25 +static inline bool is_digit(int c) 1.26 +{ 1.27 + return is_between(c, '0', '9'); 1.28 +} 1.29 + 1.30 +static inline bool is_sep(int c) 1.31 +{ 1.32 + return is_ws(c) || c == ',' || c == ';'; 1.33 +} 1.34 + 1.35 +static int to_hex(int c) 1.36 +{ 1.37 + if (is_digit(c)) 1.38 + return c - '0'; 1.39 + 1.40 + c |= 0x20; // make us lower-case 1.41 + if (is_between(c, 'a', 'f')) 1.42 + return c + 10 - 'a'; 1.43 + else 1.44 + return -1; 1.45 +} 1.46 + 1.47 +static inline bool is_hex(int c) 1.48 +{ 1.49 + return to_hex(c) >= 0; 1.50 +} 1.51 + 1.52 +static const char* skip_ws(const char str[]) 1.53 +{ 1.54 + SkASSERT(str); 1.55 + while (is_ws(*str)) 1.56 + str++; 1.57 + return str; 1.58 +} 1.59 + 1.60 +static const char* skip_sep(const char str[]) 1.61 +{ 1.62 + SkASSERT(str); 1.63 + while (is_sep(*str)) 1.64 + str++; 1.65 + return str; 1.66 +} 1.67 + 1.68 +int SkParse::Count(const char str[]) 1.69 +{ 1.70 + char c; 1.71 + int count = 0; 1.72 + goto skipLeading; 1.73 + do { 1.74 + count++; 1.75 + do { 1.76 + if ((c = *str++) == '\0') 1.77 + goto goHome; 1.78 + } while (is_sep(c) == false); 1.79 +skipLeading: 1.80 + do { 1.81 + if ((c = *str++) == '\0') 1.82 + goto goHome; 1.83 + } while (is_sep(c)); 1.84 + } while (true); 1.85 +goHome: 1.86 + return count; 1.87 +} 1.88 + 1.89 +int SkParse::Count(const char str[], char separator) 1.90 +{ 1.91 + char c; 1.92 + int count = 0; 1.93 + goto skipLeading; 1.94 + do { 1.95 + count++; 1.96 + do { 1.97 + if ((c = *str++) == '\0') 1.98 + goto goHome; 1.99 + } while (c != separator); 1.100 +skipLeading: 1.101 + do { 1.102 + if ((c = *str++) == '\0') 1.103 + goto goHome; 1.104 + } while (c == separator); 1.105 + } while (true); 1.106 +goHome: 1.107 + return count; 1.108 +} 1.109 + 1.110 +const char* SkParse::FindHex(const char str[], uint32_t* value) 1.111 +{ 1.112 + SkASSERT(str); 1.113 + str = skip_ws(str); 1.114 + 1.115 + if (!is_hex(*str)) 1.116 + return NULL; 1.117 + 1.118 + uint32_t n = 0; 1.119 + int max_digits = 8; 1.120 + int digit; 1.121 + 1.122 + while ((digit = to_hex(*str)) >= 0) 1.123 + { 1.124 + if (--max_digits < 0) 1.125 + return NULL; 1.126 + n = (n << 4) | digit; 1.127 + str += 1; 1.128 + } 1.129 + 1.130 + if (*str == 0 || is_ws(*str)) 1.131 + { 1.132 + if (value) 1.133 + *value = n; 1.134 + return str; 1.135 + } 1.136 + return NULL; 1.137 +} 1.138 + 1.139 +const char* SkParse::FindS32(const char str[], int32_t* value) 1.140 +{ 1.141 + SkASSERT(str); 1.142 + str = skip_ws(str); 1.143 + 1.144 + int sign = 0; 1.145 + if (*str == '-') 1.146 + { 1.147 + sign = -1; 1.148 + str += 1; 1.149 + } 1.150 + 1.151 + if (!is_digit(*str)) 1.152 + return NULL; 1.153 + 1.154 + int n = 0; 1.155 + while (is_digit(*str)) 1.156 + { 1.157 + n = 10*n + *str - '0'; 1.158 + str += 1; 1.159 + } 1.160 + if (value) 1.161 + *value = (n ^ sign) - sign; 1.162 + return str; 1.163 +} 1.164 + 1.165 +const char* SkParse::FindMSec(const char str[], SkMSec* value) 1.166 +{ 1.167 + SkASSERT(str); 1.168 + str = skip_ws(str); 1.169 + 1.170 + int sign = 0; 1.171 + if (*str == '-') 1.172 + { 1.173 + sign = -1; 1.174 + str += 1; 1.175 + } 1.176 + 1.177 + if (!is_digit(*str)) 1.178 + return NULL; 1.179 + 1.180 + int n = 0; 1.181 + while (is_digit(*str)) 1.182 + { 1.183 + n = 10*n + *str - '0'; 1.184 + str += 1; 1.185 + } 1.186 + int remaining10s = 3; 1.187 + if (*str == '.') { 1.188 + str++; 1.189 + while (is_digit(*str)) 1.190 + { 1.191 + n = 10*n + *str - '0'; 1.192 + str += 1; 1.193 + if (--remaining10s == 0) 1.194 + break; 1.195 + } 1.196 + } 1.197 + while (--remaining10s >= 0) 1.198 + n *= 10; 1.199 + if (value) 1.200 + *value = (n ^ sign) - sign; 1.201 + return str; 1.202 +} 1.203 + 1.204 +const char* SkParse::FindScalar(const char str[], SkScalar* value) { 1.205 + SkASSERT(str); 1.206 + str = skip_ws(str); 1.207 + 1.208 + char* stop; 1.209 + float v = (float)strtod(str, &stop); 1.210 + if (str == stop) { 1.211 + return NULL; 1.212 + } 1.213 + if (value) { 1.214 + *value = v; 1.215 + } 1.216 + return stop; 1.217 +} 1.218 + 1.219 +const char* SkParse::FindScalars(const char str[], SkScalar value[], int count) 1.220 +{ 1.221 + SkASSERT(count >= 0); 1.222 + 1.223 + if (count > 0) 1.224 + { 1.225 + for (;;) 1.226 + { 1.227 + str = SkParse::FindScalar(str, value); 1.228 + if (--count == 0 || str == NULL) 1.229 + break; 1.230 + 1.231 + // keep going 1.232 + str = skip_sep(str); 1.233 + if (value) 1.234 + value += 1; 1.235 + } 1.236 + } 1.237 + return str; 1.238 +} 1.239 + 1.240 +static bool lookup_str(const char str[], const char** table, int count) 1.241 +{ 1.242 + while (--count >= 0) 1.243 + if (!strcmp(str, table[count])) 1.244 + return true; 1.245 + return false; 1.246 +} 1.247 + 1.248 +bool SkParse::FindBool(const char str[], bool* value) 1.249 +{ 1.250 + static const char* gYes[] = { "yes", "1", "true" }; 1.251 + static const char* gNo[] = { "no", "0", "false" }; 1.252 + 1.253 + if (lookup_str(str, gYes, SK_ARRAY_COUNT(gYes))) 1.254 + { 1.255 + if (value) *value = true; 1.256 + return true; 1.257 + } 1.258 + else if (lookup_str(str, gNo, SK_ARRAY_COUNT(gNo))) 1.259 + { 1.260 + if (value) *value = false; 1.261 + return true; 1.262 + } 1.263 + return false; 1.264 +} 1.265 + 1.266 +int SkParse::FindList(const char target[], const char list[]) 1.267 +{ 1.268 + size_t len = strlen(target); 1.269 + int index = 0; 1.270 + 1.271 + for (;;) 1.272 + { 1.273 + const char* end = strchr(list, ','); 1.274 + size_t entryLen; 1.275 + 1.276 + if (end == NULL) // last entry 1.277 + entryLen = strlen(list); 1.278 + else 1.279 + entryLen = end - list; 1.280 + 1.281 + if (entryLen == len && memcmp(target, list, len) == 0) 1.282 + return index; 1.283 + if (end == NULL) 1.284 + break; 1.285 + 1.286 + list = end + 1; // skip the ',' 1.287 + index += 1; 1.288 + } 1.289 + return -1; 1.290 +} 1.291 + 1.292 +#ifdef SK_SUPPORT_UNITTEST 1.293 +void SkParse::UnitTest() 1.294 +{ 1.295 + // !!! additional parse tests go here 1.296 + SkParse::TestColor(); 1.297 +} 1.298 +#endif