aboutsummaryrefslogtreecommitdiff
path: root/contrib/bit/varbit.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bit/varbit.c')
-rw-r--r--contrib/bit/varbit.c1365
1 files changed, 715 insertions, 650 deletions
diff --git a/contrib/bit/varbit.c b/contrib/bit/varbit.c
index 2a677ec6040..20caaf9f7cb 100644
--- a/contrib/bit/varbit.c
+++ b/contrib/bit/varbit.c
@@ -4,7 +4,7 @@
* Functions for the built-in type bit() and varying bit().
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/contrib/bit/Attic/varbit.c,v 1.2 2000/04/03 20:56:40 momjian Exp $
+ * $Header: /cvsroot/pgsql/contrib/bit/Attic/varbit.c,v 1.3 2000/04/12 17:14:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -14,19 +14,19 @@
/*#include "utils/builtins.h" */
-/*
+/*
Prefixes:
- zp -- zero-padded fixed length bit string
- var -- varying bit string
+ zp -- zero-padded fixed length bit string
+ var -- varying bit string
attypmod -- contains the length of the bit string in bits, or for
- varying bits the maximum length.
+ varying bits the maximum length.
The data structure contains the following elements:
- header -- length of the whole data structure (incl header)
- in bytes. (as with all varying length datatypes)
- data section -- private data section for the bits data structures
- bitlength -- lenght of the bit string in bits
+ header -- length of the whole data structure (incl header)
+ in bytes. (as with all varying length datatypes)
+ data section -- private data section for the bits data structures
+ bitlength -- lenght of the bit string in bits
bitdata -- least significant byte first string
*/
@@ -34,214 +34,241 @@
* zpbitin -
* converts a string to the internal representation of a bitstring.
- * The length is determined by the number of bits required plus
- * VARHDRSZ bytes or from atttypmod.
- * (XXX dummy is here because we pass typelem as the second argument
- * for array_in. copied this, no idea what it means??)
+ * The length is determined by the number of bits required plus
+ * VARHDRSZ bytes or from atttypmod.
+ * (XXX dummy is here because we pass typelem as the second argument
+ * for array_in. copied this, no idea what it means??)
*/
bits8 *
-zpbitin(char *s, int dummy, int32 atttypmod)
+zpbitin(char *s, int dummy, int32 atttypmod)
{
- bits8 *result; /* the bits string that was read in */
- char *sp; /* pointer into the character string */
- bits8 *r;
- int len, /* Length of the whole data structure */
- bitlen, /* Number of bits in the bit string */
- slen; /* Length of the input string */
- int bit_not_hex = 0; /* 0 = hex string 1=bit string */
- int bc, ipad;
- bits8 x = 0;
-
-
- if (s == NULL)
- return (bits8 *) NULL;
-
- /* Check that the first character is a b or an x */
- if (s[0]=='b' || s[0]=='B')
- bit_not_hex = 1;
- else if (s[0]=='x' || s[0]=='X')
- bit_not_hex = 0;
- else
- elog(ERROR, "zpbitin: %s is not a valid bitstring",s);
-
- slen = strlen(s) - 1;
- /* Determine bitlength from input string */
- bitlen = slen;
- if (!bit_not_hex)
- bitlen *= 4;
-
- /* Sometimes atttypmod is not supplied. If it is supplied we need to make
- sure that the bitstring fits. Note that the number of infered bits can
- be larger than the number of actual bits needed, but only if we are
- reading a hex string and not by more than 3 bits, as a hex string gives
- and accurate length upto 4 bits */
- if (atttypmod == -1)
- atttypmod = bitlen;
- else
- if ((bitlen>atttypmod && bit_not_hex) ||
- (bitlen>atttypmod+3 && !bit_not_hex))
- elog(ERROR, "zpbitin: bit string of size %d cannot be written into bits(%d)",
- bitlen,atttypmod);
-
-
- len = VARBITDATALEN(atttypmod);
-
- if (len > MaxAttrSize)
- elog(ERROR, "zpbitin: length of bit() must be less than %ld",
- (MaxAttrSize-VARHDRSZ-VARBITHDRSZ)*BITSPERBYTE);
-
- result = (bits8 *) palloc(len);
- /* set to 0 so that *r is always initialised and strin is zero-padded */
- memset(result, 0, len);
- VARSIZE(result) = len;
- VARBITLEN(result) = atttypmod;
-
- /* We need to read the bitstring from the end, as we store it least
- significant byte first. s points to the byte before the beginning
- of the bitstring */
- sp = s+1;
- r = VARBITS(result);
- if (bit_not_hex)
- {
- /* Parse the bit representation of the string */
- /* We know it fits, as bitlen was compared to atttypmod */
- x = BITHIGH;
- for (bc = 0; sp != s+slen+1; sp++, bc++)
+ bits8 *result; /* the bits string that was read in */
+ char *sp; /* pointer into the character string */
+ bits8 *r;
+ int len, /* Length of the whole data structure */
+ bitlen, /* Number of bits in the bit string */
+ slen; /* Length of the input string */
+ int bit_not_hex = 0;/* 0 = hex string 1=bit string */
+ int bc,
+ ipad;
+ bits8 x = 0;
+
+
+ if (s == NULL)
+ return (bits8 *) NULL;
+
+ /* Check that the first character is a b or an x */
+ if (s[0] == 'b' || s[0] == 'B')
+ bit_not_hex = 1;
+ else if (s[0] == 'x' || s[0] == 'X')
+ bit_not_hex = 0;
+ else
+ elog(ERROR, "zpbitin: %s is not a valid bitstring", s);
+
+ slen = strlen(s) - 1;
+ /* Determine bitlength from input string */
+ bitlen = slen;
+ if (!bit_not_hex)
+ bitlen *= 4;
+
+ /*
+ * Sometimes atttypmod is not supplied. If it is supplied we need to
+ * make sure that the bitstring fits. Note that the number of infered
+ * bits can be larger than the number of actual bits needed, but only
+ * if we are reading a hex string and not by more than 3 bits, as a
+ * hex string gives and accurate length upto 4 bits
+ */
+ if (atttypmod == -1)
+ atttypmod = bitlen;
+ else if ((bitlen > atttypmod && bit_not_hex) ||
+ (bitlen > atttypmod + 3 && !bit_not_hex))
+ elog(ERROR, "zpbitin: bit string of size %d cannot be written into bits(%d)",
+ bitlen, atttypmod);
+
+
+ len = VARBITDATALEN(atttypmod);
+
+ if (len > MaxAttrSize)
+ elog(ERROR, "zpbitin: length of bit() must be less than %ld",
+ (MaxAttrSize - VARHDRSZ - VARBITHDRSZ) * BITSPERBYTE);
+
+ result = (bits8 *) palloc(len);
+ /* set to 0 so that *r is always initialised and strin is zero-padded */
+ memset(result, 0, len);
+ VARSIZE(result) = len;
+ VARBITLEN(result) = atttypmod;
+
+ /*
+ * We need to read the bitstring from the end, as we store it least
+ * significant byte first. s points to the byte before the beginning
+ * of the bitstring
+ */
+ sp = s + 1;
+ r = VARBITS(result);
+ if (bit_not_hex)
+ {
+ /* Parse the bit representation of the string */
+ /* We know it fits, as bitlen was compared to atttypmod */
+ x = BITHIGH;
+ for (bc = 0; sp != s + slen + 1; sp++, bc++)
+ {
+ if (*sp == '1')
+ *r |= x;
+ if (bc == 7)
+ {
+ bc = 0;
+ x = BITHIGH;
+ r++;
+ }
+ else
+ x >>= 1;
+ }
+ }
+ else
{
- if (*sp=='1')
- *r |= x;
- if (bc==7) {
- bc = 0;
- x = BITHIGH;
- r++;
- } else
- x >>= 1;
+ /* Parse the hex representation of the string */
+ for (bc = 0; sp != s + slen + 1; sp++)
+ {
+ if (*sp >= '0' && *sp <= '9')
+ x = (bits8) (*sp - '0');
+ else if (*sp >= 'A' && *sp <= 'F')
+ x = (bits8) (*sp - 'A') + 10;
+ else if (*sp >= 'a' && *sp <= 'f')
+ x = (bits8) (*sp - 'a') + 10;
+ else
+ elog(ERROR, "Cannot parse %c as a hex digit", *sp);
+ if (bc)
+ {
+ bc = 0;
+ *r++ |= x;
+ }
+ else
+ {
+ bc++;
+ *r = x << 4;
+ }
+ }
}
- }
- else
- {
- /* Parse the hex representation of the string */
- for (bc = 0; sp != s+slen+1; sp++)
+
+ if (bitlen > atttypmod)
{
- if (*sp>='0' && *sp<='9')
- x = (bits8) (*sp - '0');
- else if (*sp>='A' && *sp<='F')
- x = (bits8) (*sp - 'A') + 10;
- else if (*sp>='a' && *sp<='f')
- x = (bits8) (*sp - 'a') + 10;
- else
- elog(ERROR,"Cannot parse %c as a hex digit",*sp);
- if (bc) {
- bc = 0;
- *r++ |= x;
- } else {
- bc++;
- *r = x<<4;
- }
+ /* Check that this fitted */
+ r = (bits8 *) (result + len - 1);
+ ipad = VARBITPAD(result);
+
+ /*
+ * The bottom ipad bits of the byte pointed to by r need to be
+ * zero
+ */
+
+ /*
+ * printf("Byte %X shift %X %d\n",*r,(*r << (8-ipad)) & BITMASK,
+ * (*r << (8-ipad)) & BITMASK > 0);
+ */
+ if (((*r << (BITSPERBYTE - ipad)) & BITMASK) > 0)
+ elog(ERROR, "zpbitin: bit string too large for bit(%d) data type",
+ atttypmod);
}
- }
-
- if (bitlen > atttypmod) {
- /* Check that this fitted */
- r = (bits8 *) (result + len - 1);
- ipad = VARBITPAD(result);
- /* The bottom ipad bits of the byte pointed to by r need to be zero */
- /* printf("Byte %X shift %X %d\n",*r,(*r << (8-ipad)) & BITMASK,
- (*r << (8-ipad)) & BITMASK > 0);
- */
- if (((*r << (BITSPERBYTE-ipad)) & BITMASK) > 0)
- elog(ERROR, "zpbitin: bit string too large for bit(%d) data type",
- atttypmod);
- }
-
- return result;
+
+ return result;
}
/* zpbitout -
- * for the time being we print everything as hex strings, as this is likely
- * to be more compact than bit strings, and consequently much more efficient
- * for long strings
+ * for the time being we print everything as hex strings, as this is likely
+ * to be more compact than bit strings, and consequently much more efficient
+ * for long strings
*/
char *
zpbitout(bits8 *s)
{
- char *result, *r;
- bits8 *sp;
- int i, len, bitlen;
-
- if (s == NULL)
- {
- result = (char *) palloc(2);
- result[0] = '-';
- result[1] = '\0';
- }
- else
- {
- bitlen = VARBITLEN(s);
- len = bitlen/4 + (bitlen%4>0 ? 1 : 0);
- result = (char *) palloc(len + 4);
- sp = VARBITS(s);
- r = result;
- *r++ = 'X';
- *r++ = '\'';
- /* we cheat by knowing that we store full bytes zero padded */
- for (i=0; i<len; i+=2, sp++) {
- *r++ = HEXDIG((*sp)>>4);
- *r++ = HEXDIG((*sp) & 0xF);
- }
- /* Go back one step if we printed a hex number that was not part
- of the bitstring anymore */
- if (i==len+1)
- r--;
- *r++ = '\'';
- *r = '\0';
- }
- return result;
+ char *result,
+ *r;
+ bits8 *sp;
+ int i,
+ len,
+ bitlen;
+
+ if (s == NULL)
+ {
+ result = (char *) palloc(2);
+ result[0] = '-';
+ result[1] = '\0';
+ }
+ else
+ {
+ bitlen = VARBITLEN(s);
+ len = bitlen / 4 + (bitlen % 4 > 0 ? 1 : 0);
+ result = (char *) palloc(len + 4);
+ sp = VARBITS(s);
+ r = result;
+ *r++ = 'X';
+ *r++ = '\'';
+ /* we cheat by knowing that we store full bytes zero padded */
+ for (i = 0; i < len; i += 2, sp++)
+ {
+ *r++ = HEXDIG((*sp) >> 4);
+ *r++ = HEXDIG((*sp) & 0xF);
+ }
+
+ /*
+ * Go back one step if we printed a hex number that was not part
+ * of the bitstring anymore
+ */
+ if (i == len + 1)
+ r--;
+ *r++ = '\'';
+ *r = '\0';
+ }
+ return result;
}
/* zpbitsout -
- * Prints the string a bits
+ * Prints the string a bits
*/
char *
zpbitsout(bits8 *s)
{
- char *result, *r;
- bits8 *sp;
- bits8 x;
- int i, k, len;
-
- if (s == NULL)
- {
- result = (char *) palloc(2);
- result[0] = '-';
- result[1] = '\0';
- }
- else
- {
- len = VARBITLEN(s);
- result = (char *) palloc(len + 4);
- sp = VARBITS(s);
- r = result;
- *r++ = 'B';
- *r++ = '\'';
- for (i=0; i<len-BITSPERBYTE; i+=BITSPERBYTE, sp++) {
- x = *sp;
- for (k=0; k<BITSPERBYTE; k++)
- {
- *r++ = (x & BITHIGH) ? '1' : '0';
- x <<= 1;
- }
- }
- x = *sp;
- for (k=i; k<len; k++)
+ char *result,
+ *r;
+ bits8 *sp;
+ bits8 x;
+ int i,
+ k,
+ len;
+
+ if (s == NULL)
{
- *r++ = (x & BITHIGH) ? '1' : '0';
- x <<= 1;
+ result = (char *) palloc(2);
+ result[0] = '-';
+ result[1] = '\0';
}
- *r++ = '\'';
- *r = '\0';
- }
- return result;
+ else
+ {
+ len = VARBITLEN(s);
+ result = (char *) palloc(len + 4);
+ sp = VARBITS(s);
+ r = result;
+ *r++ = 'B';
+ *r++ = '\'';
+ for (i = 0; i < len - BITSPERBYTE; i += BITSPERBYTE, sp++)
+ {
+ x = *sp;
+ for (k = 0; k < BITSPERBYTE; k++)
+ {
+ *r++ = (x & BITHIGH) ? '1' : '0';
+ x <<= 1;
+ }
+ }
+ x = *sp;
+ for (k = i; k < len; k++)
+ {
+ *r++ = (x & BITHIGH) ? '1' : '0';
+ x <<= 1;
+ }
+ *r++ = '\'';
+ *r = '\0';
+ }
+ return result;
}
@@ -250,118 +277,133 @@ zpbitsout(bits8 *s)
* converts a string to the internal representation of a bitstring.
*/
bits8 *
-varbitin(char *s, int dummy, int32 atttypmod)
+varbitin(char *s, int dummy, int32 atttypmod)
{
- bits8 *result; /* The resulting bit string */
- char *sp; /* pointer into the character string */
- bits8 *r;
- int len, /* Length of the whole data structure */
- bitlen, /* Number of bits in the bit string */
- slen; /* Length of the input string */
- int bit_not_hex = 0;
- int bc, ipad;
- bits8 x = 0;
-
-
- if (s == NULL)
- return (bits8 *) NULL;
-
- /* Check that the first character is a b or an x */
- if (s[0]=='b' || s[0]=='B')
- bit_not_hex = 1;
- else if (s[0]=='x' || s[0]=='X')
- bit_not_hex = 0;
- else
- elog(ERROR, "zpbitin: %s is not a valid bitstring",s);
-
- slen = strlen(s) - 1;
- /* Determine bitlength from input string */
- bitlen = slen;
- if (!bit_not_hex)
- bitlen *= 4;
-
- /* Sometimes atttypmod is not supplied. If it is supplied we need to make
- sure that the bitstring fits. Note that the number of infered bits can
- be larger than the number of actual bits needed, but only if we are
- reading a hex string and not by more than 3 bits, as a hex string gives
- and accurate length upto 4 bits */
- if (atttypmod > -1)
- if ((bitlen>atttypmod && bit_not_hex) ||
- (bitlen>atttypmod+3 && !bit_not_hex))
- elog(ERROR, "varbitin: bit string of size %d cannot be written into varying bits(%d)",
- bitlen,atttypmod);
-
-
- len = VARBITDATALEN(bitlen);
-
- if (len > MaxAttrSize)
- elog(ERROR, "varbitin: length of bit() must be less than %ld",
- (MaxAttrSize-VARHDRSZ-VARBITHDRSZ)*BITSPERBYTE);
-
- result = (bits8 *) palloc(len);
- /* set to 0 so that *r is always initialised and strin is zero-padded */
- memset(result, 0, len);
- VARSIZE(result) = len;
- VARBITLEN(result) = bitlen;
-
- /* We need to read the bitstring from the end, as we store it least
- significant byte first. s points to the byte before the beginning
- of the bitstring */
- sp = s + 1;
- r = VARBITS(result);
- if (bit_not_hex)
- {
- /* Parse the bit representation of the string */
- x = BITHIGH;
- for (bc = 0; sp != s+slen+1; sp++, bc++)
+ bits8 *result; /* The resulting bit string */
+ char *sp; /* pointer into the character string */
+ bits8 *r;
+ int len, /* Length of the whole data structure */
+ bitlen, /* Number of bits in the bit string */
+ slen; /* Length of the input string */
+ int bit_not_hex = 0;
+ int bc,
+ ipad;
+ bits8 x = 0;
+
+
+ if (s == NULL)
+ return (bits8 *) NULL;
+
+ /* Check that the first character is a b or an x */
+ if (s[0] == 'b' || s[0] == 'B')
+ bit_not_hex = 1;
+ else if (s[0] == 'x' || s[0] == 'X')
+ bit_not_hex = 0;
+ else
+ elog(ERROR, "zpbitin: %s is not a valid bitstring", s);
+
+ slen = strlen(s) - 1;
+ /* Determine bitlength from input string */
+ bitlen = slen;
+ if (!bit_not_hex)
+ bitlen *= 4;
+
+ /*
+ * Sometimes atttypmod is not supplied. If it is supplied we need to
+ * make sure that the bitstring fits. Note that the number of infered
+ * bits can be larger than the number of actual bits needed, but only
+ * if we are reading a hex string and not by more than 3 bits, as a
+ * hex string gives and accurate length upto 4 bits
+ */
+ if (atttypmod > -1)
+ if ((bitlen > atttypmod && bit_not_hex) ||
+ (bitlen > atttypmod + 3 && !bit_not_hex))
+ elog(ERROR, "varbitin: bit string of size %d cannot be written into varying bits(%d)",
+ bitlen, atttypmod);
+
+
+ len = VARBITDATALEN(bitlen);
+
+ if (len > MaxAttrSize)
+ elog(ERROR, "varbitin: length of bit() must be less than %ld",
+ (MaxAttrSize - VARHDRSZ - VARBITHDRSZ) * BITSPERBYTE);
+
+ result = (bits8 *) palloc(len);
+ /* set to 0 so that *r is always initialised and strin is zero-padded */
+ memset(result, 0, len);
+ VARSIZE(result) = len;
+ VARBITLEN(result) = bitlen;
+
+ /*
+ * We need to read the bitstring from the end, as we store it least
+ * significant byte first. s points to the byte before the beginning
+ * of the bitstring
+ */
+ sp = s + 1;
+ r = VARBITS(result);
+ if (bit_not_hex)
+ {
+ /* Parse the bit representation of the string */
+ x = BITHIGH;
+ for (bc = 0; sp != s + slen + 1; sp++, bc++)
+ {
+ if (*sp == '1')
+ *r |= x;
+ if (bc == 7)
+ {
+ bc = 0;
+ x = BITHIGH;
+ r++;
+ }
+ else
+ x >>= 1;
+ }
+ }
+ else
{
- if (*sp=='1')
- *r |= x;
- if (bc==7) {
- bc = 0;
- x = BITHIGH;
- r++;
- } else
- x >>= 1;
+ for (bc = 0; sp != s + slen + 1; sp++)
+ {
+ if (*sp >= '0' && *sp <= '9')
+ x = (bits8) (*sp - '0');
+ else if (*sp >= 'A' && *sp <= 'F')
+ x = (bits8) (*sp - 'A') + 10;
+ else if (*sp >= 'a' && *sp <= 'f')
+ x = (bits8) (*sp - 'a') + 10;
+ else
+ elog(ERROR, "Cannot parse %c as a hex digit", *sp);
+ if (bc)
+ {
+ bc = 0;
+ *r++ |= x;
+ }
+ else
+ {
+ bc++;
+ *r = x << 4;
+ }
+ }
}
- }
- else
- {
- for (bc = 0; sp != s+slen+1; sp++)
+
+ if (bitlen > atttypmod)
{
- if (*sp>='0' && *sp<='9')
- x = (bits8) (*sp - '0');
- else if (*sp>='A' && *sp<='F')
- x = (bits8) (*sp - 'A') + 10;
- else if (*sp>='a' && *sp<='f')
- x = (bits8) (*sp - 'a') + 10;
- else
- elog(ERROR,"Cannot parse %c as a hex digit",*sp);
- if (bc) {
- bc = 0;
- *r++ |= x;
- } else {
- bc++;
- *r = x<<4;
- }
+ /* Check that this fitted */
+ r = (bits8 *) (result + len - 1);
+ ipad = VARBITPAD(result);
+
+ /*
+ * The bottom ipad bits of the byte pointed to by r need to be
+ * zero
+ */
+ if (((*r << (BITSPERBYTE - ipad)) & BITMASK) > 0)
+ elog(ERROR, "varbitin: bit string too large for varying bit(%d) data type",
+ atttypmod);
}
- }
-
- if (bitlen > atttypmod) {
- /* Check that this fitted */
- r = (bits8 *) (result + len - 1);
- ipad = VARBITPAD(result);
- /* The bottom ipad bits of the byte pointed to by r need to be zero */
- if (((*r << (BITSPERBYTE-ipad)) & BITMASK) > 0)
- elog(ERROR, "varbitin: bit string too large for varying bit(%d) data type",
- atttypmod);
- }
-
- return result;
+
+ return result;
}
/*
- the zpbitout routines are fine for varying bits as well
+ the zpbitout routines are fine for varying bits as well
*/
@@ -369,228 +411,244 @@ varbitin(char *s, int dummy, int32 atttypmod)
* Comparison operators
*
* We only need one set of comparison operators for bitstrings, as the lengths
- * are stored in the same way for zero-padded and varying bit strings.
+ * are stored in the same way for zero-padded and varying bit strings.
*
- * Note that the standard is not unambiguous about the comparison between
+ * Note that the standard is not unambiguous about the comparison between
* zero-padded bit strings and varying bitstrings. If the same value is written
- * into a zero padded bitstring as into a varying bitstring, but the zero
- * padded bitstring has greater length, it will be bigger.
+ * into a zero padded bitstring as into a varying bitstring, but the zero
+ * padded bitstring has greater length, it will be bigger.
*
* Zeros from the beginning of a bitstring cannot simply be ignored, as they
* may be part of a bit string and may be significant.
*/
bool
-biteq (bits8 *arg1, bits8 *arg2)
+biteq(bits8 *arg1, bits8 *arg2)
{
- int bitlen1,
- bitlen2;
-
- if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
- return (bool) 0;
- bitlen1 = VARBITLEN(arg1);
- bitlen2 = VARBITLEN(arg2);
- if (bitlen1 != bitlen2)
- return (bool) 0;
-
- /* bit strings are always stored in a full number of bytes */
- return memcmp((void *)VARBITS(arg1),(void *)VARBITS(arg2),
- VARBITBYTES(arg1)) == 0;
+ int bitlen1,
+ bitlen2;
+
+ if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
+ return (bool) 0;
+ bitlen1 = VARBITLEN(arg1);
+ bitlen2 = VARBITLEN(arg2);
+ if (bitlen1 != bitlen2)
+ return (bool) 0;
+
+ /* bit strings are always stored in a full number of bytes */
+ return memcmp((void *) VARBITS(arg1), (void *) VARBITS(arg2),
+ VARBITBYTES(arg1)) == 0;
}
bool
-bitne (bits8 *arg1, bits8 *arg2)
+bitne(bits8 *arg1, bits8 *arg2)
{
- int bitlen1,
- bitlen2;
-
- if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
- return (bool) 0;
- bitlen1 = VARBITLEN(arg1);
- bitlen2 = VARBITLEN(arg2);
- if (bitlen1 != bitlen2)
- return (bool) 1;
-
- /* bit strings are always stored in a full number of bytes */
- return memcmp((void *)VARBITS(arg1),(void *)VARBITS(arg2),
- VARBITBYTES(arg1)) != 0;
+ int bitlen1,
+ bitlen2;
+
+ if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
+ return (bool) 0;
+ bitlen1 = VARBITLEN(arg1);
+ bitlen2 = VARBITLEN(arg2);
+ if (bitlen1 != bitlen2)
+ return (bool) 1;
+
+ /* bit strings are always stored in a full number of bytes */
+ return memcmp((void *) VARBITS(arg1), (void *) VARBITS(arg2),
+ VARBITBYTES(arg1)) != 0;
}
/* bitcmp
- *
+ *
* Compares two bitstrings and returns -1, 0, 1 depending on whether the first
* string is smaller, equal, or bigger than the second. All bits are considered
* and additional zero bits may make one string smaller/larger than the other,
* even if their zero-padded values would be the same.
- * Anything is equal to undefined.
+ * Anything is equal to undefined.
*/
-int
-bitcmp (bits8 *arg1, bits8 *arg2)
+int
+bitcmp(bits8 *arg1, bits8 *arg2)
{
- int bitlen1, bytelen1,
- bitlen2, bytelen2;
- int cmp;
-
- if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
- return (bool) 0;
- bytelen1 = VARBITBYTES(arg1);
- bytelen2 = VARBITBYTES(arg2);
-
- cmp = memcmp(VARBITS(arg1),VARBITS(arg2),Min(bytelen1,bytelen2));
- if (cmp==0) {
- bitlen1 = VARBITLEN(arg1);
- bitlen2 = VARBITLEN(arg2);
- if (bitlen1 != bitlen2)
- return bitlen1 < bitlen2 ? -1 : 1;
- }
- return cmp;
+ int bitlen1,
+ bytelen1,
+ bitlen2,
+ bytelen2;
+ int cmp;
+
+ if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
+ return (bool) 0;
+ bytelen1 = VARBITBYTES(arg1);
+ bytelen2 = VARBITBYTES(arg2);
+
+ cmp = memcmp(VARBITS(arg1), VARBITS(arg2), Min(bytelen1, bytelen2));
+ if (cmp == 0)
+ {
+ bitlen1 = VARBITLEN(arg1);
+ bitlen2 = VARBITLEN(arg2);
+ if (bitlen1 != bitlen2)
+ return bitlen1 < bitlen2 ? -1 : 1;
+ }
+ return cmp;
}
bool
-bitlt (bits8 *arg1, bits8 *arg2)
+bitlt(bits8 *arg1, bits8 *arg2)
{
- return (bool) (bitcmp(arg1,arg2) == -1);
+ return (bool) (bitcmp(arg1, arg2) == -1);
}
bool
-bitle (bits8 *arg1, bits8 *arg2)
+bitle(bits8 *arg1, bits8 *arg2)
{
- return (bool) (bitcmp(arg1,arg2) <= 0);
+ return (bool) (bitcmp(arg1, arg2) <= 0);
}
bool
-bitge (bits8 *arg1, bits8 *arg2)
+bitge(bits8 *arg1, bits8 *arg2)
{
- return (bool) (bitcmp(arg1,arg2) >= 0);
+ return (bool) (bitcmp(arg1, arg2) >= 0);
}
bool
-bitgt (bits8 *arg1, bits8 *arg2)
+bitgt(bits8 *arg1, bits8 *arg2)
{
- return (bool) (bitcmp(arg1,arg2) == 1);
+ return (bool) (bitcmp(arg1, arg2) == 1);
}
/* bitcat
* Concatenation of bit strings
*/
bits8 *
-bitcat (bits8 *arg1, bits8 *arg2)
+bitcat(bits8 *arg1, bits8 *arg2)
{
- int bitlen1, bitlen2, bytelen, bit1pad, bit2shift;
- bits8 *result;
- bits8 *pr, *pa;
-
- if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
- return NULL;
-
- bitlen1 = VARBITLEN(arg1);
- bitlen2 = VARBITLEN(arg2);
-
- bytelen = VARBITDATALEN(bitlen1+bitlen2);
-
- result = (bits8 *) palloc(bytelen*sizeof(bits8));
- VARSIZE(result) = bytelen;
- VARBITLEN(result) = bitlen1+bitlen2;
- printf("%d %d %d \n",VARBITBYTES(arg1),VARBITLEN(arg1),VARBITPAD(arg1));
- /* Copy the first bitstring in */
- memcpy(VARBITS(result),VARBITS(arg1),VARBITBYTES(arg1));
- /* Copy the second bit string */
- bit1pad = VARBITPAD(arg1);
- if (bit1pad==0)
- {
- memcpy(VARBITS(result)+VARBITBYTES(arg1),VARBITS(arg2),
- VARBITBYTES(arg2));
- }
- else if (bitlen2>0)
- {
- /* We need to shift all the results to fit */
- bit2shift = BITSPERBYTE - bit1pad;
- pa = VARBITS(arg2);
- pr = VARBITS(result)+VARBITBYTES(arg1)-1;
- for ( ; pa < VARBITEND(arg2); pa++) {
- *pr |= ((*pa >> bit2shift) & BITMASK);
- pr++;
- if (pr < VARBITEND(result))
- *pr = (*pa << bit1pad) & BITMASK;
- }
- }
-
- return result;
+ int bitlen1,
+ bitlen2,
+ bytelen,
+ bit1pad,
+ bit2shift;
+ bits8 *result;
+ bits8 *pr,
+ *pa;
+
+ if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
+ return NULL;
+
+ bitlen1 = VARBITLEN(arg1);
+ bitlen2 = VARBITLEN(arg2);
+
+ bytelen = VARBITDATALEN(bitlen1 + bitlen2);
+
+ result = (bits8 *) palloc(bytelen * sizeof(bits8));
+ VARSIZE(result) = bytelen;
+ VARBITLEN(result) = bitlen1 + bitlen2;
+ printf("%d %d %d \n", VARBITBYTES(arg1), VARBITLEN(arg1), VARBITPAD(arg1));
+ /* Copy the first bitstring in */
+ memcpy(VARBITS(result), VARBITS(arg1), VARBITBYTES(arg1));
+ /* Copy the second bit string */
+ bit1pad = VARBITPAD(arg1);
+ if (bit1pad == 0)
+ {
+ memcpy(VARBITS(result) + VARBITBYTES(arg1), VARBITS(arg2),
+ VARBITBYTES(arg2));
+ }
+ else if (bitlen2 > 0)
+ {
+ /* We need to shift all the results to fit */
+ bit2shift = BITSPERBYTE - bit1pad;
+ pa = VARBITS(arg2);
+ pr = VARBITS(result) + VARBITBYTES(arg1) - 1;
+ for (; pa < VARBITEND(arg2); pa++)
+ {
+ *pr |= ((*pa >> bit2shift) & BITMASK);
+ pr++;
+ if (pr < VARBITEND(result))
+ *pr = (*pa << bit1pad) & BITMASK;
+ }
+ }
+
+ return result;
}
/* bitsubstr
- * retrieve a substring from the bit string.
+ * retrieve a substring from the bit string.
* Note, s is 1-based.
* SQL draft 6.10 9)
*/
-bits8 *
-bitsubstr (bits8 *arg, int32 s, int32 l)
+bits8 *
+bitsubstr(bits8 *arg, int32 s, int32 l)
{
- int bitlen,
- rbitlen,
- len,
- ipad = 0,
- ishift,
- i;
- int e, s1, e1;
- bits8 * result;
- bits8 mask, *r, *ps;
-
- if (!PointerIsValid(arg))
- return NULL;
-
- bitlen = VARBITLEN(arg);
- e = s+l;
- s1 = Max(s,1);
- e1 = Min(e,bitlen+1);
- if (s1>bitlen || e1<1)
- {
- /* Need to return a null string */
- len = VARBITDATALEN(0);
- result = (bits8 *) palloc(len);
- VARBITLEN(result) = 0;
- VARSIZE(result) = len;
- }
- else
- {
- /* OK, we've got a true substring starting at position s1-1 and
- ending at position e1-1 */
- rbitlen = e1-s1;
- len = VARBITDATALEN(rbitlen);
- result = (bits8 *) palloc(len);
- VARBITLEN(result) = rbitlen;
- VARSIZE(result) = len;
- len -= VARHDRSZ + VARBITHDRSZ;
- /* Are we copying from a byte boundary? */
- if ((s1-1)%BITSPERBYTE==0)
+ int bitlen,
+ rbitlen,
+ len,
+ ipad = 0,
+ ishift,
+ i;
+ int e,
+ s1,
+ e1;
+ bits8 *result;
+ bits8 mask,
+ *r,
+ *ps;
+
+ if (!PointerIsValid(arg))
+ return NULL;
+
+ bitlen = VARBITLEN(arg);
+ e = s + l;
+ s1 = Max(s, 1);
+ e1 = Min(e, bitlen + 1);
+ if (s1 > bitlen || e1 < 1)
{
- /* Yep, we are copying bytes */
- memcpy(VARBITS(result),VARBITS(arg)+(s1-1)/BITSPERBYTE,len);
- }
- else
- {
- /* Figure out how much we need to shift the sequence by */
- ishift = (s1-1)%BITSPERBYTE;
- r = VARBITS(result);
- ps = VARBITS(arg) + (s1-1)/BITSPERBYTE;
- for (i=0; i<len; i++)
- {
- *r = (*ps <<ishift) & BITMASK;
- if ((++ps) < VARBITEND(arg))
- *r |= *ps >>(BITSPERBYTE-ishift);
- r++;
- }
+ /* Need to return a null string */
+ len = VARBITDATALEN(0);
+ result = (bits8 *) palloc(len);
+ VARBITLEN(result) = 0;
+ VARSIZE(result) = len;
}
- /* Do we need to pad at the end? */
- ipad = VARBITPAD(result);
- if (ipad > 0)
+ else
{
- mask = BITMASK << ipad;
- *(VARBITS(result) + len - 1) &= mask;
+
+ /*
+ * OK, we've got a true substring starting at position s1-1 and
+ * ending at position e1-1
+ */
+ rbitlen = e1 - s1;
+ len = VARBITDATALEN(rbitlen);
+ result = (bits8 *) palloc(len);
+ VARBITLEN(result) = rbitlen;
+ VARSIZE(result) = len;
+ len -= VARHDRSZ + VARBITHDRSZ;
+ /* Are we copying from a byte boundary? */
+ if ((s1 - 1) % BITSPERBYTE == 0)
+ {
+ /* Yep, we are copying bytes */
+ memcpy(VARBITS(result), VARBITS(arg) + (s1 - 1) / BITSPERBYTE, len);
+ }
+ else
+ {
+ /* Figure out how much we need to shift the sequence by */
+ ishift = (s1 - 1) % BITSPERBYTE;
+ r = VARBITS(result);
+ ps = VARBITS(arg) + (s1 - 1) / BITSPERBYTE;
+ for (i = 0; i < len; i++)
+ {
+ *r = (*ps << ishift) & BITMASK;
+ if ((++ps) < VARBITEND(arg))
+ *r |= *ps >> (BITSPERBYTE - ishift);
+ r++;
+ }
+ }
+ /* Do we need to pad at the end? */
+ ipad = VARBITPAD(result);
+ if (ipad > 0)
+ {
+ mask = BITMASK << ipad;
+ *(VARBITS(result) + len - 1) &= mask;
+ }
}
- }
- return result;
+ return result;
}
/* bitand
@@ -598,32 +656,32 @@ bitsubstr (bits8 *arg, int32 s, int32 l)
* truncated to the shorter bit string
*/
bits8 *
-bitand (bits8 * arg1, bits8 * arg2)
+bitand(bits8 *arg1, bits8 *arg2)
{
- int len,
- i;
- bits8 *result;
- bits8 *p1,
- *p2,
- *r;
-
- if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
- return (bool) 0;
-
- len = Min(VARSIZE(arg1),VARSIZE(arg2));
- result = (bits8 *) palloc(len);
- VARSIZE(result) = len;
- VARBITLEN(result) = Min(VARBITLEN(arg1),VARBITLEN(arg2));
-
- p1 = (bits8 *) VARBITS(arg1);
- p2 = (bits8 *) VARBITS(arg2);
- r = (bits8 *) VARBITS(result);
- for (i=0; i<Min(VARBITBYTES(arg1),VARBITBYTES(arg2)); i++)
- *r++ = *p1++ & *p2++;
-
- /* Padding is not needed as & of 0 pad is 0 */
-
- return result;
+ int len,
+ i;
+ bits8 *result;
+ bits8 *p1,
+ *p2,
+ *r;
+
+ if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
+ return (bool) 0;
+
+ len = Min(VARSIZE(arg1), VARSIZE(arg2));
+ result = (bits8 *) palloc(len);
+ VARSIZE(result) = len;
+ VARBITLEN(result) = Min(VARBITLEN(arg1), VARBITLEN(arg2));
+
+ p1 = (bits8 *) VARBITS(arg1);
+ p2 = (bits8 *) VARBITS(arg2);
+ r = (bits8 *) VARBITS(result);
+ for (i = 0; i < Min(VARBITBYTES(arg1), VARBITBYTES(arg2)); i++)
+ *r++ = *p1++ & *p2++;
+
+ /* Padding is not needed as & of 0 pad is 0 */
+
+ return result;
}
/* bitor
@@ -631,35 +689,35 @@ bitand (bits8 * arg1, bits8 * arg2)
* truncated to the shorter bit string.
*/
bits8 *
-bitor (bits8 * arg1, bits8 * arg2)
+bitor(bits8 *arg1, bits8 *arg2)
{
- int len,
- i;
- bits8 *result;
- bits8 *p1,
- *p2,
- *r;
- bits8 mask;
-
- if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
- return (bool) 0;
-
- len = Min(VARSIZE(arg1),VARSIZE(arg2));
- result = (bits8 *) palloc(len);
- VARSIZE(result) = len;
- VARBITLEN(result) = Min(VARBITLEN(arg1),VARBITLEN(arg2));
-
- p1 = (bits8 *) VARBITS(arg1);
- p2 = (bits8 *) VARBITS(arg2);
- r = (bits8 *) VARBITS(result);
- for (i=0; i<Min(VARBITBYTES(arg1),VARBITBYTES(arg2)); i++)
- *r++ = *p1++ | *p2++;
-
- /* Pad the result */
- mask = BITMASK << VARBITPAD(result);
- *r &= mask;
-
- return result;
+ int len,
+ i;
+ bits8 *result;
+ bits8 *p1,
+ *p2,
+ *r;
+ bits8 mask;
+
+ if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
+ return (bool) 0;
+
+ len = Min(VARSIZE(arg1), VARSIZE(arg2));
+ result = (bits8 *) palloc(len);
+ VARSIZE(result) = len;
+ VARBITLEN(result) = Min(VARBITLEN(arg1), VARBITLEN(arg2));
+
+ p1 = (bits8 *) VARBITS(arg1);
+ p2 = (bits8 *) VARBITS(arg2);
+ r = (bits8 *) VARBITS(result);
+ for (i = 0; i < Min(VARBITBYTES(arg1), VARBITBYTES(arg2)); i++)
+ *r++ = *p1++ | *p2++;
+
+ /* Pad the result */
+ mask = BITMASK << VARBITPAD(result);
+ *r &= mask;
+
+ return result;
}
/* bitxor
@@ -667,160 +725,167 @@ bitor (bits8 * arg1, bits8 * arg2)
* truncated to the shorter bit string.
*/
bits8 *
-bitxor (bits8 * arg1, bits8 * arg2)
+bitxor(bits8 *arg1, bits8 *arg2)
{
- int len,
- i;
- bits8 *result;
- bits8 *p1,
- *p2,
- *r;
- bits8 mask;
-
- if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
- return (bool) 0;
-
- len = Min(VARSIZE(arg1),VARSIZE(arg2));
- result = (bits8 *) palloc(len);
- VARSIZE(result) = len;
- VARBITLEN(result) = Min(VARBITLEN(arg1),VARBITLEN(arg2));
-
- p1 = (bits8 *) VARBITS(arg1);
- p2 = (bits8 *) VARBITS(arg2);
- r = (bits8 *) VARBITS(result);
- for (i=0; i<Min(VARBITBYTES(arg1),VARBITBYTES(arg2)); i++)
- {
- *r++ = *p1++ ^ *p2++;
- }
-
- /* Pad the result */
- mask = BITMASK << VARBITPAD(result);
- *r &= mask;
-
- return result;
+ int len,
+ i;
+ bits8 *result;
+ bits8 *p1,
+ *p2,
+ *r;
+ bits8 mask;
+
+ if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
+ return (bool) 0;
+
+ len = Min(VARSIZE(arg1), VARSIZE(arg2));
+ result = (bits8 *) palloc(len);
+ VARSIZE(result) = len;
+ VARBITLEN(result) = Min(VARBITLEN(arg1), VARBITLEN(arg2));
+
+ p1 = (bits8 *) VARBITS(arg1);
+ p2 = (bits8 *) VARBITS(arg2);
+ r = (bits8 *) VARBITS(result);
+ for (i = 0; i < Min(VARBITBYTES(arg1), VARBITBYTES(arg2)); i++)
+ *r++ = *p1++ ^ *p2++;
+
+ /* Pad the result */
+ mask = BITMASK << VARBITPAD(result);
+ *r &= mask;
+
+ return result;
}
/* bitnot
* perform a logical NOT on a bit strings.
*/
bits8 *
-bitnot (bits8 * arg)
+bitnot(bits8 *arg)
{
- bits8 *result;
- bits8 *p,
- *r;
- bits8 mask;
-
- if (!PointerIsValid(arg))
- return (bool) 0;
-
- result = (bits8 *) palloc(VARSIZE(arg));
- VARSIZE(result) = VARSIZE(arg);
- VARBITLEN(result) = VARBITLEN(arg);
-
- p = (bits8 *) VARBITS(arg);
- r = (bits8 *) VARBITS(result);
- for ( ; p < VARBITEND(arg); p++, r++)
- *r = ~*p;
-
- /* Pad the result */
- mask = BITMASK << VARBITPAD(result);
- *r &= mask;
-
- return result;
+ bits8 *result;
+ bits8 *p,
+ *r;
+ bits8 mask;
+
+ if (!PointerIsValid(arg))
+ return (bool) 0;
+
+ result = (bits8 *) palloc(VARSIZE(arg));
+ VARSIZE(result) = VARSIZE(arg);
+ VARBITLEN(result) = VARBITLEN(arg);
+
+ p = (bits8 *) VARBITS(arg);
+ r = (bits8 *) VARBITS(result);
+ for (; p < VARBITEND(arg); p++, r++)
+ *r = ~*p;
+
+ /* Pad the result */
+ mask = BITMASK << VARBITPAD(result);
+ *r &= mask;
+
+ return result;
}
/* bitshiftleft
* do a left shift (i.e. to the beginning of the string) of the bit string
*/
bits8 *
-bitshiftleft (bits8 * arg, int shft)
+bitshiftleft(bits8 *arg, int shft)
{
- int byte_shift, ishift, len;
- bits8 *result;
- bits8 *p,
- *r;
-
- if (!PointerIsValid(arg))
- return (bool) 0;
-
- /* Negative shift is a shift to the right */
- if (shft < 0)
- return bitshiftright(arg, -shft);
-
- result = (bits8 *) palloc(VARSIZE(arg));
- VARSIZE(result) = VARSIZE(arg);
- VARBITLEN(result) = VARBITLEN(arg);
- r = (bits8 *) VARBITS(result);
-
- byte_shift = shft/BITSPERBYTE;
- ishift = shft % BITSPERBYTE;
- p = ((bits8 *) VARBITS(arg)) + byte_shift;
-
- if (ishift == 0) {
- /* Special case: we can do a memcpy */
- len = VARBITBYTES(arg) - byte_shift;
- memcpy(r, p, len);
- memset(r+len, 0, byte_shift);
- } else {
- for ( ; p < VARBITEND(arg); r++) {
- *r = *p <<ishift;
- if ((++p) < VARBITEND(arg))
- *r |= *p >>(BITSPERBYTE-ishift);
- }
- for ( ; r < VARBITEND(result) ; r++ )
- *r = (bits8) 0;
- }
-
- return result;
+ int byte_shift,
+ ishift,
+ len;
+ bits8 *result;
+ bits8 *p,
+ *r;
+
+ if (!PointerIsValid(arg))
+ return (bool) 0;
+
+ /* Negative shift is a shift to the right */
+ if (shft < 0)
+ return bitshiftright(arg, -shft);
+
+ result = (bits8 *) palloc(VARSIZE(arg));
+ VARSIZE(result) = VARSIZE(arg);
+ VARBITLEN(result) = VARBITLEN(arg);
+ r = (bits8 *) VARBITS(result);
+
+ byte_shift = shft / BITSPERBYTE;
+ ishift = shft % BITSPERBYTE;
+ p = ((bits8 *) VARBITS(arg)) + byte_shift;
+
+ if (ishift == 0)
+ {
+ /* Special case: we can do a memcpy */
+ len = VARBITBYTES(arg) - byte_shift;
+ memcpy(r, p, len);
+ memset(r + len, 0, byte_shift);
+ }
+ else
+ {
+ for (; p < VARBITEND(arg); r++)
+ {
+ *r = *p << ishift;
+ if ((++p) < VARBITEND(arg))
+ *r |= *p >> (BITSPERBYTE - ishift);
+ }
+ for (; r < VARBITEND(result); r++)
+ *r = (bits8) 0;
+ }
+
+ return result;
}
/* bitshiftright
* do a right shift (i.e. to the beginning of the string) of the bit string
*/
bits8 *
-bitshiftright (bits8 * arg, int shft)
+bitshiftright(bits8 *arg, int shft)
{
- int byte_shift, ishift, len;
- bits8 *result;
- bits8 *p,
- *r;
-
- if (!PointerIsValid(arg))
- return (bits8 *) 0;
-
- /* Negative shift is a shift to the left */
- if (shft < 0)
- return bitshiftleft(arg, -shft);
-
- result = (bits8 *) palloc(VARSIZE(arg));
- VARSIZE(result) = VARSIZE(arg);
- VARBITLEN(result) = VARBITLEN(arg);
- r = (bits8 *) VARBITS(result);
-
- byte_shift = shft/BITSPERBYTE;
- ishift = shft % BITSPERBYTE;
- p = (bits8 *) VARBITS(arg);
-
- /* Set the first part of the result to 0 */
- memset(r, 0, byte_shift);
-
- if (ishift == 0)
- {
- /* Special case: we can do a memcpy */
- len = VARBITBYTES(arg) - byte_shift;
- memcpy(r+byte_shift, p, len);
- }
- else
- {
- r += byte_shift;
- *r = 0; /* Initialise first byte */
- for ( ; r < VARBITEND(result); p++) {
- *r |= *p >> ishift;
- if ((++r) < VARBITEND(result))
- *r = (*p <<(BITSPERBYTE-ishift)) & BITMASK;
- }
- }
-
- return result;
+ int byte_shift,
+ ishift,
+ len;
+ bits8 *result;
+ bits8 *p,
+ *r;
+
+ if (!PointerIsValid(arg))
+ return (bits8 *) 0;
+
+ /* Negative shift is a shift to the left */
+ if (shft < 0)
+ return bitshiftleft(arg, -shft);
+
+ result = (bits8 *) palloc(VARSIZE(arg));
+ VARSIZE(result) = VARSIZE(arg);
+ VARBITLEN(result) = VARBITLEN(arg);
+ r = (bits8 *) VARBITS(result);
+
+ byte_shift = shft / BITSPERBYTE;
+ ishift = shft % BITSPERBYTE;
+ p = (bits8 *) VARBITS(arg);
+
+ /* Set the first part of the result to 0 */
+ memset(r, 0, byte_shift);
+
+ if (ishift == 0)
+ {
+ /* Special case: we can do a memcpy */
+ len = VARBITBYTES(arg) - byte_shift;
+ memcpy(r + byte_shift, p, len);
+ }
+ else
+ {
+ r += byte_shift;
+ *r = 0; /* Initialise first byte */
+ for (; r < VARBITEND(result); p++)
+ {
+ *r |= *p >> ishift;
+ if ((++r) < VARBITEND(result))
+ *r = (*p << (BITSPERBYTE - ishift)) & BITMASK;
+ }
+ }
+
+ return result;
}