180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkParse.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline bool is_between(int c, int min, int max) 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return (unsigned)(c - min) <= (unsigned)(max - min); 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline bool is_ws(int c) 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return is_between(c, 1, 32); 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline bool is_digit(int c) 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return is_between(c, '0', '9'); 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline bool is_sep(int c) 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return is_ws(c) || c == ',' || c == ';'; 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic int to_hex(int c) 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (is_digit(c)) 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return c - '0'; 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru c |= 0x20; // make us lower-case 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (is_between(c, 'a', 'f')) 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return c + 10 - 'a'; 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru else 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return -1; 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline bool is_hex(int c) 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return to_hex(c) >= 0; 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const char* skip_ws(const char str[]) 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(str); 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (is_ws(*str)) 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str++; 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return str; 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const char* skip_sep(const char str[]) 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(str); 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (is_sep(*str)) 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str++; 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return str; 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkParse::Count(const char str[]) 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char c; 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int count = 0; 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru goto skipLeading; 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru count++; 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((c = *str++) == '\0') 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru goto goHome; 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (is_sep(c) == false); 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruskipLeading: 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((c = *str++) == '\0') 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru goto goHome; 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (is_sep(c)); 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (true); 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QuerugoHome: 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return count; 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkParse::Count(const char str[], char separator) 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char c; 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int count = 0; 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru goto skipLeading; 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru count++; 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((c = *str++) == '\0') 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru goto goHome; 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (c != separator); 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruskipLeading: 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((c = *str++) == '\0') 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru goto goHome; 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (c == separator); 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (true); 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QuerugoHome: 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return count; 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* SkParse::FindHex(const char str[], uint32_t* value) 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(str); 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str = skip_ws(str); 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!is_hex(*str)) 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t n = 0; 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int max_digits = 8; 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int digit; 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while ((digit = to_hex(*str)) >= 0) 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (--max_digits < 0) 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n = (n << 4) | digit; 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str += 1; 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (*str == 0 || is_ws(*str)) 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *value = n; 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return str; 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* SkParse::FindS32(const char str[], int32_t* value) 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(str); 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str = skip_ws(str); 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sign = 0; 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (*str == '-') 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sign = -1; 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str += 1; 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!is_digit(*str)) 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int n = 0; 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (is_digit(*str)) 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n = 10*n + *str - '0'; 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str += 1; 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *value = (n ^ sign) - sign; 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return str; 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* SkParse::FindMSec(const char str[], SkMSec* value) 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(str); 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str = skip_ws(str); 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sign = 0; 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (*str == '-') 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sign = -1; 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str += 1; 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!is_digit(*str)) 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int n = 0; 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (is_digit(*str)) 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n = 10*n + *str - '0'; 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str += 1; 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int remaining10s = 3; 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (*str == '.') { 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str++; 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (is_digit(*str)) 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n = 10*n + *str - '0'; 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str += 1; 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (--remaining10s == 0) 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (--remaining10s >= 0) 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n *= 10; 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *value = (n ^ sign) - sign; 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return str; 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* SkParse::FindScalar(const char str[], SkScalar* value) { 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(str); 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str = skip_ws(str); 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* stop; 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float v = (float)strtod(str, &stop); 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (str == stop) { 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) { 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *value = v; 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return stop; 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sign = 0; 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (*str == '-') 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sign = -1; 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str += 1; 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!is_digit(*str) && *str != '.') 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int n = 0; 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (is_digit(*str)) 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n = 10*n + *str - '0'; 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (n > 0x7FFF) 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str += 1; 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n <<= 16; 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (*str == '.') 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int gFractions[] = { (1 << 24) / 10, (1 << 24) / 100, (1 << 24) / 1000, 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (1 << 24) / 10000, (1 << 24) / 100000 }; 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str += 1; 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int d = 0; 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const int* fraction = gFractions; 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const int* end = &fraction[SK_ARRAY_COUNT(gFractions)]; 24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (is_digit(*str) && fraction < end) 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru d += (*str++ - '0') * *fraction++; 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru d += 0x80; // round 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n += d >> 8; 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (is_digit(*str)) 24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str += 1; 25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) 25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n = (n ^ sign) - sign; // apply the sign 25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *value = SkFixedToScalar(n); 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return str; 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* SkParse::FindScalars(const char str[], SkScalar value[], int count) 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(count >= 0); 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count > 0) 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (;;) 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str = SkParse::FindScalar(str, value); 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (--count == 0 || str == NULL) 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // keep going 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str = skip_sep(str); 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru value += 1; 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return str; 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool lookup_str(const char str[], const char** table, int count) 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (--count >= 0) 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!strcmp(str, table[count])) 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkParse::FindBool(const char str[], bool* value) 28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const char* gYes[] = { "yes", "1", "true" }; 29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const char* gNo[] = { "no", "0", "false" }; 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (lookup_str(str, gYes, SK_ARRAY_COUNT(gYes))) 29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) *value = true; 29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru else if (lookup_str(str, gNo, SK_ARRAY_COUNT(gNo))) 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) *value = false; 30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkParse::FindList(const char target[], const char list[]) 30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t len = strlen(target); 30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int index = 0; 31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (;;) 31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* end = strchr(list, ','); 31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t entryLen; 31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (end == NULL) // last entry 31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru entryLen = strlen(list); 31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru else 31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru entryLen = end - list; 32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (entryLen == len && memcmp(target, list, len) == 0) 32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return index; 32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (end == NULL) 32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru list = end + 1; // skip the ',' 32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru index += 1; 32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return -1; 33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SUPPORT_UNITTEST 33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkParse::UnitTest() 33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // !!! additional parse tests go here 33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkParse::TestColor(); 33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 339