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
|