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

📄 pqformat.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/*------------------------------------------------------------------------- * * pqformat.c *		Routines for formatting and parsing frontend/backend messages * * Outgoing messages are built up in a StringInfo buffer (which is expansible) * and then sent in a single call to pq_putmessage.  This module provides data * formatting/conversion routines that are needed to produce valid messages. * Note in particular the distinction between "raw data" and "text"; raw data * is message protocol characters and binary values that are not subject to * MULTIBYTE conversion, while text is converted by MULTIBYTE rules. * * Incoming messages are read directly off the wire, as it were, but there * are still data-conversion tasks to be performed. * * Copyright (c) 1994, Regents of the University of California * *	$Id: pqformat.c,v 1.4.2.1 1999/09/12 22:25:32 scrappy Exp $ * *------------------------------------------------------------------------- *//* * INTERFACE ROUTINES * Message assembly and output: *		pq_beginmessage - initialize StringInfo buffer *		pq_sendbyte		- append a raw byte to a StringInfo buffer *		pq_sendint		- append a binary integer to a StringInfo buffer *		pq_sendbytes	- append raw data to a StringInfo buffer *		pq_sendcountedtext - append a text string (with MULTIBYTE conversion) *		pq_sendstring	- append a null-terminated text string (with MULTIBYTE) *		pq_endmessage	- send the completed message to the frontend * Note: it is also possible to append data to the StringInfo buffer using * the regular StringInfo routines, but this is discouraged since required * MULTIBYTE conversion may not occur. * * Special-case message output: *		pq_puttextmessage - generate a MULTIBYTE-converted message in one step * * Message input: *		pq_getint		- get an integer from connection *		pq_getstr		- get a null terminated string from connection * pq_getstr performs MULTIBYTE conversion on the collected string. * Use the raw pqcomm.c routines pq_getstring or pq_getbytes * to fetch data without conversion. */#include "postgres.h"#include "libpq/pqformat.h"#include "libpq/libpq.h"#ifdef MULTIBYTE#include "mb/pg_wchar.h"#endif#include <string.h>#ifdef HAVE_ENDIAN_H#include <endian.h>#endif#ifdef HAVE_SYS_PARAM_H#include <sys/param.h>#endif#ifndef BYTE_ORDER#error BYTE_ORDER must be defined as LITTLE_ENDIAN, BIG_ENDIAN or PDP_ENDIAN#endif#if BYTE_ORDER == LITTLE_ENDIAN#define ntoh_s(n)	n#define ntoh_l(n)	n#define hton_s(n)	n#define hton_l(n)	n#else#if BYTE_ORDER == BIG_ENDIAN#define ntoh_s(n)	(uint16)((((uint16)n & 0x00ff) <<  8) | \				 (((uint16)n & 0xff00) >>  8))#define ntoh_l(n)	(uint32)((((uint32)n & 0x000000ff) << 24) | \				 (((uint32)n & 0x0000ff00) <<  8) | \				 (((uint32)n & 0x00ff0000) >>  8) | \				 (((uint32)n & 0xff000000) >> 24))#define hton_s(n)	(ntoh_s(n))#define hton_l(n)	(ntoh_l(n))#else#if BYTE_ORDER == PDP_ENDIAN#error PDP_ENDIAN macros not written yet#else#error BYTE_ORDER not defined as anything understood#endif#endif#endif/* -------------------------------- *		pq_sendbyte		- append a raw byte to a StringInfo buffer * -------------------------------- */voidpq_sendbyte(StringInfo buf, int byt){	appendStringInfoChar(buf, byt);}/* -------------------------------- *		pq_sendbytes	- append raw data to a StringInfo buffer * -------------------------------- */voidpq_sendbytes(StringInfo buf, const char *data, int datalen){	appendBinaryStringInfo(buf, data, datalen);}/* -------------------------------- *		pq_sendcountedtext - append a text string (with MULTIBYTE conversion) * * The data sent to the frontend by this routine is a 4-byte count field * (the count includes itself, by convention) followed by the string. * The passed text string need not be null-terminated, and the data sent * to the frontend isn't either. * -------------------------------- */voidpq_sendcountedtext(StringInfo buf, const char *str, int slen){#ifdef MULTIBYTE	const char *p;	p = (const char *) pg_server_to_client((unsigned char *) str, slen);	if (p != str)				/* actual conversion has been done? */	{		str = p;		slen = strlen(str);	}#endif	pq_sendint(buf, slen + 4, 4);	appendBinaryStringInfo(buf, str, slen);}/* -------------------------------- *		pq_sendstring	- append a null-terminated text string (with MULTIBYTE) * * NB: passed text string must be null-terminated, and so is the data * sent to the frontend. * -------------------------------- */voidpq_sendstring(StringInfo buf, const char *str){	int			slen = strlen(str);#ifdef MULTIBYTE	const char *p;	p = (const char *) pg_server_to_client((unsigned char *) str, slen);	if (p != str)				/* actual conversion has been done? */	{		str = p;		slen = strlen(str);	}#endif	appendBinaryStringInfo(buf, str, slen + 1);}/* -------------------------------- *		pq_sendint		- append a binary integer to a StringInfo buffer * -------------------------------- */voidpq_sendint(StringInfo buf, int i, int b){	unsigned char n8;	uint16		n16;	uint32		n32;	switch (b)	{		case 1:			n8 = (unsigned char) i;			appendBinaryStringInfo(buf, (char *) &n8, 1);			break;		case 2:			n16 = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_s(i) : htons((uint16) i));			appendBinaryStringInfo(buf, (char *) &n16, 2);			break;		case 4:			n32 = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_l(i) : htonl((uint32) i));			appendBinaryStringInfo(buf, (char *) &n32, 4);			break;		default:			elog(ERROR, "pq_sendint: unsupported size %d", b);			break;	}}/* -------------------------------- *		pq_endmessage	- send the completed message to the frontend * * The data buffer is pfree()d, but if the StringInfo was allocated with * makeStringInfo then the caller must still pfree it. * -------------------------------- */voidpq_endmessage(StringInfo buf){	if (pq_putmessage('\0', buf->data, buf->len))	{		snprintf(PQerrormsg, ERROR_MSG_LENGTH,				 "FATAL: pq_endmessage failed: errno=%d\n", errno);		fputs(PQerrormsg, stderr);		pqdebug("%s", PQerrormsg);	}	pfree(buf->data);	buf->data = NULL;}/* -------------------------------- *		pq_puttextmessage - generate a MULTIBYTE-converted message in one step * *		This is the same as the pqcomm.c routine pq_putmessage, except that *		the message body is a null-terminated string to which MULTIBYTE *		conversion applies. * *		returns 0 if OK, EOF if trouble * -------------------------------- */intpq_puttextmessage(char msgtype, const char *str){	int			slen = strlen(str);#ifdef MULTIBYTE	const char *p;	p = (const char *) pg_server_to_client((unsigned char *) str, slen);	if (p != str)				/* actual conversion has been done? */	{		str = p;		slen = strlen(str);	}#endif	return pq_putmessage(msgtype, str, slen + 1);}/* -------------------------------- *		pq_getint - get an integer from connection * *		returns 0 if OK, EOF if trouble * -------------------------------- */intpq_getint(int *result, int b){	int			status;	unsigned char n8;	uint16		n16;	uint32		n32;	switch (b)	{		case 1:			status = pq_getbytes((char *) &n8, 1);			*result = (int) n8;			break;		case 2:			status = pq_getbytes((char *) &n16, 2);			*result = (int) ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ?							 ntoh_s(n16) : ntohs(n16));			break;		case 4:			status = pq_getbytes((char *) &n32, 4);			*result = (int) ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ?							 ntoh_l(n32) : ntohl(n32));			break;		default:			/*			 * if we elog(ERROR) here, we will lose sync with the			 * frontend, so just complain to postmaster log instead...			 */			fprintf(stderr, "pq_getint: unsupported size %d\n", b);			status = EOF;			*result = 0;			break;	}	return status;}/* -------------------------------- *		pq_getstr - get a null terminated string from connection * *		FIXME: we ought to use an expansible StringInfo buffer, *		rather than dropping data if the message is too long. * *		returns 0 if OK, EOF if trouble * -------------------------------- */intpq_getstr(char *s, int maxlen){	int			c;#ifdef MULTIBYTE	char	   *p;#endif	c = pq_getstring(s, maxlen);#ifdef MULTIBYTE	p = (char *) pg_client_to_server((unsigned char *) s, strlen(s));	if (p != s)					/* actual conversion has been done? */	{		int			newlen = strlen(p);		if (newlen < maxlen)			strcpy(s, p);		else		{			strncpy(s, p, maxlen);			s[maxlen - 1] = '\0';		}	}#endif	return c;}

⌨️ 快捷键说明

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