std::string HessianUtils::peekString()

in source/extensions/filters/network/dubbo_proxy/hessian_utils.cc [39:130]


std::string HessianUtils::peekString(Buffer::Instance& buffer, size_t* size, uint64_t offset) {
  ASSERT(buffer.length() > offset);
  uint8_t code = buffer.peekInt<uint8_t>(offset);
  size_t delta_length = 0;
  std::string result;
  switch (code) {
  case 0x00:
  case 0x01:
  case 0x02:
  case 0x03:
  case 0x04:
  case 0x05:
  case 0x06:
  case 0x07:
  case 0x08:
  case 0x09:
  case 0x0a:
  case 0x0b:
  case 0x0c:
  case 0x0d:
  case 0x0e:
  case 0x0f:
  case 0x10:
  case 0x11:
  case 0x12:
  case 0x13:
  case 0x14:
  case 0x15:
  case 0x16:
  case 0x17:
  case 0x18:
  case 0x19:
  case 0x1a:
  case 0x1b:
  case 0x1c:
  case 0x1d:
  case 0x1e:
  case 0x1f:
    delta_length = code - 0x00;
    if (delta_length + 1 + offset > buffer.length()) {
      throw EnvoyException("buffer underflow");
    }
    buffer.copyOut(offset + 1, delta_length, allocStringBuffer(&result, delta_length + 1));
    *size = delta_length + 1;
    return result;

  case 0x30:
  case 0x31:
  case 0x32:
  case 0x33:
    if (offset + 2 > buffer.length()) {
      throw EnvoyException("buffer underflow");
    }

    delta_length = (code - 0x30) * 256 + buffer.peekInt<uint8_t>(offset + 1);
    if (delta_length + 2 + offset > buffer.length()) {
      throw EnvoyException("buffer underflow");
    }

    buffer.copyOut(offset + 2, delta_length, allocStringBuffer(&result, delta_length + 1));
    *size = delta_length + 2;
    return result;

  case 0x53:
    if (offset + 3 > buffer.length()) {
      throw EnvoyException("buffer underflow");
    }

    delta_length = buffer.peekBEInt<uint16_t>(offset + 1);

    if (delta_length + 3 + offset > buffer.length()) {
      throw EnvoyException("buffer underflow");
    }

    buffer.copyOut(offset + 3, delta_length, allocStringBuffer(&result, delta_length + 1));
    *size = delta_length + 3;
    return result;

  case 0x52:
    if (offset + 3 > buffer.length()) {
      throw EnvoyException("buffer underflow");
    }

    delta_length = buffer.peekBEInt<uint16_t>(offset + 1);
    buffer.copyOut(offset + 3, delta_length, allocStringBuffer(&result, delta_length + 1));
    size_t next_size = 0;
    result.append(peekString(buffer, &next_size, delta_length + 3 + offset));
    *size = next_size + delta_length + 3;
    return result;
  }
  throw EnvoyException(fmt::format("hessian type is not string {}", code));
}