[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: QUESTIONS 2



Jose> Angus Leeming wrote:
Jose> > Stick to the standard! I'll just have to go back and play with xdr.h. My
Jose> > version aligned everything on 64 bit boundaries. Tell me what to do here; I'm
Jose> > not clear about your meaning "we should stick to 32 bits and discard higher 
Jose> > bits".

Jose> Yes, I've noticed. I'm also not very fond of the member variables
Jose> idata, fdata,... Are you sure they're required?

No they're not. I was playing around trying to get rid of all those bl&@dy
unaligned access errors. The current code (attached) is cleaner.

However, I'll have another go at xdr.h and try and get everything on 32 bit
boundaries. At least with all this hacking I know a bit about the code! Glad to
see you're fairly happy with giop.h.

Angus
/*
 * XTL - the eXternalization Template Library
 * Copyright (C) 1998, 1999 Jose' Orlando Pereira, Universidade do Minho
 *
 * jop@di.uminho.pt - http://gsd.di.uminho.pt/~jop
 *
 * Departamento de Informatica, Universidade do Minho
 * Campus de Gualtar, 4710-057 Braga, Portugal
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 * 
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA
 *
 * $Id: xdr.h 1.10 Tue, 28 Dec 1999 18:37:31 +0000 jop $
 */

#ifndef __XTL_XDR
#define __XTL_XDR

#include <xtl/md.h>
#include <cstring>

// This is global because g++ is buggy...

// Storage types for the intrinsic types
#if (XTL_WORDLENGTH == 64)
	typedef long int word;
	typedef double   fword;
#else
	typedef int   word;
	typedef float fword;
#endif	

#if (__BYTE_ORDER == __LITTLE_ENDIAN)
inline void XDR_format_bswap_i(char const in[], char out[])
#if (XTL_WORDLENGTH == 64)
	{ *reinterpret_cast<word*>(out)=bswap_64(*reinterpret_cast<const word*>(in)); }
#else
	{ *reinterpret_cast<word*>(out)=bswap_32(*reinterpret_cast<const word*>(in)); }
#endif
inline void XDR_format_bswap_ll(char const in[], char out[])
	{ *reinterpret_cast<longlong*>(out)=bswap_64(*reinterpret_cast<const longlong*>(in)); }

#elif (__BYTE_ORDER == __BIG_ENDIAN)
inline void XDR_format_bswap_i(char in[], char out[])
	{ *reinterpret_cast<word*>(out)=*reinterpret_cast<const word*>(in); }

inline void XDR_format_bswap_ll(char in[], char out[])
	{ *reinterpret_cast<longlong*>(out)=*reinterpret_cast<const longlong*>(in); }

#else
#error "Architecture not supported."
#endif

// Macros to keep things neat and tidy in class XDR_format.
// Data is cast to store (of length WORDLENGTH or a multiple thereof)
// for storage in the character string.
#define def_input_simple_i(type1, type2) \
	void input_simple(type1& data) { \
		type2 store; \
		XDR_format_bswap_i( reinterpret_cast<char*>( require(RWORD) ), \
				    reinterpret_cast<char*>( &store ) ); \
		data = static_cast<type1>( store ); \
	} 

#define def_input_simple_ll(type1, type2) \
	void input_simple(type1& data) { \
		type2 store; \
		XDR_format_bswap_ll( reinterpret_cast<char*>( require(RLONGLONG) ), \
				     reinterpret_cast<char*>( &store ) ); \
		data = static_cast<type1>( store ); \
	} 

#define def_output_simple_i(type1, type2) \
 	void output_simple(type1 const& data) { \
		type2 store = static_cast<type2>( data ); \
		XDR_format_bswap_i( reinterpret_cast<char*>( &store ), \
				    reinterpret_cast<char*>( require(RWORD) ) ); \
	}

#define def_output_simple_ll(type1, type2) \
 	void output_simple(type1 const& data) { \
		type2 store = static_cast<type2>( data ); \
		XDR_format_bswap_ll( reinterpret_cast<char*>( &store ), \
				     reinterpret_cast<char*>( require(RLONGLONG) ) ); \
	}

template <class Buffer>
class XDR_format: public generic_format<Buffer> {
 private:
// Storage requirements for the intrinsic types
#if (XTL_WORDLENGTH == 64)
	static const int RWORD=8;
#else
	static const int RWORD=4;
#endif	
	static const int RLONGLONG=8;

 public:
 	typedef Buffer buffer;

	XDR_format(Buffer& buf):generic_format<Buffer>(buf) {}
	
	void input_start_array(int& n) {input_simple(n);}
	bool input_end_array(int& n) {return n--<=0;}

	def_input_simple_i(bool, word)
	def_input_simple_i(char, word)
	def_input_simple_i(unsigned char, word)
	def_input_simple_i(short, word)
	def_input_simple_i(unsigned short, word)
	def_input_simple_i(int, word)
	def_input_simple_i(unsigned int, word)
	def_input_simple_i(long, word)
	def_input_simple_i(unsigned long, word)
	def_input_simple_ll(longlong, longlong)
	def_input_simple_ll(unsignedlonglong, longlong)
	def_input_simple_i(float, fword)
	def_input_simple_ll(double, double)

	void input_chars(char* data, int size) {
		input_raw(data, size);
	}

	void input_raw(char* data, int size) {
		int i;
		for(i=0;i<(size>>RWORD)-1;i++,data+=256)
			memcpy(data, require(256), 256);
		int res=size-(i<<RWORD);
		memcpy(data, require(res), res);
		if (res%RWORD!=0)
			require(RWORD-res%RWORD);
	}

	void output_start_array(int n) {output_simple(n);}
	void output_end_array() {}

	def_output_simple_i(bool, word)
	def_output_simple_i(char, word)
	def_output_simple_i(unsigned char, word)
	def_output_simple_i(short, word)
	def_output_simple_i(unsigned short, word)
	def_output_simple_i(int, word)
	def_output_simple_i(unsigned int, word)
	def_output_simple_i(long, word)
	def_output_simple_i(unsigned long, word)
	def_output_simple_ll(longlong, longlong)
	def_output_simple_ll(unsignedlonglong, longlong)
	def_output_simple_i(float, fword)
	def_output_simple_ll(double, double)

	void output_chars(char const* data, int size) {
		output_raw(data, size);
	}

	void output_raw(char const* data, int size) {
		int i;
		for(i=0;i<(size>>RWORD)-1;i++,data+=256)
			memcpy(require(256), data, 256);
		int res=size-(i<<RWORD);
		memcpy(require(res), data, res);
		if (res%RWORD!=0)
			memset(require(RWORD-res%RWORD), 0, RWORD-res%RWORD);
	}
};

#undef def_input_simple_i
#undef def_input_simple_ll
#undef def_output_simple_i
#undef def_output_simple_ll

#endif