# HG changeset patch # User František Kučera # Date 1532272765 -7200 # Node ID 3613617d3076c5a36099417fa238a388d4f586e1 # Parent 8fd6c4d44071d12dafd5e7f25d8789b4bba723c6 writeAttribute() with raw pointer and type_info diff -r 8fd6c4d44071 -r 3613617d3076 include/RelationalWriter.h --- a/include/RelationalWriter.h Sun Jul 22 10:26:22 2018 +0200 +++ b/include/RelationalWriter.h Sun Jul 22 17:19:25 2018 +0200 @@ -22,6 +22,12 @@ virtual void startRelation(string_t name, std::vector> attributes, boolean_t writeHeader) = 0; virtual void writeRecord(std::vector attributes) = 0; + + // TODO: write bitmap + attribute: + // virtual void writeBitmap(...) = 0; + // virtual void writeAttribute(string_t attribute) = 0; + + virtual void writeAttribute(const void* value, const std::type_info& type) = 0; }; diff -r 8fd6c4d44071 -r 3613617d3076 src/DataTypeWriter.h --- a/src/DataTypeWriter.h Sun Jul 22 10:26:22 2018 +0200 +++ b/src/DataTypeWriter.h Sun Jul 22 17:19:25 2018 +0200 @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "DataTypeWriterBase.h" namespace relpipe { @@ -16,6 +19,17 @@ virtual void writeValue(std::ostream& output, const T& value) = 0; + void writeRaw(std::ostream& output, const void * value, const std::type_info& type) override { + if (type == typeid (T)) { + const T v = *(static_cast(value)); + writeValue(output, v); + } else { + wstringstream message; + message << L"Data type in writeRaw() does not match – got: " << type.name() << " but expected: " << typeid (T).name(); + throw RelpipeWriterException(message.str()); + } + } + void writeString(std::ostream& output, const string_t &stringValue) override { writeValue(output, toValue(stringValue)); } diff -r 8fd6c4d44071 -r 3613617d3076 src/DataTypeWriterBase.h --- a/src/DataTypeWriterBase.h Sun Jul 22 10:26:22 2018 +0200 +++ b/src/DataTypeWriterBase.h Sun Jul 22 17:19:25 2018 +0200 @@ -32,6 +32,15 @@ virtual void writeString(std::ostream& output, const string_t &stringValue) = 0; /** + * @param output output stream, should be at position where the value is to be written; the stream will not be closed not flushed after writing + * @param value raw pointer to the value, must exactly match data type of this writer + * @param type used as a safety mechanism to avoid wrong pointer interpretation; + * should be called in this way: writeRaw(output, valuePointer, typeid(valuePointer)); + * if the type does not match, the RelpipeWriterException is thrown + */ + virtual void writeRaw(std::ostream& output, const void * value, const std::type_info& type) = 0; + + /** * @param dataType data type code as defined in DDP L0 * @return whether this class supports conversions of this type */ diff -r 8fd6c4d44071 -r 3613617d3076 src/StreamRelationalWriter.h --- a/src/StreamRelationalWriter.h Sun Jul 22 10:26:22 2018 +0200 +++ b/src/StreamRelationalWriter.h Sun Jul 22 17:19:25 2018 +0200 @@ -28,6 +28,10 @@ * count of columns in the current table */ integer_t columnCount; + /** + * number of column (0 = first) that will be written; after writing, the number is increased and prepared for next one + */ + integer_t currentColumn; /** * types of columns in the current table @@ -36,7 +40,12 @@ void writeString(const string_t &stringValue, const TypeId typeId) { for (DataTypeWriterBase* writer : writers) if (writer->supports(typeId)) return writer->writeString(output, stringValue); - throw RelpipeWriterException(L"Unsupported data type: " + static_cast(typeId)); + throw RelpipeWriterException(L"Unsupported data type: " + static_cast (typeId)); + } + + void writeRaw(const void* value, const type_info& typeInfo, const TypeId typeId) { + for (DataTypeWriterBase* writer : writers) if (writer->supports(typeId)) return writer->writeRaw(output, value, typeInfo); + throw RelpipeWriterException(L"Unsupported data type: " + static_cast (typeId)); } public: @@ -52,12 +61,13 @@ string_t toTypeCode(const TypeId typeId) override { for (DataTypeWriterBase* writer : writers) if (writer->supports(typeId)) return writer->getTypeCode(); - throw RelpipeWriterException(L"Unsupported data type: " + static_cast(typeId)); + throw RelpipeWriterException(L"Unsupported data type: " + static_cast (typeId)); } - + void startRelation(string_t name, std::vector > attributes, boolean_t writeHeader) override { string_t tableName = name; columnCount = attributes.size(); + currentColumn = 0; // Write table name and column count: integerWriter.writeValue(output, DATA_PART_START); @@ -76,7 +86,7 @@ // Write column types: for (size_t c = 0; c < columnCount; c++) { TypeId typeId = attributes[c].second; - integerWriter.writeValue(output, static_cast(typeId)); + integerWriter.writeValue(output, static_cast (typeId)); columnTypes[c] = typeId; } @@ -84,8 +94,9 @@ void writeRecord(std::vector attributes) override { // FIXME: check vector size + // FIXME: check currentColumn == 0 for (size_t c = 0; c < columnCount; c++) { - // TODO: support multiple rows in a single method call? + // TODO: do not support multiple rows in a single method call if (c % columnCount == 0) { integerWriter.writeValue(output, DATA_PART_ROW); } @@ -96,6 +107,12 @@ } } + void writeAttribute(const void* value, const std::type_info& type) override { + if (currentColumn == 0) integerWriter.writeValue(output, DATA_PART_ROW); + writeRaw(value, type, columnTypes[currentColumn]); + if (++currentColumn == columnCount) currentColumn = 0; + } + }; }