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

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

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

//
// Domain objects definitions (i.e. "natural types" in unified bindings)
//
namespace fidl {
namespace test {
namespace byteandbytes {

extern "C" const fidl_type_t fidl_test_byteandbytes_ByteAndBytesTable;
const fidl_type_t* ByteAndBytes::FidlType =
    &fidl_test_byteandbytes_ByteAndBytesTable;

void ByteAndBytes::Encode(::fidl::Encoder* _encoder, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<ByteAndBytes>::value) {
    memcpy(_encoder->template GetPtr<ByteAndBytes>(_offset), this,
           sizeof(ByteAndBytes));
  } else {
    ::fidl::Encode(_encoder, &single_byte, _offset + 0);
    ::fidl::Encode(_encoder, &many_bytes, _offset + 8);
    ::fidl::Encode(_encoder, &only_one_k_bytes, _offset + 24);
    ::fidl::Encode(_encoder, &opt_only_one_k_bytes, _offset + 40);
  }
}

void ByteAndBytes::Decode(::fidl::Decoder* _decoder, ByteAndBytes* _value,
                          size_t _offset) {
  if (::fidl::IsMemcpyCompatible<ByteAndBytes>::value) {
    memcpy(_value, _decoder->template GetPtr<ByteAndBytes>(_offset),
           sizeof(ByteAndBytes));
  } else {
    ::fidl::Decode(_decoder, &_value->single_byte, _offset + 0);
    ::fidl::Decode(_decoder, &_value->many_bytes, _offset + 8);
    ::fidl::Decode(_decoder, &_value->only_one_k_bytes, _offset + 24);
    ::fidl::Decode(_decoder, &_value->opt_only_one_k_bytes, _offset + 40);
  }
}

zx_status_t ByteAndBytes::Clone(ByteAndBytes* _result) const {
  zx_status_t _status = ::fidl::Clone(single_byte, &_result->single_byte);
  if (_status != ZX_OK) return _status;
  _status = ::fidl::Clone(many_bytes, &_result->many_bytes);
  if (_status != ZX_OK) return _status;
  _status = ::fidl::Clone(only_one_k_bytes, &_result->only_one_k_bytes);
  if (_status != ZX_OK) return _status;
  _status = ::fidl::Clone(opt_only_one_k_bytes, &_result->opt_only_one_k_bytes);
  if (_status != ZX_OK) return _status;
  return ZX_OK;
}
}  // namespace byteandbytes
}  // namespace test
}  // namespace fidl

//
// Proxies and stubs definitions
//
namespace fidl {
namespace test {
namespace byteandbytes {}  // namespace byteandbytes
}  // namespace test
}  // namespace fidl
