// WARNING: This file is machine generated by fidlgen.

#include <fuchsia/blobfs/llcpp/fidl.h>
#include <memory>

namespace llcpp {

namespace fuchsia {
namespace blobfs {

namespace {

[[maybe_unused]]
constexpr uint64_t kCorruptBlobHandler_CorruptBlob_Ordinal = 0x432ee88e00000000lu;
[[maybe_unused]]
constexpr uint64_t kCorruptBlobHandler_CorruptBlob_GenOrdinal = 0x264e37ffa416cdf1lu;
extern "C" const fidl_type_t v1_fuchsia_blobfs_CorruptBlobHandlerCorruptBlobRequestTable;
extern "C" const fidl_type_t v1_fuchsia_blobfs_CorruptBlobHandlerCorruptBlobResponseTable;

}  // namespace
template <>
CorruptBlobHandler::ResultOf::CorruptBlob_Impl<CorruptBlobHandler::CorruptBlobResponse>::CorruptBlob_Impl(::zx::unowned_channel _client_end, ::fidl::VectorView<uint8_t> merkleroot) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<CorruptBlobRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  CorruptBlobRequest _request = {};
  _request.merkleroot = std::move(merkleroot);
  auto _linearize_result = ::fidl::Linearize(&_request, _write_bytes_array.view());
  if (_linearize_result.status != ZX_OK) {
    Super::SetFailure(std::move(_linearize_result));
    return;
  }
  ::fidl::DecodedMessage<CorruptBlobRequest> _decoded_request = std::move(_linearize_result.message);
  Super::SetResult(
      CorruptBlobHandler::InPlace::CorruptBlob(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
}

CorruptBlobHandler::ResultOf::CorruptBlob CorruptBlobHandler::SyncClient::CorruptBlob(::fidl::VectorView<uint8_t> merkleroot) {
    return ResultOf::CorruptBlob(::zx::unowned_channel(this->channel_), std::move(merkleroot));
}

CorruptBlobHandler::ResultOf::CorruptBlob CorruptBlobHandler::Call::CorruptBlob(::zx::unowned_channel _client_end, ::fidl::VectorView<uint8_t> merkleroot) {
  return ResultOf::CorruptBlob(std::move(_client_end), std::move(merkleroot));
}

template <>
CorruptBlobHandler::UnownedResultOf::CorruptBlob_Impl<CorruptBlobHandler::CorruptBlobResponse>::CorruptBlob_Impl(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::VectorView<uint8_t> merkleroot, ::fidl::BytePart _response_buffer) {
  if (_request_buffer.capacity() < CorruptBlobRequest::PrimarySize) {
    Super::SetFailure(::fidl::DecodeResult<CorruptBlobResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
    return;
  }
  CorruptBlobRequest _request = {};
  _request.merkleroot = std::move(merkleroot);
  auto _linearize_result = ::fidl::Linearize(&_request, std::move(_request_buffer));
  if (_linearize_result.status != ZX_OK) {
    Super::SetFailure(std::move(_linearize_result));
    return;
  }
  ::fidl::DecodedMessage<CorruptBlobRequest> _decoded_request = std::move(_linearize_result.message);
  Super::SetResult(
      CorruptBlobHandler::InPlace::CorruptBlob(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
}

CorruptBlobHandler::UnownedResultOf::CorruptBlob CorruptBlobHandler::SyncClient::CorruptBlob(::fidl::BytePart _request_buffer, ::fidl::VectorView<uint8_t> merkleroot, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::CorruptBlob(::zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(merkleroot), std::move(_response_buffer));
}

CorruptBlobHandler::UnownedResultOf::CorruptBlob CorruptBlobHandler::Call::CorruptBlob(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::VectorView<uint8_t> merkleroot, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::CorruptBlob(std::move(_client_end), std::move(_request_buffer), std::move(merkleroot), std::move(_response_buffer));
}

::fidl::DecodeResult<CorruptBlobHandler::CorruptBlobResponse> CorruptBlobHandler::InPlace::CorruptBlob(::zx::unowned_channel _client_end, ::fidl::DecodedMessage<CorruptBlobRequest> params, ::fidl::BytePart response_buffer) {
  CorruptBlobHandler::SetTransactionHeaderFor::CorruptBlobRequest(params);
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<CorruptBlobHandler::CorruptBlobResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<CorruptBlobRequest, CorruptBlobResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<CorruptBlobHandler::CorruptBlobResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


bool CorruptBlobHandler::TryDispatch(Interface* impl, fidl_msg_t* msg, ::fidl::Transaction* txn) {
  if (msg->num_bytes < sizeof(fidl_message_header_t)) {
    zx_handle_close_many(msg->handles, msg->num_handles);
    txn->Close(ZX_ERR_INVALID_ARGS);
    return true;
  }
  fidl_message_header_t* hdr = reinterpret_cast<fidl_message_header_t*>(msg->bytes);
  zx_status_t status = fidl_validate_txn_header(hdr);
  if (status != ZX_OK) {
    txn->Close(status);
    return true;
  }
  switch (hdr->ordinal) {
    case kCorruptBlobHandler_CorruptBlob_Ordinal:
    case kCorruptBlobHandler_CorruptBlob_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<CorruptBlobRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->CorruptBlob(std::move(message->merkleroot),
          Interface::CorruptBlobCompleter::Sync(txn));
      return true;
    }
    default: {
      return false;
    }
  }
}

bool CorruptBlobHandler::Dispatch(Interface* impl, fidl_msg_t* msg, ::fidl::Transaction* txn) {
  bool found = TryDispatch(impl, msg, txn);
  if (!found) {
    zx_handle_close_many(msg->handles, msg->num_handles);
    txn->Close(ZX_ERR_NOT_SUPPORTED);
  }
  return found;
}


void CorruptBlobHandler::Interface::CorruptBlobCompleterBase::Reply(::llcpp::fuchsia::blobfs::TakeAction action) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<CorruptBlobResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<CorruptBlobResponse*>(_write_bytes);
  CorruptBlobHandler::SetTransactionHeaderFor::CorruptBlobResponse(
      ::fidl::DecodedMessage<CorruptBlobResponse>(
          ::fidl::BytePart(reinterpret_cast<uint8_t*>(&_response),
              CorruptBlobResponse::PrimarySize,
              CorruptBlobResponse::PrimarySize)));
  _response.action = std::move(action);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(CorruptBlobResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<CorruptBlobResponse>(std::move(_response_bytes)));
}

void CorruptBlobHandler::Interface::CorruptBlobCompleterBase::Reply(::fidl::BytePart _buffer, ::llcpp::fuchsia::blobfs::TakeAction action) {
  if (_buffer.capacity() < CorruptBlobResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<CorruptBlobResponse*>(_buffer.data());
  CorruptBlobHandler::SetTransactionHeaderFor::CorruptBlobResponse(
      ::fidl::DecodedMessage<CorruptBlobResponse>(
          ::fidl::BytePart(reinterpret_cast<uint8_t*>(&_response),
              CorruptBlobResponse::PrimarySize,
              CorruptBlobResponse::PrimarySize)));
  _response.action = std::move(action);
  _buffer.set_actual(sizeof(CorruptBlobResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<CorruptBlobResponse>(std::move(_buffer)));
}

void CorruptBlobHandler::Interface::CorruptBlobCompleterBase::Reply(::fidl::DecodedMessage<CorruptBlobResponse> params) {
  CorruptBlobHandler::SetTransactionHeaderFor::CorruptBlobResponse(params);
  CompleterBase::SendReply(std::move(params));
}



void CorruptBlobHandler::SetTransactionHeaderFor::CorruptBlobRequest(const ::fidl::DecodedMessage<CorruptBlobHandler::CorruptBlobRequest>& _msg) {
  fidl_init_txn_header(&_msg.message()->_hdr, 0, kCorruptBlobHandler_CorruptBlob_GenOrdinal);
  _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
}
void CorruptBlobHandler::SetTransactionHeaderFor::CorruptBlobResponse(const ::fidl::DecodedMessage<CorruptBlobHandler::CorruptBlobResponse>& _msg) {
  fidl_init_txn_header(&_msg.message()->_hdr, 0, kCorruptBlobHandler_CorruptBlob_GenOrdinal);
  _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
}

namespace {

[[maybe_unused]]
constexpr uint64_t kBlobfsAdmin_HandleCorruptBlobs_Ordinal = 0x22c0c04c00000000lu;
[[maybe_unused]]
constexpr uint64_t kBlobfsAdmin_HandleCorruptBlobs_GenOrdinal = 0x5f405690ad00f87elu;
extern "C" const fidl_type_t v1_fuchsia_blobfs_BlobfsAdminHandleCorruptBlobsRequestTable;
extern "C" const fidl_type_t v1_fuchsia_blobfs_BlobfsAdminHandleCorruptBlobsResponseTable;

}  // namespace
template <>
BlobfsAdmin::ResultOf::HandleCorruptBlobs_Impl<BlobfsAdmin::HandleCorruptBlobsResponse>::HandleCorruptBlobs_Impl(::zx::unowned_channel _client_end, ::zx::channel handler) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<HandleCorruptBlobsRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, HandleCorruptBlobsRequest::PrimarySize);
  auto& _request = *reinterpret_cast<HandleCorruptBlobsRequest*>(_write_bytes);
  _request.handler = std::move(handler);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(HandleCorruptBlobsRequest));
  ::fidl::DecodedMessage<HandleCorruptBlobsRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      BlobfsAdmin::InPlace::HandleCorruptBlobs(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
}

BlobfsAdmin::ResultOf::HandleCorruptBlobs BlobfsAdmin::SyncClient::HandleCorruptBlobs(::zx::channel handler) {
    return ResultOf::HandleCorruptBlobs(::zx::unowned_channel(this->channel_), std::move(handler));
}

BlobfsAdmin::ResultOf::HandleCorruptBlobs BlobfsAdmin::Call::HandleCorruptBlobs(::zx::unowned_channel _client_end, ::zx::channel handler) {
  return ResultOf::HandleCorruptBlobs(std::move(_client_end), std::move(handler));
}

template <>
BlobfsAdmin::UnownedResultOf::HandleCorruptBlobs_Impl<BlobfsAdmin::HandleCorruptBlobsResponse>::HandleCorruptBlobs_Impl(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::zx::channel handler, ::fidl::BytePart _response_buffer) {
  if (_request_buffer.capacity() < HandleCorruptBlobsRequest::PrimarySize) {
    Super::SetFailure(::fidl::DecodeResult<HandleCorruptBlobsResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
    return;
  }
  memset(_request_buffer.data(), 0, HandleCorruptBlobsRequest::PrimarySize);
  auto& _request = *reinterpret_cast<HandleCorruptBlobsRequest*>(_request_buffer.data());
  _request.handler = std::move(handler);
  _request_buffer.set_actual(sizeof(HandleCorruptBlobsRequest));
  ::fidl::DecodedMessage<HandleCorruptBlobsRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      BlobfsAdmin::InPlace::HandleCorruptBlobs(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
}

BlobfsAdmin::UnownedResultOf::HandleCorruptBlobs BlobfsAdmin::SyncClient::HandleCorruptBlobs(::fidl::BytePart _request_buffer, ::zx::channel handler, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::HandleCorruptBlobs(::zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(handler), std::move(_response_buffer));
}

BlobfsAdmin::UnownedResultOf::HandleCorruptBlobs BlobfsAdmin::Call::HandleCorruptBlobs(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::zx::channel handler, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::HandleCorruptBlobs(std::move(_client_end), std::move(_request_buffer), std::move(handler), std::move(_response_buffer));
}

::fidl::DecodeResult<BlobfsAdmin::HandleCorruptBlobsResponse> BlobfsAdmin::InPlace::HandleCorruptBlobs(::zx::unowned_channel _client_end, ::fidl::DecodedMessage<HandleCorruptBlobsRequest> params, ::fidl::BytePart response_buffer) {
  BlobfsAdmin::SetTransactionHeaderFor::HandleCorruptBlobsRequest(params);
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<BlobfsAdmin::HandleCorruptBlobsResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<HandleCorruptBlobsRequest, HandleCorruptBlobsResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<BlobfsAdmin::HandleCorruptBlobsResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


bool BlobfsAdmin::TryDispatch(Interface* impl, fidl_msg_t* msg, ::fidl::Transaction* txn) {
  if (msg->num_bytes < sizeof(fidl_message_header_t)) {
    zx_handle_close_many(msg->handles, msg->num_handles);
    txn->Close(ZX_ERR_INVALID_ARGS);
    return true;
  }
  fidl_message_header_t* hdr = reinterpret_cast<fidl_message_header_t*>(msg->bytes);
  zx_status_t status = fidl_validate_txn_header(hdr);
  if (status != ZX_OK) {
    txn->Close(status);
    return true;
  }
  switch (hdr->ordinal) {
    case kBlobfsAdmin_HandleCorruptBlobs_Ordinal:
    case kBlobfsAdmin_HandleCorruptBlobs_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<HandleCorruptBlobsRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->HandleCorruptBlobs(std::move(message->handler),
          Interface::HandleCorruptBlobsCompleter::Sync(txn));
      return true;
    }
    default: {
      return false;
    }
  }
}

bool BlobfsAdmin::Dispatch(Interface* impl, fidl_msg_t* msg, ::fidl::Transaction* txn) {
  bool found = TryDispatch(impl, msg, txn);
  if (!found) {
    zx_handle_close_many(msg->handles, msg->num_handles);
    txn->Close(ZX_ERR_NOT_SUPPORTED);
  }
  return found;
}


void BlobfsAdmin::Interface::HandleCorruptBlobsCompleterBase::Reply(int32_t status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<HandleCorruptBlobsResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<HandleCorruptBlobsResponse*>(_write_bytes);
  BlobfsAdmin::SetTransactionHeaderFor::HandleCorruptBlobsResponse(
      ::fidl::DecodedMessage<HandleCorruptBlobsResponse>(
          ::fidl::BytePart(reinterpret_cast<uint8_t*>(&_response),
              HandleCorruptBlobsResponse::PrimarySize,
              HandleCorruptBlobsResponse::PrimarySize)));
  _response.status = std::move(status);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(HandleCorruptBlobsResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<HandleCorruptBlobsResponse>(std::move(_response_bytes)));
}

void BlobfsAdmin::Interface::HandleCorruptBlobsCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
  if (_buffer.capacity() < HandleCorruptBlobsResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<HandleCorruptBlobsResponse*>(_buffer.data());
  BlobfsAdmin::SetTransactionHeaderFor::HandleCorruptBlobsResponse(
      ::fidl::DecodedMessage<HandleCorruptBlobsResponse>(
          ::fidl::BytePart(reinterpret_cast<uint8_t*>(&_response),
              HandleCorruptBlobsResponse::PrimarySize,
              HandleCorruptBlobsResponse::PrimarySize)));
  _response.status = std::move(status);
  _buffer.set_actual(sizeof(HandleCorruptBlobsResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<HandleCorruptBlobsResponse>(std::move(_buffer)));
}

void BlobfsAdmin::Interface::HandleCorruptBlobsCompleterBase::Reply(::fidl::DecodedMessage<HandleCorruptBlobsResponse> params) {
  BlobfsAdmin::SetTransactionHeaderFor::HandleCorruptBlobsResponse(params);
  CompleterBase::SendReply(std::move(params));
}



void BlobfsAdmin::SetTransactionHeaderFor::HandleCorruptBlobsRequest(const ::fidl::DecodedMessage<BlobfsAdmin::HandleCorruptBlobsRequest>& _msg) {
  fidl_init_txn_header(&_msg.message()->_hdr, 0, kBlobfsAdmin_HandleCorruptBlobs_GenOrdinal);
  _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
}
void BlobfsAdmin::SetTransactionHeaderFor::HandleCorruptBlobsResponse(const ::fidl::DecodedMessage<BlobfsAdmin::HandleCorruptBlobsResponse>& _msg) {
  fidl_init_txn_header(&_msg.message()->_hdr, 0, kBlobfsAdmin_HandleCorruptBlobs_GenOrdinal);
  _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
}

namespace {

[[maybe_unused]]
constexpr uint64_t kBlobfs_GetAllocatedRegions_Ordinal = 0xf6a24a800000000lu;
[[maybe_unused]]
constexpr uint64_t kBlobfs_GetAllocatedRegions_GenOrdinal = 0x3e4b9606dbb8073dlu;
extern "C" const fidl_type_t v1_fuchsia_blobfs_BlobfsGetAllocatedRegionsRequestTable;
extern "C" const fidl_type_t v1_fuchsia_blobfs_BlobfsGetAllocatedRegionsResponseTable;

}  // namespace
template <>
Blobfs::ResultOf::GetAllocatedRegions_Impl<Blobfs::GetAllocatedRegionsResponse>::GetAllocatedRegions_Impl(::zx::unowned_channel _client_end) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetAllocatedRegionsRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, GetAllocatedRegionsRequest::PrimarySize);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetAllocatedRegionsRequest));
  ::fidl::DecodedMessage<GetAllocatedRegionsRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Blobfs::InPlace::GetAllocatedRegions(std::move(_client_end), Super::response_buffer()));
}

Blobfs::ResultOf::GetAllocatedRegions Blobfs::SyncClient::GetAllocatedRegions() {
    return ResultOf::GetAllocatedRegions(::zx::unowned_channel(this->channel_));
}

Blobfs::ResultOf::GetAllocatedRegions Blobfs::Call::GetAllocatedRegions(::zx::unowned_channel _client_end) {
  return ResultOf::GetAllocatedRegions(std::move(_client_end));
}

template <>
Blobfs::UnownedResultOf::GetAllocatedRegions_Impl<Blobfs::GetAllocatedRegionsResponse>::GetAllocatedRegions_Impl(::zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(GetAllocatedRegionsRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  memset(_request_buffer.data(), 0, GetAllocatedRegionsRequest::PrimarySize);
  _request_buffer.set_actual(sizeof(GetAllocatedRegionsRequest));
  ::fidl::DecodedMessage<GetAllocatedRegionsRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Blobfs::InPlace::GetAllocatedRegions(std::move(_client_end), std::move(_response_buffer)));
}

Blobfs::UnownedResultOf::GetAllocatedRegions Blobfs::SyncClient::GetAllocatedRegions(::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetAllocatedRegions(::zx::unowned_channel(this->channel_), std::move(_response_buffer));
}

Blobfs::UnownedResultOf::GetAllocatedRegions Blobfs::Call::GetAllocatedRegions(::zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetAllocatedRegions(std::move(_client_end), std::move(_response_buffer));
}

::fidl::DecodeResult<Blobfs::GetAllocatedRegionsResponse> Blobfs::InPlace::GetAllocatedRegions(::zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  constexpr uint32_t _write_num_bytes = sizeof(GetAllocatedRegionsRequest);
  ::fidl::internal::AlignedBuffer<_write_num_bytes> _write_bytes;
  ::fidl::BytePart _request_buffer = _write_bytes.view();
  _request_buffer.set_actual(_write_num_bytes);
  ::fidl::DecodedMessage<GetAllocatedRegionsRequest> params(std::move(_request_buffer));
  Blobfs::SetTransactionHeaderFor::GetAllocatedRegionsRequest(params);
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Blobfs::GetAllocatedRegionsResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<GetAllocatedRegionsRequest, GetAllocatedRegionsResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Blobfs::GetAllocatedRegionsResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


bool Blobfs::TryDispatch(Interface* impl, fidl_msg_t* msg, ::fidl::Transaction* txn) {
  if (msg->num_bytes < sizeof(fidl_message_header_t)) {
    zx_handle_close_many(msg->handles, msg->num_handles);
    txn->Close(ZX_ERR_INVALID_ARGS);
    return true;
  }
  fidl_message_header_t* hdr = reinterpret_cast<fidl_message_header_t*>(msg->bytes);
  zx_status_t status = fidl_validate_txn_header(hdr);
  if (status != ZX_OK) {
    txn->Close(status);
    return true;
  }
  switch (hdr->ordinal) {
    case kBlobfs_GetAllocatedRegions_Ordinal:
    case kBlobfs_GetAllocatedRegions_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<GetAllocatedRegionsRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->GetAllocatedRegions(
          Interface::GetAllocatedRegionsCompleter::Sync(txn));
      return true;
    }
    default: {
      return false;
    }
  }
}

bool Blobfs::Dispatch(Interface* impl, fidl_msg_t* msg, ::fidl::Transaction* txn) {
  bool found = TryDispatch(impl, msg, txn);
  if (!found) {
    zx_handle_close_many(msg->handles, msg->num_handles);
    txn->Close(ZX_ERR_NOT_SUPPORTED);
  }
  return found;
}


void Blobfs::Interface::GetAllocatedRegionsCompleterBase::Reply(int32_t status, ::zx::vmo regions, uint64_t count) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetAllocatedRegionsResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<GetAllocatedRegionsResponse*>(_write_bytes);
  Blobfs::SetTransactionHeaderFor::GetAllocatedRegionsResponse(
      ::fidl::DecodedMessage<GetAllocatedRegionsResponse>(
          ::fidl::BytePart(reinterpret_cast<uint8_t*>(&_response),
              GetAllocatedRegionsResponse::PrimarySize,
              GetAllocatedRegionsResponse::PrimarySize)));
  _response.status = std::move(status);
  _response.regions = std::move(regions);
  _response.count = std::move(count);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetAllocatedRegionsResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<GetAllocatedRegionsResponse>(std::move(_response_bytes)));
}

void Blobfs::Interface::GetAllocatedRegionsCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status, ::zx::vmo regions, uint64_t count) {
  if (_buffer.capacity() < GetAllocatedRegionsResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<GetAllocatedRegionsResponse*>(_buffer.data());
  Blobfs::SetTransactionHeaderFor::GetAllocatedRegionsResponse(
      ::fidl::DecodedMessage<GetAllocatedRegionsResponse>(
          ::fidl::BytePart(reinterpret_cast<uint8_t*>(&_response),
              GetAllocatedRegionsResponse::PrimarySize,
              GetAllocatedRegionsResponse::PrimarySize)));
  _response.status = std::move(status);
  _response.regions = std::move(regions);
  _response.count = std::move(count);
  _buffer.set_actual(sizeof(GetAllocatedRegionsResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<GetAllocatedRegionsResponse>(std::move(_buffer)));
}

void Blobfs::Interface::GetAllocatedRegionsCompleterBase::Reply(::fidl::DecodedMessage<GetAllocatedRegionsResponse> params) {
  Blobfs::SetTransactionHeaderFor::GetAllocatedRegionsResponse(params);
  CompleterBase::SendReply(std::move(params));
}



void Blobfs::SetTransactionHeaderFor::GetAllocatedRegionsRequest(const ::fidl::DecodedMessage<Blobfs::GetAllocatedRegionsRequest>& _msg) {
  fidl_init_txn_header(&_msg.message()->_hdr, 0, kBlobfs_GetAllocatedRegions_GenOrdinal);
  _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
}
void Blobfs::SetTransactionHeaderFor::GetAllocatedRegionsResponse(const ::fidl::DecodedMessage<Blobfs::GetAllocatedRegionsResponse>& _msg) {
  fidl_init_txn_header(&_msg.message()->_hdr, 0, kBlobfs_GetAllocatedRegions_GenOrdinal);
  _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
}

}  // namespace blobfs
}  // namespace fuchsia
}  // namespace llcpp
