| /* This module exports part of the C API to the XDR routines into Python. |
| * 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 |
| * 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. |
| * |
| * 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. |
| */ |
| |
| #include "Python.h" |
| |
| #include <rpc/rpc.h> |
| #include <rpc/xdr.h> |
| |
| static PyObject* xdr_error; |
| |
| |
| |
| static PyObject* |
| pack_float(self, args) |
| PyObject* self; |
| PyObject* args; |
| { |
| 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; |
| } |
| |
| |
| |
| static PyObject* |
| pack_double(self, args) |
| PyObject* self; |
| PyObject* args; |
| { |
| 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; |
| } |
| |
| |
| |
| static PyObject* |
| unpack_float(self, args) |
| PyObject* self; |
| PyObject* args; |
| { |
| XDR xdr; |
| float value; |
| char* string; |
| int strlen; |
| PyObject* rtn = NULL; |
| |
| if (!PyArg_ParseTuple(args, "s#", &string, &strlen)) |
| return NULL; |
| |
| if (strlen != 4) { |
| PyErr_SetString(PyExc_ValueError, "4 byte string expected"); |
| return NULL; |
| } |
| |
| /* Python guarantees that the string is 4 byte aligned */ |
| 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; |
| } |
| |
| |
| |
| static PyObject* |
| unpack_double(self, args) |
| PyObject* self; |
| PyObject* args; |
| { |
| XDR xdr; |
| double value; |
| char* string; |
| int strlen; |
| PyObject* rtn = NULL; |
| |
| if (!PyArg_ParseTuple(args, "s#", &string, &strlen)) |
| return NULL; |
| |
| if (strlen != 8) { |
| PyErr_SetString(PyExc_ValueError, "8 byte string expected"); |
| return NULL; |
| } |
| |
| /* Python guarantees that the string is 4 byte aligned */ |
| 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; |
| } |
| |
| |
| |
| static struct PyMethodDef |
| xdr_methods[] = { |
| {"pack_float", pack_float, 1}, |
| {"pack_double", pack_double, 1}, |
| {"unpack_float", unpack_float, 1}, |
| {"unpack_double", unpack_double, 1}, |
| {NULL, NULL, 0} /* sentinel */ |
| }; |
| |
| |
| |
| void |
| init_xdr() |
| { |
| PyObject* module; |
| PyObject* dict; |
| |
| module = Py_InitModule("_xdr", xdr_methods); |
| dict = PyModule_GetDict(module); |
| |
| xdr_error = PyString_FromString("_xdr.error"); |
| PyDict_SetItemString(dict, "error", xdr_error); |
| } |