Commit e1058170 authored by Daniel Friesel's avatar Daniel Friesel
Browse files

Switch to an OS-independent XDR implementation for protocol evaluations

parent bfd8f297
Loading
Loading
Loading
Loading

include/lib/xdr.h

0 → 100644
+66 −0
Original line number Diff line number Diff line
#ifndef XDR_H
#define XDR_H

#include <stdint.h>

class XDRWriter
{
private:
	XDRWriter(const XDRWriter &copy);
	char *buffer;
	uint32_t next_array_len;
	uint32_t pos;
	bool is_fixed_length;

public:
	XDRWriter(char *output_buf) : buffer(output_buf), next_array_len(0), pos(0) {}

	inline void setNextArrayLen(uint32_t len) { next_array_len = len; }
	inline void setFixedLength() { is_fixed_length = true; }
	inline void setVariableLength() { is_fixed_length = false; }
	inline void startList()
	{
		if (!is_fixed_length)
		{
			put(next_array_len);
		}
	}

	inline void put(char c) { put((int32_t)c); }
	inline void put(unsigned char c) { put((uint32_t)c); }
	inline void put(uint16_t number) { put((int32_t)number); }
	inline void put(int16_t number) { put((uint32_t)number); }
	void put(uint32_t number);
	void put(int32_t number);
	void put(uint64_t number);
	void put(int64_t number);
	void put(float number);
	void put(double number);
	void put(char const *text);
	template <uint32_t TSize>
	void put(char const (&text)[TSize]);

	inline uint32_t size() { return pos; }
};

class XDRReader
{
private:
	XDRReader(const XDRReader &copy);
	char *data;
	uint32_t pos;

public:
	XDRReader(char *d) : pos(0) { data = d; }
	uint32_t get_uint32();
	int32_t get_int32();
	uint64_t get_uint64();
	int64_t get_int64();
	float get_float();
	double get_double();
	uint32_t get_opaque_length();
	char *get_opaque(uint32_t length);
	void get_string(char *target);
};

#endif

include/lib/xdr16.h

0 → 100644
+68 −0
Original line number Diff line number Diff line
#ifndef XDR16_H
#define XDR16_H

#include <stdint.h>

class XDRWriter
{
private:
	XDRWriter(const XDRWriter &copy);
	char *buffer;
	uint16_t next_array_len;
	uint16_t pos;
	bool is_fixed_length;

public:
	XDRWriter(char *output_buf) : buffer(output_buf), next_array_len(0), pos(0) {}

	inline void setNextArrayLen(uint16_t len) { next_array_len = len; }
	inline void setFixedLength() { is_fixed_length = true; }
	inline void setVariableLength() { is_fixed_length = false; }
	inline void startList()
	{
		if (!is_fixed_length)
		{
			put(next_array_len);
		}
	}

	inline void put(char c) { put((int16_t)c); }
	inline void put(unsigned char c) { put((uint16_t)c); }
	void put(uint16_t number);
	void put(int16_t number);
	void put(uint32_t number);
	void put(int32_t number);
	void put(uint64_t number);
	void put(int64_t number);
	void put(float number);
	void put(double number);
	void put(char const *text);
	template <uint16_t TSize>
	void put(char const (&text)[TSize]);

	inline uint16_t size() { return pos; }
};

class XDRReader
{
private:
	XDRReader(const XDRReader &copy);
	char *data;
	uint32_t pos;

public:
	XDRReader(char *d) : pos(0) { data = d; }
	int16_t get_int16();
	uint16_t get_uint16();
	uint32_t get_uint32();
	int32_t get_int32();
	uint64_t get_uint64();
	int64_t get_int64();
	float get_float();
	double get_double();
	uint32_t get_opaque_length();
	char *get_opaque(uint32_t length);
	void get_string(char *target);
};

#endif
+2 −2
Original line number Diff line number Diff line
@@ -69,12 +69,12 @@ endif

ifeq (${prototest_xdr}, 1)
	COMMON_FLAGS += -DPROTOTEST_XDR
	CXX_TARGETS += src/os/object/xdrstream.cc src/os/object/xdrinput.cc
	CXX_TARGETS += src/lib/xdr.cc
endif

ifeq (${prototest_xdr16}, 1)
	COMMON_FLAGS += -DPROTOTEST_XDR16
	CXX_TARGETS += src/os/object/xdr16stream.cc src/os/object/xdr16input.cc
	CXX_TARGETS += src/lib/xdr16.cc
endif

# Don't try to make .capnp from .capnp.c
+2 −6
Original line number Diff line number Diff line
@@ -35,14 +35,10 @@
#include "ubj.h"
#endif
#ifdef PROTOTEST_XDR
#include "object/stdbuf.h"
#include "object/xdrstream.h"
#include "object/xdrinput.h"
#include "lib/xdr.h"
#endif
#ifdef PROTOTEST_XDR16
#include "object/stdbuf.h"
#include "object/xdr16stream.h"
#include "object/xdr16input.h"
#include "lib/xdr16.h"
#endif

#include <stdint.h>

src/lib/xdr.cc

0 → 100644
+187 −0
Original line number Diff line number Diff line
#include "lib/xdr.h"


void XDRWriter::put(uint32_t number)
{
	*buffer++ = ((number >> 24) & 0xffU);
	*buffer++ = ((number >> 16) & 0xffU);
	*buffer++ = ((number >> 8) & 0xffU);
	*buffer++ = (number & 0xffU);
	pos += 4;
}

void XDRWriter::put(int32_t number)
{
	*buffer++ = ((number >> 24) & 0xffU);
	*buffer++ = ((number >> 16) & 0xffU);
	*buffer++ = ((number >> 8) & 0xffU);
	*buffer++ = (number & 0xffU);
	pos += 4;
}

void XDRWriter::put(uint64_t number)
{
	*buffer++ = ((number >> 56) & 0xffU);
	*buffer++ = ((number >> 48) & 0xffU);
	*buffer++ = ((number >> 40) & 0xffU);
	*buffer++ = ((number >> 32) & 0xffU);
	*buffer++ = ((number >> 24) & 0xffU);
	*buffer++ = ((number >> 16) & 0xffU);
	*buffer++ = ((number >> 8) & 0xffU);
	*buffer++ = (number & 0xffU);
	pos += 8;
}

void XDRWriter::put(int64_t number)
{
	*buffer++ = ((number >> 56) & 0xffU);
	*buffer++ = ((number >> 48) & 0xffU);
	*buffer++ = ((number >> 40) & 0xffU);
	*buffer++ = ((number >> 32) & 0xffU);
	*buffer++ = ((number >> 24) & 0xffU);
	*buffer++ = ((number >> 16) & 0xffU);
	*buffer++ = ((number >> 8) & 0xffU);
	*buffer++ = (number & 0xffU);
	pos += 8;
}

void XDRWriter::put(float number)
{
	union {
		uint32_t i;
		float f;
	} v;
	// Setting one member of a struct and then reading another is undefined
	// behaviour, but works as intended in nearly any (embedded) compiler
	v.f = number;
	put(v.i);
}

void XDRWriter::put(double number)
{
	union {
		uint64_t i;
		double d;
	} v;
	// Setting one member of a struct and then reading another is undefined
	// behaviour, but works as intended in nearly any (embedded) compiler
	v.d = number;
	put(v.i);
}

void XDRWriter::put(char const *data){
	if (!is_fixed_length) {
		put(next_array_len);
	}
	uint32_t i;
	for (i = 0; i < next_array_len; i++) {
		*buffer++ = data[i];
	}
	while ((i++) % 4 != 0){
		*buffer++ = 0;
	}
	pos += i;
}

template<uint32_t TSize>
void XDRWriter::put(char const (&data)[TSize]){
	if (!is_fixed_length) {
		put(TSize);
	}
	uint32_t i;
	for (i = 0; i < TSize; i++) {
		*buffer++ = data[i];
	}
	while ((i++) % 4 != 0){
		*buffer++ = 0;
	}
	pos += i;
}

uint32_t XDRReader::get_uint32()
{
	uint32_t ret = ((uint8_t)data[pos]<<24) | ((uint8_t)data[pos+1]<<16)
		| ((uint8_t)data[pos+2]<<8) | (uint8_t)data[pos+3];
	pos += 4;
	return ret;
}

int32_t XDRReader::get_int32()
{
	int32_t ret = (data[pos]<<24) | (data[pos+1]<<16) | (data[pos+2]<<8) | data[pos+3];
	pos += 4;
	return ret;
}

uint64_t XDRReader::get_uint64()
{
	uint64_t ret0 = ((uint8_t)data[pos]<<24) | ((uint8_t)data[pos+1]<<16)
		| ((uint8_t)data[pos+2]<<8) | (uint8_t)data[pos+3];
	pos += 4;
	uint64_t ret1 = ((uint8_t)data[pos]<<24) | ((uint8_t)data[pos+1]<<16)
		| ((uint8_t)data[pos+2]<<8) | (uint8_t)data[pos+3];
	pos += 4;
	return (ret0 << 32) | ret1;
}

int64_t XDRReader::get_int64()
{
	int64_t ret0 = (data[pos]<<24) | (data[pos+1]<<16) | (data[pos+2]<<8) | data[pos+3];
	pos += 4;
	int64_t ret1 = (data[pos]<<24) | (data[pos+1]<<16) | (data[pos+2]<<8) | data[pos+3];
	pos += 4;
	return (ret0 << 32) | ret1;
}

float XDRReader::get_float()
{
	union {
		uint32_t i;
		float f;
	} v;
	// Setting one member of a struct and then reading another is undefined
	// behaviour, but works as intended in nearly any (embedded) compiler
	v.i = get_uint32();
	return v.f;
}

double XDRReader::get_double()
{
	union {
		uint64_t i;
		double d;
	} v;
	// Setting one member of a struct and then reading another is undefined
	// behaviour, but works as intended in nearly any (embedded) compiler
	v.i = get_uint64();
	return v.d;
}

uint32_t XDRReader::get_opaque_length()
{
	return get_uint32();
}

char *XDRReader::get_opaque(uint32_t length)
{
	char *ret = data + pos;
	pos += length;
	if (length % 4) {
		pos += 4 - (length % 4);
	}
	return ret;
}

void XDRReader::get_string(char* target)
{
	uint16_t length = get_opaque_length();
	uint16_t i;
	for (i = 0; i < length; i++) {
		target[i] = data[pos + i];
	}
	target[i] = 0;
	pos += length;
	if (length % 4) {
		pos += 4 - (length % 4);
	}
}
Loading