Index: doc/src/sgml/datatype.sgml
===================================================================
RCS file: /home/cvs/pgsql/pgsql/doc/src/sgml/datatype.sgml,v
retrieving revision 1.55
diff --unified -r1.55 datatype.sgml
--- doc/src/sgml/datatype.sgml 2001/05/22 16:37:15 1.55
+++ doc/src/sgml/datatype.sgml 2001/06/22 20:09:08
@@ -48,6 +48,12 @@
+ bytea
+
+ a variable-length raw string, could contain nulls
+
+
+
bigint
int8
signed eight-byte integer
Index: doc/src/sgml/func.sgml
===================================================================
RCS file: /home/cvs/pgsql/pgsql/doc/src/sgml/func.sgml,v
retrieving revision 1.61
diff --unified -r1.61 func.sgml
--- doc/src/sgml/func.sgml 2001/06/15 21:03:07 1.61
+++ doc/src/sgml/func.sgml 2001/06/22 20:19:41
@@ -1037,6 +1037,32 @@
a23x5
+
+
+ base64_encode(string bytea)
+
+ text
+
+ Uses base64 algorithm to encode binary data in string.
+ Returns text value guaranteed to contain only printable string
+
+ base64_encode('123\\000\\001')
+ MTIzAAE=
+
+
+
+
+ base64_decode(string text)
+
+ bytea
+
+ Decodes binary data from string previously
+ encoded with base64 algorithm.
+
+ base64_decode('MTIzAAE=')
+ 123\000\001
+
+
Index: src/backend/utils/adt/varlena.c
===================================================================
RCS file: /home/cvs/pgsql/pgsql/src/backend/utils/adt/varlena.c,v
retrieving revision 1.70
diff --unified -r1.70 varlena.c
--- src/backend/utils/adt/varlena.c 2001/05/03 19:00:36 1.70
+++ src/backend/utils/adt/varlena.c 2001/06/22 21:12:51
@@ -20,7 +20,14 @@
#include "miscadmin.h"
#include "utils/builtins.h"
+static char base64_dtable[256];
+static char base64_etable[256];
+static bool base64_tables_set=false;
+
static int text_cmp(text *arg1, text *arg2);
+static void init_base64_tables(void);
+static int do_base64_encode(char *in, int maxlen, char *out);
+static int do_base64_decode(char *in, int maxlen, char *out);
/*****************************************************************************
@@ -875,3 +882,172 @@
PG_RETURN_TEXT_P(result);
}
+
+/* base64_encode()
+ * Converts a bytea value to base-64 encoded 'text' string
+ */
+Datum
+base64_encode(PG_FUNCTION_ARGS)
+{
+ bytea *s = PG_GETARG_BYTEA_P(0);
+ text *result;
+ int lenin, lenout;
+
+ lenin = VARSIZE(s) - VARHDRSZ;
+
+ result = (text *) palloc(lenin*4/3+10+VARHDRSZ);
+
+ lenout=do_base64_encode(VARDATA(s), lenin, VARDATA(result));
+
+ VARATT_SIZEP(result) = lenout+VARHDRSZ;
+
+ PG_RETURN_TEXT_P(result);
+}
+
+/* base64_decode()
+ * Converts base-64 encoded 'text' string to bytea value
+ */
+Datum
+base64_decode(PG_FUNCTION_ARGS)
+{
+ text * s = PG_GETARG_TEXT_P(0);
+ bytea *result;
+ int lenin, lenout;
+
+ lenin = VARSIZE(s) - VARHDRSZ;
+
+ result = (bytea *) palloc((int) lenin*3/4+10+VARHDRSZ);
+
+ lenout = do_base64_decode(VARDATA(s), lenin, VARDATA(result));
+
+ VARATT_SIZEP(result) = lenout+VARHDRSZ;
+
+ PG_RETURN_BYTEA_P(result);
+}
+
+/* most of code lifted from public-domain base64 by John Walker */
+
+void init_base64_tables(void) {
+ int i;
+ if (base64_tables_set) return;
+
+ for (i = 0; i < 26; i++) {
+ base64_etable[i] = 'A' + i;
+ base64_etable[26 + i] = 'a' + i;
+ }
+ for (i = 0; i < 10; i++) {
+ base64_etable[52 + i] = '0' + i;
+ }
+ base64_etable[62] = '+';
+ base64_etable[63] = '/';
+
+ for (i = 0; i < 255; i++) {
+ base64_dtable[i] = 0x80;
+ }
+ for (i = 'A'; i <= 'Z'; i++) {
+ base64_dtable[i] = 0 + (i - 'A');
+ }
+ for (i = 'a'; i <= 'z'; i++) {
+ base64_dtable[i] = 26 + (i - 'a');
+ }
+ for (i = '0'; i <= '9'; i++) {
+ base64_dtable[i] = 52 + (i - '0');
+ }
+
+ base64_dtable['+'] = 62;
+ base64_dtable['/'] = 63;
+ base64_dtable['='] = 0;
+
+ base64_tables_set=true;
+}
+
+
+/* this function requires out to be already allocated,
+ it must have (maxlen*4/3)+3 bytes
+ returns number of characters in out
+*/
+int do_base64_encode(char *in, int maxlen, char *out)
+{
+ int i;
+ bool hiteof = false; /* read the last character */
+ int p; /* index of current character */
+ char *s=out;
+ char igroup[3];
+ char ogroup[4];
+ int n;
+
+ init_base64_tables();
+
+ for(p=0;p 0) {
+ ogroup[0] = base64_etable[igroup[0] >> 2];
+ ogroup[1] = base64_etable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
+ ogroup[2] = base64_etable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
+ ogroup[3] = base64_etable[igroup[2] & 0x3F];
+
+ /* Replace characters in output stream with "=" pad
+ characters if fewer than three characters were
+ read from the end of the input stream. */
+
+ if (n < 3) {
+ ogroup[3] = '=';
+ if (n < 2) {
+ ogroup[2] = '=';
+ }
+ }
+ for (i = 0; i < 4; i++) {
+ *s++=ogroup[i];
+ }
+ }
+ }
+ return s-out;
+}
+
+
+int do_base64_decode(char *in, int maxlen, char *out)
+{
+ int p=0;
+ int i,j;
+ char *s=out;
+ init_base64_tables();
+ while (true) {
+ char a[4], b[4], o[3];
+ int c;
+
+ for (i = 0; i < 4; i++) {
+ while (true) { /* get a printable character*/
+ if (p==maxlen) { /* end of string */
+ if (i > 0)
+ elog(ERROR, "base64_decode: Input string incomplete");
+ return s-out; /* done */
+ }
+ c = in[p++];
+ if ( c > ' ' ) break;
+ }
+
+ if ( (base64_dtable[c] & 0x80) || (!isprint(c)) )
+ elog(ERROR, "base64_decode: Illegal character '%c' in input string.\n", c);
+ a[i] = c;
+ b[i] = base64_dtable[c];
+ }
+ o[0] = (b[0] << 2) | (b[1] >> 4);
+ o[1] = (b[1] << 4) | (b[2] >> 2);
+ o[2] = (b[2] << 6) | b[3];
+ i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3);
+
+ for (j=0;j