std::unique_ptr Decoder::decode()

in hessian2/basic_codec/list_codec.cc [10:102]


std::unique_ptr<TypedListObject> Decoder::decode() {
  std::string type;
  Object::TypedList obj_list;

  auto result = std::make_unique<TypedListObject>();
  values_ref_.push_back(result.get());

  auto ret = reader_->read<uint8_t>();
  if (!ret.first) {
    return nullptr;
  }

  auto code = ret.second;

  auto ReadNumsObject = [&](int nums) -> bool {
    for (int i = 0; i < nums; i++) {
      auto o = decode<Object>();
      if (!o) {
        return false;
      }
      obj_list.values_.emplace_back(std::move(o));
    }
    return true;
  };

  auto ReadObjectUntilEnd = [&]() -> bool {
    auto ret = reader_->peek<uint8_t>();
    if (!ret.first) {
      return false;
    }

    while (ret.second != 'Z') {
      auto o = decode<Object>();
      if (!o) {
        return false;
      }
      obj_list.values_.emplace_back(std::move(o));
      ret = reader_->peek<uint8_t>();
      if (!ret.first) {
        return false;
      }
    }

    // Skip last 'Z'
    reader_->read<uint8_t>();
    return true;
  };

  auto type_str = decode<Object::TypeRef>();
  if (!type_str) {
    return nullptr;
  }

  obj_list.type_name_ = std::move(type_str->type_);

  switch (code) {
    case 0x55: {
      if (!ReadObjectUntilEnd()) {
        return nullptr;
      }
      break;
    }

    case 'V': {
      auto ret = decode<int32_t>();
      if (!ret) {
        return nullptr;
      }

      if (!ReadNumsObject(*ret)) {
        return nullptr;
      }
      break;
    }
    case 0x70:
    case 0x71:
    case 0x72:
    case 0x73:
    case 0x74:
    case 0x75:
    case 0x76:
    case 0x77: {
      if (!ReadNumsObject(code - 0x70)) {
        return nullptr;
      }
      break;
    }
    default:
      return nullptr;
  }
  result->setTypedList(std::move(obj_list));
  return result;
}