ClickHouse/libs/libmysqlxx/include/mysqlxx/String.h

261 lines
4.7 KiB
C
Raw Normal View History

2011-03-03 19:57:34 +00:00
#ifndef MYSQLXX_STRING_H
#define MYSQLXX_STRING_H
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <string>
#include <limits>
#include <Yandex/DateLUT.h>
#include <mysqlxx/Types.h>
#include <mysqlxx/Exception.h>
namespace mysqlxx
{
template <typename T>
static void readIntText(T & x, const char * buf, size_t length)
{
bool negative = false;
x = 0;
const char * end = buf + length;
while (buf != end)
{
switch (*buf)
{
case '+':
break;
case '-':
negative = true;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
x *= 10;
x += *buf - '0';
break;
default:
if (negative)
x = -x;
return;
}
++buf;
}
if (negative)
x = -x;
}
/// грубо
template <typename T>
static void readFloatText(T & x, const char * buf, size_t length)
{
bool negative = false;
x = 0;
bool after_point = false;
double power_of_ten = 1;
const char * end = buf + length;
while (buf != end)
{
switch (*buf)
{
case '+':
break;
case '-':
negative = true;
break;
case '.':
after_point = true;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (after_point)
{
power_of_ten /= 10;
x += (*buf - '0') * power_of_ten;
}
else
{
x *= 10;
x += *buf - '0';
}
break;
case 'e':
case 'E':
{
++buf;
Int32 exponent = 0;
readIntText(exponent, buf, end - buf);
if (exponent == 0)
{
if (negative)
x = -x;
return;
}
else if (exponent > 0)
{
for (Int32 i = 0; i < exponent; ++i)
x *= 10;
if (negative)
x = -x;
return;
}
else
{
for (Int32 i = 0; i < exponent; ++i)
x /= 10;
if (negative)
x = -x;
return;
}
}
case 'i':
case 'I':
x = std::numeric_limits<T>::infinity();
if (negative)
x = -x;
return;
case 'n':
case 'N':
x = std::numeric_limits<T>::quiet_NaN();
return;
default:
if (negative)
x = -x;
return;
}
++buf;
}
if (negative)
x = -x;
}
class String
{
public:
String(const char * data_, size_t length_) : m_data(data_), m_length(length_)
{
}
2011-03-04 20:58:19 +00:00
bool getBool() const
{
return m_length > 0 && m_data[0] != '0';
}
UInt64 getUInt() const
2011-03-03 19:57:34 +00:00
{
UInt64 res;
readIntText(res, m_data, m_length);
return res;
}
2011-03-04 20:58:19 +00:00
Int64 getInt() const
2011-03-03 19:57:34 +00:00
{
Int64 res;
readIntText(res, m_data, m_length);
return res;
}
2011-03-04 20:58:19 +00:00
double getDouble() const
2011-03-03 19:57:34 +00:00
{
double res;
readFloatText(res, m_data, m_length);
return res;
}
2011-03-04 20:58:19 +00:00
time_t getDateTime() const
2011-03-03 19:57:34 +00:00
{
Yandex::DateLUTSingleton & date_lut = Yandex::DateLUTSingleton::instance();
if (m_length == 10)
{
return date_lut.makeDate(
m_data[0] * 1000 + m_data[1] * 100 + m_data[2] * 10 + m_data[3],
m_data[5] * 10 + m_data[6],
m_data[8] * 10 + m_data[9]);
}
else if (m_length == 19)
{
return date_lut.makeDateTime(
m_data[0] * 1000 + m_data[1] * 100 + m_data[2] * 10 + m_data[3],
m_data[5] * 10 + m_data[6],
m_data[8] * 10 + m_data[9],
m_data[11] * 10 + m_data[12],
m_data[14] * 10 + m_data[15],
m_data[17] * 10 + m_data[18]);
}
else
throw Exception("Cannot parse DateTime: " + getString());
}
2011-03-04 20:58:19 +00:00
std::string getString() const
2011-03-03 19:57:34 +00:00
{
return std::string(m_data, m_length);
}
2011-03-04 20:58:19 +00:00
template <typename T> T get();
2011-03-03 19:57:34 +00:00
2011-03-04 20:58:19 +00:00
const char * data() const { return m_data; }
size_t length() const { return m_length; }
size_t size() const { return m_length; }
2011-03-03 19:57:34 +00:00
private:
const char * m_data;
size_t m_length;
2011-03-04 20:58:19 +00:00
bool checkDateTime() const
2011-03-03 19:57:34 +00:00
{
return m_length >= 10 && m_data[4] == '-' && m_data[7] == '-';
}
};
2011-03-04 20:58:19 +00:00
template <> bool String::get() { return getBool(); }
template <> char String::get() { return getInt(); }
template <> signed char String::get() { return getInt(); }
template <> unsigned char String::get() { return getUInt(); }
template <> short String::get() { return getInt(); }
template <> unsigned short String::get() { return getUInt(); }
template <> int String::get() { return getInt(); }
template <> unsigned int String::get() { return getUInt(); }
template <> long String::get() { return getInt(); }
template <> unsigned long String::get() { return getUInt(); }
template <> long long String::get() { return getInt(); }
template <> unsigned long long String::get() { return getUInt(); }
template <> float String::get() { return getDouble(); }
template <> double String::get() { return getDouble(); }
inline std::ostream & operator<< (std::ostream & ostr, const String & x)
2011-03-03 19:57:34 +00:00
{
return ostr.write(x.data(), x.size());
}
}
#endif