blob: 27a8d5cff622a1ba0f1b5e73baa60b301e0b9195 [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 *
13 * Note: this has so far, only been tested on Solaris 2.5 and SGI IRIX 5.3.
14 * On these systems, you will need to link with -lnsl for these
15 * symbols to be defined.
16 */
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)
30 PyObject* self;
31 PyObject* args;
32{
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
44 xdrmem_create(&xdr, addr.buffer, 4, XDR_ENCODE);
45 if (xdr_float(&xdr, &value))
46 rtn = PyString_FromStringAndSize(addr.buffer, 4);
47 else
48 PyErr_SetString(xdr_error, "conversion from float failed");
49
50 xdr_destroy(&xdr);
51 return rtn;
52}
53
54static PyObject*
55pack_double(self, args)
56 PyObject* self;
57 PyObject* args;
58{
59 XDR xdr;
60 double value;
61 union { /* guarantees proper alignment */
62 long dummy;
63 char buffer[8];
64 } addr;
65 PyObject* rtn = NULL;
66
67 if (!PyArg_ParseTuple(args, "d", &value))
68 return NULL;
69
70 xdrmem_create(&xdr, addr.buffer, 8, XDR_ENCODE);
71 if (xdr_double(&xdr, &value))
72 rtn = PyString_FromStringAndSize(addr.buffer, 8);
73 else
74 PyErr_SetString(xdr_error, "conversion from double failed");
75
76 xdr_destroy(&xdr);
77 return rtn;
78}
79
80
81
82static PyObject*
83unpack_float(self, args)
84 PyObject* self;
85 PyObject* args;
86{
87 XDR xdr;
88 float value;
89 char* string;
90 int strlen;
91 PyObject* rtn = NULL;
92
93 if (!PyArg_ParseTuple(args, "s#", &string, &strlen))
94 return NULL;
95
96 if (strlen != 4) {
97 PyErr_SetString(PyExc_ValueError, "4 byte string expected");
98 return NULL;
99 }
100
101 /* Python guarantees that the string is 4 byte aligned */
102 xdrmem_create(&xdr, (caddr_t)string, 4, XDR_DECODE);
103 if (xdr_float(&xdr, &value))
104 rtn = Py_BuildValue("f", value);
105 else
106 PyErr_SetString(xdr_error, "conversion to float failed");
107
108 xdr_destroy(&xdr);
109 return rtn;
110}
111
112
113static PyObject*
114unpack_double(self, args)
115 PyObject* self;
116 PyObject* args;
117{
118 XDR xdr;
119 double value;
120 char* string;
121 int strlen;
122 PyObject* rtn;
123
124 if (!PyArg_ParseTuple(args, "s#", &string, &strlen))
125 return NULL;
126
127 if (strlen != 8) {
128 PyErr_SetString(PyExc_ValueError, "8 byte string expected");
129 return NULL;
130 }
131
132 /* Python guarantees that the string is 4 byte aligned */
133 xdrmem_create(&xdr, (caddr_t)string, 8, XDR_DECODE);
134 if (xdr_double(&xdr, &value))
135 rtn = Py_BuildValue("d", value);
136 else
137 PyErr_SetString(xdr_error, "conversion to double failed");
138
139 xdr_destroy(&xdr);
140 return rtn;
141}
142
143
144
145static struct PyMethodDef
146xdr_methods[] = {
147 {"pack_float", pack_float, 1},
148 {"pack_double", pack_double, 1},
149 {"unpack_float", unpack_float, 1},
150 {"unpack_double", unpack_double, 1},
151 {NULL, NULL, 0} /* sentinel */
152};
153
154
155
156void
157init_xdr()
158{
159 PyObject* module;
160 PyObject* dict;
161
162 module = Py_InitModule("_xdr", xdr_methods);
163 dict = PyModule_GetDict(module);
164
165 xdr_error = PyString_FromString("_xdr.error");
166 PyDict_SetItemString(dict, "error", xdr_error);
167}