1f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 2f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/* 3f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Copyright 2006 The Android Open Source Project 4f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * 5f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 6f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * found in the LICENSE file. 7f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger */ 8f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 9f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 10f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkParse.h" 11f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 12f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline bool is_between(int c, int min, int max) 13f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 14f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return (unsigned)(c - min) <= (unsigned)(max - min); 15f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 16f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 17f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline bool is_ws(int c) 18f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 19f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return is_between(c, 1, 32); 20f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 21f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 22f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline bool is_digit(int c) 23f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 24f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return is_between(c, '0', '9'); 25f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 26f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 27f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline bool is_sep(int c) 28f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 29f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return is_ws(c) || c == ',' || c == ';'; 30f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 31f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 32f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic int to_hex(int c) 33f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 34f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (is_digit(c)) 35f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return c - '0'; 36f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 37f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger c |= 0x20; // make us lower-case 38f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (is_between(c, 'a', 'f')) 39f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return c + 10 - 'a'; 40f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger else 41f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return -1; 42f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 43f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 44f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline bool is_hex(int c) 45f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 46f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return to_hex(c) >= 0; 47f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 48f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 49f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic const char* skip_ws(const char str[]) 50f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 51f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(str); 52f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while (is_ws(*str)) 53f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str++; 54f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return str; 55f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 56f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 57f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic const char* skip_sep(const char str[]) 58f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 59f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(str); 60f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while (is_sep(*str)) 61f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str++; 62f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return str; 63f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 64f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 65f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerint SkParse::Count(const char str[]) 66f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 67f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger char c; 68f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int count = 0; 69f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger goto skipLeading; 70f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 71f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger count++; 72f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 73f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((c = *str++) == '\0') 74f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger goto goHome; 75f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (is_sep(c) == false); 76f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerskipLeading: 77f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 78f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((c = *str++) == '\0') 79f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger goto goHome; 80f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (is_sep(c)); 81f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (true); 82f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergergoHome: 83f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return count; 84f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 85f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 86f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerint SkParse::Count(const char str[], char separator) 87f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 88f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger char c; 89f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int count = 0; 90f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger goto skipLeading; 91f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 92f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger count++; 93f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 94f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((c = *str++) == '\0') 95f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger goto goHome; 96f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (c != separator); 97f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerskipLeading: 98f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 99f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((c = *str++) == '\0') 100f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger goto goHome; 101f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (c == separator); 102f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (true); 103f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergergoHome: 104f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return count; 105f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 106f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 107f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerconst char* SkParse::FindHex(const char str[], uint32_t* value) 108f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 109f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(str); 110f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str = skip_ws(str); 111f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 112f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (!is_hex(*str)) 113f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return NULL; 114f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 115f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger uint32_t n = 0; 116f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int max_digits = 8; 117f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int digit; 118f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 119f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while ((digit = to_hex(*str)) >= 0) 120f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 121f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (--max_digits < 0) 122f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return NULL; 123f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger n = (n << 4) | digit; 124f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str += 1; 125f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 126f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 127f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (*str == 0 || is_ws(*str)) 128f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 129f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (value) 130f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *value = n; 131f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return str; 132f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 133f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return NULL; 134f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 135f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 136f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerconst char* SkParse::FindS32(const char str[], int32_t* value) 137f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 138f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(str); 139f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str = skip_ws(str); 140f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 141f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sign = 0; 142f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (*str == '-') 143f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 144f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger sign = -1; 145f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str += 1; 146f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 147f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 148f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (!is_digit(*str)) 149f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return NULL; 150f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 151f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int n = 0; 152f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while (is_digit(*str)) 153f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 154f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger n = 10*n + *str - '0'; 155f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str += 1; 156f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 157f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (value) 158f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *value = (n ^ sign) - sign; 159f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return str; 160f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 161f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 162f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerconst char* SkParse::FindMSec(const char str[], SkMSec* value) 163f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 164f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(str); 165f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str = skip_ws(str); 166f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 167f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sign = 0; 168f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (*str == '-') 169f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 170f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger sign = -1; 171f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str += 1; 172f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 173f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 174f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (!is_digit(*str)) 175f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return NULL; 176f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 177f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int n = 0; 178f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while (is_digit(*str)) 179f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 180f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger n = 10*n + *str - '0'; 181f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str += 1; 182f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 183f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int remaining10s = 3; 184f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (*str == '.') { 185f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str++; 186f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while (is_digit(*str)) 187f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 188f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger n = 10*n + *str - '0'; 189f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str += 1; 190f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (--remaining10s == 0) 191f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger break; 192f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 193f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 194f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while (--remaining10s >= 0) 195f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger n *= 10; 196f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (value) 197f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *value = (n ^ sign) - sign; 198f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return str; 199f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 200f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 201f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerconst char* SkParse::FindScalar(const char str[], SkScalar* value) { 202f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(str); 203f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str = skip_ws(str); 204f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#ifdef SK_SCALAR_IS_FLOAT 205f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger char* stop; 206f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger float v = (float)strtod(str, &stop); 207f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (str == stop) { 208f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return NULL; 209f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 210f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (value) { 211f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *value = v; 212f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 213f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return stop; 214f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#else 215f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sign = 0; 216f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (*str == '-') 217f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 218f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger sign = -1; 219f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str += 1; 220f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 221f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 222f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (!is_digit(*str) && *str != '.') 223f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return NULL; 224f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 225f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int n = 0; 226f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while (is_digit(*str)) 227f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 228f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger n = 10*n + *str - '0'; 229f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (n > 0x7FFF) 230f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return NULL; 231f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str += 1; 232f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 233f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger n <<= 16; 234f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 235f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (*str == '.') 236f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 237f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger static const int gFractions[] = { (1 << 24) / 10, (1 << 24) / 100, (1 << 24) / 1000, 238f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger (1 << 24) / 10000, (1 << 24) / 100000 }; 239f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str += 1; 240f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int d = 0; 241f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const int* fraction = gFractions; 242f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const int* end = &fraction[SK_ARRAY_COUNT(gFractions)]; 243f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while (is_digit(*str) && fraction < end) 244f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger d += (*str++ - '0') * *fraction++; 245f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger d += 0x80; // round 246f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger n += d >> 8; 247f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 248f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while (is_digit(*str)) 249f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str += 1; 250f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (value) 251f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 252f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger n = (n ^ sign) - sign; // apply the sign 253f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *value = SkFixedToScalar(n); 254f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 255f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#endif 256f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return str; 257f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 258f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 259f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerconst char* SkParse::FindScalars(const char str[], SkScalar value[], int count) 260f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 261f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(count >= 0); 262f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 263f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (count > 0) 264f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 265f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (;;) 266f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 267f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str = SkParse::FindScalar(str, value); 268f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (--count == 0 || str == NULL) 269f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger break; 270f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 271f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // keep going 272f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger str = skip_sep(str); 273f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (value) 274f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger value += 1; 275f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 276f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 277f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return str; 278f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 279f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 280f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic bool lookup_str(const char str[], const char** table, int count) 281f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 282f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while (--count >= 0) 283f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (!strcmp(str, table[count])) 284f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return true; 285f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 286f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 287f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 288f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkParse::FindBool(const char str[], bool* value) 289f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 290f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger static const char* gYes[] = { "yes", "1", "true" }; 291f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger static const char* gNo[] = { "no", "0", "false" }; 292f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 293f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (lookup_str(str, gYes, SK_ARRAY_COUNT(gYes))) 294f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 295f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (value) *value = true; 296f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return true; 297f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 298f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger else if (lookup_str(str, gNo, SK_ARRAY_COUNT(gNo))) 299f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 300f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (value) *value = false; 301f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return true; 302f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 303f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 304f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 305f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 306f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerint SkParse::FindList(const char target[], const char list[]) 307f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 308f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger size_t len = strlen(target); 309f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int index = 0; 310f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 311f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (;;) 312f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 313f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const char* end = strchr(list, ','); 314f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger size_t entryLen; 315f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 316f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (end == NULL) // last entry 317f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger entryLen = strlen(list); 318f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger else 319f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger entryLen = end - list; 320f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 321f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (entryLen == len && memcmp(target, list, len) == 0) 322f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return index; 323f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (end == NULL) 324f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger break; 325f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 326f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger list = end + 1; // skip the ',' 327f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger index += 1; 328f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 329f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return -1; 330f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 331f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 332f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#ifdef SK_SUPPORT_UNITTEST 333f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkParse::UnitTest() 334f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 335f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // !!! additional parse tests go here 336f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkParse::TestColor(); 337f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 338f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#endif 339