You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
6.3 KiB
268 lines
6.3 KiB
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program Execution Server
|
|
* ---------------------------------------------
|
|
*
|
|
* Copyright 2014 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*//*!
|
|
* \file
|
|
* \brief Execution Server Protocol.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "xsProtocol.hpp"
|
|
|
|
using std::string;
|
|
using std::vector;
|
|
|
|
namespace xs
|
|
{
|
|
|
|
inline deUint32 swapEndianess (deUint32 value)
|
|
{
|
|
deUint32 b0 = (value >> 0) & 0xFF;
|
|
deUint32 b1 = (value >> 8) & 0xFF;
|
|
deUint32 b2 = (value >> 16) & 0xFF;
|
|
deUint32 b3 = (value >> 24) & 0xFF;
|
|
return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
|
}
|
|
|
|
template <typename T> T networkToHost (T value);
|
|
template <typename T> T hostToNetwork (T value);
|
|
|
|
template <> int networkToHost (int value) { return (int)swapEndianess((deUint32)value); }
|
|
template <> int hostToNetwork (int value) { return (int)swapEndianess((deUint32)value); }
|
|
|
|
class MessageParser
|
|
{
|
|
public:
|
|
MessageParser (const deUint8* data, size_t dataSize)
|
|
: m_data (data)
|
|
, m_size (dataSize)
|
|
, m_pos (0)
|
|
{
|
|
}
|
|
|
|
template <typename T>
|
|
T get (void)
|
|
{
|
|
XS_CHECK_MSG(m_pos + sizeof(T) <= m_size, "Invalid payload size");
|
|
T netValue;
|
|
deMemcpy(&netValue, &m_data[m_pos], sizeof(T));
|
|
m_pos += sizeof(T);
|
|
return networkToHost(netValue);
|
|
}
|
|
|
|
void getString (std::string& dst)
|
|
{
|
|
// \todo [2011-09-30 pyry] We should really send a size parameter instead.
|
|
while (m_data[m_pos] != 0)
|
|
{
|
|
dst += (char)m_data[m_pos++];
|
|
XS_CHECK_MSG(m_pos < m_size, "Unterminated string payload");
|
|
}
|
|
|
|
m_pos += 1;
|
|
}
|
|
|
|
void assumEnd (void)
|
|
{
|
|
if (m_pos != m_size)
|
|
XS_FAIL("Invalid payload size");
|
|
}
|
|
|
|
private:
|
|
const deUint8* m_data;
|
|
size_t m_size;
|
|
size_t m_pos;
|
|
};
|
|
|
|
class MessageWriter
|
|
{
|
|
public:
|
|
MessageWriter (MessageType msgType, std::vector<deUint8>& buf)
|
|
: m_buf(buf)
|
|
{
|
|
// Place for size.
|
|
put<int>(0);
|
|
|
|
// Write message type.
|
|
put<int>(msgType);
|
|
}
|
|
|
|
~MessageWriter (void)
|
|
{
|
|
finalize();
|
|
}
|
|
|
|
void finalize (void)
|
|
{
|
|
DE_ASSERT(m_buf.size() >= MESSAGE_HEADER_SIZE);
|
|
|
|
// Write actual size.
|
|
int size = hostToNetwork((int)m_buf.size());
|
|
deMemcpy(&m_buf[0], &size, sizeof(int));
|
|
}
|
|
|
|
template <typename T>
|
|
void put (T value)
|
|
{
|
|
T netValue = hostToNetwork(value);
|
|
size_t curPos = m_buf.size();
|
|
m_buf.resize(curPos + sizeof(T));
|
|
deMemcpy(&m_buf[curPos], &netValue, sizeof(T));
|
|
}
|
|
|
|
private:
|
|
std::vector<deUint8>& m_buf;
|
|
};
|
|
|
|
template <>
|
|
void MessageWriter::put<const char*> (const char* value)
|
|
{
|
|
int curPos = (int)m_buf.size();
|
|
int strLen = (int)strlen(value);
|
|
|
|
m_buf.resize(curPos + strLen+1);
|
|
deMemcpy(&m_buf[curPos], &value[0], strLen+1);
|
|
}
|
|
|
|
void Message::parseHeader (const deUint8* data, size_t dataSize, MessageType& type, size_t& size)
|
|
{
|
|
XS_CHECK_MSG(dataSize >= MESSAGE_HEADER_SIZE, "Incomplete header");
|
|
MessageParser parser(data, dataSize);
|
|
size = (size_t)(MessageType)parser.get<int>();
|
|
type = (MessageType)parser.get<int>();
|
|
}
|
|
|
|
void Message::writeHeader (MessageType type, size_t messageSize, deUint8* dst, size_t bufSize)
|
|
{
|
|
XS_CHECK_MSG(bufSize >= MESSAGE_HEADER_SIZE, "Incomplete header");
|
|
int netSize = hostToNetwork((int)messageSize);
|
|
int netType = hostToNetwork((int)type);
|
|
deMemcpy(dst+0, &netSize, sizeof(netSize));
|
|
deMemcpy(dst+4, &netType, sizeof(netType));
|
|
}
|
|
|
|
void Message::writeNoData (vector<deUint8>& buf) const
|
|
{
|
|
MessageWriter writer(type, buf);
|
|
}
|
|
|
|
HelloMessage::HelloMessage (const deUint8* data, size_t dataSize)
|
|
: Message(MESSAGETYPE_HELLO)
|
|
{
|
|
MessageParser parser(data, dataSize);
|
|
version = parser.get<int>();
|
|
parser.assumEnd();
|
|
}
|
|
|
|
void HelloMessage::write (vector<deUint8>& buf) const
|
|
{
|
|
MessageWriter writer(type, buf);
|
|
writer.put(version);
|
|
}
|
|
|
|
TestMessage::TestMessage (const deUint8* data, size_t dataSize)
|
|
: Message(MESSAGETYPE_TEST)
|
|
{
|
|
MessageParser parser(data, dataSize);
|
|
parser.getString(test);
|
|
parser.assumEnd();
|
|
}
|
|
|
|
void TestMessage::write (vector<deUint8>& buf) const
|
|
{
|
|
MessageWriter writer(type, buf);
|
|
writer.put(test.c_str());
|
|
}
|
|
|
|
ExecuteBinaryMessage::ExecuteBinaryMessage (const deUint8* data, size_t dataSize)
|
|
: Message(MESSAGETYPE_EXECUTE_BINARY)
|
|
{
|
|
MessageParser parser(data, dataSize);
|
|
parser.getString(name);
|
|
parser.getString(params);
|
|
parser.getString(workDir);
|
|
parser.getString(caseList);
|
|
parser.assumEnd();
|
|
}
|
|
|
|
void ExecuteBinaryMessage::write (vector<deUint8>& buf) const
|
|
{
|
|
MessageWriter writer(type, buf);
|
|
writer.put(name.c_str());
|
|
writer.put(params.c_str());
|
|
writer.put(workDir.c_str());
|
|
writer.put(caseList.c_str());
|
|
}
|
|
|
|
ProcessLogDataMessage::ProcessLogDataMessage (const deUint8* data, size_t dataSize)
|
|
: Message(MESSAGETYPE_PROCESS_LOG_DATA)
|
|
{
|
|
MessageParser parser(data, dataSize);
|
|
parser.getString(logData);
|
|
parser.assumEnd();
|
|
}
|
|
|
|
void ProcessLogDataMessage::write (vector<deUint8>& buf) const
|
|
{
|
|
MessageWriter writer(type, buf);
|
|
writer.put(logData.c_str());
|
|
}
|
|
|
|
ProcessLaunchFailedMessage::ProcessLaunchFailedMessage (const deUint8* data, size_t dataSize)
|
|
: Message(MESSAGETYPE_PROCESS_LAUNCH_FAILED)
|
|
{
|
|
MessageParser parser(data, dataSize);
|
|
parser.getString(reason);
|
|
parser.assumEnd();
|
|
}
|
|
|
|
void ProcessLaunchFailedMessage::write (vector<deUint8>& buf) const
|
|
{
|
|
MessageWriter writer(type, buf);
|
|
writer.put(reason.c_str());
|
|
}
|
|
|
|
ProcessFinishedMessage::ProcessFinishedMessage (const deUint8* data, size_t dataSize)
|
|
: Message(MESSAGETYPE_PROCESS_FINISHED)
|
|
{
|
|
MessageParser parser(data, dataSize);
|
|
exitCode = parser.get<int>();
|
|
parser.assumEnd();
|
|
}
|
|
|
|
void ProcessFinishedMessage::write (vector<deUint8>& buf) const
|
|
{
|
|
MessageWriter writer(type, buf);
|
|
writer.put(exitCode);
|
|
}
|
|
|
|
InfoMessage::InfoMessage (const deUint8* data, size_t dataSize)
|
|
: Message(MESSAGETYPE_INFO)
|
|
{
|
|
MessageParser parser(data, dataSize);
|
|
parser.getString(info);
|
|
parser.assumEnd();
|
|
}
|
|
|
|
void InfoMessage::write (vector<deUint8>& buf) const
|
|
{
|
|
MessageWriter writer(type, buf);
|
|
writer.put(info.c_str());
|
|
}
|
|
|
|
} // xs
|