1 /*-------------------------------------------------------------------------
4 * Functions for the variable-length built-in types.
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.14 1997/04/21 04:31:53 vadim Exp $
12 *-------------------------------------------------------------------------
18 #include "utils/palloc.h"
19 #include "utils/builtins.h" /* where function declarations go */
21 /*****************************************************************************
23 *****************************************************************************/
26 #define VAL(CH) ((CH) - '0')
27 #define DIG(VAL) ((VAL) + '0')
30 * byteain - converts from printable representation of byte array
32 * Non-printable characters must be passed as '\nnn' (octal) and are
33 * converted to internal form. '\' must be passed as '\\'.
34 * elog(WARN, ...) if bad form.
37 * The input is scaned twice.
38 * The error checking of input is minimal.
41 byteain(char *inputText)
46 struct varlena *result;
48 if (inputText == NULL)
49 elog(WARN, "Bad input string for type bytea");
51 for (byte = 0, tp = inputText; *tp != '\0'; byte++)
56 else if (!isdigit(*tp++) ||
59 elog(WARN, "Bad input string for type bytea");
62 byte += sizeof(int32); /* varlena? */
63 result = (struct varlena *) palloc(byte);
64 result->vl_len = byte; /* varlena? */
67 if (*tp != '\\' || *++tp == '\\')
74 *rp++ = byte + VAL(*tp++);
80 * Shoves a bunch of memory pointed at by bytes into varlena.
81 * BUGS: Extremely unportable as things shoved can be string
82 * representations of structs, etc.
85 shove_bytes(unsigned char *stuff, int len)
87 struct varlena *result;
89 result = (struct varlena *) palloc(len + sizeof(int32));
91 memmove(result->vl_dat,
92 stuff + sizeof(int32),
100 * byteaout - converts to printable representation of byte array
102 * Non-printable characters are inserted as '\nnn' (octal) and '\' as
105 * NULL vlena should be an error--returning string with NULL for now.
108 byteaout(struct varlena *vlena)
112 register int val; /* holds unprintable chars */
118 result = (char *) palloc(2);
124 len = 1; /* empty string has 1 char */
125 for (i = vlena->vl_len - sizeof(int32); i != 0; i--, vp++) /* varlena? */
128 else if (isascii(*vp) && isprint(*vp))
132 rp = result = (char *) palloc(len);
134 for (i = vlena->vl_len - sizeof(int32); i != 0; i--) /* varlena? */
139 } else if (isascii(*vp) && isprint(*vp))
145 *rp-- = DIG(val & 07);
147 *rp-- = DIG(val & 07);
158 * textin - converts "..." to internal representation
161 textin(char *inputText)
163 struct varlena *result;
166 if (inputText == NULL)
168 len = strlen(inputText) + VARHDRSZ;
169 result = (struct varlena *) palloc(len);
170 VARSIZE(result) = len;
171 memmove(VARDATA(result), inputText, len - VARHDRSZ);
176 * textout - converts internal representation to "..."
179 textout(struct varlena *vlena)
185 result = (char *) palloc(2);
190 len = VARSIZE(vlena) - VARHDRSZ;
191 result = (char *) palloc(len + 1);
192 memmove(result, VARDATA(vlena), len);
198 /* ========== PUBLIC ROUTINES ========== */
202 * returns the actual length of a text* (which may be less than
203 * the VARSIZE of the text*)
206 int textlen (text* t)
209 int max = VARSIZE(t) - VARHDRSZ;
210 char *ptr = VARDATA(t);
211 while (i < max && *ptr++)
218 * takes two text* and returns a text* that is the concatentation of
223 * Rewrited by Sapa, sapa@hq.icb.chel.su. 8-Jul-96.
227 textcat(text* t1, text* t2)
229 int len1, len2, newlen;
233 /* Check for NULL strings... */
234 if (t1 == NULL) return t2;
235 if (t2 == NULL) return t1;
237 /* Check for ZERO-LENGTH strings... */
238 /* I use <= instead of == , I know - it's paranoia, but... */
239 if((len1 = VARSIZE(t1) - VARHDRSZ) <= 0) return t2;
240 if((len2 = VARSIZE(t2) - VARHDRSZ) <= 0) return t1;
242 result = (text *)palloc(newlen = len1 + len2 + VARHDRSZ);
244 /* Fill data field of result string... */
245 memcpy(ptr = VARDATA(result), VARDATA(t1), len1);
246 memcpy(ptr + len1, VARDATA(t2), len2);
248 /* Set size of result string... */
249 VARSIZE(result) = newlen;
255 * texteq - returns 1 iff arguments are equal
256 * textne - returns 1 iff arguments are not equal
259 texteq(struct varlena *arg1, struct varlena *arg2)
262 register char *a1p, *a2p;
264 if (arg1 == NULL || arg2 == NULL)
266 if ((len = arg1->vl_len) != arg2->vl_len)
271 * Varlenas are stored as the total size (data + size variable)
272 * followed by the data. The size variable is an int32 so the
273 * length of the data is the total length less sizeof(int32)
275 len -= sizeof(int32);
277 if (*a1p++ != *a2p++)
283 textne(struct varlena *arg1, struct varlena *arg2)
285 return((bool) !texteq(arg1, arg2));
289 * Comparison function for text strings.
290 * Includes locale support, but must copy strings to temporary memory
291 * to allow null-termination for inputs to strcoll().
294 text_lt(struct varlena *arg1, struct varlena *arg2)
297 #ifdef UNSIGNED_CHAR_TEXT
305 if (arg1 == NULL || arg2 == NULL)
306 return((bool) FALSE);
308 len = (((VARSIZE(arg1) <= VARSIZE(arg2))? VARSIZE(arg1): VARSIZE(arg2))-VARHDRSZ);
312 a1p = palloc (len+1);
313 a2p = palloc (len+1);
315 memcpy(a1p, VARDATA(arg1), len);
317 memcpy(a2p, VARDATA(arg2), len);
320 cval = strcoll(a1p,a2p);
325 return((bool) ( (cval < 0) ||
326 ( (cval == 0) && (VARSIZE(arg1) < VARSIZE(arg2)) ) ) );
330 a1p = (unsigned char *)VARDATA(arg1);
331 a2p = (unsigned char *)VARDATA(arg2);
333 while (len != 0 && *a1p == *a2p) {
338 return((bool) (len? (*a1p < *a2p): (VARSIZE(arg1) < VARSIZE(arg2))));
345 * Comparison function for text strings.
346 * Includes locale support, but must copy strings to temporary memory
347 * to allow null-termination for inputs to strcoll().
350 text_le(struct varlena *arg1, struct varlena *arg2)
353 #ifdef UNSIGNED_CHAR_TEXT
361 if (arg1 == NULL || arg2 == NULL)
364 len = (((VARSIZE(arg1) <= VARSIZE(arg2))? VARSIZE(arg1): VARSIZE(arg2))-VARHDRSZ);
368 a1p = palloc (len+1);
369 a2p = palloc (len+1);
371 memcpy(a1p, VARDATA(arg1), len);
373 memcpy(a2p, VARDATA(arg2), len);
376 cval = strcoll(a1p,a2p);
381 return ((bool) ( (cval < 0) ||
382 ( (cval == 0) && (VARSIZE(arg1) <= VARSIZE(arg2)) ) ) );
386 a1p = (unsigned char *)VARDATA(arg1);
387 a2p = (unsigned char *)VARDATA(arg2);
389 while (len != 0 && *a1p == *a2p) {
395 return((bool) (len? (*a1p <= *a2p): (VARSIZE(arg1) <= VARSIZE(arg2))));
402 text_gt(struct varlena *arg1, struct varlena *arg2)
404 return ((bool) !text_le(arg1, arg2));
408 text_ge(struct varlena *arg1, struct varlena *arg2)
410 return ((bool) !text_lt(arg1, arg2));
413 /*-------------------------------------------------------------
416 * get the number of bytes contained in an instance of type 'bytea'
417 *-------------------------------------------------------------
420 byteaGetSize(struct varlena *v)
424 len = v->vl_len - sizeof(v->vl_len);
429 /*-------------------------------------------------------------
432 * this routine treats "bytea" as an array of bytes.
433 * It returns the Nth byte (a number between 0 and 255) or
434 * it dies if the length of this array is less than n.
435 *-------------------------------------------------------------
438 byteaGetByte(struct varlena *v, int32 n)
443 len = byteaGetSize(v);
446 elog(WARN, "byteaGetByte: index (=%d) out of range [0..%d]",
450 byte = (unsigned char) (v->vl_dat[n]);
452 return((int32) byte);
455 /*-------------------------------------------------------------
458 * This routine treats a "bytea" type like an array of bits.
459 * It returns the value of the Nth bit (0 or 1).
460 * If 'n' is out of range, it dies!
462 *-------------------------------------------------------------
465 byteaGetBit(struct varlena *v, int32 n)
473 byte = byteaGetByte(v, byteNo);
475 if (byte & (1<<bitNo)) {
481 /*-------------------------------------------------------------
484 * Given an instance of type 'bytea' creates a new one with
485 * the Nth byte set to the given value.
487 *-------------------------------------------------------------
490 byteaSetByte(struct varlena *v, int32 n, int32 newByte)
495 len = byteaGetSize(v);
499 "byteaSetByte: index (=%d) out of range [0..%d]",
504 * Make a copy of the original varlena.
506 res = (struct varlena *) palloc(VARSIZE(v));
508 elog(WARN, "byteaSetByte: Out of memory (%d bytes requested)",
511 memmove((char *)res, (char *)v, VARSIZE(v));
516 res->vl_dat[n] = newByte;
521 /*-------------------------------------------------------------
524 * Given an instance of type 'bytea' creates a new one with
525 * the Nth bit set to the given value.
527 *-------------------------------------------------------------
530 byteaSetBit(struct varlena *v, int32 n, int32 newBit)
533 int oldByte, newByte;
539 if (newBit != 0 && newBit != 1) {
540 elog(WARN, "byteaSetByte: new bit must be 0 or 1");
544 * get the byte where the bit we want is stored.
548 oldByte = byteaGetByte(v, byteNo);
551 * calculate the new value for that byte
554 newByte = oldByte & (~(1<<bitNo));
556 newByte = oldByte | (1<<bitNo);
560 * NOTE: 'byteaSetByte' creates a copy of 'v' & sets the byte.
562 res = byteaSetByte(v, byteNo, newByte);