int_type getInteger(const MYSQL_BIND& bind) { if (isNull(bind)) throw NullValue(); switch (bind.buffer_type) { case MYSQL_TYPE_TINY: if (bind.is_unsigned) return *static_cast<unsigned char*>(bind.buffer); else return *static_cast<signed char*>(bind.buffer); case MYSQL_TYPE_SHORT: if (bind.is_unsigned) return *static_cast<unsigned short int*>(bind.buffer); else return *static_cast<short int*>(bind.buffer); case MYSQL_TYPE_INT24: { unsigned char* ptr = reinterpret_cast<unsigned char*>(bind.buffer); if (bind.is_unsigned) { #if __BYTE_ORDER == __LITTLE_ENDIAN return (static_cast<int_type>(ptr[0])) + (static_cast<int_type>(ptr[1]) << 8) + (static_cast<int_type>(ptr[2]) << 16); #else return (static_cast<int_type>(ptr[2])) + (static_cast<int_type>(ptr[1]) << 8) + (static_cast<int_type>(ptr[0]) << 16); #endif } else { #if __BYTE_ORDER == __LITTLE_ENDIAN if (ptr[2] < 128) { return static_cast<int_type>(ptr[0]) + (static_cast<int_type>(ptr[1]) << 8) + (static_cast<int_type>(ptr[2]) << 16); } else { int32_t val; unsigned char* vptr = reinterpret_cast<unsigned char*>(&val); vptr[0] = ptr[0]; vptr[1] = ptr[1]; vptr[2] = ptr[2]; vptr[3] = '\xff'; return static_cast<int_type>(val); } #else if (ptr[2] < 128) { return (static_cast<int_type>(ptr[2])) + (static_cast<int_type>(ptr[1]) << 8) + (static_cast<int_type>(ptr[0]) << 16); } else { int32_t val; unsigned char* vptr = reinterpret_cast<unsigned char*>(&val); vptr[0] = '\xff'; vptr[1] = ptr[0]; vptr[2] = ptr[1]; vptr[3] = ptr[2]; return static_cast<int_type>(val); } #endif } } case MYSQL_TYPE_LONG: if (bind.is_unsigned) return *static_cast<unsigned int*>(bind.buffer); else return *static_cast<int*>(bind.buffer); case MYSQL_TYPE_LONGLONG: if (bind.is_unsigned) return *static_cast<long long unsigned*>(bind.buffer); else return *static_cast<long long int*>(bind.buffer); case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: { std::string data(static_cast<char*>(bind.buffer), *bind.length); log_debug("extract integer-type from decimal \"" << data << '"'); std::istringstream in(data); Decimal decimal; decimal.read(in); if (in.eof() || !in.fail()) { int_type ret = decimal.getInteger<int_type>(); return ret; } log_error("type-error in getInteger, type=" << bind.buffer_type); throw TypeError("type-error in getInteger"); } case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: { std::string data(static_cast<char*>(bind.buffer), *bind.length); log_debug("extract integer-type from string \"" << data << '"'); std::istringstream in(data); int_type ret; in >> ret; if (in.eof() || !in.fail()) return ret; // no break!!! } default: log_error("type-error in getInteger, type=" << bind.buffer_type); throw TypeError("type-error in getInteger"); } }