aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/varbit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/varbit.c')
-rw-r--r--src/backend/utils/adt/varbit.c75
1 files changed, 74 insertions, 1 deletions
diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c
index bad71288632..e494c03369d 100644
--- a/src/backend/utils/adt/varbit.c
+++ b/src/backend/utils/adt/varbit.c
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.29 2002/11/13 00:39:47 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.30 2003/05/12 23:08:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,6 +17,7 @@
#include "postgres.h"
#include "catalog/pg_type.h"
+#include "libpq/pqformat.h"
#include "utils/array.h"
#include "utils/fmgroids.h"
#include "utils/memutils.h"
@@ -204,6 +205,26 @@ bit_out(PG_FUNCTION_ARGS)
#endif
}
+/*
+ * bit_recv - converts external binary format to bit
+ */
+Datum
+bit_recv(PG_FUNCTION_ARGS)
+{
+ /* Exactly the same as varbit_recv, so share code */
+ return varbit_recv(fcinfo);
+}
+
+/*
+ * bit_send - converts bit to binary format
+ */
+Datum
+bit_send(PG_FUNCTION_ARGS)
+{
+ /* Exactly the same as varbit_send, so share code */
+ return varbit_send(fcinfo);
+}
+
/* bit()
* Converts a bit() type to a specific internal length.
* len is the bitlength specified in the column definition.
@@ -407,6 +428,58 @@ varbit_out(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result);
}
+/*
+ * varbit_recv - converts external binary format to varbit
+ *
+ * External format is the bitlen as an int32, then the byte array.
+ */
+Datum
+varbit_recv(PG_FUNCTION_ARGS)
+{
+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
+ VarBit *result;
+ int len,
+ bitlen;
+ int ipad;
+ bits8 mask;
+
+ bitlen = pq_getmsgint(buf, sizeof(int32));
+ if (bitlen < 0)
+ elog(ERROR, "Invalid length in external bit string");
+
+ len = VARBITTOTALLEN(bitlen);
+ result = (VarBit *) palloc(len);
+ VARATT_SIZEP(result) = len;
+ VARBITLEN(result) = bitlen;
+
+ pq_copymsgbytes(buf, (char *) VARBITS(result), VARBITBYTES(result));
+
+ /* Make sure last byte is zero-padded if needed */
+ ipad = VARBITPAD(result);
+ if (ipad > 0)
+ {
+ mask = BITMASK << ipad;
+ *(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
+ }
+
+ PG_RETURN_VARBIT_P(result);
+}
+
+/*
+ * varbit_send - converts varbit to binary format
+ */
+Datum
+varbit_send(PG_FUNCTION_ARGS)
+{
+ VarBit *s = PG_GETARG_VARBIT_P(0);
+ StringInfoData buf;
+
+ pq_begintypsend(&buf);
+ pq_sendint(&buf, VARBITLEN(s), sizeof(int32));
+ pq_sendbytes(&buf, VARBITS(s), VARBITBYTES(s));
+ PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+}
+
/* varbit()
* Converts a varbit() type to a specific internal length.
* len is the maximum bitlength specified in the column definition.