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

// fidl_experiment = output_index_json

#include <test/drivertwoway/cpp/fidl.h>

#include "lib/fidl/cpp/internal/implementation.h"

//
// Domain objects definitions
//
namespace test {
namespace drivertwoway {

extern "C" const fidl_type_t test_drivertwoway_TwoWayAddRequestTable;
const fidl_type_t* TwoWayAddRequest::FidlType = &test_drivertwoway_TwoWayAddRequestTable;

void TwoWayAddRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                              cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<TwoWayAddRequest>::value) {
    memcpy(_encoder->template GetPtr<TwoWayAddRequest>(_offset), this, sizeof(TwoWayAddRequest));
  } else {
    ::fidl::Encode(_encoder, &addend1, _offset + 0);
    ::fidl::Encode(_encoder, &addend2, _offset + 2);
  }
}

void TwoWayAddRequest::Decode(::fidl::Decoder* _decoder, TwoWayAddRequest* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<TwoWayAddRequest>::value) {
    memcpy(_value, _decoder->template GetPtr<TwoWayAddRequest>(_offset), sizeof(TwoWayAddRequest));
  } else {
    ::fidl::Decode(_decoder, &_value->addend1, _offset + 0);
    ::fidl::Decode(_decoder, &_value->addend2, _offset + 2);
  }
}

zx_status_t TwoWayAddRequest::Clone(TwoWayAddRequest* _result) const {
  zx_status_t _status = ::fidl::Clone(addend1, &_result->addend1);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(addend2, &_result->addend2);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

extern "C" const fidl_type_t test_drivertwoway_TwoWayAddResponseTable;
const fidl_type_t* TwoWayAddResponse::FidlType = &test_drivertwoway_TwoWayAddResponseTable;

void TwoWayAddResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                               cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<TwoWayAddResponse>::value) {
    memcpy(_encoder->template GetPtr<TwoWayAddResponse>(_offset), this, sizeof(TwoWayAddResponse));
  } else {
    ::fidl::Encode(_encoder, &sum, _offset + 0);
  }
}

void TwoWayAddResponse::Decode(::fidl::Decoder* _decoder, TwoWayAddResponse* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<TwoWayAddResponse>::value) {
    memcpy(_value, _decoder->template GetPtr<TwoWayAddResponse>(_offset), sizeof(TwoWayAddResponse));
  } else {
    ::fidl::Decode(_decoder, &_value->sum, _offset + 0);
  }
}

zx_status_t TwoWayAddResponse::Clone(TwoWayAddResponse* _result) const {
  zx_status_t _status = ::fidl::Clone(sum, &_result->sum);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

//
// Proxies and stubs definitions
//
}  // namespace drivertwoway
}  // namespace test
