blob: d2c94536a2980027d5dccf4a6f4c0cb76058fa7a [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
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)
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000029 PyObject* self;
30 PyObject* args;
Guido van Rossum73363b51996-08-19 22:58:53 +000031{
32 XDR xdr;
33 float value;
34 union { /* guarantees proper alignment */
35 long dummy;
36 char buffer[4];
37 } addr;
38 PyObject* rtn = NULL;
39
40 if (!PyArg_ParseTuple(args, "f", &value))
41 return NULL;
42
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000043 xdr.x_ops = NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +000044 xdrmem_create(&xdr, addr.buffer, 4, XDR_ENCODE);
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000045 if( xdr.x_ops == NULL )
46 PyErr_SetString(xdr_error, "XDR stream initialization failed.");
47 else if (xdr_float(&xdr, &value))
Guido van Rossum73363b51996-08-19 22:58:53 +000048 rtn = PyString_FromStringAndSize(addr.buffer, 4);
49 else
50 PyErr_SetString(xdr_error, "conversion from float failed");
51
52 xdr_destroy(&xdr);
53 return rtn;
54}
55
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000056
57
Guido van Rossum73363b51996-08-19 22:58:53 +000058static PyObject*
59pack_double(self, args)
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000060 PyObject* self;
61 PyObject* args;
Guido van Rossum73363b51996-08-19 22:58:53 +000062{
63 XDR xdr;
64 double value;
65 union { /* guarantees proper alignment */
66 long dummy;
67 char buffer[8];
68 } addr;
69 PyObject* rtn = NULL;
70
71 if (!PyArg_ParseTuple(args, "d", &value))
72 return NULL;
73
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000074 xdr.x_ops = NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +000075 xdrmem_create(&xdr, addr.buffer, 8, XDR_ENCODE);
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000076 if( xdr.x_ops == NULL )
77 PyErr_SetString(xdr_error, "XDR stream initialization failed.");
78 else if (xdr_double(&xdr, &value))
Guido van Rossum73363b51996-08-19 22:58:53 +000079 rtn = PyString_FromStringAndSize(addr.buffer, 8);
80 else
81 PyErr_SetString(xdr_error, "conversion from double failed");
82
83 xdr_destroy(&xdr);
84 return rtn;
85}
86
87
88
89static PyObject*
90unpack_float(self, args)
Guido van Rossumd62d8bc1996-08-20 19:47:44 +000091 PyObject* self;
92 PyObject* args;
Guido van Rossum73363b51996-08-19 22:58:53 +000093{
94 XDR xdr;
95 float value;
96 char* string;
97 int strlen;
98 PyObject* rtn = NULL;
99
100 if (!PyArg_ParseTuple(args, "s#", &string, &strlen))
101 return NULL;
102
103 if (strlen != 4) {
104 PyErr_SetString(PyExc_ValueError, "4 byte string expected");
105 return NULL;
106 }
107
108 /* Python guarantees that the string is 4 byte aligned */
Guido van Rossumd62d8bc1996-08-20 19:47:44 +0000109 xdr.x_ops = NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +0000110 xdrmem_create(&xdr, (caddr_t)string, 4, XDR_DECODE);
Guido van Rossumd62d8bc1996-08-20 19:47:44 +0000111 if( xdr.x_ops == NULL )
112 PyErr_SetString(xdr_error, "XDR stream initialization failed.");
113 else if (xdr_float(&xdr, &value))
Guido van Rossum73363b51996-08-19 22:58:53 +0000114 rtn = Py_BuildValue("f", value);
115 else
116 PyErr_SetString(xdr_error, "conversion to float failed");
117
118 xdr_destroy(&xdr);
119 return rtn;
120}
121
122
Guido van Rossumd62d8bc1996-08-20 19:47:44 +0000123
Guido van Rossum73363b51996-08-19 22:58:53 +0000124static PyObject*
125unpack_double(self, args)
Guido van Rossumd62d8bc1996-08-20 19:47:44 +0000126 PyObject* self;
127 PyObject* args;
Guido van Rossum73363b51996-08-19 22:58:53 +0000128{
129 XDR xdr;
130 double value;
131 char* string;
132 int strlen;
Guido van Rossum6c0b2341996-08-30 20:39:43 +0000133 PyObject* rtn = NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +0000134
135 if (!PyArg_ParseTuple(args, "s#", &string, &strlen))
136 return NULL;
137
138 if (strlen != 8) {
139 PyErr_SetString(PyExc_ValueError, "8 byte string expected");
140 return NULL;
141 }
142
143 /* Python guarantees that the string is 4 byte aligned */
Guido van Rossumd62d8bc1996-08-20 19:47:44 +0000144 xdr.x_ops = NULL;
Guido van Rossum73363b51996-08-19 22:58:53 +0000145 xdrmem_create(&xdr, (caddr_t)string, 8, XDR_DECODE);
Guido van Rossumd62d8bc1996-08-20 19:47:44 +0000146 if( xdr.x_ops == NULL )
147 PyErr_SetString(xdr_error, "XDR stream initialization failed.");
148 else if (xdr_double(&xdr, &value))
Guido van Rossum73363b51996-08-19 22:58:53 +0000149 rtn = Py_BuildValue("d", value);
150 else
151 PyErr_SetString(xdr_error, "conversion to double failed");
152
153 xdr_destroy(&xdr);
154 return rtn;
155}
156
157
158
159static struct PyMethodDef
160xdr_methods[] = {
161 {"pack_float", pack_float, 1},
162 {"pack_double", pack_double, 1},
163 {"unpack_float", unpack_float, 1},
164 {"unpack_double", unpack_double, 1},
165 {NULL, NULL, 0} /* sentinel */
166};
167
168
169
170void
171init_xdr()
172{
173 PyObject* module;
174 PyObject* dict;
175
176 module = Py_InitModule("_xdr", xdr_methods);
177 dict = PyModule_GetDict(module);
178
179 xdr_error = PyString_FromString("_xdr.error");
180 PyDict_SetItemString(dict, "error", xdr_error);
181}