Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 #ifndef COMMUNICATION_H | 1 #ifndef COMMUNICATION_H |
2 #define COMMUNICATION_H | 2 #define COMMUNICATION_H |
3 | 3 |
4 #include <memory> | |
4 #include <sstream> | 5 #include <sstream> |
6 #include <stdexcept> | |
5 #include <stdint.h> | 7 #include <stdint.h> |
6 #include <string> | 8 #include <string> |
7 #include <vector> | 9 #include <vector> |
8 #include <Windows.h> | 10 #include <Windows.h> |
9 | 11 |
10 namespace Communication | 12 namespace Communication |
11 { | 13 { |
12 extern const std::wstring pipeName; | 14 extern const std::wstring pipeName; |
13 const int bufferSize = 1024; | 15 const int bufferSize = 1024; |
14 | 16 |
15 enum ValueType {TYPE_STRING, TYPE_WSTRING, TYPE_INT64, TYPE_INT32, TYPE_BOOL}; | 17 enum {TYPE_STRING, TYPE_WSTRING, TYPE_INT64, TYPE_INT32, TYPE_BOOL}; |
18 typedef int32_t ValueType; | |
19 typedef uint32_t SizeType; | |
16 | 20 |
17 class InputBuffer | 21 class InputBuffer |
18 { | 22 { |
19 public: | 23 public: |
20 InputBuffer(const std::string& data) : buffer(data) {} | 24 InputBuffer(const std::string& data) : buffer(data), hasType(false) {} |
21 InputBuffer& operator>>(std::string& value) { return ReadString(value, TYPE_ STRING); } | 25 InputBuffer& operator>>(std::string& value) { return ReadString(value, TYPE_ STRING); } |
22 InputBuffer& operator>>(std::wstring& value) { return ReadString(value, TYPE _WSTRING); } | 26 InputBuffer& operator>>(std::wstring& value) { return ReadString(value, TYPE _WSTRING); } |
23 InputBuffer& operator>>(int64_t& value) { return Read(value, TYPE_INT64); } | 27 InputBuffer& operator>>(int64_t& value) { return Read(value, TYPE_INT64); } |
24 InputBuffer& operator>>(int32_t& value) { return Read(value, TYPE_INT32); } | 28 InputBuffer& operator>>(int32_t& value) { return Read(value, TYPE_INT32); } |
25 InputBuffer& operator>>(bool& value) { return Read(value, TYPE_BOOL); } | 29 InputBuffer& operator>>(bool& value) { return Read(value, TYPE_BOOL); } |
26 private: | 30 private: |
27 std::istringstream buffer; | 31 std::istringstream buffer; |
32 ValueType currentType; | |
33 bool hasType; | |
34 | |
35 void CheckType(ValueType expectedType) | |
36 { | |
37 if (!hasType) | |
38 ReadBinary(currentType); | |
39 | |
40 if (currentType != expectedType) | |
41 { | |
42 // Make sure we don't attempt to read the type again | |
43 hasType = true; | |
44 throw new std::runtime_error("Unexpected type found in input buffer"); | |
45 } | |
46 else | |
47 hasType = false; | |
48 } | |
28 | 49 |
29 template<class T> | 50 template<class T> |
30 InputBuffer& ReadString(T& value, ValueType expectedType) | 51 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
| |
31 { | 52 { |
32 int32_t type; | 53 CheckType(expectedType); |
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 :)
| |
33 ReadBinary(type); | |
34 if (type != expectedType) | |
35 throw new std::runtime_error("Unexpected type found in input buffer"); | |
36 | 54 |
37 uint32_t length; | 55 SizeType length; |
Felix Dahlke
2013/06/03 11:25:41
Would prefer a typedef for this.
| |
38 ReadBinary(length); | 56 ReadBinary(length); |
39 | 57 |
40 std::auto_ptr<T::value_type> data(new T::value_type[length]); | 58 std::auto_ptr<T::value_type> data(new T::value_type[length]); |
41 buffer.read(reinterpret_cast<char*>(data.get()), sizeof(T::value_type) * l ength); | 59 buffer.read(reinterpret_cast<char*>(data.get()), sizeof(T::value_type) * l ength); |
42 if (buffer.fail()) | 60 if (buffer.fail()) |
43 throw new std::runtime_error("Unexpected end of input buffer"); | 61 throw new std::runtime_error("Unexpected end of input buffer"); |
44 | 62 |
45 value.assign(data.get(), length); | 63 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
| |
46 return *this; | 64 return *this; |
47 } | 65 } |
48 | 66 |
49 template<class T> | 67 template<class T> |
50 InputBuffer& Read(T& value, ValueType expectedType) | 68 InputBuffer& Read(T& value, ValueType expectedType) |
51 { | 69 { |
52 int32_t type; | 70 CheckType(expectedType); |
Felix Dahlke
2013/06/03 11:25:41
Like above, I think this should be ValueType
| |
53 ReadBinary(type); | |
54 if (type != expectedType) | |
55 throw new std::runtime_error("Unexpected type found in input buffer"); | |
56 | |
57 ReadBinary(value); | 71 ReadBinary(value); |
58 return *this; | 72 return *this; |
59 } | 73 } |
60 | 74 |
61 template<class T> | 75 template<class T> |
62 void ReadBinary(T& value) | 76 void ReadBinary(T& value) |
63 { | 77 { |
64 buffer.read(reinterpret_cast<char*>(&value), sizeof(T)); | 78 buffer.read(reinterpret_cast<char*>(&value), sizeof(T)); |
65 if (buffer.fail()) | 79 if (buffer.fail()) |
66 throw new std::runtime_error("Unexpected end of input buffer"); | 80 throw new std::runtime_error("Unexpected end of input buffer"); |
67 } | 81 } |
68 }; | 82 }; |
69 | 83 |
70 class OutputBuffer | 84 class OutputBuffer |
71 { | 85 { |
72 public: | 86 public: |
73 OutputBuffer() {} | 87 OutputBuffer() {} |
74 | 88 |
75 // Explicit copy constructor to allow returning OutputBuffer by value | 89 // 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 :)
| |
76 OutputBuffer(const OutputBuffer& copy) : buffer(copy.buffer.str()) {} | 90 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
| |
77 | 91 |
78 std::string Get() | 92 std::string Get() |
79 { | 93 { |
80 return buffer.str(); | 94 return buffer.str(); |
81 } | 95 } |
82 OutputBuffer& operator<<(const std::string& value) { return WriteString(valu e, TYPE_STRING); } | 96 OutputBuffer& operator<<(const std::string& value) { return WriteString(valu e, TYPE_STRING); } |
83 OutputBuffer& operator<<(const std::wstring& value) { return WriteString(val ue, TYPE_WSTRING); } | 97 OutputBuffer& operator<<(const std::wstring& value) { return WriteString(val ue, TYPE_WSTRING); } |
84 OutputBuffer& operator<<(int64_t value) { return Write(value, TYPE_INT64); } | 98 OutputBuffer& operator<<(int64_t value) { return Write(value, TYPE_INT64); } |
85 OutputBuffer& operator<<(int32_t value) { return Write(value, TYPE_INT32); } | 99 OutputBuffer& operator<<(int32_t value) { return Write(value, TYPE_INT32); } |
86 OutputBuffer& operator<<(bool value) { return Write(value, TYPE_BOOL); } | 100 OutputBuffer& operator<<(bool value) { return Write(value, TYPE_BOOL); } |
87 private: | 101 private: |
88 std::ostringstream buffer; | 102 std::ostringstream buffer; |
89 | 103 |
104 // Disallow copying | |
105 const OutputBuffer& operator=(const OutputBuffer&); | |
106 | |
90 template<class T> | 107 template<class T> |
91 OutputBuffer& WriteString(const T& value, int32_t type) | 108 OutputBuffer& WriteString(const T& value, ValueType type) |
Felix Dahlke
2013/06/03 11:25:41
Should be ValueType instead of int32_t I guess.
| |
92 { | 109 { |
93 WriteBinary(type); | 110 WriteBinary(type); |
94 | 111 |
95 uint32_t length = value.size(); | 112 SizeType length = value.size(); |
96 WriteBinary(length); | 113 WriteBinary(length); |
97 | 114 |
98 buffer.write(reinterpret_cast<const char*>(value.c_str()), sizeof(T::value _type) * length); | 115 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
| |
99 if (buffer.fail()) | 116 if (buffer.fail()) |
100 throw new std::runtime_error("Unexpected error writing to output buffer" ); | 117 throw new std::runtime_error("Unexpected error writing to output buffer" ); |
101 | 118 |
102 return *this; | 119 return *this; |
103 } | 120 } |
104 | 121 |
105 template<class T> | 122 template<class T> |
106 OutputBuffer& Write(const T value, int32_t type) | 123 OutputBuffer& Write(const T value, ValueType type) |
Felix Dahlke
2013/06/03 11:25:41
Should be ValueType instead of int32_t I think. Al
|
Felix Dahlke
2013/06/03 12:23:54
Shouldn't value be passed by reference?
Wladimir Palant
2013/06/03 12:25:55
Given that this function is meant for primitive ty
Felix Dahlke
2013/06/04 06:41:38
Right, didn't think of that. Won't hurt, but it wo
|
107 { | 124 { |
108 WriteBinary(type); | 125 WriteBinary(type); |
109 WriteBinary(value); | 126 WriteBinary(value); |
110 return *this; | 127 return *this; |
111 } | 128 } |
112 | 129 |
113 template<class T> | 130 template<class T> |
114 void WriteBinary(const T& value) | 131 void WriteBinary(const T& value) |
115 { | 132 { |
116 buffer.write(reinterpret_cast<const char*>(&value), sizeof(T)); | 133 buffer.write(reinterpret_cast<const char*>(&value), sizeof(T)); |
117 if (buffer.fail()) | 134 if (buffer.fail()) |
118 throw new std::runtime_error("Unexpected error writing to output buffer" ); | 135 throw new std::runtime_error("Unexpected error writing to output buffer" ); |
119 } | 136 } |
120 }; | 137 }; |
121 | 138 |
122 InputBuffer ReadMessage(HANDLE pipe); | 139 class PipeConnectionError : public std::runtime_error |
123 void WriteMessage(HANDLE pipe, OutputBuffer& message); | 140 { |
141 public: | |
142 PipeConnectionError(); | |
143 }; | |
144 | |
145 class Pipe | |
146 { | |
147 public: | |
148 enum Mode {MODE_CREATE, MODE_CONNECT}; | |
149 | |
150 Pipe(const std::wstring& name, Mode mode); | |
151 ~Pipe(); | |
152 | |
153 InputBuffer ReadMessage(); | |
154 void WriteMessage(OutputBuffer& message); | |
155 | |
156 protected: | |
157 HANDLE pipe; | |
158 }; | |
124 } | 159 } |
125 | 160 |
126 #endif | 161 #endif |
LEFT | RIGHT |