Commit 7eff804b authored by Tom Lane's avatar Tom Lane

Clean up encode/decode functions a little bit.

parent 12054ba5
...@@ -7,13 +7,14 @@ ...@@ -7,13 +7,14 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/encode.c,v 1.2 2001/09/14 17:46:40 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/encode.c,v 1.3 2001/09/30 22:03:41 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include <ctype.h> #include <ctype.h>
#include "utils/builtins.h" #include "utils/builtins.h"
...@@ -38,24 +39,25 @@ binary_encode(PG_FUNCTION_ARGS) ...@@ -38,24 +39,25 @@ binary_encode(PG_FUNCTION_ARGS)
Datum name = PG_GETARG_DATUM(1); Datum name = PG_GETARG_DATUM(1);
text *result; text *result;
char *namebuf; char *namebuf;
int namelen, datalen, resultlen, res; int datalen, resultlen, res;
struct pg_encoding *enc; struct pg_encoding *enc;
datalen = VARSIZE(data) - VARHDRSZ; datalen = VARSIZE(data) - VARHDRSZ;
namelen = VARSIZE(name) - VARHDRSZ;
namebuf = (char *)DirectFunctionCall1(textout, name); namebuf = DatumGetCString(DirectFunctionCall1(textout, name));
enc = pg_find_encoding(namebuf); enc = pg_find_encoding(namebuf);
if (enc == NULL) if (enc == NULL)
elog(ERROR, "No such encoding"); elog(ERROR, "No such encoding as '%s'", namebuf);
resultlen = enc->encode_len(VARDATA(data), datalen); resultlen = enc->encode_len(VARDATA(data), datalen);
result = palloc(VARHDRSZ + resultlen); result = palloc(VARHDRSZ + resultlen);
res = enc->encode(VARDATA(data), datalen, VARDATA(result)); res = enc->encode(VARDATA(data), datalen, VARDATA(result));
/* Make this FATAL 'cause we've trodden on memory ... */
if (res > resultlen) if (res > resultlen)
elog(ERROR, "Overflow - encode estimate too small"); elog(FATAL, "Overflow - encode estimate too small");
VARATT_SIZEP(result) = VARHDRSZ + res; VARATT_SIZEP(result) = VARHDRSZ + res;
...@@ -69,24 +71,25 @@ binary_decode(PG_FUNCTION_ARGS) ...@@ -69,24 +71,25 @@ binary_decode(PG_FUNCTION_ARGS)
Datum name = PG_GETARG_DATUM(1); Datum name = PG_GETARG_DATUM(1);
bytea *result; bytea *result;
char *namebuf; char *namebuf;
int namelen, datalen, resultlen, res; int datalen, resultlen, res;
struct pg_encoding *enc; struct pg_encoding *enc;
datalen = VARSIZE(data) - VARHDRSZ; datalen = VARSIZE(data) - VARHDRSZ;
namelen = VARSIZE(name) - VARHDRSZ;
namebuf = (char *)DirectFunctionCall1(textout, name); namebuf = DatumGetCString(DirectFunctionCall1(textout, name));
enc = pg_find_encoding(namebuf); enc = pg_find_encoding(namebuf);
if (enc == NULL) if (enc == NULL)
elog(ERROR, "No such encoding"); elog(ERROR, "No such encoding as '%s'", namebuf);
resultlen = enc->decode_len(VARDATA(data), datalen); resultlen = enc->decode_len(VARDATA(data), datalen);
result = palloc(VARHDRSZ + resultlen); result = palloc(VARHDRSZ + resultlen);
res = enc->decode(VARDATA(data), datalen, VARDATA(result)); res = enc->decode(VARDATA(data), datalen, VARDATA(result));
/* Make this FATAL 'cause we've trodden on memory ... */
if (res > resultlen) if (res > resultlen)
elog(ERROR, "Overflow - decode estimate too small"); elog(FATAL, "Overflow - decode estimate too small");
VARATT_SIZEP(result) = VARHDRSZ + res; VARATT_SIZEP(result) = VARHDRSZ + res;
...@@ -339,14 +342,12 @@ esc_encode(const uint8 *src, unsigned srclen, uint8 *dst) ...@@ -339,14 +342,12 @@ esc_encode(const uint8 *src, unsigned srclen, uint8 *dst)
{ {
const uint8 *end = src + srclen; const uint8 *end = src + srclen;
uint8 *rp = dst; uint8 *rp = dst;
int val;
int len = 0; int len = 0;
while (src < end) while (src < end)
{ {
if (*src == '\0') if (*src == '\0')
{ {
val = *src;
rp[0] = '\\'; rp[0] = '\\';
rp[1] = '0'; rp[1] = '0';
rp[2] = '0'; rp[2] = '0';
...@@ -356,7 +357,6 @@ esc_encode(const uint8 *src, unsigned srclen, uint8 *dst) ...@@ -356,7 +357,6 @@ esc_encode(const uint8 *src, unsigned srclen, uint8 *dst)
} }
else if (*src == '\\') else if (*src == '\\')
{ {
val = *src;
rp[0] = '\\'; rp[0] = '\\';
rp[1] = '\\'; rp[1] = '\\';
rp += 2; rp += 2;
...@@ -370,7 +370,6 @@ esc_encode(const uint8 *src, unsigned srclen, uint8 *dst) ...@@ -370,7 +370,6 @@ esc_encode(const uint8 *src, unsigned srclen, uint8 *dst)
src++; src++;
} }
*rp = '\0';
return len; return len;
} }
...@@ -380,7 +379,6 @@ esc_decode(const uint8 *src, unsigned srclen, uint8 *dst) ...@@ -380,7 +379,6 @@ esc_decode(const uint8 *src, unsigned srclen, uint8 *dst)
{ {
const uint8 *end = src + srclen; const uint8 *end = src + srclen;
uint8 *rp = dst; uint8 *rp = dst;
int val;
int len = 0; int len = 0;
while (src < end) while (src < end)
...@@ -389,11 +387,13 @@ esc_decode(const uint8 *src, unsigned srclen, uint8 *dst) ...@@ -389,11 +387,13 @@ esc_decode(const uint8 *src, unsigned srclen, uint8 *dst)
{ {
*rp++ = *src++; *rp++ = *src++;
} }
else if ( (src[0] == '\\') && else if ( src+3 < end &&
(src[1] >= '0' && src[1] <= '3') && (src[1] >= '0' && src[1] <= '3') &&
(src[2] >= '0' && src[2] <= '7') && (src[2] >= '0' && src[2] <= '7') &&
(src[3] >= '0' && src[3] <= '7') ) (src[3] >= '0' && src[3] <= '7') )
{ {
int val;
val = VAL(src[1]); val = VAL(src[1]);
val <<= 3; val <<= 3;
val += VAL(src[2]); val += VAL(src[2]);
...@@ -401,7 +401,7 @@ esc_decode(const uint8 *src, unsigned srclen, uint8 *dst) ...@@ -401,7 +401,7 @@ esc_decode(const uint8 *src, unsigned srclen, uint8 *dst)
*rp++ = val + VAL(src[3]); *rp++ = val + VAL(src[3]);
src += 4; src += 4;
} }
else if ( (src[0] == '\\') && else if ( src+1 < end &&
(src[1] == '\\') ) (src[1] == '\\') )
{ {
*rp++ = '\\'; *rp++ = '\\';
...@@ -418,6 +418,7 @@ esc_decode(const uint8 *src, unsigned srclen, uint8 *dst) ...@@ -418,6 +418,7 @@ esc_decode(const uint8 *src, unsigned srclen, uint8 *dst)
len++; len++;
} }
return len; return len;
} }
...@@ -439,11 +440,6 @@ esc_enc_len(const uint8 *src, unsigned srclen) ...@@ -439,11 +440,6 @@ esc_enc_len(const uint8 *src, unsigned srclen)
src++; src++;
} }
/*
* Allow for null terminator
*/
len++;
return len; return len;
} }
...@@ -459,7 +455,7 @@ esc_dec_len(const uint8 *src, unsigned srclen) ...@@ -459,7 +455,7 @@ esc_dec_len(const uint8 *src, unsigned srclen)
{ {
src++; src++;
} }
else if ( (src[0] == '\\') && else if ( src+3 < end &&
(src[1] >= '0' && src[1] <= '3') && (src[1] >= '0' && src[1] <= '3') &&
(src[2] >= '0' && src[2] <= '7') && (src[2] >= '0' && src[2] <= '7') &&
(src[3] >= '0' && src[3] <= '7') ) (src[3] >= '0' && src[3] <= '7') )
...@@ -469,7 +465,7 @@ esc_dec_len(const uint8 *src, unsigned srclen) ...@@ -469,7 +465,7 @@ esc_dec_len(const uint8 *src, unsigned srclen)
*/ */
src += 4; src += 4;
} }
else if ( (src[0] == '\\') && else if ( src+1 < end &&
(src[1] == '\\') ) (src[1] == '\\') )
{ {
/* /*
...@@ -510,7 +506,7 @@ pg_find_encoding(const char *name) ...@@ -510,7 +506,7 @@ pg_find_encoding(const char *name)
int i; int i;
for (i = 0; enclist[i].name; i++) for (i = 0; enclist[i].name; i++)
if (!strcasecmp(enclist[i].name, name)) if (strcasecmp(enclist[i].name, name) == 0)
return &enclist[i].enc; return &enclist[i].enc;
return NULL; return NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment