1/*
2 * Copyright (c) 2011-2014, Intel Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors
16 * may be used to endorse or promote products derived from this software without
17 * specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30#include "RequestMessage.h"
31#include <assert.h>
32#include <algorithm>
33#include <ctype.h>
34
35#define base CMessage
36
37using std::string;
38
39const char *const CRequestMessage::gacDelimiters = " \t\n\v\f\r";
40
41CRequestMessage::CRequestMessage(const string &strCommand)
42    : base(MsgType::ECommandRequest), _strCommand(strCommand)
43{
44}
45
46CRequestMessage::CRequestMessage()
47{
48}
49
50// Command Name
51void CRequestMessage::setCommand(const string &strCommand)
52{
53    _strCommand = trim(strCommand);
54}
55
56const string &CRequestMessage::getCommand() const
57{
58    return _strCommand;
59}
60
61// Arguments
62void CRequestMessage::addArgument(const string &strArgument)
63{
64    _argumentVector.push_back(trim(strArgument));
65}
66
67size_t CRequestMessage::getArgumentCount() const
68{
69    return _argumentVector.size();
70}
71
72const std::vector<string> &CRequestMessage::getArguments() const
73{
74    return _argumentVector;
75}
76
77const string &CRequestMessage::getArgument(size_t argument) const
78{
79    assert(argument < _argumentVector.size());
80
81    return _argumentVector[argument];
82}
83
84const string CRequestMessage::packArguments(size_t uiStartArgument, size_t uiNbArguments) const
85{
86    string strPackedArguments;
87
88    assert(uiStartArgument + uiNbArguments <= _argumentVector.size());
89
90    // Pack arguments, separating them with a space
91    bool bFirst = true;
92
93    for (size_t argument = uiStartArgument; argument < uiStartArgument + uiNbArguments;
94         argument++) {
95
96        if (!bFirst) {
97
98            strPackedArguments += " ";
99        } else {
100
101            bFirst = false;
102        }
103
104        strPackedArguments += _argumentVector[argument];
105    }
106
107    return strPackedArguments;
108}
109
110// Fill data to send
111void CRequestMessage::fillDataToSend()
112{
113    // Send command
114    writeString(getCommand());
115
116    // Arguments
117    for (size_t argument = 0; argument < getArgumentCount(); argument++) {
118
119        writeString(getArgument(argument));
120    }
121}
122
123// Collect received data
124void CRequestMessage::collectReceivedData()
125{
126    // Receive command
127    string strCommand;
128
129    readString(strCommand);
130
131    setCommand(strCommand);
132
133    // Arguments
134    while (getRemainingDataSize()) {
135
136        string strArgument;
137
138        readString(strArgument);
139
140        addArgument(strArgument);
141    }
142}
143
144// Size
145size_t CRequestMessage::getDataSize() const
146{
147    // Command
148    size_t uiSize = getStringSize(getCommand());
149
150    // Arguments
151    for (size_t uiArgument = 0; uiArgument < getArgumentCount(); uiArgument++) {
152
153        uiSize += getStringSize(getArgument(uiArgument));
154    }
155    return uiSize;
156}
157
158// Trim input string
159string CRequestMessage::trim(const string &strToTrim)
160{
161    // Trim string
162    string strTrimmed = strToTrim;
163
164    strTrimmed.erase(strTrimmed.find_last_not_of(gacDelimiters) + 1);
165
166    strTrimmed.erase(0, strTrimmed.find_first_not_of(gacDelimiters));
167
168    return strTrimmed;
169}
170