1996-08-19 19:58:53 -03:00
|
|
|
|
/* This module exports part of the C API to the XDR routines into Python.
|
1996-12-16 20:01:40 -04:00
|
|
|
|
* XDR is Sun's eXternal Data Representation, as described in RFC 1014.
|
|
|
|
|
* This module is used by xdrlib.py to support the float and double data
|
|
|
|
|
* types which are too much of a pain to support in Python directly. It is
|
1996-08-19 19:58:53 -03:00
|
|
|
|
* not required by xdrlib.py -- when not available, these types aren't
|
|
|
|
|
* supported at the Python layer. Note that representations that can be
|
|
|
|
|
* implemented solely in Python, are *not* reproduced here.
|
|
|
|
|
*
|
|
|
|
|
* Module version number: 1.0
|
|
|
|
|
*
|
|
|
|
|
* See xdrlib.py for usage notes.
|
|
|
|
|
*
|
1996-08-20 16:47:44 -03:00
|
|
|
|
* Note: this has so far, only been tested on Solaris 2.5 and IRIX 5.3. On
|
|
|
|
|
* these systems, you will need to link with -lnsl for these symbols to be
|
|
|
|
|
* defined.
|
1996-08-19 19:58:53 -03:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "Python.h"
|
|
|
|
|
|
|
|
|
|
#include <rpc/rpc.h>
|
|
|
|
|
#include <rpc/xdr.h>
|
|
|
|
|
|
|
|
|
|
static PyObject* xdr_error;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static PyObject*
|
|
|
|
|
pack_float(self, args)
|
1996-12-16 20:01:40 -04:00
|
|
|
|
PyObject* self;
|
|
|
|
|
PyObject* args;
|
1996-08-19 19:58:53 -03:00
|
|
|
|
{
|
1996-12-16 20:01:40 -04:00
|
|
|
|
XDR xdr;
|
|
|
|
|
float value;
|
|
|
|
|
union { /* guarantees proper alignment */
|
|
|
|
|
long dummy;
|
|
|
|
|
char buffer[4];
|
|
|
|
|
} addr;
|
|
|
|
|
PyObject* rtn = NULL;
|
|
|
|
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "f", &value))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
xdr.x_ops = NULL;
|
|
|
|
|
xdrmem_create(&xdr, addr.buffer, 4, XDR_ENCODE);
|
|
|
|
|
if (xdr.x_ops == NULL)
|
|
|
|
|
PyErr_SetString(xdr_error,
|
|
|
|
|
"XDR stream initialization failed.");
|
|
|
|
|
else if (xdr_float(&xdr, &value))
|
|
|
|
|
rtn = PyString_FromStringAndSize(addr.buffer, 4);
|
|
|
|
|
else
|
|
|
|
|
PyErr_SetString(xdr_error, "conversion from float failed");
|
|
|
|
|
|
|
|
|
|
xdr_destroy(&xdr);
|
|
|
|
|
return rtn;
|
1996-08-19 19:58:53 -03:00
|
|
|
|
}
|
|
|
|
|
|
1996-08-20 16:47:44 -03:00
|
|
|
|
|
|
|
|
|
|
1996-08-19 19:58:53 -03:00
|
|
|
|
static PyObject*
|
|
|
|
|
pack_double(self, args)
|
1996-12-16 20:01:40 -04:00
|
|
|
|
PyObject* self;
|
|
|
|
|
PyObject* args;
|
1996-08-19 19:58:53 -03:00
|
|
|
|
{
|
1996-12-16 20:01:40 -04:00
|
|
|
|
XDR xdr;
|
|
|
|
|
double value;
|
|
|
|
|
union { /* guarantees proper alignment */
|
|
|
|
|
long dummy;
|
|
|
|
|
char buffer[8];
|
|
|
|
|
} addr;
|
|
|
|
|
PyObject* rtn = NULL;
|
|
|
|
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "d", &value))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
xdr.x_ops = NULL;
|
|
|
|
|
xdrmem_create(&xdr, addr.buffer, 8, XDR_ENCODE);
|
|
|
|
|
if (xdr.x_ops == NULL)
|
|
|
|
|
PyErr_SetString(xdr_error,
|
|
|
|
|
"XDR stream initialization failed.");
|
|
|
|
|
else if (xdr_double(&xdr, &value))
|
|
|
|
|
rtn = PyString_FromStringAndSize(addr.buffer, 8);
|
|
|
|
|
else
|
|
|
|
|
PyErr_SetString(xdr_error, "conversion from double failed");
|
|
|
|
|
|
|
|
|
|
xdr_destroy(&xdr);
|
|
|
|
|
return rtn;
|
1996-08-19 19:58:53 -03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static PyObject*
|
|
|
|
|
unpack_float(self, args)
|
1996-12-16 20:01:40 -04:00
|
|
|
|
PyObject* self;
|
|
|
|
|
PyObject* args;
|
1996-08-19 19:58:53 -03:00
|
|
|
|
{
|
1996-12-16 20:01:40 -04:00
|
|
|
|
XDR xdr;
|
|
|
|
|
float value;
|
|
|
|
|
char* string;
|
|
|
|
|
int strlen;
|
|
|
|
|
PyObject* rtn = NULL;
|
1996-08-19 19:58:53 -03:00
|
|
|
|
|
1996-12-16 20:01:40 -04:00
|
|
|
|
if (!PyArg_ParseTuple(args, "s#", &string, &strlen))
|
|
|
|
|
return NULL;
|
1996-08-19 19:58:53 -03:00
|
|
|
|
|
1996-12-16 20:01:40 -04:00
|
|
|
|
if (strlen != 4) {
|
|
|
|
|
PyErr_SetString(PyExc_ValueError, "4 byte string expected");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
1996-08-19 19:58:53 -03:00
|
|
|
|
|
|
|
|
|
/* Python guarantees that the string is 4 byte aligned */
|
1996-12-16 20:01:40 -04:00
|
|
|
|
xdr.x_ops = NULL;
|
|
|
|
|
xdrmem_create(&xdr, (caddr_t)string, 4, XDR_DECODE);
|
|
|
|
|
if (xdr.x_ops == NULL)
|
|
|
|
|
PyErr_SetString(xdr_error,
|
|
|
|
|
"XDR stream initialization failed.");
|
|
|
|
|
else if (xdr_float(&xdr, &value))
|
|
|
|
|
rtn = Py_BuildValue("f", value);
|
|
|
|
|
else
|
|
|
|
|
PyErr_SetString(xdr_error, "conversion to float failed");
|
|
|
|
|
|
|
|
|
|
xdr_destroy(&xdr);
|
|
|
|
|
return rtn;
|
1996-08-19 19:58:53 -03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1996-08-20 16:47:44 -03:00
|
|
|
|
|
1996-08-19 19:58:53 -03:00
|
|
|
|
static PyObject*
|
|
|
|
|
unpack_double(self, args)
|
1996-12-16 20:01:40 -04:00
|
|
|
|
PyObject* self;
|
|
|
|
|
PyObject* args;
|
1996-08-19 19:58:53 -03:00
|
|
|
|
{
|
1996-12-16 20:01:40 -04:00
|
|
|
|
XDR xdr;
|
|
|
|
|
double value;
|
|
|
|
|
char* string;
|
|
|
|
|
int strlen;
|
|
|
|
|
PyObject* rtn = NULL;
|
1996-08-19 19:58:53 -03:00
|
|
|
|
|
1996-12-16 20:01:40 -04:00
|
|
|
|
if (!PyArg_ParseTuple(args, "s#", &string, &strlen))
|
|
|
|
|
return NULL;
|
1996-08-19 19:58:53 -03:00
|
|
|
|
|
1996-12-16 20:01:40 -04:00
|
|
|
|
if (strlen != 8) {
|
|
|
|
|
PyErr_SetString(PyExc_ValueError, "8 byte string expected");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
1996-08-19 19:58:53 -03:00
|
|
|
|
|
|
|
|
|
/* Python guarantees that the string is 4 byte aligned */
|
1996-12-16 20:01:40 -04:00
|
|
|
|
xdr.x_ops = NULL;
|
|
|
|
|
xdrmem_create(&xdr, (caddr_t)string, 8, XDR_DECODE);
|
|
|
|
|
if (xdr.x_ops == NULL)
|
|
|
|
|
PyErr_SetString(xdr_error,
|
|
|
|
|
"XDR stream initialization failed.");
|
|
|
|
|
else if (xdr_double(&xdr, &value))
|
|
|
|
|
rtn = Py_BuildValue("d", value);
|
|
|
|
|
else
|
|
|
|
|
PyErr_SetString(xdr_error, "conversion to double failed");
|
|
|
|
|
|
|
|
|
|
xdr_destroy(&xdr);
|
|
|
|
|
return rtn;
|
1996-08-19 19:58:53 -03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct PyMethodDef
|
|
|
|
|
xdr_methods[] = {
|
1996-12-16 20:01:40 -04:00
|
|
|
|
{"pack_float", pack_float, 1},
|
|
|
|
|
{"pack_double", pack_double, 1},
|
|
|
|
|
{"unpack_float", unpack_float, 1},
|
|
|
|
|
{"unpack_double", unpack_double, 1},
|
|
|
|
|
{NULL, NULL, 0} /* sentinel */
|
1996-08-19 19:58:53 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
init_xdr()
|
|
|
|
|
{
|
1996-12-16 20:01:40 -04:00
|
|
|
|
PyObject* module;
|
|
|
|
|
PyObject* dict;
|
1996-08-19 19:58:53 -03:00
|
|
|
|
|
1996-12-16 20:01:40 -04:00
|
|
|
|
module = Py_InitModule("_xdr", xdr_methods);
|
|
|
|
|
dict = PyModule_GetDict(module);
|
1996-08-19 19:58:53 -03:00
|
|
|
|
|
1996-12-16 20:01:40 -04:00
|
|
|
|
xdr_error = PyString_FromString("_xdr.error");
|
|
|
|
|
PyDict_SetItemString(dict, "error", xdr_error);
|
|
|
|
|
if (PyErr_Occurred())
|
|
|
|
|
Py_FatalError("can't initialize module _xdr");
|
1996-08-19 19:58:53 -03:00
|
|
|
|
}
|