Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: src/shared/Communication.h

Issue 10824027: Implement better marshaling (Closed)
Left Patch Set: Created May 31, 2013, 8:26 a.m.
Right Patch Set: Created June 3, 2013, 12:05 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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
LEFTRIGHT
« no previous file | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
This is Rietveld