#pragma once
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include <locale>
#include <codecvt>
#include "DataType.h"
#include "RelpipeException.h"
#include "IntegerDataType.h"
using namespace std;
namespace rp_prototype {
/**
* The prototype does not recognize any encoding,
* it just works with c++ strings in encoding default to given platform.
* In the real implementation of relational pipes, there will be DataTypes for particular encodings.
*/
class StringDataType : public DataType<wstring> {
private:
IntegerDataType integerType;
wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
public:
StringDataType() : DataType<wstring>(DATA_TYPE_ID_STRING, DATA_TYPE_CODE_STRING) {
}
wstring readValue(istream &input) override {
integer_t length = integerType.readValue(input);
// TODO: check maximum length of single field
// if (length > 4000) throw RelpipeException("data too long", EXIT_CODE_DATA_ERROR);
vector<char> buf(length);
input.read(buf.data(), length);
if (input.good()) {
return convertor.from_bytes(string(buf.data(), length));
} else {
throw RelpipeException(L"Error while reading string from the stream.", EXIT_CODE_DATA_ERROR);
}
}
void writeValue(ostream &output, const wstring &value) override {
string s = convertor.to_bytes(value);
integerType.writeValue(output, s.length());
output << s.c_str();
}
wstring toValue(const wstring &stringValue) override {
return stringValue;
}
wstring toString(const wstring &value) override {
return value;
}
};
}