blob: 42e545f17a11a401fedbcbc3b76518e5e5004e4c [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.
2 * XDR is Sun's eXternal Data Representation, as described in RFC 1014. This
3 * module is used by xdrlib.py to support the float and double data types
4 * which are too much of a pain to support in Python directly. It is
5 * 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
20#include <netconfig.h>
21#include <rpc/rpc.h>
22#include <rpc/xdr.h>
23
24static PyObject* xdr_error;
25
26
27
28static PyObject*
29pack_float(self, args)
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000030 PyObject* self;
31 PyObject* args;
Guido van Rossum73363b51996-08-19 22:58:53 +000032{
33 XDR xdr;
34 float value;
35 union { /* guarantees proper alignment */
36 long dummy;
37 char buffer[4];
38 } addr;
39 PyObject* rtn = NULL;
40
41 if (!PyArg_ParseTuple(args, "f", &value))
42 return NULL;
43
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000044 xdr.x_ops = NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +000045 xdrmem_create(&xdr, addr.buffer, 4, XDR_ENCODE);
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000046 if( xdr.x_ops == NULL )
47 PyErr_SetString(xdr_error, "XDR stream initialization failed.");
48 else if (xdr_float(&xdr, &value))
Guido van Rossum73363b51996-08-19 22:58:53 +000049 rtn = PyString_FromStringAndSize(addr.buffer, 4);
50 else
51 PyErr_SetString(xdr_error, "conversion from float failed");
52
53 xdr_destroy(&xdr);
54 return rtn;
55}
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)
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000061 PyObject* self;
62 PyObject* args;
Guido van Rossum73363b51996-08-19 22:58:53 +000063{
64 XDR xdr;
65 double value;
66 union { /* guarantees proper alignment */
67 long dummy;
68 char buffer[8];
69 } addr;
70 PyObject* rtn = NULL;
71
72 if (!PyArg_ParseTuple(args, "d", &value))
73 return NULL;
74
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000075 xdr.x_ops = NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +000076 xdrmem_create(&xdr, addr.buffer, 8, XDR_ENCODE);
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000077 if( xdr.x_ops == NULL )
78 PyErr_SetString(xdr_error, "XDR stream initialization failed.");
79 else if (xdr_double(&xdr, &value))
Guido van Rossum73363b51996-08-19 22:58:53 +000080 rtn = PyString_FromStringAndSize(addr.buffer, 8);
81 else
82 PyErr_SetString(xdr_error, "conversion from double failed");
83
84 xdr_destroy(&xdr);
85 return rtn;
86}
87
88
89
90static PyObject*
91unpack_float(self, args)
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000092 PyObject* self;
93 PyObject* args;
Guido van Rossum73363b51996-08-19 22:58:53 +000094{
95 XDR xdr;
96 float value;
97 char* string;
98 int strlen;
99 PyObject* rtn = NULL;
100
101 if (!PyArg_ParseTuple(args, "s#", &string, &strlen))
102 return NULL;
103
104 if (strlen != 4) {
105 PyErr_SetString(PyExc_ValueError, "4 byte string expected");
106 return NULL;
107 }
108
109 /* Python guarantees that the string is 4 byte aligned */
Guido van Rossumd62d8bc1996-08-20 19:47:44 +0000110 xdr.x_ops = NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +0000111 xdrmem_create(&xdr, (caddr_t)string, 4, XDR_DECODE);
Guido van Rossumd62d8bc1996-08-20 19:47:44 +0000112 if( xdr.x_ops == NULL )
113 PyErr_SetString(xdr_error, "XDR stream initialization failed.");
114 else if (xdr_float(&xdr, &value))
Guido van Rossum73363b51996-08-19 22:58:53 +0000115 rtn = Py_BuildValue("f", value);
116 else
117 PyErr_SetString(xdr_error, "conversion to float failed");
118
119 xdr_destroy(&xdr);
120 return rtn;
121}
122
123
Guido van Rossumd62d8bc1996-08-20 19:47:44 +0000124
Guido van Rossum73363b51996-08-19 22:58:53 +0000125static PyObject*
126unpack_double(self, args)
Guido van Rossumd62d8bc1996-08-20 19:47:44 +0000127 PyObject* self;
128 PyObject* args;
Guido van Rossum73363b51996-08-19 22:58:53 +0000129{
130 XDR xdr;
131 double value;
132 char* string;
133 int strlen;
134 PyObject* rtn;
135
136 if (!PyArg_ParseTuple(args, "s#", &string, &strlen))
137 return NULL;
138
139 if (strlen != 8) {
140 PyErr_SetString(PyExc_ValueError, "8 byte string expected");
141 return NULL;
142 }
143
144 /* Python guarantees that the string is 4 byte aligned */
Guido van Rossumd62d8bc1996-08-20 19:47:44 +0000145 xdr.x_ops = NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +0000146 xdrmem_create(&xdr, (caddr_t)string, 8, XDR_DECODE);
Guido van Rossumd62d8bc1996-08-20 19:47:44 +0000147 if( xdr.x_ops == NULL )
148 PyErr_SetString(xdr_error, "XDR stream initialization failed.");
149 else if (xdr_double(&xdr, &value))
Guido van Rossum73363b51996-08-19 22:58:53 +0000150 rtn = Py_BuildValue("d", value);
151 else
152 PyErr_SetString(xdr_error, "conversion to double failed");
153
154 xdr_destroy(&xdr);
155 return rtn;
156}
157
158
159
160static struct PyMethodDef
161xdr_methods[] = {
162 {"pack_float", pack_float, 1},
163 {"pack_double", pack_double, 1},
164 {"unpack_float", unpack_float, 1},
165 {"unpack_double", unpack_double, 1},
166 {NULL, NULL, 0} /* sentinel */
167};
168
169
170
171void
172init_xdr()
173{
174 PyObject* module;
175 PyObject* dict;
176
177 module = Py_InitModule("_xdr", xdr_methods);
178 dict = PyModule_GetDict(module);
179
180 xdr_error = PyString_FromString("_xdr.error");
181 PyDict_SetItemString(dict, "error", xdr_error);
182}