#pragma once #include #include #include #include namespace DB { /** Реализует часть интерфейса IDataType, общую для всяких чисел фиксированной ширины * - ввод и вывод в текстовом и бинарном виде. * Остаётся лишь чисто виртуальный метод getName() и clone(). * * Параметры: FieldType - тип единичного значения, ColumnType - тип столбца со значениями. * (см. Core/Field.h, Columns/IColumn.h) */ template class IDataTypeNumberFixed : public IDataTypeNumber { typedef IDataType::WriteCallback WriteCallback; public: /** Формат платформозависимый (зависит от представления данных в памяти). */ void serializeBinary(const Field & field, WriteBuffer & ostr) const { /// ColumnType::value_type - более узкий тип. Например, UInt8, когда тип Field - UInt64 typename ColumnType::value_type x = boost::get::Type>(field); writeBinary(x, ostr); } void deserializeBinary(Field & field, ReadBuffer & istr) const { typename ColumnType::value_type x; readBinary(x, istr); field = typename NearestFieldType::Type(x); } void serializeBinary(const IColumn & column, WriteBuffer & ostr, WriteCallback callback = WriteCallback()) const { const typename ColumnType::Container_t & x = dynamic_cast(column).getData(); size_t prev_callback_point = 0; size_t next_callback_point = 0; size_t size = x.size(); while (next_callback_point < size) { next_callback_point = callback ? callback() : size; if (next_callback_point > size) next_callback_point = size; ostr.write(reinterpret_cast(&x[prev_callback_point]), sizeof(typename ColumnType::value_type) * (next_callback_point - prev_callback_point)); } } void deserializeBinary(IColumn & column, ReadBuffer & istr, size_t limit) const { typename ColumnType::Container_t & x = dynamic_cast(column).getData(); x.resize(limit); size_t size = istr.read(reinterpret_cast(&x[0]), sizeof(typename ColumnType::value_type) * limit); x.resize(size / sizeof(typename ColumnType::value_type)); } ColumnPtr createColumn() const { return new ColumnType; } ColumnPtr createConstColumn(size_t size, const Field & field) const { return new ColumnConst(size, boost::get::Type>(field)); } }; }