OIIO_NAMESPACE_BEGIN TypeDesc::TypeDesc (string_view typestring) : basetype(UNKNOWN), aggregate(SCALAR), vecsemantics(NOXFORM), reserved(0), arraylen(0) { fromstring (typestring); }
//strtof exists in C99, but let's not use that bool fromstring(cstring s, float& out) { out = 0; double tmp; if (!fromstring(s, tmp)) return false; if (tmp < -FLT_MAX || tmp > FLT_MAX) return false; out = tmp; return true; }
void HTML::entity_decode(string& out, cstring& in, bool isattr) { //this follows the HTML5 spec <https://html.spec.whatwg.org/#character-reference-state> //12.2.5.72 Character reference state if (isalnum(in[1])) { //12.2.5.73 Named character reference state const char * ent = find_entity(in.substr(1, ~0)); if (!ent) goto fail; size_t entlen = strlen(ent); size_t entlen_cons = 1+entlen; if (ent[entlen-1]!=';') { if (in[entlen_cons]==';') entlen_cons++; else { if (isattr && // If the character reference was consumed as part of an attribute, /* checked above */ // and the last character matched is not a U+003B SEMICOLON character (;), (in[entlen_cons]=='=' || // and the next input character is either a U+003D EQUALS SIGN character (=) isalnum(in[entlen_cons]))) // or an ASCII alphanumeric, { // then, for historical reasons, goto fail; // flush code points consumed as a character reference and switch to the return state } } } in = in.substr(entlen_cons, ~0); const char * entval = (ent+entlen+1); if (*entval == '?') entval++; out += entval; return; } else if (in[1]=='#') { //12.2.5.75 Numeric character reference state size_t ccode; if (in[2]=='x' || in[2]=='X') { //12.2.5.76 Hexademical character reference start state size_t n = 3; while (isxdigit(in[n])) n++; if (n==3) goto fail; if (!fromstringhex(in.substr(3, n), ccode)) ccode = 0xFFFD; if (in[n]==';') n++; in = in.substr(n, ~0); } else { //12.2.5.77 Decimal character reference start state size_t n = 2; while (isdigit(in[n])) n++; if (n==2) goto fail; if (!fromstring(in.substr(2, n), ccode)) ccode = 0xFFFD; if (in[n]==';') n++; in = in.substr(n, ~0); } //12.2.5.80 Numeric character reference end state if (ccode == 0x00) ccode = 0xFFFD; if (ccode > 0x10FFFF) ccode = 0xFFFD; if (ccode >= 0xD800 && ccode <= 0xDFFF) ccode = 0xFFFD; if (ccode >= 0x80 && ccode <= 0x9F) { #define X 0xFFFD static const uint16_t windows1252[32]={ //00 to 7F map to themselves 0x20AC, X, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, X, 0x017D, X, X, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, X, 0x017E, 0x0178, //A0 to FF map to themselves }; #undef X uint32_t newcp = windows1252[ccode-0x80]; // yes, this is in the spec if (newcp != 0xFFFD) ccode = newcp; } out += string::codepoint(ccode); return; } //else fall through fail: out += '&'; in = in.substr(1, ~0); }
template<typename T> void testundec(const char * S, T V) { T a; assert_eq(fromstring(S, a), true); assert_eq(a, V); }
assert_eq(bar[1], 0x34); assert_eq(bar[2], 0x56); assert_eq(bar[3], 0x78); assert_eq(bar[4], 0x90); assert(!fromstringhex("123456", arrayvieww<byte>(foo))); // not 4 bytes assert(!fromstringhex("1234567", bar)); // odd length assert(!fromstringhex("0x123456", bar)); // no 0x allowed uint8_t u8; int32_t i32; uint32_t u32; uint64_t u64; float f; double d; assert(!fromstring("", u32)); // this isn't an integer assert(!fromstringhex("", u32)); assert(!fromstring("", f)); assert(!fromstring("2,5", f)); // this is not the decimal separator, has never been and will never be string s; s += '7'; s += '\0'; assert(!fromstring(s, u32)); // no nul allowed assert(!fromstring(s, f)); assert(!fromstringhex(s, u32)); assert(!fromstring("-0", u32)); // if -1 is invalid, -0 should be too assert(!fromstringhex("-0", u32)); assert( fromstring("-0", i32)); // but if -1 is valid, -0 should be too
uuid_t(const std::string & source) { fromstring(source.c_str()); }
uuid_t(const char * source) { fromstring(source); }
TypeDesc::TypeDesc (const char *typestring) : basetype(UNKNOWN), aggregate(SCALAR), vecsemantics(NOXFORM), reserved(0), arraylen(0) { fromstring (typestring); }
size_t TypeDesc::fromstring (const char *typestring) { return fromstring (string_view(typestring)); }