[automerger skipped] DO NOT MERGE: Make the tests permissive for Lollipop MR1 am...
[platform/upstream/VK-GL-CTS.git] / execserver / xsProtocol.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program Execution Server
3  * ---------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Execution Server Protocol.
22  *//*--------------------------------------------------------------------*/
23
24 #include "xsProtocol.hpp"
25
26 using std::string;
27 using std::vector;
28
29 namespace xs
30 {
31
32 inline deUint32 swapEndianess (deUint32 value)
33 {
34         deUint32 b0 = (value >>  0) & 0xFF;
35         deUint32 b1 = (value >>  8) & 0xFF;
36         deUint32 b2 = (value >> 16) & 0xFF;
37         deUint32 b3 = (value >> 24) & 0xFF;
38         return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
39 }
40
41 template <typename T> T networkToHost (T value);
42 template <typename T> T hostToNetwork (T value);
43
44 template <> int networkToHost (int value) { return (int)swapEndianess((deUint32)value); }
45 template <> int hostToNetwork (int value) { return (int)swapEndianess((deUint32)value); }
46
47 class MessageParser
48 {
49 public:
50         MessageParser (const deUint8* data, size_t dataSize)
51                 : m_data        (data)
52                 , m_size        (dataSize)
53                 , m_pos         (0)
54         {
55         }
56
57         template <typename T>
58         T get (void)
59         {
60                 XS_CHECK_MSG(m_pos + sizeof(T) <= m_size, "Invalid payload size");
61                 T netValue;
62                 deMemcpy(&netValue, &m_data[m_pos], sizeof(T));
63                 m_pos += sizeof(T);
64                 return networkToHost(netValue);
65         }
66
67         void getString (std::string& dst)
68         {
69                 // \todo [2011-09-30 pyry] We should really send a size parameter instead.
70                 while (m_data[m_pos] != 0)
71                 {
72                         dst += (char)m_data[m_pos++];
73                         XS_CHECK_MSG(m_pos < m_size, "Unterminated string payload");
74                 }
75
76                 m_pos += 1;
77         }
78
79         void assumEnd (void)
80         {
81                 if (m_pos != m_size)
82                         XS_FAIL("Invalid payload size");
83         }
84
85 private:
86         const deUint8*  m_data;
87         size_t                  m_size;
88         size_t                  m_pos;
89 };
90
91 class MessageWriter
92 {
93 public:
94         MessageWriter (MessageType msgType, std::vector<deUint8>& buf)
95                 : m_buf(buf)
96         {
97                 // Place for size.
98                 put<int>(0);
99
100                 // Write message type.
101                 put<int>(msgType);
102         }
103
104         ~MessageWriter (void)
105         {
106                 finalize();
107         }
108
109         void finalize (void)
110         {
111                 DE_ASSERT(m_buf.size() >= MESSAGE_HEADER_SIZE);
112
113                 // Write actual size.
114                 int size = hostToNetwork((int)m_buf.size());
115                 deMemcpy(&m_buf[0], &size, sizeof(int));
116         }
117
118         template <typename T>
119         void put (T value)
120         {
121                 T netValue = hostToNetwork(value);
122                 size_t curPos = m_buf.size();
123                 m_buf.resize(curPos + sizeof(T));
124                 deMemcpy(&m_buf[curPos], &netValue, sizeof(T));
125         }
126
127 private:
128         std::vector<deUint8>& m_buf;
129 };
130
131 template <>
132 void MessageWriter::put<const char*> (const char* value)
133 {
134         int curPos = (int)m_buf.size();
135         int strLen = (int)strlen(value);
136
137         m_buf.resize(curPos + strLen+1);
138         deMemcpy(&m_buf[curPos], &value[0], strLen+1);
139 }
140
141 void Message::parseHeader (const deUint8* data, size_t dataSize, MessageType& type, size_t& size)
142 {
143         XS_CHECK_MSG(dataSize >= MESSAGE_HEADER_SIZE, "Incomplete header");
144         MessageParser parser(data, dataSize);
145         size    = (size_t)(MessageType)parser.get<int>();
146         type    = (MessageType)parser.get<int>();
147 }
148
149 void Message::writeHeader (MessageType type, size_t messageSize, deUint8* dst, size_t bufSize)
150 {
151         XS_CHECK_MSG(bufSize >= MESSAGE_HEADER_SIZE, "Incomplete header");
152         int netSize = hostToNetwork((int)messageSize);
153         int netType = hostToNetwork((int)type);
154         deMemcpy(dst+0, &netSize, sizeof(netSize));
155         deMemcpy(dst+4, &netType, sizeof(netType));
156 }
157
158 void Message::writeNoData (vector<deUint8>& buf) const
159 {
160         MessageWriter writer(type, buf);
161 }
162
163 HelloMessage::HelloMessage (const deUint8* data, size_t dataSize)
164         : Message(MESSAGETYPE_HELLO)
165 {
166         MessageParser parser(data, dataSize);
167         version = parser.get<int>();
168         parser.assumEnd();
169 }
170
171 void HelloMessage::write (vector<deUint8>& buf) const
172 {
173         MessageWriter writer(type, buf);
174         writer.put(version);
175 }
176
177 TestMessage::TestMessage (const deUint8* data, size_t dataSize)
178         : Message(MESSAGETYPE_TEST)
179 {
180         MessageParser parser(data, dataSize);
181         parser.getString(test);
182         parser.assumEnd();
183 }
184
185 void TestMessage::write (vector<deUint8>& buf) const
186 {
187         MessageWriter writer(type, buf);
188         writer.put(test.c_str());
189 }
190
191 ExecuteBinaryMessage::ExecuteBinaryMessage (const deUint8* data, size_t dataSize)
192         : Message(MESSAGETYPE_EXECUTE_BINARY)
193 {
194         MessageParser parser(data, dataSize);
195         parser.getString(name);
196         parser.getString(params);
197         parser.getString(workDir);
198         parser.getString(caseList);
199         parser.assumEnd();
200 }
201
202 void ExecuteBinaryMessage::write (vector<deUint8>& buf) const
203 {
204         MessageWriter writer(type, buf);
205         writer.put(name.c_str());
206         writer.put(params.c_str());
207         writer.put(workDir.c_str());
208         writer.put(caseList.c_str());
209 }
210
211 ProcessLogDataMessage::ProcessLogDataMessage (const deUint8* data, size_t dataSize)
212         : Message(MESSAGETYPE_PROCESS_LOG_DATA)
213 {
214         MessageParser parser(data, dataSize);
215         parser.getString(logData);
216         parser.assumEnd();
217 }
218
219 void ProcessLogDataMessage::write (vector<deUint8>& buf) const
220 {
221         MessageWriter writer(type, buf);
222         writer.put(logData.c_str());
223 }
224
225 ProcessLaunchFailedMessage::ProcessLaunchFailedMessage (const deUint8* data, size_t dataSize)
226         : Message(MESSAGETYPE_PROCESS_LAUNCH_FAILED)
227 {
228         MessageParser parser(data, dataSize);
229         parser.getString(reason);
230         parser.assumEnd();
231 }
232
233 void ProcessLaunchFailedMessage::write (vector<deUint8>& buf) const
234 {
235         MessageWriter writer(type, buf);
236         writer.put(reason.c_str());
237 }
238
239 ProcessFinishedMessage::ProcessFinishedMessage (const deUint8* data, size_t dataSize)
240         : Message(MESSAGETYPE_PROCESS_FINISHED)
241 {
242         MessageParser parser(data, dataSize);
243         exitCode = parser.get<int>();
244         parser.assumEnd();
245 }
246
247 void ProcessFinishedMessage::write (vector<deUint8>& buf) const
248 {
249         MessageWriter writer(type, buf);
250         writer.put(exitCode);
251 }
252
253 InfoMessage::InfoMessage (const deUint8* data, size_t dataSize)
254         : Message(MESSAGETYPE_INFO)
255 {
256         MessageParser parser(data, dataSize);
257         parser.getString(info);
258         parser.assumEnd();
259 }
260
261 void InfoMessage::write (vector<deUint8>& buf) const
262 {
263         MessageWriter writer(type, buf);
264         writer.put(info.c_str());
265 }
266
267 } // xs