diff -r 000000000000 -r 6474c204b198 gfx/skia/trunk/src/utils/SkParse.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/skia/trunk/src/utils/SkParse.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,295 @@ + +/* + * Copyright 2006 The Android Open Source Project + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + +#include "SkParse.h" + +static inline bool is_between(int c, int min, int max) +{ + return (unsigned)(c - min) <= (unsigned)(max - min); +} + +static inline bool is_ws(int c) +{ + return is_between(c, 1, 32); +} + +static inline bool is_digit(int c) +{ + return is_between(c, '0', '9'); +} + +static inline bool is_sep(int c) +{ + return is_ws(c) || c == ',' || c == ';'; +} + +static int to_hex(int c) +{ + if (is_digit(c)) + return c - '0'; + + c |= 0x20; // make us lower-case + if (is_between(c, 'a', 'f')) + return c + 10 - 'a'; + else + return -1; +} + +static inline bool is_hex(int c) +{ + return to_hex(c) >= 0; +} + +static const char* skip_ws(const char str[]) +{ + SkASSERT(str); + while (is_ws(*str)) + str++; + return str; +} + +static const char* skip_sep(const char str[]) +{ + SkASSERT(str); + while (is_sep(*str)) + str++; + return str; +} + +int SkParse::Count(const char str[]) +{ + char c; + int count = 0; + goto skipLeading; + do { + count++; + do { + if ((c = *str++) == '\0') + goto goHome; + } while (is_sep(c) == false); +skipLeading: + do { + if ((c = *str++) == '\0') + goto goHome; + } while (is_sep(c)); + } while (true); +goHome: + return count; +} + +int SkParse::Count(const char str[], char separator) +{ + char c; + int count = 0; + goto skipLeading; + do { + count++; + do { + if ((c = *str++) == '\0') + goto goHome; + } while (c != separator); +skipLeading: + do { + if ((c = *str++) == '\0') + goto goHome; + } while (c == separator); + } while (true); +goHome: + return count; +} + +const char* SkParse::FindHex(const char str[], uint32_t* value) +{ + SkASSERT(str); + str = skip_ws(str); + + if (!is_hex(*str)) + return NULL; + + uint32_t n = 0; + int max_digits = 8; + int digit; + + while ((digit = to_hex(*str)) >= 0) + { + if (--max_digits < 0) + return NULL; + n = (n << 4) | digit; + str += 1; + } + + if (*str == 0 || is_ws(*str)) + { + if (value) + *value = n; + return str; + } + return NULL; +} + +const char* SkParse::FindS32(const char str[], int32_t* value) +{ + SkASSERT(str); + str = skip_ws(str); + + int sign = 0; + if (*str == '-') + { + sign = -1; + str += 1; + } + + if (!is_digit(*str)) + return NULL; + + int n = 0; + while (is_digit(*str)) + { + n = 10*n + *str - '0'; + str += 1; + } + if (value) + *value = (n ^ sign) - sign; + return str; +} + +const char* SkParse::FindMSec(const char str[], SkMSec* value) +{ + SkASSERT(str); + str = skip_ws(str); + + int sign = 0; + if (*str == '-') + { + sign = -1; + str += 1; + } + + if (!is_digit(*str)) + return NULL; + + int n = 0; + while (is_digit(*str)) + { + n = 10*n + *str - '0'; + str += 1; + } + int remaining10s = 3; + if (*str == '.') { + str++; + while (is_digit(*str)) + { + n = 10*n + *str - '0'; + str += 1; + if (--remaining10s == 0) + break; + } + } + while (--remaining10s >= 0) + n *= 10; + if (value) + *value = (n ^ sign) - sign; + return str; +} + +const char* SkParse::FindScalar(const char str[], SkScalar* value) { + SkASSERT(str); + str = skip_ws(str); + + char* stop; + float v = (float)strtod(str, &stop); + if (str == stop) { + return NULL; + } + if (value) { + *value = v; + } + return stop; +} + +const char* SkParse::FindScalars(const char str[], SkScalar value[], int count) +{ + SkASSERT(count >= 0); + + if (count > 0) + { + for (;;) + { + str = SkParse::FindScalar(str, value); + if (--count == 0 || str == NULL) + break; + + // keep going + str = skip_sep(str); + if (value) + value += 1; + } + } + return str; +} + +static bool lookup_str(const char str[], const char** table, int count) +{ + while (--count >= 0) + if (!strcmp(str, table[count])) + return true; + return false; +} + +bool SkParse::FindBool(const char str[], bool* value) +{ + static const char* gYes[] = { "yes", "1", "true" }; + static const char* gNo[] = { "no", "0", "false" }; + + if (lookup_str(str, gYes, SK_ARRAY_COUNT(gYes))) + { + if (value) *value = true; + return true; + } + else if (lookup_str(str, gNo, SK_ARRAY_COUNT(gNo))) + { + if (value) *value = false; + return true; + } + return false; +} + +int SkParse::FindList(const char target[], const char list[]) +{ + size_t len = strlen(target); + int index = 0; + + for (;;) + { + const char* end = strchr(list, ','); + size_t entryLen; + + if (end == NULL) // last entry + entryLen = strlen(list); + else + entryLen = end - list; + + if (entryLen == len && memcmp(target, list, len) == 0) + return index; + if (end == NULL) + break; + + list = end + 1; // skip the ',' + index += 1; + } + return -1; +} + +#ifdef SK_SUPPORT_UNITTEST +void SkParse::UnitTest() +{ + // !!! additional parse tests go here + SkParse::TestColor(); +} +#endif