65 std::string_view input(buffer, length);
67 if (input.empty() || input[0] !=
'*') {
68 resp.error =
"Invalid request: missing array marker";
72 size_t pos = input.find(CRLF);
73 if (pos == std::string_view::npos) {
74 resp.error =
"Invalid request: malformed array header";
80 num_args = std::stoi(std::string(input.substr(1, pos - 1)));
81 }
catch (std::exception &) {
82 resp.error =
"Invalid request: invalid argument count";
86 if (num_args < 2 || num_args > 3) {
87 resp.error =
"Invalid request: unexpected argument count";
91 input.remove_prefix(pos + 2);
92 if (!parseOperation(input, resp)) {
96 if (!parseKey(input, resp)) {
100 if (resp.operation == SET) {
102 resp.error =
"Invalid request: SET requires a value";
106 if (!parseValue(input, resp)) {
109 }
else if (num_args > 2) {
110 resp.error =
"Invalid request: too many arguments";
114 if (!input.empty() && input != CRLF) {
115 resp.error =
"Invalid request: extra data after command";
129 return decode(buffer, std::strlen(buffer));
139 static bool parseOperation(std::string_view &input,
Resp &resp) {
140 if (input.empty() || input[0] !=
'$') {
141 resp.error =
"Invalid request: missing operation string marker";
145 size_t pos = input.find(CRLF);
146 if (pos == std::string_view::npos) {
147 resp.error =
"Invalid request: malformed operation length";
153 op_len = std::stoi(std::string(input.substr(1, pos - 1)));
154 }
catch (std::exception &) {
155 resp.error =
"Invalid request: invalid operation length";
159 input.remove_prefix(pos + 2);
160 if (input.size() <
static_cast<size_t>(op_len) + 2) {
161 resp.error =
"Invalid request: truncated operation";
165 std::string_view op = input.substr(0, op_len);
168 resp.operation = DEL;
169 }
else if (op ==
"GET") {
170 resp.operation = GET;
171 }
else if (op ==
"SET") {
172 resp.operation = SET;
174 resp.error =
"Invalid request: unknown operation";
178 input.remove_prefix(op_len + 2);
188 static bool parseKey(std::string_view &input, Resp &resp) {
189 if (input.empty() || input[0] !=
'$') {
190 resp.error =
"Invalid request: missing key string marker";
194 size_t pos = input.find(CRLF);
195 if (pos == std::string_view::npos) {
196 resp.error =
"Invalid request: malformed key length";
202 key_len = std::stoi(std::string(input.substr(1, pos - 1)));
203 }
catch (std::exception &) {
204 resp.error =
"Invalid request: invalid key length";
208 input.remove_prefix(pos + 2);
210 if (input.size() <
static_cast<size_t>(key_len) + 2) {
211 resp.error =
"Invalid request: truncated key";
215 resp.key = std::string(input.substr(0, key_len));
216 input.remove_prefix(key_len + 2);
226 static bool parseValue(std::string_view &input, Resp &resp) {
227 if (input.empty() || input[0] !=
'$') {
228 resp.error =
"Invalid request: missing value string marker";
232 size_t pos = input.find(CRLF);
233 if (pos == std::string_view::npos) {
234 resp.error =
"Invalid request: malformed value length";
240 value_len = std::stoi(std::string(input.substr(1, pos - 1)));
241 }
catch (std::exception &) {
242 resp.error =
"Invalid request: invalid value length";
246 input.remove_prefix(pos + 2);
248 if (input.size() <
static_cast<size_t>(value_len) + 2) {
249 resp.error =
"Invalid request: truncated value";
253 resp.value = std::string(input.substr(0, value_len));
254 input.remove_prefix(value_len + 2);
static Resp decode(const char *buffer)
Decode a RESP command from a null-terminated string.
Definition resp_decoder.hpp:128
static Resp decode(const char *buffer, size_t length)
Decode a RESP command from a buffer.
Definition resp_decoder.hpp:62