Index: src/shared/Communication.h |
=================================================================== |
--- a/src/shared/Communication.h |
+++ b/src/shared/Communication.h |
@@ -1,19 +1,126 @@ |
#ifndef COMMUNICATION_H |
#define COMMUNICATION_H |
+#include <sstream> |
+#include <stdint.h> |
#include <string> |
#include <vector> |
#include <Windows.h> |
namespace Communication |
{ |
extern const std::wstring pipeName; |
const int bufferSize = 1024; |
- std::string MarshalStrings(const std::vector<std::string>& strings); |
- std::vector<std::string> UnmarshalStrings(const std::string& message); |
- std::string ReadMessage(HANDLE pipe); |
- void WriteMessage(HANDLE pipe, const std::string& message); |
+ enum ValueType {TYPE_STRING, TYPE_WSTRING, TYPE_INT64, TYPE_INT32, TYPE_BOOL}; |
+ |
+ class InputBuffer |
+ { |
+ public: |
+ InputBuffer(const std::string& data) : buffer(data) {} |
+ InputBuffer& operator>>(std::string& value) { return ReadString(value, TYPE_STRING); } |
+ InputBuffer& operator>>(std::wstring& value) { return ReadString(value, TYPE_WSTRING); } |
+ InputBuffer& operator>>(int64_t& value) { return Read(value, TYPE_INT64); } |
+ InputBuffer& operator>>(int32_t& value) { return Read(value, TYPE_INT32); } |
+ InputBuffer& operator>>(bool& value) { return Read(value, TYPE_BOOL); } |
+ private: |
+ std::istringstream buffer; |
+ |
+ template<class T> |
+ InputBuffer& ReadString(T& value, ValueType expectedType) |
Felix Dahlke
2013/06/03 11:25:41
I'd just call this "ReadArray", since it would wor
Wladimir Palant
2013/06/03 11:53:00
Nope - this is expecting std::base_string rather t
|
+ { |
+ int32_t type; |
Felix Dahlke
2013/06/03 11:25:41
Should be ValueType, not int32_t I guess?
Wladimir Palant
2013/06/03 11:53:00
I'm not sure whether the internal representation o
Felix Dahlke
2013/06/03 12:02:09
Fair enough. But I'd want a typedef then :)
|
+ ReadBinary(type); |
+ if (type != expectedType) |
+ throw new std::runtime_error("Unexpected type found in input buffer"); |
+ |
+ uint32_t length; |
Felix Dahlke
2013/06/03 11:25:41
Would prefer a typedef for this.
|
+ ReadBinary(length); |
+ |
+ std::auto_ptr<T::value_type> data(new T::value_type[length]); |
+ buffer.read(reinterpret_cast<char*>(data.get()), sizeof(T::value_type) * length); |
+ if (buffer.fail()) |
+ throw new std::runtime_error("Unexpected end of input buffer"); |
+ |
+ value.assign(data.get(), length); |
Felix Dahlke
2013/06/03 11:25:41
Based on some quick searching, only std::basic_str
Wladimir Palant
2013/06/03 11:53:00
See above - this function is used both for std::st
Felix Dahlke
2013/06/03 12:02:09
I thought basic_string was a base class, but it's
|
+ return *this; |
+ } |
+ |
+ template<class T> |
+ InputBuffer& Read(T& value, ValueType expectedType) |
+ { |
+ int32_t type; |
Felix Dahlke
2013/06/03 11:25:41
Like above, I think this should be ValueType
|
+ ReadBinary(type); |
+ if (type != expectedType) |
+ throw new std::runtime_error("Unexpected type found in input buffer"); |
+ |
+ ReadBinary(value); |
+ return *this; |
+ } |
+ |
+ template<class T> |
+ void ReadBinary(T& value) |
+ { |
+ buffer.read(reinterpret_cast<char*>(&value), sizeof(T)); |
+ if (buffer.fail()) |
+ throw new std::runtime_error("Unexpected end of input buffer"); |
+ } |
+ }; |
+ |
+ class OutputBuffer |
+ { |
+ public: |
+ OutputBuffer() {} |
+ |
+ // Explicit copy constructor to allow returning OutputBuffer by value |
Felix Dahlke
2013/06/03 11:25:41
I find this kind of obvious :P
Wladimir Palant
2013/06/03 11:53:00
It wasn't to me :)
|
+ OutputBuffer(const OutputBuffer& copy) : buffer(copy.buffer.str()) {} |
Felix Dahlke
2013/06/03 11:25:41
We should implement the copy assign operator as we
Wladimir Palant
2013/06/03 11:53:00
I think I'm fine with copy assignment failing - I
Felix Dahlke
2013/06/03 12:02:09
Assignment won't fail if the copy assignment opera
|
+ |
+ std::string Get() |
+ { |
+ return buffer.str(); |
+ } |
+ OutputBuffer& operator<<(const std::string& value) { return WriteString(value, TYPE_STRING); } |
+ OutputBuffer& operator<<(const std::wstring& value) { return WriteString(value, TYPE_WSTRING); } |
+ OutputBuffer& operator<<(int64_t value) { return Write(value, TYPE_INT64); } |
+ OutputBuffer& operator<<(int32_t value) { return Write(value, TYPE_INT32); } |
+ OutputBuffer& operator<<(bool value) { return Write(value, TYPE_BOOL); } |
+ private: |
+ std::ostringstream buffer; |
+ |
+ template<class T> |
+ OutputBuffer& WriteString(const T& value, int32_t type) |
Felix Dahlke
2013/06/03 11:25:41
Should be ValueType instead of int32_t I guess.
|
+ { |
+ WriteBinary(type); |
+ |
+ uint32_t length = value.size(); |
+ WriteBinary(length); |
+ |
+ buffer.write(reinterpret_cast<const char*>(value.c_str()), sizeof(T::value_type) * length); |
Felix Dahlke
2013/06/03 11:25:41
AFAIK, only std::basic_string has c_str(). So no n
Wladimir Palant
2013/06/03 11:53:00
See above - both std::string and std::wstring are
|
+ if (buffer.fail()) |
+ throw new std::runtime_error("Unexpected error writing to output buffer"); |
+ |
+ return *this; |
+ } |
+ |
+ template<class T> |
+ OutputBuffer& Write(const T value, int32_t type) |
Felix Dahlke
2013/06/03 11:25:41
Should be ValueType instead of int32_t I think. Al
|
+ { |
+ WriteBinary(type); |
+ WriteBinary(value); |
+ return *this; |
+ } |
+ |
+ template<class T> |
+ void WriteBinary(const T& value) |
+ { |
+ buffer.write(reinterpret_cast<const char*>(&value), sizeof(T)); |
+ if (buffer.fail()) |
+ throw new std::runtime_error("Unexpected error writing to output buffer"); |
+ } |
+ }; |
+ |
+ InputBuffer ReadMessage(HANDLE pipe); |
+ void WriteMessage(HANDLE pipe, OutputBuffer& message); |
} |
#endif |