示例#1
0
bool McParser::readUmbrellaData() {
  while (!readBuffer_.empty()) {
    auto st = um_parse_header(readBuffer_.data(),
                              readBuffer_.length(),
                              &umMsgInfo_);
    if (st == um_not_enough_data) {
      return true;
    }

    if (st != um_ok) {
      errorHelper(McReply(mc_res_remote_error,
                          "Error parsing Umbrella header"));
      return false;
    }

    /* Three cases: */
    if (readBuffer_.length() >= umMsgInfo_.message_size) {
      /* 1) we already have the entire message */
      if (!umMessageReady(
            readBuffer_.data(),
            readBuffer_.data() + umMsgInfo_.header_size,
            readBuffer_)) {
        readBuffer_.clear();
        return false;
      }
      /* Re-enter the loop */
      readBuffer_.trimStart(umMsgInfo_.message_size);
      continue;
    } else if (readBuffer_.length() >= umMsgInfo_.header_size &&
               umMsgInfo_.message_size - readBuffer_.length() >
               minBufferSize_) {
      /* 2) we have the entire header, but body is incomplete.
         Copy the partially read body into the new buffer.
         TODO: this copy could be eliminated, but needs
         some modification of umbrella library. */
      auto partial = readBuffer_.length() - umMsgInfo_.header_size;
      umBodyBuffer_ = folly::IOBuf::copyBuffer(
        readBuffer_.data() + umMsgInfo_.header_size,
        partial,
        /* headroom= */ 0,
        /* minTailroom= */ umMsgInfo_.body_size - partial);
      return true;
    }
    /* 3) else header is incomplete */
    return true;
  }
  return true;
}
示例#2
0
um_status_t um_consume_no_copy(const uint8_t* header, size_t nheader,
                               const uint8_t* body, size_t nbody,
                               uint64_t* reqid_out,
                               mc_msg_t* msg_out) {
  FBI_ASSERT(header && body && reqid_out && msg_out);
  um_message_info_t info;
  um_status_t header_rv = um_parse_header(header, nheader, &info);
  if (header_rv != um_ok) {
    return header_rv;
  }
  if (!(nheader == info.header_size &&
        nbody == info.body_size &&
        nheader + nbody == info.message_size)) {
    return um_invalid_range;
  }

  entry_list_t elist;
  entry_list_init(&elist);
  /* We know that header/body won't be modified here,
     but the interface is messed up */
  ssize_t rv = entry_list_read_from_buf(&elist,
                                        (char*)header, nheader,
                                        (char*)body, nbody,
                                        /*free_buf_when_done=*/0);
  if (rv < 0 || rv != info.message_size) {
    return um_message_parse_error;
  }

  _parse_info_t parse_info;
  if (_fill_base_msg(&elist, msg_out, &parse_info) != 0) {
    return um_message_parse_error;
  }

  /* TODO: support stats with no_copy API */
  if (parse_info.stats_count > 0) {
    return um_message_parse_error;
  }

  if (_fill_msg_strs(msg_out, &elist, body, &parse_info) != 0) {
    return um_message_parse_error;
  }

  *reqid_out = parse_info.reqid;

  return um_ok;
}