src/StringDataType.h
author František Kučera <franta-hg@frantovo.cz>
Sat, 14 Jul 2018 23:24:22 +0200
branchv_0
changeset 7 489e52138771
permissions -rw-r--r--
add data type and catalog classes from the prototype

#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;
	}

};

}