ClickHouse/dbms/include/DB/IO/ReadHelpers.h

222 lines
3.5 KiB
C
Raw Normal View History

2010-06-04 18:25:25 +00:00
#ifndef DBMS_COMMON_READHELPERS_H
#define DBMS_COMMON_READHELPERS_H
2010-05-28 19:13:55 +00:00
2010-06-01 13:35:09 +00:00
#include <cstring>
2010-06-01 13:41:51 +00:00
#include <limits>
2010-05-28 19:13:55 +00:00
#include <algorithm>
#include <DB/Core/Types.h>
#include <DB/Core/Exception.h>
#include <DB/Core/ErrorCodes.h>
2010-06-04 18:25:25 +00:00
#include <DB/IO/ReadBuffer.h>
2010-05-28 19:13:55 +00:00
namespace DB
{
2010-06-01 13:35:09 +00:00
/// Функции-помошники для форматированного чтения
static inline char parseEscapeSequence(char c)
{
switch(c)
2010-05-28 19:13:55 +00:00
{
2010-06-01 13:35:09 +00:00
case 'b':
return '\b';
case 'f':
return '\f';
case 'n':
return '\n';
case 'r':
return '\r';
case 't':
return '\t';
case '0':
return '\0';
default:
return c;
2010-05-28 19:13:55 +00:00
}
2010-06-01 13:35:09 +00:00
}
2010-05-28 19:13:55 +00:00
2010-06-04 18:25:25 +00:00
static inline void throwReadAfterEOF()
{
throw Exception("Attempt to read after eof", ErrorCodes::ATTEMPT_TO_READ_AFTER_EOF);
}
inline void readChar(char & x, ReadBuffer & buf)
{
if (!buf.eof())
{
x = *buf.position();
++buf.position();
}
else
throwReadAfterEOF();
}
2010-06-01 14:12:28 +00:00
void assertString(const char * s, ReadBuffer & buf);
2010-06-01 13:35:09 +00:00
/// грубо
template <typename T>
void readIntText(T & x, ReadBuffer & buf)
{
bool negative = false;
x = 0;
2010-06-04 18:25:25 +00:00
if (buf.eof())
throwReadAfterEOF();
2010-06-01 13:35:09 +00:00
while (!buf.eof())
{
switch (*buf.position())
2010-05-28 19:13:55 +00:00
{
2010-06-01 13:35:09 +00:00
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.position() - '0';
break;
default:
if (negative)
2010-05-28 19:13:55 +00:00
x = -x;
2010-06-01 13:35:09 +00:00
return;
2010-05-28 19:13:55 +00:00
}
2010-06-01 13:35:09 +00:00
++buf.position();
2010-05-28 19:13:55 +00:00
}
2010-06-01 13:35:09 +00:00
if (negative)
x = -x;
}
/// грубо
template <typename T>
void readFloatText(T & x, ReadBuffer & buf)
{
bool negative = false;
x = 0;
bool after_point = false;
double power_of_ten = 1;
2010-05-28 19:13:55 +00:00
2010-06-04 18:25:25 +00:00
if (buf.eof())
throwReadAfterEOF();
2010-06-01 13:35:09 +00:00
while (!buf.eof())
2010-05-28 19:13:55 +00:00
{
2010-06-01 13:35:09 +00:00
switch (*buf.position())
2010-05-28 19:13:55 +00:00
{
2010-06-01 13:35:09 +00:00
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.position() - '0') * power_of_ten;
}
else
{
x *= 10;
x += *buf.position() - '0';
}
break;
case 'e':
case 'E':
2010-05-28 19:13:55 +00:00
{
2010-06-01 13:35:09 +00:00
++buf.position();
Int32 exponent = 0;
readIntText(exponent, buf);
if (exponent == 0)
{
if (negative)
x = -x;
return;
}
else if (exponent > 0)
{
for (Int32 i = 0; i < exponent; ++i)
2010-05-28 19:13:55 +00:00
x *= 10;
2010-06-01 13:35:09 +00:00
if (negative)
x = -x;
2010-05-28 19:13:55 +00:00
return;
2010-06-01 13:35:09 +00:00
}
else
{
for (Int32 i = 0; i < exponent; ++i)
x /= 10;
if (negative)
x = -x;
return;
}
2010-05-28 19:13:55 +00:00
}
2010-06-01 13:35:09 +00:00
case 'i':
++buf.position();
assertString("nf", buf);
x = std::numeric_limits<T>::infinity();
if (negative)
x = -x;
return;
case 'I':
++buf.position();
assertString("NF", buf);
x = std::numeric_limits<T>::infinity();
if (negative)
x = -x;
return;
case 'n':
++buf.position();
assertString("an", buf);
x = std::numeric_limits<T>::quiet_NaN();
return;
case 'N':
++buf.position();
assertString("AN", buf);
x = std::numeric_limits<T>::quiet_NaN();
return;
default:
if (negative)
x = -x;
2010-05-28 19:13:55 +00:00
return;
}
2010-06-01 13:35:09 +00:00
++buf.position();
2010-05-28 19:13:55 +00:00
}
2010-06-01 13:35:09 +00:00
if (negative)
x = -x;
}
2010-05-28 19:13:55 +00:00
2010-06-01 13:35:09 +00:00
/// грубо; всё до '\n' или '\t'
2010-06-01 14:12:28 +00:00
void readString(String & s, ReadBuffer & buf);
2010-05-28 19:13:55 +00:00
2010-06-01 14:12:28 +00:00
void readEscapedString(String & s, ReadBuffer & buf);
2010-05-28 19:13:55 +00:00
2010-06-01 14:12:28 +00:00
void readQuotedString(String & s, ReadBuffer & buf);
2010-05-28 19:13:55 +00:00
}
#endif