Skip to content
Snippets Groups Projects
Commit e1058170 authored by Daniel Friesel's avatar Daniel Friesel
Browse files

Switch to an OS-independent XDR implementation for protocol evaluations

parent bfd8f297
No related branches found
No related tags found
No related merge requests found
#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
#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
......@@ -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
......
......@@ -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>
......
#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);
}
}
#include "lib/xdr16.h"
void XDRWriter::put(uint16_t number)
{
*buffer++ = ((number >> 8) & 0xffU);
*buffer++ = (number & 0xffU);
pos += 2;
}
void XDRWriter::put(int16_t number)
{
*buffer++ = ((number >> 8) & 0xffU);
*buffer++ = (number & 0xffU);
pos += 2;
}
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);
}
uint16_t i;
for (i = 0; i < next_array_len; i++) {
*buffer++ = data[i];
}
while ((i++) % 2 != 0){
*buffer++ = 0;
}
pos += i;
}
template<uint16_t TSize>
void XDRWriter::put(char const (&data)[TSize]){
if (!is_fixed_length) {
put(TSize);
}
uint16_t i;
for (i = 0; i < TSize; i++) {
*buffer++ = data[i];
}
while ((i++) % 2 != 0){
*buffer++ = 0;
}
pos += i;
}
uint16_t XDRReader::get_uint16()
{
uint16_t ret = ((uint8_t)data[pos]<<8) | (uint8_t)data[pos+1];
pos += 2;
return ret;
}
int16_t XDRReader::get_int16()
{
int16_t ret = (data[pos]<<8) | data[pos+1];
pos += 2;
return ret;
}
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_uint16();
}
char *XDRReader::get_opaque(uint32_t length)
{
char *ret = data + pos;
pos += length;
if (length % 2) {
pos += 2 - (length % 2);
}
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 % 2) {
pos += 2 - (length % 2);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment