blob: 731bf347965607bc9dcb3e9993ea102930dcffb9 [file] [log] [blame]
Guido van Rossum73363b51996-08-19 22:58:53 +00001/* This module exports part of the C API to the XDR routines into Python.
Barry Warsaw10f124c1996-12-17 00:01:40 +00002 * XDR is Sun's eXternal Data Representation, as described in RFC 1014.
3 * This module is used by xdrlib.py to support the float and double data
4 * types which are too much of a pain to support in Python directly. It is
Guido van Rossum73363b51996-08-19 22:58:53 +00005 * not required by xdrlib.py -- when not available, these types aren't
6 * supported at the Python layer. Note that representations that can be
7 * implemented solely in Python, are *not* reproduced here.
8 *
9 * Module version number: 1.0
10 *
11 * See xdrlib.py for usage notes.
12 *
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000013 * Note: this has so far, only been tested on Solaris 2.5 and IRIX 5.3. On
14 * these systems, you will need to link with -lnsl for these symbols to be
15 * defined.
Guido van Rossum73363b51996-08-19 22:58:53 +000016 */
17
18#include "Python.h"
19
Guido van Rossum73363b51996-08-19 22:58:53 +000020#include <rpc/rpc.h>
21#include <rpc/xdr.h>
22
23static PyObject* xdr_error;
24
25
26
27static PyObject*
28pack_float(self, args)
Barry Warsaw10f124c1996-12-17 00:01:40 +000029 PyObject* self;
30 PyObject* args;
Guido van Rossum73363b51996-08-19 22:58:53 +000031{
Barry Warsaw10f124c1996-12-17 00:01:40 +000032 XDR xdr;
33 float value;
34 union { /* guarantees proper alignment */
35 long dummy;
36 char buffer[4];
37 } addr;
38 PyObject* rtn = NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +000039
Barry Warsaw10f124c1996-12-17 00:01:40 +000040 if (!PyArg_ParseTuple(args, "f", &value))
41 return NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +000042
Barry Warsaw10f124c1996-12-17 00:01:40 +000043 xdr.x_ops = NULL;
44 xdrmem_create(&xdr, addr.buffer, 4, XDR_ENCODE);
45 if (xdr.x_ops == NULL)
46 PyErr_SetString(xdr_error,
47 "XDR stream initialization failed.");
48 else if (xdr_float(&xdr, &value))
49 rtn = PyString_FromStringAndSize(addr.buffer, 4);
50 else
51 PyErr_SetString(xdr_error, "conversion from float failed");
Guido van Rossum73363b51996-08-19 22:58:53 +000052
Barry Warsaw10f124c1996-12-17 00:01:40 +000053 xdr_destroy(&xdr);
54 return rtn;
Guido van Rossum73363b51996-08-19 22:58:53 +000055}
56
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000057
58
Guido van Rossum73363b51996-08-19 22:58:53 +000059static PyObject*
60pack_double(self, args)
Barry Warsaw10f124c1996-12-17 00:01:40 +000061 PyObject* self;
62 PyObject* args;
Guido van Rossum73363b51996-08-19 22:58:53 +000063{
Barry Warsaw10f124c1996-12-17 00:01:40 +000064 XDR xdr;
65 double value;
66 union { /* guarantees proper alignment */
67 long dummy;
68 char buffer[8];
69 } addr;
70 PyObject* rtn = NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +000071
Barry Warsaw10f124c1996-12-17 00:01:40 +000072 if (!PyArg_ParseTuple(args, "d", &value))
73 return NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +000074
Barry Warsaw10f124c1996-12-17 00:01:40 +000075 xdr.x_ops = NULL;
76 xdrmem_create(&xdr, addr.buffer, 8, XDR_ENCODE);
77 if (xdr.x_ops == NULL)
78 PyErr_SetString(xdr_error,
79 "XDR stream initialization failed.");
80 else if (xdr_double(&xdr, &value))
81 rtn = PyString_FromStringAndSize(addr.buffer, 8);
82 else
83 PyErr_SetString(xdr_error, "conversion from double failed");
Guido van Rossum73363b51996-08-19 22:58:53 +000084
Barry Warsaw10f124c1996-12-17 00:01:40 +000085 xdr_destroy(&xdr);
86 return rtn;
Guido van Rossum73363b51996-08-19 22:58:53 +000087}
88
89
90
91static PyObject*
92unpack_float(self, args)
Barry Warsaw10f124c1996-12-17 00:01:40 +000093 PyObject* self;
94 PyObject* args;
Guido van Rossum73363b51996-08-19 22:58:53 +000095{
Barry Warsaw10f124c1996-12-17 00:01:40 +000096 XDR xdr;
97 float value;
98 char* string;
99 int strlen;
100 PyObject* rtn = NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +0000101
Barry Warsaw10f124c1996-12-17 00:01:40 +0000102 if (!PyArg_ParseTuple(args, "s#", &string, &strlen))
103 return NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +0000104
Barry Warsaw10f124c1996-12-17 00:01:40 +0000105 if (strlen != 4) {
106 PyErr_SetString(PyExc_ValueError, "4 byte string expected");
107 return NULL;
108 }
Guido van Rossum73363b51996-08-19 22:58:53 +0000109
110 /* Python guarantees that the string is 4 byte aligned */
Barry Warsaw10f124c1996-12-17 00:01:40 +0000111 xdr.x_ops = NULL;
112 xdrmem_create(&xdr, (caddr_t)string, 4, XDR_DECODE);
113 if (xdr.x_ops == NULL)
114 PyErr_SetString(xdr_error,
115 "XDR stream initialization failed.");
116 else if (xdr_float(&xdr, &value))
117 rtn = Py_BuildValue("f", value);
118 else
119 PyErr_SetString(xdr_error, "conversion to float failed");
Guido van Rossum73363b51996-08-19 22:58:53 +0000120
Barry Warsaw10f124c1996-12-17 00:01:40 +0000121 xdr_destroy(&xdr);
122 return rtn;
Guido van Rossum73363b51996-08-19 22:58:53 +0000123}
124
125
Guido van Rossumd62d8bc1996-08-20 19:47:44 +0000126
Guido van Rossum73363b51996-08-19 22:58:53 +0000127static PyObject*
128unpack_double(self, args)
Barry Warsaw10f124c1996-12-17 00:01:40 +0000129 PyObject* self;
130 PyObject* args;
Guido van Rossum73363b51996-08-19 22:58:53 +0000131{
Barry Warsaw10f124c1996-12-17 00:01:40 +0000132 XDR xdr;
133 double value;
134 char* string;
135 int strlen;
136 PyObject* rtn = NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +0000137
Barry Warsaw10f124c1996-12-17 00:01:40 +0000138 if (!PyArg_ParseTuple(args, "s#", &string, &strlen))
139 return NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +0000140
Barry Warsaw10f124c1996-12-17 00:01:40 +0000141 if (strlen != 8) {
142 PyErr_SetString(PyExc_ValueError, "8 byte string expected");
143 return NULL;
144 }
Guido van Rossum73363b51996-08-19 22:58:53 +0000145
146 /* Python guarantees that the string is 4 byte aligned */
Barry Warsaw10f124c1996-12-17 00:01:40 +0000147 xdr.x_ops = NULL;
148 xdrmem_create(&xdr, (caddr_t)string, 8, XDR_DECODE);
149 if (xdr.x_ops == NULL)
150 PyErr_SetString(xdr_error,
151 "XDR stream initialization failed.");
152 else if (xdr_double(&xdr, &value))
153 rtn = Py_BuildValue("d", value);
154 else
155 PyErr_SetString(xdr_error, "conversion to double failed");
Guido van Rossum73363b51996-08-19 22:58:53 +0000156
Barry Warsaw10f124c1996-12-17 00:01:40 +0000157 xdr_destroy(&xdr);
158 return rtn;
Guido van Rossum73363b51996-08-19 22:58:53 +0000159}
160
161
162
163static struct PyMethodDef
164xdr_methods[] = {
Barry Warsaw10f124c1996-12-17 00:01:40 +0000165 {"pack_float", pack_float, 1},
166 {"pack_double", pack_double, 1},
167 {"unpack_float", unpack_float, 1},
168 {"unpack_double", unpack_double, 1},
169 {NULL, NULL, 0} /* sentinel */
Guido van Rossum73363b51996-08-19 22:58:53 +0000170};
171
172
173
174void
175init_xdr()
176{
Barry Warsaw10f124c1996-12-17 00:01:40 +0000177 PyObject* module;
178 PyObject* dict;
Guido van Rossum73363b51996-08-19 22:58:53 +0000179
Barry Warsaw10f124c1996-12-17 00:01:40 +0000180 module = Py_InitModule("_xdr", xdr_methods);
181 dict = PyModule_GetDict(module);
Guido van Rossum73363b51996-08-19 22:58:53 +0000182
Barry Warsaw10f124c1996-12-17 00:01:40 +0000183 xdr_error = PyString_FromString("_xdr.error");
184 PyDict_SetItemString(dict, "error", xdr_error);
185 if (PyErr_Occurred())
186 Py_FatalError("can't initialize module _xdr");
Guido van Rossum73363b51996-08-19 22:58:53 +0000187}