mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-19 16:20:50 +00:00
dbms: development.
This commit is contained in:
parent
8e0a378c90
commit
7a360b0cd6
@ -2,6 +2,8 @@
|
||||
#define DB_VARINT_H
|
||||
|
||||
#include <DB/Core/Types.h>
|
||||
#include <DB/Core/ReadBuffer.h>
|
||||
#include <DB/Core/WriteBuffer.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -10,10 +12,12 @@ namespace DB
|
||||
|
||||
/** Записать UInt64 в формате переменной длины (base128) */
|
||||
void writeVarUInt(UInt64 x, std::ostream & ostr);
|
||||
void writeVarUInt(UInt64 x, WriteBuffer & ostr);
|
||||
|
||||
|
||||
/** Прочитать UInt64, записанный в формате переменной длины (base128) */
|
||||
void readVarUInt(UInt64 & x, std::istream & istr);
|
||||
void readVarUInt(UInt64 & x, ReadBuffer & istr);
|
||||
|
||||
|
||||
/** Получить длину UInt64 в формате VarUInt */
|
||||
@ -21,28 +25,31 @@ size_t getLengthOfVarUInt(UInt64 x);
|
||||
|
||||
|
||||
/** Записать Int64 в формате переменной длины (base128) */
|
||||
inline void writeVarInt(Int64 x, std::ostream & ostr)
|
||||
template <typename OUT>
|
||||
inline void writeVarInt(Int64 x, OUT & ostr)
|
||||
{
|
||||
writeVarUInt(static_cast<UInt64>((x << 1) ^ (x >> 63)), ostr);
|
||||
}
|
||||
|
||||
|
||||
/** Прочитать Int64, записанный в формате переменной длины (base128) */
|
||||
inline void readVarInt(Int64 & x, std::istream & istr)
|
||||
template <typename IN>
|
||||
inline void readVarInt(Int64 & x, IN & istr)
|
||||
{
|
||||
readVarUInt(*reinterpret_cast<UInt64*>(&x), istr);
|
||||
x = (static_cast<UInt64>(x) >> 1) ^ -(x & 1);
|
||||
}
|
||||
|
||||
|
||||
template <typename T> inline void writeVarT(T x, std::ostream & ostr);
|
||||
template <> inline void writeVarT<UInt64>(UInt64 x, std::ostream & ostr) { writeVarUInt(x, ostr); }
|
||||
template <> inline void writeVarT<Int64>(Int64 x, std::ostream & ostr) { writeVarInt(x, ostr); }
|
||||
|
||||
template <typename T> inline void readVarT(T & x, std::istream & istr);
|
||||
template <> inline void readVarT<UInt64>(UInt64 & x, std::istream & istr) { readVarUInt(x, istr); }
|
||||
template <> inline void readVarT<Int64>(Int64 & x, std::istream & istr) { readVarInt(x, istr); }
|
||||
inline void writeVarT(UInt64 x, std::ostream & ostr) { writeVarUInt(x, ostr); }
|
||||
inline void writeVarT(Int64 x, std::ostream & ostr) { writeVarInt(x, ostr); }
|
||||
inline void writeVarT(UInt64 x, WriteBuffer & ostr) { writeVarUInt(x, ostr); }
|
||||
inline void writeVarT(Int64 x, WriteBuffer & ostr) { writeVarInt(x, ostr); }
|
||||
|
||||
inline void readVarT(UInt64 & x, std::istream & istr) { readVarUInt(x, istr); }
|
||||
inline void readVarT(Int64 & x, std::istream & istr) { readVarInt(x, istr); }
|
||||
inline void readVarT(UInt64 & x, ReadBuffer & istr) { readVarUInt(x, istr); }
|
||||
inline void readVarT(Int64 & x, ReadBuffer & istr) { readVarInt(x, istr); }
|
||||
|
||||
}
|
||||
|
||||
|
@ -113,16 +113,7 @@ static inline char parseEscapeSequence(char c)
|
||||
}
|
||||
}
|
||||
|
||||
static void assertString(const char * s, ReadBuffer & buf)
|
||||
{
|
||||
for (; *s; ++s)
|
||||
{
|
||||
if (buf.eof() || *buf.position() != *s)
|
||||
throw Exception(String("Cannot parse input: expected ") + s, ErrorCodes::CANNOT_PARSE_INPUT_ASSERTION_FAILED);
|
||||
++buf.position();
|
||||
}
|
||||
}
|
||||
|
||||
void assertString(const char * s, ReadBuffer & buf);
|
||||
|
||||
/// грубо
|
||||
template <typename T>
|
||||
@ -270,89 +261,11 @@ void readFloatText(T & x, ReadBuffer & buf)
|
||||
}
|
||||
|
||||
/// грубо; всё до '\n' или '\t'
|
||||
void readString(String & s, ReadBuffer & buf)
|
||||
{
|
||||
s = "";
|
||||
while (!buf.eof())
|
||||
{
|
||||
size_t bytes = 0;
|
||||
for (; buf.position() + bytes != buf.buffer().end(); ++bytes)
|
||||
if (buf.position()[bytes] == '\t' || buf.position()[bytes] == '\n')
|
||||
break;
|
||||
void readString(String & s, ReadBuffer & buf);
|
||||
|
||||
s.append(buf.position(), bytes);
|
||||
buf.position() += bytes;
|
||||
void readEscapedString(String & s, ReadBuffer & buf);
|
||||
|
||||
if (buf.position() != buf.buffer().end())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void readEscapedString(String & s, ReadBuffer & buf)
|
||||
{
|
||||
s = "";
|
||||
while (!buf.eof())
|
||||
{
|
||||
size_t bytes = 0;
|
||||
for (; buf.position() + bytes != buf.buffer().end(); ++bytes)
|
||||
if (buf.position()[bytes] == '\\' || buf.position()[bytes] == '\t' || buf.position()[bytes] == '\n')
|
||||
break;
|
||||
|
||||
s.append(buf.position(), bytes);
|
||||
buf.position() += bytes;
|
||||
|
||||
if (*buf.position() == '\t' || *buf.position() == '\n')
|
||||
return;
|
||||
|
||||
if (*buf.position() == '\\')
|
||||
{
|
||||
++buf.position();
|
||||
if (buf.eof())
|
||||
throw Exception("Cannot parse escape sequence", ErrorCodes::CANNOT_PARSE_ESCAPE_SEQUENCE);
|
||||
s += parseEscapeSequence(*buf.position());
|
||||
++buf.position();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void readQuotedString(String & s, ReadBuffer & buf)
|
||||
{
|
||||
s = "";
|
||||
|
||||
if (buf.eof() || *buf.position() != '\'')
|
||||
throw Exception("Cannot parse quoted string: expected opening single quote",
|
||||
ErrorCodes::CANNOT_PARSE_QUOTED_STRING);
|
||||
++buf.position();
|
||||
|
||||
while (!buf.eof())
|
||||
{
|
||||
size_t bytes = 0;
|
||||
for (; buf.position() + bytes != buf.buffer().end(); ++bytes)
|
||||
if (buf.position()[bytes] == '\\' || buf.position()[bytes] == '\'')
|
||||
break;
|
||||
|
||||
s.append(buf.position(), bytes);
|
||||
buf.position() += bytes;
|
||||
|
||||
if (*buf.position() == '\'')
|
||||
{
|
||||
++buf.position();
|
||||
return;
|
||||
}
|
||||
|
||||
if (*buf.position() == '\\')
|
||||
{
|
||||
++buf.position();
|
||||
if (buf.eof())
|
||||
throw Exception("Cannot parse escape sequence", ErrorCodes::CANNOT_PARSE_ESCAPE_SEQUENCE);
|
||||
s += parseEscapeSequence(*buf.position());
|
||||
++buf.position();
|
||||
}
|
||||
}
|
||||
|
||||
throw Exception("Cannot parse quoted string: expected closing single quote",
|
||||
ErrorCodes::CANNOT_PARSE_QUOTED_STRING);
|
||||
}
|
||||
void readQuotedString(String & s, ReadBuffer & buf);
|
||||
|
||||
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ protected:
|
||||
|
||||
/// Функции-помошники для форматированной записи
|
||||
|
||||
void writeChar(char x, WriteBuffer & buf)
|
||||
inline void writeChar(char x, WriteBuffer & buf)
|
||||
{
|
||||
buf.nextIfAtEnd();
|
||||
*buf.position() = x;
|
||||
@ -100,16 +100,7 @@ void writeChar(char x, WriteBuffer & buf)
|
||||
|
||||
|
||||
template <typename T> struct IntFormat { static const char * format; };
|
||||
template <> const char * IntFormat<Int8>::format = "%hhi";
|
||||
template <> const char * IntFormat<Int16>::format = "%hi";
|
||||
template <> const char * IntFormat<Int32>::format = "%li";
|
||||
template <> const char * IntFormat<Int64>::format = "%lli";
|
||||
template <> const char * IntFormat<UInt8>::format = "%hhi";
|
||||
template <> const char * IntFormat<UInt16>::format = "%hi";
|
||||
template <> const char * IntFormat<UInt32>::format = "%li";
|
||||
template <> const char * IntFormat<UInt64>::format = "%lli";
|
||||
|
||||
/// грубо
|
||||
template <typename T>
|
||||
void writeIntText(T x, WriteBuffer & buf)
|
||||
{
|
||||
@ -135,57 +126,15 @@ void writeFloatText(T x, WriteBuffer & buf, unsigned precision = DEFAULT_FLOAT_P
|
||||
buf.write(tmp, res - 1);
|
||||
}
|
||||
|
||||
void writeString(const String & s, WriteBuffer & buf)
|
||||
inline void writeString(const String & s, WriteBuffer & buf)
|
||||
{
|
||||
buf.write(s.data(), s.size());
|
||||
}
|
||||
|
||||
/// предполагается, что строка в оперативке хранится непрерывно, и \0-terminated.
|
||||
void writeEscapedString(const String & s, WriteBuffer & buf)
|
||||
{
|
||||
for (String::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
{
|
||||
switch (*it)
|
||||
{
|
||||
case '\b':
|
||||
writeChar('\\', buf);
|
||||
writeChar('b', buf);
|
||||
break;
|
||||
case '\f':
|
||||
writeChar('\\', buf);
|
||||
writeChar('f', buf);
|
||||
break;
|
||||
case '\n':
|
||||
writeChar('\\', buf);
|
||||
writeChar('n', buf);
|
||||
break;
|
||||
case '\r':
|
||||
writeChar('\\', buf);
|
||||
writeChar('r', buf);
|
||||
break;
|
||||
case '\t':
|
||||
writeChar('\\', buf);
|
||||
writeChar('t', buf);
|
||||
break;
|
||||
case '\0':
|
||||
writeChar('\\', buf);
|
||||
writeChar('0', buf);
|
||||
break;
|
||||
case '\'':
|
||||
writeChar('\\', buf);
|
||||
writeChar('\'', buf);
|
||||
break;
|
||||
case '\\':
|
||||
writeChar('\\', buf);
|
||||
writeChar('\\', buf);
|
||||
break;
|
||||
default:
|
||||
writeChar(*it, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
void writeEscapedString(const String & s, WriteBuffer & buf);
|
||||
|
||||
void writeQuotedString(const String & s, WriteBuffer & buf)
|
||||
inline void writeQuotedString(const String & s, WriteBuffer & buf)
|
||||
{
|
||||
writeChar('\'', buf);
|
||||
writeEscapedString(s, buf);
|
||||
|
@ -25,12 +25,12 @@ class IDataTypeNumberVariable : public IDataTypeNumber<FieldType>
|
||||
public:
|
||||
void serializeBinary(const Field & field, std::ostream & ostr) const
|
||||
{
|
||||
writeVarT<typename ColumnType::value_type>(boost::get<FieldType>(field), ostr);
|
||||
writeVarT(static_cast<typename ColumnType::value_type>(boost::get<FieldType>(field)), ostr);
|
||||
}
|
||||
|
||||
void deserializeBinary(Field & field, std::istream & istr) const
|
||||
{
|
||||
readVarT<typename ColumnType::value_type>(boost::get<FieldType>(field), istr);
|
||||
readVarT(static_cast<typename ColumnType::value_type &>(boost::get<FieldType>(field)), istr);
|
||||
}
|
||||
|
||||
void serializeBinary(const IColumn & column, std::ostream & ostr) const
|
||||
@ -38,7 +38,7 @@ public:
|
||||
const typename ColumnType::Container_t & x = dynamic_cast<const ColumnType &>(column).getData();
|
||||
size_t size = x.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
writeVarT<typename ColumnType::value_type>(x[i], ostr);
|
||||
writeVarT(x[i], ostr);
|
||||
}
|
||||
|
||||
void deserializeBinary(IColumn & column, std::istream & istr, size_t limit) const
|
||||
@ -47,7 +47,7 @@ public:
|
||||
x.resize(limit);
|
||||
for (size_t i = 0; i < limit; ++i)
|
||||
{
|
||||
readVarT<typename ColumnType::value_type>(x[i], istr);
|
||||
readVarT(x[i], istr);
|
||||
|
||||
if (istr.eof())
|
||||
{
|
||||
|
100
dbms/src/Core/ReadBuffer.cpp
Normal file
100
dbms/src/Core/ReadBuffer.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include <DB/Core/ReadBuffer.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void assertString(const char * s, ReadBuffer & buf)
|
||||
{
|
||||
for (; *s; ++s)
|
||||
{
|
||||
if (buf.eof() || *buf.position() != *s)
|
||||
throw Exception(String("Cannot parse input: expected ") + s, ErrorCodes::CANNOT_PARSE_INPUT_ASSERTION_FAILED);
|
||||
++buf.position();
|
||||
}
|
||||
}
|
||||
|
||||
void readString(String & s, ReadBuffer & buf)
|
||||
{
|
||||
s = "";
|
||||
while (!buf.eof())
|
||||
{
|
||||
size_t bytes = 0;
|
||||
for (; buf.position() + bytes != buf.buffer().end(); ++bytes)
|
||||
if (buf.position()[bytes] == '\t' || buf.position()[bytes] == '\n')
|
||||
break;
|
||||
|
||||
s.append(buf.position(), bytes);
|
||||
buf.position() += bytes;
|
||||
|
||||
if (buf.position() != buf.buffer().end())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void readEscapedString(String & s, ReadBuffer & buf)
|
||||
{
|
||||
s = "";
|
||||
while (!buf.eof())
|
||||
{
|
||||
size_t bytes = 0;
|
||||
for (; buf.position() + bytes != buf.buffer().end(); ++bytes)
|
||||
if (buf.position()[bytes] == '\\' || buf.position()[bytes] == '\t' || buf.position()[bytes] == '\n')
|
||||
break;
|
||||
|
||||
s.append(buf.position(), bytes);
|
||||
buf.position() += bytes;
|
||||
|
||||
if (*buf.position() == '\t' || *buf.position() == '\n')
|
||||
return;
|
||||
|
||||
if (*buf.position() == '\\')
|
||||
{
|
||||
++buf.position();
|
||||
if (buf.eof())
|
||||
throw Exception("Cannot parse escape sequence", ErrorCodes::CANNOT_PARSE_ESCAPE_SEQUENCE);
|
||||
s += parseEscapeSequence(*buf.position());
|
||||
++buf.position();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void readQuotedString(String & s, ReadBuffer & buf)
|
||||
{
|
||||
s = "";
|
||||
|
||||
if (buf.eof() || *buf.position() != '\'')
|
||||
throw Exception("Cannot parse quoted string: expected opening single quote",
|
||||
ErrorCodes::CANNOT_PARSE_QUOTED_STRING);
|
||||
++buf.position();
|
||||
|
||||
while (!buf.eof())
|
||||
{
|
||||
size_t bytes = 0;
|
||||
for (; buf.position() + bytes != buf.buffer().end(); ++bytes)
|
||||
if (buf.position()[bytes] == '\\' || buf.position()[bytes] == '\'')
|
||||
break;
|
||||
|
||||
s.append(buf.position(), bytes);
|
||||
buf.position() += bytes;
|
||||
|
||||
if (*buf.position() == '\'')
|
||||
{
|
||||
++buf.position();
|
||||
return;
|
||||
}
|
||||
|
||||
if (*buf.position() == '\\')
|
||||
{
|
||||
++buf.position();
|
||||
if (buf.eof())
|
||||
throw Exception("Cannot parse escape sequence", ErrorCodes::CANNOT_PARSE_ESCAPE_SEQUENCE);
|
||||
s += parseEscapeSequence(*buf.position());
|
||||
++buf.position();
|
||||
}
|
||||
}
|
||||
|
||||
throw Exception("Cannot parse quoted string: expected closing single quote",
|
||||
ErrorCodes::CANNOT_PARSE_QUOTED_STRING);
|
||||
}
|
||||
|
||||
}
|
60
dbms/src/Core/WriteBuffer.cpp
Normal file
60
dbms/src/Core/WriteBuffer.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#include <DB/Core/WriteBuffer.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
template <> const char * IntFormat<Int8>::format = "%hhi";
|
||||
template <> const char * IntFormat<Int16>::format = "%hi";
|
||||
template <> const char * IntFormat<Int32>::format = "%li";
|
||||
template <> const char * IntFormat<Int64>::format = "%lli";
|
||||
template <> const char * IntFormat<UInt8>::format = "%hhi";
|
||||
template <> const char * IntFormat<UInt16>::format = "%hi";
|
||||
template <> const char * IntFormat<UInt32>::format = "%li";
|
||||
template <> const char * IntFormat<UInt64>::format = "%lli";
|
||||
|
||||
|
||||
void writeEscapedString(const String & s, WriteBuffer & buf)
|
||||
{
|
||||
for (String::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
{
|
||||
switch (*it)
|
||||
{
|
||||
case '\b':
|
||||
writeChar('\\', buf);
|
||||
writeChar('b', buf);
|
||||
break;
|
||||
case '\f':
|
||||
writeChar('\\', buf);
|
||||
writeChar('f', buf);
|
||||
break;
|
||||
case '\n':
|
||||
writeChar('\\', buf);
|
||||
writeChar('n', buf);
|
||||
break;
|
||||
case '\r':
|
||||
writeChar('\\', buf);
|
||||
writeChar('r', buf);
|
||||
break;
|
||||
case '\t':
|
||||
writeChar('\\', buf);
|
||||
writeChar('t', buf);
|
||||
break;
|
||||
case '\0':
|
||||
writeChar('\\', buf);
|
||||
writeChar('0', buf);
|
||||
break;
|
||||
case '\'':
|
||||
writeChar('\\', buf);
|
||||
writeChar('\'', buf);
|
||||
break;
|
||||
case '\\':
|
||||
writeChar('\\', buf);
|
||||
writeChar('\\', buf);
|
||||
break;
|
||||
default:
|
||||
writeChar(*it, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user