Skip to content

Commit 79d78bb

Browse files
committed
Add missing encode file.
1 parent b9f3a92 commit 79d78bb

File tree

3 files changed

+393
-26
lines changed

3 files changed

+393
-26
lines changed

src/backend/utils/adt/encode.c

Lines changed: 346 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* encode.c
4+
* Various data encoding/decoding things.
5+
*
6+
* Copyright (c) 2001 PostgreSQL Global Development Group
7+
*
8+
*
9+
* IDENTIFICATION
10+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/encode.c,v 1.1 2001/07/12 14:05:31 momjian Exp $
11+
*
12+
*-------------------------------------------------------------------------
13+
*/
14+
#include "postgres.h"
15+
16+
#include <ctype.h>
17+
#include "utils/builtins.h"
18+
19+
20+
struct pg_encoding
21+
{
22+
unsigned (*encode_len) (unsigned dlen);
23+
unsigned (*decode_len) (unsigned dlen);
24+
unsigned (*encode) (const uint8 *data, unsigned dlen, uint8 *res);
25+
unsigned (*decode) (const uint8 *data, unsigned dlen, uint8 *res);
26+
};
27+
28+
static struct pg_encoding * pg_find_encoding(const char *name);
29+
30+
/*
31+
* SQL functions.
32+
*/
33+
34+
Datum
35+
binary_encode(PG_FUNCTION_ARGS)
36+
{
37+
bytea *data = PG_GETARG_BYTEA_P(0);
38+
Datum name = PG_GETARG_DATUM(1);
39+
text *result;
40+
char *namebuf;
41+
int namelen, datalen, resultlen, res;
42+
struct pg_encoding *enc;
43+
44+
datalen = VARSIZE(data) - VARHDRSZ;
45+
namelen = VARSIZE(name) - VARHDRSZ;
46+
47+
namebuf = (char *)DirectFunctionCall1(textout, name);
48+
49+
enc = pg_find_encoding(namebuf);
50+
if (enc == NULL)
51+
elog(ERROR, "No such encoding");
52+
53+
resultlen = enc->encode_len(datalen);
54+
result = palloc(VARHDRSZ + resultlen);
55+
56+
res = enc->encode(VARDATA(data), datalen, VARDATA(result));
57+
if (res > resultlen)
58+
elog(ERROR, "Overflow - encode estimate too small");
59+
60+
VARATT_SIZEP(result) = VARHDRSZ + res;
61+
62+
PG_RETURN_TEXT_P(result);
63+
}
64+
65+
Datum
66+
binary_decode(PG_FUNCTION_ARGS)
67+
{
68+
text *data = PG_GETARG_TEXT_P(0);
69+
Datum name = PG_GETARG_DATUM(1);
70+
bytea *result;
71+
char *namebuf;
72+
int namelen, datalen, resultlen, res;
73+
struct pg_encoding *enc;
74+
75+
datalen = VARSIZE(data) - VARHDRSZ;
76+
namelen = VARSIZE(name) - VARHDRSZ;
77+
78+
namebuf = (char *)DirectFunctionCall1(textout, name);
79+
80+
enc = pg_find_encoding(namebuf);
81+
if (enc == NULL)
82+
elog(ERROR, "No such encoding");
83+
84+
resultlen = enc->decode_len(datalen);
85+
result = palloc(VARHDRSZ + resultlen);
86+
87+
res = enc->decode(VARDATA(data), datalen, VARDATA(result));
88+
if (res > resultlen)
89+
elog(ERROR, "Overflow - decode estimate too small");
90+
91+
VARATT_SIZEP(result) = VARHDRSZ + res;
92+
93+
PG_RETURN_BYTEA_P(result);
94+
}
95+
96+
97+
/*
98+
* HEX
99+
*/
100+
101+
static const char *hextbl = "0123456789abcdef";
102+
103+
static const int8 hexlookup[128] = {
104+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
105+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
106+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
107+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
108+
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
109+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
110+
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
111+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
112+
};
113+
114+
static unsigned
115+
hex_encode(const uint8 * src, unsigned len, uint8 * dst)
116+
{
117+
const uint8 *end = src + len;
118+
119+
while (src < end)
120+
{
121+
*dst++ = hextbl[(*src >> 4) & 0xF];
122+
*dst++ = hextbl[*src & 0xF];
123+
src++;
124+
}
125+
return len * 2;
126+
}
127+
128+
static uint8
129+
get_hex(unsigned c)
130+
{
131+
int res = -1;
132+
133+
if (c > 0 && c < 127)
134+
res = hexlookup[c];
135+
136+
if (res < 0)
137+
elog(ERROR, "Bad hex code: '%c'", c);
138+
139+
return (uint8)res;
140+
}
141+
142+
static unsigned
143+
hex_decode(const uint8 * src, unsigned len, uint8 * dst)
144+
{
145+
const uint8 *s,
146+
*srcend;
147+
uint8 v1,
148+
v2,
149+
*p = dst;
150+
151+
srcend = src + len;
152+
s = src;
153+
p = dst;
154+
while (s < srcend)
155+
{
156+
if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '\r')
157+
{
158+
s++;
159+
continue;
160+
}
161+
v1 = get_hex(*s++) << 4;
162+
if (s >= srcend)
163+
elog(ERROR, "hex_decode: invalid data");
164+
v2 = get_hex(*s++);
165+
*p++ = v1 | v2;
166+
}
167+
168+
return p - dst;
169+
}
170+
171+
static unsigned
172+
hex_enc_len(unsigned srclen)
173+
{
174+
return srclen << 1;
175+
}
176+
177+
static unsigned
178+
hex_dec_len(unsigned srclen)
179+
{
180+
return srclen >> 1;
181+
}
182+
183+
/*
184+
* BASE64
185+
*/
186+
187+
static const unsigned char _base64[] =
188+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
189+
190+
static const int8 b64lookup[128] = {
191+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
192+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
193+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
194+
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
195+
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
196+
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
197+
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
198+
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
199+
};
200+
201+
static unsigned
202+
b64_encode(const uint8 * src, unsigned len, uint8 * dst)
203+
{
204+
uint8 *p,
205+
*lend = dst + 76;
206+
const uint8 *s,
207+
*end = src + len;
208+
int pos = 2;
209+
uint32 buf = 0;
210+
211+
s = src;
212+
p = dst;
213+
214+
while (s < end)
215+
{
216+
buf |= *s << (pos << 3);
217+
pos--;
218+
s++;
219+
220+
/* write it out */
221+
if (pos < 0)
222+
{
223+
*p++ = _base64[(buf >> 18) & 0x3f];
224+
*p++ = _base64[(buf >> 12) & 0x3f];
225+
*p++ = _base64[(buf >> 6) & 0x3f];
226+
*p++ = _base64[buf & 0x3f];
227+
228+
pos = 2;
229+
buf = 0;
230+
}
231+
if (p >= lend)
232+
{
233+
*p++ = '\n';
234+
lend = p + 76;
235+
}
236+
}
237+
if (pos != 2)
238+
{
239+
*p++ = _base64[(buf >> 18) & 0x3f];
240+
*p++ = _base64[(buf >> 12) & 0x3f];
241+
*p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '=';
242+
*p++ = '=';
243+
}
244+
245+
return p - dst;
246+
}
247+
248+
static unsigned
249+
b64_decode(const uint8 * src, unsigned len, uint8 * dst)
250+
{
251+
const char *srcend = src + len,
252+
*s = src;
253+
uint8 *p = dst;
254+
unsigned c;
255+
int b = 0;
256+
uint32 buf = 0;
257+
int pos = 0,
258+
end = 0;
259+
260+
while (s < srcend)
261+
{
262+
c = *s++;
263+
264+
if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
265+
continue;
266+
267+
if (c == '=')
268+
{
269+
/* end sequence */
270+
if (!end)
271+
{
272+
if (pos == 2)
273+
end = 1;
274+
else if (pos == 3)
275+
end = 2;
276+
else
277+
elog(ERROR, "base64: unexpected '='");
278+
}
279+
b = 0;
280+
}
281+
else {
282+
b = -1;
283+
if (c > 0 && c < 127)
284+
b = b64lookup[c];
285+
if (b < 0)
286+
elog(ERROR, "base64: Invalid symbol");
287+
}
288+
/* add it to buffer */
289+
buf = (buf << 6) + b;
290+
pos++;
291+
if (pos == 4)
292+
{
293+
*p++ = (buf >> 16) & 255;
294+
if (end == 0 || end > 1)
295+
*p++ = (buf >> 8) & 255;
296+
if (end == 0 || end > 2)
297+
*p++ = buf & 255;
298+
buf = 0;
299+
pos = 0;
300+
}
301+
}
302+
303+
if (pos != 0)
304+
elog(ERROR, "base64: invalid end sequence");
305+
306+
return p - dst;
307+
}
308+
309+
310+
static unsigned
311+
b64_enc_len(unsigned srclen)
312+
{
313+
/* 3 bytes will be converted to 4, linefeed after 76 chars */
314+
return (srclen + 2) * 4 / 3 + srclen / (76 * 3 / 4);
315+
}
316+
317+
static unsigned
318+
b64_dec_len(unsigned srclen)
319+
{
320+
return (srclen * 3) >> 2;
321+
}
322+
323+
/*
324+
* Common
325+
*/
326+
327+
static struct {
328+
const char *name;
329+
struct pg_encoding enc;
330+
} enclist[] = {
331+
{"hex", { hex_enc_len, hex_dec_len, hex_encode, hex_decode }},
332+
{"base64", { b64_enc_len, b64_dec_len, b64_encode, b64_decode }},
333+
{NULL, { NULL, NULL, NULL, NULL } }
334+
};
335+
336+
static struct pg_encoding *
337+
pg_find_encoding(const char *name)
338+
{
339+
int i;
340+
341+
for (i = 0; enclist[i].name; i++)
342+
if (!strcasecmp(enclist[i].name, name))
343+
return &enclist[i].enc;
344+
345+
return NULL;
346+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy