123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- /*
- * 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 "include/utils/SkParse.h"
- #include <stdlib.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 nullptr;
- uint32_t n = 0;
- int max_digits = 8;
- int digit;
- while ((digit = to_hex(*str)) >= 0)
- {
- if (--max_digits < 0)
- return nullptr;
- n = (n << 4) | digit;
- str += 1;
- }
- if (*str == 0 || is_ws(*str))
- {
- if (value)
- *value = n;
- return str;
- }
- return nullptr;
- }
- 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 nullptr;
- 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 nullptr;
- 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 nullptr;
- }
- 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 == nullptr)
- 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 == nullptr) // last entry
- entryLen = strlen(list);
- else
- entryLen = end - list;
- if (entryLen == len && memcmp(target, list, len) == 0)
- return index;
- if (end == nullptr)
- break;
- list = end + 1; // skip the ','
- index += 1;
- }
- return -1;
- }
|