Index: source/_ctypes.c
===================================================================
RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v
retrieving revision 1.226.2.36
diff -c -r1.226.2.36 _ctypes.c
*** source/_ctypes.c	8 Nov 2005 20:34:23 -0000	1.226.2.36
--- source/_ctypes.c	14 Nov 2005 18:50:10 -0000
***************
*** 1934,1939 ****
--- 1934,1952 ----
  	return (PyObject *)pd;
  }
  
+ char *IsExactSimpleType(PyObject *obj)
+ {
+ 	PyTypeObject *type = (PyTypeObject *)obj;
+ 	
+ 	/* Is the first check really needed? */
+ 	if (SimpleTypeObject_Check(type) && type->tp_base == &Simple_Type) {
+ 		StgDictObject *dict = PyType_stgdict(obj);
+ 		assert(PyString_Check(dict->proto));
+ 		return PyString_AS_STRING(dict->proto);
+ 	}
+ 	return NULL;
+ }
+ 
  PyObject *
  CData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
  	  int index, int size, char *adr)
Index: source/cfield.c
===================================================================
RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v
retrieving revision 1.74.2.7
diff -c -r1.74.2.7 cfield.c
*** source/cfield.c	14 Nov 2005 18:43:31 -0000	1.74.2.7
--- source/cfield.c	14 Nov 2005 18:50:11 -0000
***************
*** 43,54 ****
--- 43,61 ----
  	SETFUNC setfunc = NULL;
  	GETFUNC getfunc = NULL;
  	StgDictObject *dict;
+ 	int native_order;
  	int fieldtype;
  #define NO_BITFIELD 0
  #define NEW_BITFIELD 1
  #define CONT_BITFIELD 2
  #define EXPAND_BITFIELD 3
  
+ #ifdef IS_BIG_ENDIAN
+ 	native_order = 1;
+ #else
+ 	native_order = 0;
+ #endif
+ 
  	self = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type,
  						   NULL);
  	if (self == NULL)
***************
*** 94,99 ****
--- 101,128 ----
  	length = dict->length;
  	proto = desc;
  
+ 	getfunc = dict->getfunc;
+ 	setfunc = dict->setfunc;
+ 
+ 	/* Python's struct module doesn't allow to specify the byte
+ 	   order for structures that contain pointers.  Should we do
+ 	   the same?  Or should we disallow non-native byte order for
+ 	   structures containing anything else than characters, ints
+ 	   and floats/doubles?
+ 
+ 	   We could raise an error if 
+ 	*/
+ 	if (big_endian != native_order) {
+ 		extern char *IsExactSimpleType(PyObject *obj);
+ 		struct fielddesc *fd;
+ 		char *code = IsExactSimpleType(desc);
+ 		if (code) {
+ 			fd = getentry(code);
+ 			getfunc = fd->swapped_getfunc;
+ 			setfunc = fd->swapped_setfunc;
+ 		}
+ 	}
+ 
  	/*  Field descriptors for 'c_char * n' are be scpecial cased to
  	    return a Python string instead of an Array object instance...
  	*/
***************
*** 301,307 ****
  	0,					/* tp_free */
  };
  
! 
  /******************************************************************/
  /*
    Accessor functions
--- 330,336 ----
  	0,					/* tp_free */
  };
  
! 	
  /******************************************************************/
  /*
    Accessor functions
***************
*** 443,448 ****
--- 472,488 ----
   * integer accessor methods, supporting bit fields
   */
  
+ /* byte swapping macros */
+ #define SWAP_2(v)				\
+ 	( ( (v >> 8) & 0x00FF) |		\
+ 	  ( (v << 8) & 0xFF00) )
+ 
+ #define SWAP_4(v)			\
+ 	( ( (v & 0x000000FF) << 24 ) |  \
+ 	  ( (v & 0x0000FF00) <<  8 ) |  \
+ 	  ( (v & 0x00FF0000) >>  8 ) |  \
+ 	  ( ((v >> 24) & 0xFF)) )
+ 
  static PyObject *
  b_set(void *ptr, PyObject *value, unsigned size)
  {
***************
*** 612,617 ****
--- 652,671 ----
  	_RET(value);
  }
  
+ static PyObject *
+ sw_L_set(void *ptr, PyObject *value, unsigned size)
+ {
+ 	unsigned long val;
+ 	unsigned long field;
+ 	if (get_ulong(value, &val) < 0)
+ 		return  NULL;
+ 	field = *(unsigned long *)ptr;
+ 	field = SWAP_4(field);
+ 	field = SET(field, val, size);
+ 	field = SWAP_4(field);
+ 	*(unsigned long *)ptr = field;
+ 	_RET(value);
+ }
  
  static PyObject *
  L_get(void *ptr, unsigned size)
***************
*** 621,626 ****
--- 675,690 ----
  	return PyLong_FromUnsignedLong(val);
  }
  
+ static PyObject *
+ sw_L_get(void *ptr, unsigned size)
+ {
+ 	unsigned long val = *(unsigned long *)ptr;
+ 	val = SWAP_4(val);
+ 	GET_BITFIELD(val, size);
+ 	val = SWAP_4(val);
+ 	return PyLong_FromUnsignedLong(val);
+ }
+ 
  #ifdef HAVE_LONG_LONG
  static PyObject *
  q_set(void *ptr, PyObject *value, unsigned size)
***************
*** 1134,1140 ****
  	{ 's', s_set, s_get, &ffi_type_pointer},
  	{ 'b', b_set, b_get, &ffi_type_schar},
  	{ 'B', B_set, B_get, &ffi_type_uchar},
! 	{ 'c', c_set, c_get, &ffi_type_schar},
  	{ 'd', d_set, d_get, &ffi_type_double},
  	{ 'f', f_set, f_get, &ffi_type_float},
  	{ 'h', h_set, h_get, &ffi_type_sshort},
--- 1198,1204 ----
  	{ 's', s_set, s_get, &ffi_type_pointer},
  	{ 'b', b_set, b_get, &ffi_type_schar},
  	{ 'B', B_set, B_get, &ffi_type_uchar},
! 	{ 'c', c_set, c_get, &ffi_type_schar, c_set, c_get },
  	{ 'd', d_set, d_get, &ffi_type_double},
  	{ 'f', f_set, f_get, &ffi_type_float},
  	{ 'h', h_set, h_get, &ffi_type_sshort},
***************
*** 1144,1154 ****
  /* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */
  /* As soon as we can get rid of the type codes, this is no longer a problem */
  #if SIZEOF_LONG == 4
! 	{ 'l', l_set, l_get, &ffi_type_sint},
! 	{ 'L', L_set, L_get, &ffi_type_uint},
  #elif SIZEOF_LONG == 8
! 	{ 'l', l_set, l_get, &ffi_type_slong},
! 	{ 'L', L_set, L_get, &ffi_type_ulong},
  #else
  # error
  #endif
--- 1208,1218 ----
  /* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */
  /* As soon as we can get rid of the type codes, this is no longer a problem */
  #if SIZEOF_LONG == 4
! 	{ 'l', l_set, l_get, &ffi_type_sint, sw_L_set, sw_L_get},
! 	{ 'L', L_set, L_get, &ffi_type_uint, sw_L_set, sw_L_get},
  #elif SIZEOF_LONG == 8
! 	{ 'l', l_set, l_get, &ffi_type_slong, sw_L_set, sw_L_get},
! 	{ 'L', L_set, L_get, &ffi_type_ulong, sw_L_set, sw_L_get},
  #else
  # error
  #endif
Index: source/ctypes.h
===================================================================
RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v
retrieving revision 1.74.2.6
diff -c -r1.74.2.6 ctypes.h
*** source/ctypes.h	11 Nov 2005 08:10:26 -0000	1.74.2.6
--- source/ctypes.h	14 Nov 2005 18:50:11 -0000
***************
*** 158,163 ****
--- 158,165 ----
  	SETFUNC setfunc;
  	GETFUNC getfunc;
  	ffi_type *pffi_type; /* always statically allocated */
+ 	SETFUNC swapped_setfunc;
+ 	GETFUNC swapped_getfunc;
  };
  
  typedef struct {
Index: source/stgdict.c
===================================================================
RCS file: /cvsroot/ctypes/ctypes/source/stgdict.c,v
retrieving revision 1.32.2.3
diff -c -r1.32.2.3 stgdict.c
*** source/stgdict.c	11 Nov 2005 08:10:26 -0000	1.32.2.3
--- source/stgdict.c	14 Nov 2005 18:50:11 -0000
***************
*** 215,220 ****
--- 215,224 ----
  	} else
  		PyErr_Clear();
  
+ 	if (PyObject_HasAttrString(type, "_swapped_")) {
+ 		big_endian = !big_endian;
+ 	}
+ 
  	len = PySequence_Length(fields);
  	if (len == -1) {
  		PyErr_SetString(PyExc_TypeError,
Index: ctypes/test/test_byteswap.py
===================================================================
RCS file: /cvsroot/ctypes/ctypes/ctypes/test/Attic/test_byteswap.py,v
retrieving revision 1.1.2.2
diff -c -r1.1.2.2 test_byteswap.py
*** ctypes/test/test_byteswap.py	10 Nov 2005 21:14:55 -0000	1.1.2.2
--- ctypes/test/test_byteswap.py	14 Nov 2005 18:50:11 -0000
***************
*** 7,16 ****
  requires("swap")
  
  class BITS(Structure):
      _fields_ = [("i%d" % i, c_uint, 1) for i in range(32)]
  
  for i in range(32):
!     print getattr(BITS, "i%d" % i)
  
  def dump(s):
      print hexlify(buffer(s))
--- 7,19 ----
  requires("swap")
  
  class BITS(Structure):
+     _swapped_ = 1
      _fields_ = [("i%d" % i, c_uint, 1) for i in range(32)]
  
  for i in range(32):
!     field = getattr(BITS, "i%d" % i)
!     print field
!     print field.offset, hex(field.size)
  
  def dump(s):
      print hexlify(buffer(s))
