bool Variant::toBool() const { switch (type) { case TYPE_BOOL: return data._Bool; break; case TYPE_CHAR: return data._Char != 0; break; case TYPE_UCHAR: return data._UChar != 0; break; case TYPE_INT16: return data._Int16 != 0; break; case TYPE_UINT16: return data._UInt16 != 0; break; case TYPE_INT32: return data._Int32 != 0; break; case TYPE_UINT32: return data._UInt32 != 0; break; case TYPE_INT64: return data._Int64 != 0; break; case TYPE_UINT64: return data._UInt64 != 0; break; case TYPE_STRING: { std::string upperstr(*data._String); std::transform(upperstr.begin(), upperstr.end(), upperstr.begin(), (int(*)(int))toupper);if ( upperstr == "YES") return true; else if (upperstr == "NO") return false; if (upperstr == "TRUE") return true; else if (upperstr == "FALSE") return false; if (upperstr == "1") return true; else if (upperstr == "0") return false; else throw bad_conversion(type, TYPE_BOOL); } break; case TYPE_FLOAT: case TYPE_DOUBLE: case TYPE_NONE: throw bad_conversion(type, TYPE_BOOL); break; } return false; }
const std::basic_string<CharType> in( const std::basic_string<Byte>& external_str, const std::codecvt<CharType, Byte, mbstate_t>& codecvt) { typedef std::basic_string<CharType> wstring; typedef std::basic_string<Byte> string; typedef std::codecvt<CharType, Byte, mbstate_t> codecvt_type; typename string::size_type external_str_size = external_str.length(); const Byte* first_external = external_str.data(); const Byte* last_external = first_external + external_str_size; const Byte* next_external = last_external; wstring internal_str; // Zero initialized typename codecvt_type::state_type state; std::memset(&state, 0, sizeof(state)); typename wstring::size_type out_buf_size = static_cast<typename wstring::size_type>( codecvt.length(state, first_external, last_external, internal_str.max_size())); #if defined(MA_USE_CXX11_STDLIB_MEMORY) detail::unique_ptr<CharType[]> out_buf(new CharType[out_buf_size]); #else detail::scoped_array<CharType> out_buf(new CharType[out_buf_size]); #endif CharType* first_internal = out_buf.get(); CharType* last_internal = first_internal + out_buf_size; CharType* next_internal = first_internal; typename codecvt_type::result r = codecvt.in(state, first_external, last_external, next_external, first_internal, last_internal, next_internal); if (codecvt_type::ok == r) { internal_str.assign(first_internal, last_internal); } else if (codecvt_type::noconv == r) { internal_str.assign(reinterpret_cast<const CharType*>(first_external), reinterpret_cast<const CharType*>(last_external)); } else { boost::throw_exception(bad_conversion()); } return internal_str; }
const std::basic_string<Byte> out( const std::basic_string<CharType>& internal_str, const std::codecvt<CharType, Byte, mbstate_t>& codecvt) { typedef std::basic_string<CharType> wstring; typedef std::basic_string<Byte> string; typedef std::codecvt<CharType, Byte, mbstate_t> codecvt_type; string external_str; typename wstring::size_type internal_str_size = internal_str.length(); typename wstring::size_type out_buf_size = static_cast<typename wstring::size_type>(codecvt.max_length()) * internal_str_size; #if defined(MA_USE_CXX11_STDLIB_MEMORY) std::unique_ptr<Byte[]> out_buf(new Byte[out_buf_size]); #else boost::scoped_array<Byte> out_buf(new Byte[out_buf_size]); #endif const CharType* first_internal = internal_str.data(); const CharType* last_internal = first_internal + internal_str_size; const CharType* next_internal = first_internal; Byte* first_external = out_buf.get(); Byte* last_external = first_external + out_buf_size; Byte* next_external = first_external; typename codecvt_type::state_type state(0); typename codecvt_type::result r = codecvt.out(state, first_internal, last_internal, next_internal, first_external, last_external, next_external); if (codecvt_type::ok == r) { external_str.assign(first_external, next_external); } else if (codecvt_type::noconv == r) { external_str.assign(reinterpret_cast<const Byte*>(first_internal), reinterpret_cast<const Byte*>(last_internal)); } else { boost::throw_exception(bad_conversion()); } return external_str; }
const std::basic_string<CharType> in( const std::basic_string<Byte>& external_str, const std::codecvt<CharType, Byte, mbstate_t>& codecvt) { typedef std::basic_string<CharType> wstring; typedef std::basic_string<Byte> string; typedef std::codecvt<CharType, Byte, mbstate_t> codecvt_type; typename string::size_type external_str_size = external_str.length(); const Byte* first_external = external_str.data(); const Byte* last_external = first_external + external_str_size; const Byte* next_external = last_external; wstring internal_str; typename codecvt_type::state_type state(0); typename wstring::size_type out_buf_size = codecvt.length(state, first_external, last_external, internal_str.max_size()); boost::scoped_array<CharType> out_buf(new CharType[out_buf_size]); CharType* first_internal = out_buf.get(); CharType* last_internal = first_internal + out_buf_size; CharType* next_internal = first_internal; typename codecvt_type::result r = codecvt.in(state, first_external, last_external, next_external, first_internal, last_internal, next_internal); if (codecvt_type::ok != r) { boost::throw_exception(bad_conversion()); } else if (codecvt_type::noconv == r) { internal_str.assign(reinterpret_cast<const CharType*>(first_external), reinterpret_cast<const CharType*>(last_external)); } else { internal_str.assign(first_internal, last_internal); } return internal_str; }
void Variant::check(const Type t) { if (type == TYPE_NONE) { std::memset(&data, 0, sizeof(data)); switch (t) { case TYPE_STRING: data._String = new std::string; break; default: break; } type = t; } else if (type != t) { throw bad_conversion(type, t); } }
void Variant::check(const Type t) const { if (type != t) throw bad_conversion(type, t); }
Variant Variant::fromString(const std::string &str, Type type) { std::stringstream sstr(str); switch (type) { case TYPE_BOOL: { std::string upperstr(str); std::transform(upperstr.begin(), upperstr.end(), upperstr.begin(), (int(*)(int))toupper);if ( upperstr == "YES") return Variant(true); else if (upperstr == "NO") return Variant(false); if (upperstr == "TRUE") return Variant(true); else if (upperstr == "FALSE") return Variant(false); if (upperstr == "1") return Variant(true); else if (upperstr == "0") return Variant(false); throw bad_conversion(type, TYPE_BOOL); } case TYPE_CHAR: { char c; sstr >> c; return Variant(c); } case TYPE_UCHAR: { unsigned char c; sstr >> c; return Variant(c); } case TYPE_INT16: { int16_t c; sstr >> c; return Variant(c); } case TYPE_UINT16: { uint16_t c; sstr >> c; return Variant(c); } case TYPE_INT32: { int32_t c; sstr >> c; return Variant(c); } case TYPE_UINT32: { uint32_t c; sstr >> c; return Variant(c); } case TYPE_INT64: { int64_t c; sstr >> c; return Variant(c); } case TYPE_UINT64: { uint64_t c; sstr >> c; return Variant(c); } case TYPE_FLOAT: { float c; sstr >> c; return Variant(c); } case TYPE_DOUBLE: { double c; sstr >> c; return Variant(c); } case TYPE_STRING: { return Variant(str); } default: throw std::runtime_error("pxl::Variant::fromString: unknown type"); } }
/* * Note: caller must do CELL cleanup. * The format parameter is modified, but restored. * * This routine does both printf and sprintf (if fp==0) */ static STRING * do_printf( FILE *fp, char *format, unsigned argcnt, /* number of args on eval stack */ CELL *cp) /* ptr to an array of arguments (on the eval stack) */ { char save; char *p; register char *q = format; register char *target; int l_flag, h_flag; /* seen %ld or %hd */ int ast_cnt; int ast[2]; UInt Uval = 0; Int Ival = 0; int sfmt_width, sfmt_prec, sfmt_flags, s_format; int num_conversion = 0; /* for error messages */ const char *who; /*ditto */ int pf_type = 0; /* conversion type */ PRINTER printer; /* pts at fprintf() or sprintf() */ STRING onechr; #ifdef SHORT_INTS char xbuff[256]; /* splice in l qualifier here */ #endif if (fp == (FILE *) 0) { /* doing sprintf */ target = sprintf_buff; printer = (PRINTER) sprintf; who = "sprintf"; } else { /* doing printf */ target = (char *) fp; /* will never change */ printer = (PRINTER) fprintf; who = "printf"; } while (1) { if (fp) { /* printf */ while (*q != '%') { if (*q == 0) { if (ferror(fp)) write_error(); /* return is ignored */ return (STRING *) 0; } else { putc(*q, fp); q++; } } } else { /* sprintf */ while (*q != '%') { if (*q == 0) { if (target > sprintf_limit) /* damaged */ { /* hope this works */ rt_overflow("sprintf buffer", (unsigned) (sprintf_limit - sprintf_buff)); } else { /* really done */ return new_STRING1(sprintf_buff, (size_t) (target - sprintf_buff)); } } else { *target++ = *q++; } } } /* *q == '%' */ num_conversion++; if (*++q == '%') { /* %% */ if (fp) putc(*q, fp); else *target++ = *q; q++; continue; } /* mark the '%' with p */ p = q - 1; /* eat the flags */ while (*q == '-' || *q == '+' || *q == ' ' || *q == '#' || *q == '0') q++; ast_cnt = 0; ast[0] = 0; if (*q == '*') { if (cp->type != C_DOUBLE) cast1_to_d(cp); ast[ast_cnt++] = d_to_i(cp++->dval); argcnt--; q++; } else while (scan_code[*(unsigned char *) q] == SC_DIGIT) q++; /* width is done */ if (*q == '.') { /* have precision */ q++; if (*q == '*') { if (cp->type != C_DOUBLE) cast1_to_d(cp); ast[ast_cnt++] = d_to_i(cp++->dval); argcnt--; q++; } else { while (scan_code[*(unsigned char *) q] == SC_DIGIT) q++; } } if (argcnt <= 0) rt_error("not enough arguments passed to %s(\"%s\")", who, format); l_flag = h_flag = 0; if (*q == 'l') { q++; l_flag = 1; } else if (*q == 'h') { q++; h_flag = 1; } switch (*q++) { case 's': if (l_flag + h_flag) bad_conversion(num_conversion, who, format); if (cp->type < C_STRING) cast1_to_s(cp); pf_type = PF_S; break; case 'c': if (l_flag + h_flag) bad_conversion(num_conversion, who, format); switch (cp->type) { case C_NOINIT: Ival = 0; break; case C_STRNUM: case C_DOUBLE: Ival = d_to_I(cp->dval); break; case C_STRING: /* fall thru to check for bad number formats */ //Ival = string(cp)->str[0]; //break; /* fall thru */ case C_FIELDWIDTHS: case C_MBSTRN: check_strnum(cp); Ival = ((cp->type == C_STRING) ? string(cp)->str[0] : d_to_I(cp->dval)); break; default: bozo("printf %c"); } onechr.len = 1; onechr.str[0] = (char) Ival; pf_type = PF_C; break; case 'd': case 'i': if (cp->type != C_DOUBLE) cast1_to_d(cp); Ival = d_to_I(cp->dval); pf_type = PF_D; break; case 'o': case 'x': case 'X': case 'u': if (cp->type != C_DOUBLE) cast1_to_d(cp); Uval = d_to_U(cp->dval); pf_type = PF_U; break; case 'e': case 'g': case 'f': case 'E': case 'G': if (h_flag + l_flag) bad_conversion(num_conversion, who, format); if (cp->type != C_DOUBLE) cast1_to_d(cp); pf_type = PF_F; break; default: bad_conversion(num_conversion, who, format); } save = *q; *q = 0; #ifdef SHORT_INTS if (pf_type == PF_D) { /* need to splice in long modifier */ strcpy(xbuff, p); if (l_flag) /* do nothing */ ; else { int k = q - p; if (h_flag) { Ival = (short) Ival; /* replace the 'h' with 'l' (really!) */ xbuff[k - 2] = 'l'; if (xbuff[k - 1] != 'd' && xbuff[k - 1] != 'i') Ival &= 0xffff; } else { /* the usual case */ xbuff[k] = xbuff[k - 1]; xbuff[k - 1] = 'l'; xbuff[k + 1] = 0; } } } #endif #define PUTS_C_ARGS target, fp, 0, &onechr, sfmt_width, sfmt_prec, sfmt_flags #define PUTS_S_ARGS target, fp, cp, 0, sfmt_width, sfmt_prec, sfmt_flags /* ready to call printf() */ s_format = 0; switch (AST(ast_cnt, pf_type)) { case AST(0, PF_C): /* FALLTHRU */ case AST(1, PF_C): /* FALLTHRU */ case AST(2, PF_C): s_format = 1; make_sfmt(p, ast, &sfmt_width, &sfmt_prec, &sfmt_flags); target = puts_sfmt(PUTS_C_ARGS); break; case AST(0, PF_S): /* FALLTHRU */ case AST(1, PF_S): /* FALLTHRU */ case AST(2, PF_S): s_format = 1; make_sfmt(p, ast, &sfmt_width, &sfmt_prec, &sfmt_flags); target = puts_sfmt(PUTS_S_ARGS); break; #ifdef SHORT_INTS #define FMT xbuff /* format in xbuff */ #else #define FMT p /* p -> format */ #endif case AST(0, PF_D): if (cp->dval > Max_Int && l_flag == 0 && h_flag == 0) { STRING *newp; char *np; newp = new_STRING0(strlen(p)+5); np = (char *) newp->str; while (*p != '\0') { if (*p == 'd' || *p == 'i') { *np++ = '.'; *np++ = '0'; *np++ = 'f'; ++p; } else *np++ = *p++; } np = '\0'; (*printer) ((PTR) target, newp->str, cp->dval); free_STRING(newp); } else (*printer) ((PTR) target, FMT, Ival); break; case AST(1, PF_D): (*printer) ((PTR) target, FMT, ast[0], Ival); break; case AST(2, PF_D): (*printer) ((PTR) target, FMT, ast[0], ast[1], Ival); break; case AST(0, PF_U): if (*(p+1) == 'u' && cp->dval > Max_Int ) { STRING *newp; char *np; newp = new_STRING0(strlen(p)+5); np = (char *) newp->str; while (*p != '\0') { if (*p == 'u') { *np++ = '.'; *np++ = '0'; *np++ = 'f'; ++p; } else *np++ = *p++; } np = '\0'; (*printer) ((PTR) target, newp->str, cp->dval); free_STRING(newp); } else (*printer) ((PTR) target, FMT, Uval); break; case AST(1, PF_U): (*printer) ((PTR) target, FMT, ast[0], Uval); break; case AST(2, PF_U): (*printer) ((PTR) target, FMT, ast[0], ast[1], Uval); break; #undef FMT case AST(0, PF_F): (*printer) ((PTR) target, p, cp->dval); break; case AST(1, PF_F): (*printer) ((PTR) target, p, ast[0], cp->dval); break; case AST(2, PF_F): (*printer) ((PTR) target, p, ast[0], ast[1], cp->dval); break; } if (fp == (FILE *) 0 && !s_format) { while (*target) target++; } *q = save; argcnt--; cp++; } }