⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 varlena.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * varlena.c *	  Functions for the variable-length built-in types. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.48.2.1 1999/08/02 05:24:58 scrappy Exp $ * *------------------------------------------------------------------------- */#include <ctype.h>#include "postgres.h"#include "mb/pg_wchar.h"#include "utils/builtins.h"static int	text_cmp(text *arg1, text *arg2);/***************************************************************************** *	 USER I/O ROUTINES														 * *****************************************************************************/#define VAL(CH)			((CH) - '0')#define DIG(VAL)		((VAL) + '0')/* *		byteain			- converts from printable representation of byte array * *		Non-printable characters must be passed as '\nnn' (octal) and are *		converted to internal form.  '\' must be passed as '\\'. *		elog(ERROR, ...) if bad form. * *		BUGS: *				The input is scaned twice. *				The error checking of input is minimal. */text *byteain(char *inputText){	char	   *tp;	char	   *rp;	int			byte;	text	   *result;	if (inputText == NULL)		elog(ERROR, "Bad input string for type bytea");	for (byte = 0, tp = inputText; *tp != '\0'; byte++)		if (*tp++ == '\\')		{			if (*tp == '\\')				tp++;			else if (!isdigit(*tp++) ||					 !isdigit(*tp++) ||					 !isdigit(*tp++))				elog(ERROR, "Bad input string for type bytea");		}	tp = inputText;	byte += VARHDRSZ;	result = (text *) palloc(byte);	result->vl_len = byte;		/* varlena? */	rp = result->vl_dat;	while (*tp != '\0')		if (*tp != '\\' || *++tp == '\\')			*rp++ = *tp++;		else		{			byte = VAL(*tp++);			byte <<= 3;			byte += VAL(*tp++);			byte <<= 3;			*rp++ = byte + VAL(*tp++);		}	return result;}/* *		byteaout		- converts to printable representation of byte array * *		Non-printable characters are inserted as '\nnn' (octal) and '\' as *		'\\'. * *		NULL vlena should be an error--returning string with NULL for now. */char *byteaout(text *vlena){	char	   *result;	char	   *vp;	char	   *rp;	int			val;			/* holds unprintable chars */	int			i;	int			len;	if (vlena == NULL)	{		result = (char *) palloc(2);		result[0] = '-';		result[1] = '\0';		return result;	}	vp = vlena->vl_dat;	len = 1;					/* empty string has 1 char */	for (i = vlena->vl_len - VARHDRSZ; i != 0; i--, vp++)		if (*vp == '\\')			len += 2;		else if (isascii(*vp) && isprint(*vp))			len++;		else			len += VARHDRSZ;	rp = result = (char *) palloc(len);	vp = vlena->vl_dat;	for (i = vlena->vl_len - VARHDRSZ; i != 0; i--)		if (*vp == '\\')		{			vp++;			*rp++ = '\\';			*rp++ = '\\';		}		else if (isascii(*vp) && isprint(*vp))			*rp++ = *vp++;		else		{			val = *vp++;			*rp = '\\';			rp += 3;			*rp-- = DIG(val & 07);			val >>= 3;			*rp-- = DIG(val & 07);			val >>= 3;			*rp = DIG(val & 03);			rp += 3;		}	*rp = '\0';	return result;}/* *		textin			- converts "..." to internal representation */text *textin(char *inputText){	text	   *result;	int			len;	if (inputText == NULL)		return NULL;	len = strlen(inputText) + VARHDRSZ;	result = (text *) palloc(len);	VARSIZE(result) = len;	memmove(VARDATA(result), inputText, len - VARHDRSZ);#ifdef CYR_RECODE	convertstr(VARDATA(result), len - VARHDRSZ, 0);#endif	return result;}/* *		textout			- converts internal representation to "..." */char *textout(text *vlena){	int			len;	char	   *result;	if (vlena == NULL)	{		result = (char *) palloc(2);		result[0] = '-';		result[1] = '\0';		return result;	}	len = VARSIZE(vlena) - VARHDRSZ;	result = (char *) palloc(len + 1);	memmove(result, VARDATA(vlena), len);	result[len] = '\0';#ifdef CYR_RECODE	convertstr(result, len, 1);#endif	return result;}/* ========== PUBLIC ROUTINES ========== *//* * textlen - *	  returns the logical length of a text* *	   (which is less than the VARSIZE of the text*) */int32textlen(text *t){#ifdef MULTIBYTE	unsigned char *s;	int			len,				l,				wl;#endif	if (!PointerIsValid(t))		elog(ERROR, "Null input to textlen");#ifdef MULTIBYTE	len = 0;	s = VARDATA(t);	l = VARSIZE(t) - VARHDRSZ;	while (l > 0)	{		wl = pg_mblen(s);		l -= wl;		s += wl;		len++;	}	return (len);#else	return VARSIZE(t) - VARHDRSZ;#endif}	/* textlen() *//* * textoctetlen - *	  returns the physical length of a text* *	   (which is less than the VARSIZE of the text*) */int32textoctetlen(text *t){	if (!PointerIsValid(t))		elog(ERROR, "Null input to textoctetlen");	return VARSIZE(t) - VARHDRSZ;}	/* textoctetlen() *//* * textcat - *	  takes two text* and returns a text* that is the concatentation of *	  the two. * * Rewritten by Sapa, sapa@hq.icb.chel.su. 8-Jul-96. * Updated by Thomas, Thomas.Lockhart@jpl.nasa.gov 1997-07-10. * Allocate space for output in all cases. * XXX - thomas 1997-07-10 */text *textcat(text *t1, text *t2){	int			len1,				len2,				len;	char	   *ptr;	text	   *result;	if (!PointerIsValid(t1) || !PointerIsValid(t2))		return NULL;	len1 = (VARSIZE(t1) - VARHDRSZ);	if (len1 < 0)		len1 = 0;	while (len1 > 0 && VARDATA(t1)[len1 - 1] == '\0')		len1--;	len2 = (VARSIZE(t2) - VARHDRSZ);	if (len2 < 0)		len2 = 0;	while (len2 > 0 && VARDATA(t2)[len2 - 1] == '\0')		len2--;	len = len1 + len2 + VARHDRSZ;	result = palloc(len);	/* Set size of result string... */	VARSIZE(result) = len;	/* Fill data field of result string... */	ptr = VARDATA(result);	if (len1 > 0)		memcpy(ptr, VARDATA(t1), len1);	if (len2 > 0)		memcpy(ptr + len1, VARDATA(t2), len2);	return result;}	/* textcat() *//* * text_substr() * Return a substring starting at the specified position. * - thomas 1997-12-31 * * Input: *	- string *	- starting position (is one-based) *	- string length * * If the starting position is zero or less, then return from the start of the string *	adjusting the length to be consistant with the "negative start" per SQL92. * If the length is less than zero, return the remaining string. * * Note that the arguments operate on octet length, *	so not aware of multi-byte character sets. * * Added multi-byte support. * - Tatsuo Ishii 1998-4-21 * Changed behavior if starting position is less than one to conform to SQL92 behavior. * Formerly returned the entire string; now returns a portion. * - Thomas Lockhart 1998-12-10 */text *text_substr(text *string, int32 m, int32 n){	text	   *ret;	int			len;#ifdef MULTIBYTE	int			i;	char	   *p;#endif	if (string == (text *) NULL)		return string;	len = VARSIZE(string) - VARHDRSZ;#ifdef MULTIBYTE	len = pg_mbstrlen_with_len(VARDATA(string), len);#endif	/* starting position after the end of the string? */	if (m > len)	{		m = 1;		n = 0;	}	/*	 * starting position before the start of the string? then offset into	 * the string per SQL92 spec...	 */	else if (m < 1)	{		n += (m - 1);		m = 1;	}	/* m will now become a zero-based starting position */	m--;	if (((m + n) > len) || (n < 0))		n = (len - m);#ifdef MULTIBYTE	p = VARDATA(string);	for (i = 0; i < m; i++)		p += pg_mblen(p);	m = p - VARDATA(string);	for (i = 0; i < n; i++)		p += pg_mblen(p);	n = p - (VARDATA(string) + m);#endif	ret = (text *) palloc(VARHDRSZ + n);	VARSIZE(ret) = VARHDRSZ + n;	memcpy(VARDATA(ret), VARDATA(string) + m, n);	return ret;}	/* text_substr() *//* * textpos - *	  Return the position of the specified substring. *	  Implements the SQL92 POSITION() function. *	  Ref: A Guide To The SQL Standard, Date & Darwen, 1997 * - thomas 1997-07-27 * * Added multi-byte support. * - Tatsuo Ishii 1998-4-21 */int32textpos(text *t1, text *t2){	int			pos;	int			px,				p;	int			len1,				len2;	pg_wchar   *p1,			   *p2;#ifdef MULTIBYTE	pg_wchar   *ps1,			   *ps2;#endif	if (!PointerIsValid(t1) || !PointerIsValid(t2))		return 0;	if (VARSIZE(t2) <= 0)		return 1;	len1 = (VARSIZE(t1) - VARHDRSZ);	len2 = (VARSIZE(t2) - VARHDRSZ);#ifdef MULTIBYTE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -