##// END OF EJS Templates
base85: clean up function definition style...
Augie Fackler -
r27060:4613a89b default
parent child Browse files
Show More
@@ -1,185 +1,182 b''
1 /*
1 /*
2 base85 codec
2 base85 codec
3
3
4 Copyright 2006 Brendan Cully <brendan@kublai.com>
4 Copyright 2006 Brendan Cully <brendan@kublai.com>
5
5
6 This software may be used and distributed according to the terms of
6 This software may be used and distributed according to the terms of
7 the GNU General Public License, incorporated herein by reference.
7 the GNU General Public License, incorporated herein by reference.
8
8
9 Largely based on git's implementation
9 Largely based on git's implementation
10 */
10 */
11
11
12 #define PY_SSIZE_T_CLEAN
12 #define PY_SSIZE_T_CLEAN
13 #include <Python.h>
13 #include <Python.h>
14
14
15 #include "util.h"
15 #include "util.h"
16
16
17 static const char b85chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
17 static const char b85chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
18 "abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
18 "abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
19 static char b85dec[256];
19 static char b85dec[256];
20
20
21 static void
21 static void b85prep(void)
22 b85prep(void)
23 {
22 {
24 unsigned i;
23 unsigned i;
25
24
26 memset(b85dec, 0, sizeof(b85dec));
25 memset(b85dec, 0, sizeof(b85dec));
27 for (i = 0; i < sizeof(b85chars); i++)
26 for (i = 0; i < sizeof(b85chars); i++)
28 b85dec[(int)(b85chars[i])] = i + 1;
27 b85dec[(int)(b85chars[i])] = i + 1;
29 }
28 }
30
29
31 static PyObject *
30 static PyObject *b85encode(PyObject *self, PyObject *args)
32 b85encode(PyObject *self, PyObject *args)
33 {
31 {
34 const unsigned char *text;
32 const unsigned char *text;
35 PyObject *out;
33 PyObject *out;
36 char *dst;
34 char *dst;
37 Py_ssize_t len, olen, i;
35 Py_ssize_t len, olen, i;
38 unsigned int acc, val, ch;
36 unsigned int acc, val, ch;
39 int pad = 0;
37 int pad = 0;
40
38
41 if (!PyArg_ParseTuple(args, "s#|i", &text, &len, &pad))
39 if (!PyArg_ParseTuple(args, "s#|i", &text, &len, &pad))
42 return NULL;
40 return NULL;
43
41
44 if (pad)
42 if (pad)
45 olen = ((len + 3) / 4 * 5) - 3;
43 olen = ((len + 3) / 4 * 5) - 3;
46 else {
44 else {
47 olen = len % 4;
45 olen = len % 4;
48 if (olen)
46 if (olen)
49 olen++;
47 olen++;
50 olen += len / 4 * 5;
48 olen += len / 4 * 5;
51 }
49 }
52 if (!(out = PyBytes_FromStringAndSize(NULL, olen + 3)))
50 if (!(out = PyBytes_FromStringAndSize(NULL, olen + 3)))
53 return NULL;
51 return NULL;
54
52
55 dst = PyBytes_AsString(out);
53 dst = PyBytes_AsString(out);
56
54
57 while (len) {
55 while (len) {
58 acc = 0;
56 acc = 0;
59 for (i = 24; i >= 0; i -= 8) {
57 for (i = 24; i >= 0; i -= 8) {
60 ch = *text++;
58 ch = *text++;
61 acc |= ch << i;
59 acc |= ch << i;
62 if (--len == 0)
60 if (--len == 0)
63 break;
61 break;
64 }
62 }
65 for (i = 4; i >= 0; i--) {
63 for (i = 4; i >= 0; i--) {
66 val = acc % 85;
64 val = acc % 85;
67 acc /= 85;
65 acc /= 85;
68 dst[i] = b85chars[val];
66 dst[i] = b85chars[val];
69 }
67 }
70 dst += 5;
68 dst += 5;
71 }
69 }
72
70
73 if (!pad)
71 if (!pad)
74 _PyBytes_Resize(&out, olen);
72 _PyBytes_Resize(&out, olen);
75
73
76 return out;
74 return out;
77 }
75 }
78
76
79 static PyObject *
77 static PyObject *b85decode(PyObject *self, PyObject *args)
80 b85decode(PyObject *self, PyObject *args)
81 {
78 {
82 PyObject *out;
79 PyObject *out;
83 const char *text;
80 const char *text;
84 char *dst;
81 char *dst;
85 Py_ssize_t len, i, j, olen, cap;
82 Py_ssize_t len, i, j, olen, cap;
86 int c;
83 int c;
87 unsigned int acc;
84 unsigned int acc;
88
85
89 if (!PyArg_ParseTuple(args, "s#", &text, &len))
86 if (!PyArg_ParseTuple(args, "s#", &text, &len))
90 return NULL;
87 return NULL;
91
88
92 olen = len / 5 * 4;
89 olen = len / 5 * 4;
93 i = len % 5;
90 i = len % 5;
94 if (i)
91 if (i)
95 olen += i - 1;
92 olen += i - 1;
96 if (!(out = PyBytes_FromStringAndSize(NULL, olen)))
93 if (!(out = PyBytes_FromStringAndSize(NULL, olen)))
97 return NULL;
94 return NULL;
98
95
99 dst = PyBytes_AsString(out);
96 dst = PyBytes_AsString(out);
100
97
101 i = 0;
98 i = 0;
102 while (i < len)
99 while (i < len)
103 {
100 {
104 acc = 0;
101 acc = 0;
105 cap = len - i - 1;
102 cap = len - i - 1;
106 if (cap > 4)
103 if (cap > 4)
107 cap = 4;
104 cap = 4;
108 for (j = 0; j < cap; i++, j++)
105 for (j = 0; j < cap; i++, j++)
109 {
106 {
110 c = b85dec[(int)*text++] - 1;
107 c = b85dec[(int)*text++] - 1;
111 if (c < 0)
108 if (c < 0)
112 return PyErr_Format(
109 return PyErr_Format(
113 PyExc_ValueError,
110 PyExc_ValueError,
114 "bad base85 character at position %d",
111 "bad base85 character at position %d",
115 (int)i);
112 (int)i);
116 acc = acc * 85 + c;
113 acc = acc * 85 + c;
117 }
114 }
118 if (i++ < len)
115 if (i++ < len)
119 {
116 {
120 c = b85dec[(int)*text++] - 1;
117 c = b85dec[(int)*text++] - 1;
121 if (c < 0)
118 if (c < 0)
122 return PyErr_Format(
119 return PyErr_Format(
123 PyExc_ValueError,
120 PyExc_ValueError,
124 "bad base85 character at position %d",
121 "bad base85 character at position %d",
125 (int)i);
122 (int)i);
126 /* overflow detection: 0xffffffff == "|NsC0",
123 /* overflow detection: 0xffffffff == "|NsC0",
127 * "|NsC" == 0x03030303 */
124 * "|NsC" == 0x03030303 */
128 if (acc > 0x03030303 || (acc *= 85) > 0xffffffff - c)
125 if (acc > 0x03030303 || (acc *= 85) > 0xffffffff - c)
129 return PyErr_Format(
126 return PyErr_Format(
130 PyExc_ValueError,
127 PyExc_ValueError,
131 "bad base85 sequence at position %d",
128 "bad base85 sequence at position %d",
132 (int)i);
129 (int)i);
133 acc += c;
130 acc += c;
134 }
131 }
135
132
136 cap = olen < 4 ? olen : 4;
133 cap = olen < 4 ? olen : 4;
137 olen -= cap;
134 olen -= cap;
138 for (j = 0; j < 4 - cap; j++)
135 for (j = 0; j < 4 - cap; j++)
139 acc *= 85;
136 acc *= 85;
140 if (cap && cap < 4)
137 if (cap && cap < 4)
141 acc += 0xffffff >> (cap - 1) * 8;
138 acc += 0xffffff >> (cap - 1) * 8;
142 for (j = 0; j < cap; j++)
139 for (j = 0; j < cap; j++)
143 {
140 {
144 acc = (acc << 8) | (acc >> 24);
141 acc = (acc << 8) | (acc >> 24);
145 *dst++ = acc;
142 *dst++ = acc;
146 }
143 }
147 }
144 }
148
145
149 return out;
146 return out;
150 }
147 }
151
148
152 static char base85_doc[] = "Base85 Data Encoding";
149 static char base85_doc[] = "Base85 Data Encoding";
153
150
154 static PyMethodDef methods[] = {
151 static PyMethodDef methods[] = {
155 {"b85encode", b85encode, METH_VARARGS,
152 {"b85encode", b85encode, METH_VARARGS,
156 "Encode text in base85.\n\n"
153 "Encode text in base85.\n\n"
157 "If the second parameter is true, pad the result to a multiple of "
154 "If the second parameter is true, pad the result to a multiple of "
158 "five characters.\n"},
155 "five characters.\n"},
159 {"b85decode", b85decode, METH_VARARGS, "Decode base85 text.\n"},
156 {"b85decode", b85decode, METH_VARARGS, "Decode base85 text.\n"},
160 {NULL, NULL}
157 {NULL, NULL}
161 };
158 };
162
159
163 #ifdef IS_PY3K
160 #ifdef IS_PY3K
164 static struct PyModuleDef base85_module = {
161 static struct PyModuleDef base85_module = {
165 PyModuleDef_HEAD_INIT,
162 PyModuleDef_HEAD_INIT,
166 "base85",
163 "base85",
167 base85_doc,
164 base85_doc,
168 -1,
165 -1,
169 methods
166 methods
170 };
167 };
171
168
172 PyMODINIT_FUNC PyInit_base85(void)
169 PyMODINIT_FUNC PyInit_base85(void)
173 {
170 {
174 b85prep();
171 b85prep();
175
172
176 return PyModule_Create(&base85_module);
173 return PyModule_Create(&base85_module);
177 }
174 }
178 #else
175 #else
179 PyMODINIT_FUNC initbase85(void)
176 PyMODINIT_FUNC initbase85(void)
180 {
177 {
181 Py_InitModule3("base85", methods, base85_doc);
178 Py_InitModule3("base85", methods, base85_doc);
182
179
183 b85prep();
180 b85prep();
184 }
181 }
185 #endif
182 #endif
General Comments 0
You need to be logged in to leave comments. Login now