#pragma once
#if defined(_WIN32)
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#if defined(HAVE_LIBTIRPC)
#include <cstdint>
#include <cstring>
#include <cstdio>
#include <Winsock2.h>
uint32_t constexpr W32_XDR_DECODE = 0U;
uint32_t constexpr W32_XDR_ENCODE = 1U;
struct Win32XDR
{
FILE* file;
struct
{
char* data;
char* dataCursor;
size_t memSize;
} nonFileMem;
uint32_t fileMode;
};
void w32_xdrstdio_create(Win32XDR* xdrs, FILE* file, uint32_t op);
void w32_xdr_destroy(Win32XDR* xdrs);
void w32_xdrmem_create(
Win32XDR* xdrs, char* addr, unsigned int size,
uint32_t op
);
template<typename T>
bool w32_internal_xdr_write_raw_bytes(Win32XDR* xdr, T& data)
{
if (xdr->file != nullptr)
{
auto written = fwrite(&data, sizeof(T), 1, xdr->file);
return written == 1;
}
else
{
memcpy(xdr->nonFileMem.dataCursor, reinterpret_cast<char*>(&data), sizeof(T));
xdr->nonFileMem.dataCursor += sizeof(T);
return true;
}
}
template<typename T>
bool w32_internal_xdr_read_raw_bytes(Win32XDR* xdr, T& result)
{
if (xdr->file != nullptr)
{
auto readNum = fread(&result, sizeof(T), 1, xdr->file);
return readNum == 1;
}
else
{
result = *reinterpret_cast<T*>(xdr->nonFileMem.dataCursor);
xdr->nonFileMem.dataCursor += sizeof(T);
return xdr->nonFileMem.dataCursor <= xdr->nonFileMem.data + xdr->nonFileMem.memSize;
}
}
template<typename THostType>
struct w32_internal_xdr_conv_fn {};
template<>
struct w32_internal_xdr_conv_fn<uint8_t>
{
typedef uint8_t NetType;
static uint8_t identity(uint8_t in)
{
return in;
}
static auto constexpr host2NetFn = identity;
static auto constexpr net2HostFn = identity;
};
template<>
struct w32_internal_xdr_conv_fn<uint16_t>
{
typedef u_short NetType;
static auto constexpr host2NetFn = htons;
static auto constexpr net2HostFn = ntohs;
};
template<>
struct w32_internal_xdr_conv_fn<uint32_t>
{
typedef unsigned __int32 NetType;
static auto constexpr host2NetFn = htonl;
static auto constexpr net2HostFn = ntohl;
};
template<>
struct w32_internal_xdr_conv_fn<uint64_t>
{
typedef unsigned __int64 NetType;
static auto constexpr host2NetFn = htonll;
static auto constexpr net2HostFn = ntohll;
};
template<>
struct w32_internal_xdr_conv_fn<double>
{
typedef unsigned __int64 NetType;
static auto constexpr host2NetFn = htond;
static auto constexpr net2HostFn = ntohd;
};
template<>
struct w32_internal_xdr_conv_fn<float>
{
typedef unsigned __int32 NetType;
static auto constexpr host2NetFn = htonf;
static auto constexpr net2HostFn = ntohf;
};
template<typename THostType>
bool w32_internal_xdr_u_type(Win32XDR* xdrs, THostType* ip)
{
typedef w32_internal_xdr_conv_fn<THostType>::NetType NetType;
static_assert(sizeof(NetType) == sizeof(THostType));
if (xdrs->fileMode == W32_XDR_DECODE)
{
NetType rawValue;
auto const result = w32_internal_xdr_read_raw_bytes<NetType>(xdrs, rawValue);
if (result)
{
*ip = w32_internal_xdr_conv_fn<THostType>::net2HostFn(rawValue);
}
return result;
}
else
{
NetType translated = w32_internal_xdr_conv_fn<THostType>::host2NetFn(*ip);
return w32_internal_xdr_write_raw_bytes<NetType>(xdrs, translated);
}
}
bool w32_xdr_int32_t(Win32XDR* xdrs, int32_t* ip);
bool w32_xdr_u_int32_t(Win32XDR* xdrs, uint32_t* ip);
bool w32_xdr_int64_t(Win32XDR* xdrs, int64_t* ip);
bool w32_xdr_u_int64_t(Win32XDR* xdrs, uint64_t* ip);
bool w32_xdr_int16_t(Win32XDR* xdrs, int16_t* ip);
bool w32_xdr_u_int16_t(Win32XDR* xdrs, uint16_t* ip);
bool w32_xdr_char(Win32XDR* xdrs, char* ip);
bool w32_xdr_u_char(Win32XDR* xdrs, unsigned char* ip);
bool w32_xdr_float(Win32XDR* xdrs, float* ip);
bool w32_xdr_double(Win32XDR* xdrs, double* ip);
typedef Win32XDR XDR;
#define xdrstdio_create w32_xdrstdio_create
#define xdr_destroy w32_xdr_destroy
#define xdrmem_create w32_xdrmem_create
#define xdr_int16_t w32_xdr_int16_t
#define xdr_u_int16_t w32_xdr_u_int16_t
#define xdr_int32_t w32_xdr_int32_t
#define xdr_u_int32_t w32_xdr_u_int32_t
#define xdr_int64_t w32_xdr_int64_t
#define xdr_u_int64_t w32_xdr_u_int64_t
#define xdr_char w32_xdr_char
#define xdr_u_char w32_xdr_u_char
#define xdr_float w32_xdr_float
#define xdr_double w32_xdr_double
#define XDR_DECODE W32_XDR_DECODE
#define XDR_ENCODE W32_XDR_ENCODE
#endif
#endif