MCPcopy Create free account
hub / github.com/apache/brpc / ConsumeImpl

Method ConsumeImpl

src/brpc/redis_command.cpp:397–555  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

395}
396
397RedisCommandConsumeState RedisCommandParser::ConsumeImpl(butil::IOBuf& buf,
398 butil::Arena* arena,
399 ParseError* err) {
400 const auto pfc = static_cast<const char *>(buf.fetch1());
401 if (pfc == NULL) {
402 *err = PARSE_ERROR_NOT_ENOUGH_DATA;
403 return CONSUME_STATE_ERROR;
404 }
405 // '*' stands for array "*<size>\r\n<sub-reply1><sub-reply2>..."
406 if (!_parsing_array && *pfc != '*') {
407 if (!std::isalpha(static_cast<unsigned char>(*pfc))) {
408 *err = PARSE_ERROR_TRY_OTHERS;
409 return CONSUME_STATE_ERROR;
410 }
411 const size_t buf_size = buf.size();
412 const auto copy_str = static_cast<char *>(arena->allocate(buf_size + 1));
413 // arena->allocate() may return NULL on allocation failure
414 if (copy_str == NULL) {
415 LOG(FATAL) << "Arena failed allocation";
416 *err = PARSE_ERROR_ABSOLUTELY_WRONG;
417 return CONSUME_STATE_ERROR;
418 }
419 buf.copy_to(copy_str, buf_size);
420 if (*copy_str == ' ') {
421 *err = PARSE_ERROR_ABSOLUTELY_WRONG;
422 return CONSUME_STATE_ERROR;
423 }
424 copy_str[buf_size] = '\0';
425 const size_t crlf_pos = butil::StringPiece(copy_str, buf_size).find("\r\n");
426 if (crlf_pos == butil::StringPiece::npos) { // not enough data
427 *err = PARSE_ERROR_NOT_ENOUGH_DATA;
428 return CONSUME_STATE_ERROR;
429 }
430 size_t offset = 0;
431 while (offset < crlf_pos && copy_str[offset] != ' ') {
432 ++offset;
433 }
434 const auto first_arg = static_cast<char*>(arena->allocate(offset));
435 memcpy(first_arg, copy_str, offset);
436 for (size_t i = 0; i < offset; ++i) {
437 first_arg[i] = tolower(first_arg[i]);
438 }
439 _args.push_back(butil::StringPiece(first_arg, offset));
440 if (offset == crlf_pos) {
441 // only one argument, directly return
442 buf.pop_front(crlf_pos + 2);
443 return CONSUME_STATE_DONE;
444 }
445 size_t arg_start_pos = ++offset;
446
447 for (; offset < crlf_pos; ++offset) {
448 if (copy_str[offset] != ' ') {
449 continue;
450 }
451 const auto arg_length = offset - arg_start_pos;
452 const auto arg = static_cast<char *>(arena->allocate(arg_length));
453 memcpy(arg, copy_str + arg_start_pos, arg_length);
454 _args.push_back(butil::StringPiece(arg, arg_length));

Callers

nothing calls this directly

Calls 11

tolowerFunction · 0.85
fetch1Method · 0.45
sizeMethod · 0.45
allocateMethod · 0.45
copy_toMethod · 0.45
findMethod · 0.45
push_backMethod · 0.45
pop_frontMethod · 0.45
resizeMethod · 0.45
cutnMethod · 0.45
setMethod · 0.45

Tested by

no test coverage detected