pqformat.c

来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 689 行 · 第 1/2 页

C
689
字号
 * makeStringInfo then the caller must still pfree it. * -------------------------------- */voidpq_endmessage(StringInfo buf){	/* msgtype was saved in cursor field */	(void) pq_putmessage(buf->cursor, buf->data, buf->len);	/* no need to complain about any failure, since pqcomm.c already did */	pfree(buf->data);	buf->data = NULL;}/* -------------------------------- *		pq_begintypsend		- initialize for constructing a bytea result * -------------------------------- */voidpq_begintypsend(StringInfo buf){	initStringInfo(buf);	/* Reserve four bytes for the bytea length word */	appendStringInfoCharMacro(buf, '\0');	appendStringInfoCharMacro(buf, '\0');	appendStringInfoCharMacro(buf, '\0');	appendStringInfoCharMacro(buf, '\0');}/* -------------------------------- *		pq_endtypsend	- finish constructing a bytea result * * The data buffer is returned as the palloc'd bytea value.  (We expect * that it will be suitably aligned for this because it has been palloc'd.) * We assume the StringInfoData is just a local variable in the caller and * need not be pfree'd. * -------------------------------- */bytea *pq_endtypsend(StringInfo buf){	bytea	   *result = (bytea *) buf->data;	/* Insert correct length into bytea length word */	Assert(buf->len >= VARHDRSZ);	VARATT_SIZEP(result) = buf->len;	return result;}/* -------------------------------- *		pq_puttextmessage - generate a character set-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 encoding *		conversion applies. * -------------------------------- */voidpq_puttextmessage(char msgtype, const char *str){	int			slen = strlen(str);	char	   *p;	p = (char *) pg_server_to_client((unsigned char *) str, slen);	if (p != str)				/* actual conversion has been done? */	{		(void) pq_putmessage(msgtype, p, strlen(p) + 1);		pfree(p);		return;	}	(void) pq_putmessage(msgtype, str, slen + 1);}/* -------------------------------- *		pq_putemptymessage - convenience routine for message with empty body * -------------------------------- */voidpq_putemptymessage(char msgtype){	(void) pq_putmessage(msgtype, NULL, 0);}/* -------------------------------- *		pq_getmsgbyte	- get a raw byte from a message buffer * -------------------------------- */intpq_getmsgbyte(StringInfo msg){	if (msg->cursor >= msg->len)		ereport(ERROR,				(errcode(ERRCODE_PROTOCOL_VIOLATION),				 errmsg("no data left in message")));	return (unsigned char) msg->data[msg->cursor++];}/* -------------------------------- *		pq_getmsgint	- get a binary integer from a message buffer * *		Values are treated as unsigned. * -------------------------------- */unsigned intpq_getmsgint(StringInfo msg, int b){	unsigned int result;	unsigned char n8;	uint16		n16;	uint32		n32;	switch (b)	{		case 1:			pq_copymsgbytes(msg, (char *) &n8, 1);			result = n8;			break;		case 2:			pq_copymsgbytes(msg, (char *) &n16, 2);			result = ntohs(n16);			break;		case 4:			pq_copymsgbytes(msg, (char *) &n32, 4);			result = ntohl(n32);			break;		default:			elog(ERROR, "unsupported integer size %d", b);			result = 0;			/* keep compiler quiet */			break;	}	return result;}/* -------------------------------- *		pq_getmsgint64	- get a binary 8-byte int from a message buffer * * It is tempting to merge this with pq_getmsgint, but we'd have to make the * result int64 for all data widths --- that could be a big performance * hit on machines where int64 isn't efficient. * -------------------------------- */int64pq_getmsgint64(StringInfo msg){	int64		result;	uint32		h32;	uint32		l32;	pq_copymsgbytes(msg, (char *) &h32, 4);	pq_copymsgbytes(msg, (char *) &l32, 4);	h32 = ntohl(h32);	l32 = ntohl(l32);#ifdef INT64_IS_BUSTED	/* just lose the high half */	result = l32;#else	result = h32;	result <<= 32;	result |= l32;#endif	return result;}/* -------------------------------- *		pq_getmsgfloat4 - get a float4 from a message buffer * * See notes for pq_sendfloat4. * -------------------------------- */float4pq_getmsgfloat4(StringInfo msg){	union	{		float4		f;		uint32		i;	}			swap;	swap.i = pq_getmsgint(msg, 4);	return swap.f;}/* -------------------------------- *		pq_getmsgfloat8 - get a float8 from a message buffer * * See notes for pq_sendfloat8. * -------------------------------- */float8pq_getmsgfloat8(StringInfo msg){#ifdef INT64_IS_BUSTED	union	{		float8		f;		uint32		h[2];	}			swap;	/* Have to figure out endianness by testing... */	if (((uint32) 1) == htonl((uint32) 1))	{		/* machine seems to be big-endian, receive h[0] first */		swap.h[0] = pq_getmsgint(msg, 4);		swap.h[1] = pq_getmsgint(msg, 4);	}	else	{		/* machine seems to be little-endian, receive h[1] first */		swap.h[1] = pq_getmsgint(msg, 4);		swap.h[0] = pq_getmsgint(msg, 4);	}	return swap.f;#else	union	{		float8		f;		int64		i;	}			swap;	swap.i = pq_getmsgint64(msg);	return swap.f;#endif}/* -------------------------------- *		pq_getmsgbytes	- get raw data from a message buffer * *		Returns a pointer directly into the message buffer; note this *		may not have any particular alignment. * -------------------------------- */const char *pq_getmsgbytes(StringInfo msg, int datalen){	const char *result;	if (datalen < 0 || datalen > (msg->len - msg->cursor))		ereport(ERROR,				(errcode(ERRCODE_PROTOCOL_VIOLATION),				 errmsg("insufficient data left in message")));	result = &msg->data[msg->cursor];	msg->cursor += datalen;	return result;}/* -------------------------------- *		pq_copymsgbytes - copy raw data from a message buffer * *		Same as above, except data is copied to caller's buffer. * -------------------------------- */voidpq_copymsgbytes(StringInfo msg, char *buf, int datalen){	if (datalen < 0 || datalen > (msg->len - msg->cursor))		ereport(ERROR,				(errcode(ERRCODE_PROTOCOL_VIOLATION),				 errmsg("insufficient data left in message")));	memcpy(buf, &msg->data[msg->cursor], datalen);	msg->cursor += datalen;}/* -------------------------------- *		pq_getmsgtext	- get a counted text string (with conversion) * *		Always returns a pointer to a freshly palloc'd result. *		The result has a trailing null, *and* we return its strlen in *nbytes. * -------------------------------- */char *pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes){	char	   *str;	char	   *p;	if (rawbytes < 0 || rawbytes > (msg->len - msg->cursor))		ereport(ERROR,				(errcode(ERRCODE_PROTOCOL_VIOLATION),				 errmsg("insufficient data left in message")));	str = &msg->data[msg->cursor];	msg->cursor += rawbytes;	p = (char *) pg_client_to_server((unsigned char *) str, rawbytes);	if (p != str)				/* actual conversion has been done? */		*nbytes = strlen(p);	else	{		p = (char *) palloc(rawbytes + 1);		memcpy(p, str, rawbytes);		p[rawbytes] = '\0';		*nbytes = rawbytes;	}	return p;}/* -------------------------------- *		pq_getmsgstring - get a null-terminated text string (with conversion) * *		May return a pointer directly into the message buffer, or a pointer *		to a palloc'd conversion result. * -------------------------------- */const char *pq_getmsgstring(StringInfo msg){	char	   *str;	int			slen;	str = &msg->data[msg->cursor];	/*	 * It's safe to use strlen() here because a StringInfo is guaranteed	 * to have a trailing null byte.  But check we found a null inside the	 * message.	 */	slen = strlen(str);	if (msg->cursor + slen >= msg->len)		ereport(ERROR,				(errcode(ERRCODE_PROTOCOL_VIOLATION),				 errmsg("invalid string in message")));	msg->cursor += slen + 1;	return (const char *) pg_client_to_server((unsigned char *) str, slen);}/* -------------------------------- *		pq_getmsgend	- verify message fully consumed * -------------------------------- */voidpq_getmsgend(StringInfo msg){	if (msg->cursor != msg->len)		ereport(ERROR,				(errcode(ERRCODE_PROTOCOL_VIOLATION),				 errmsg("invalid message format")));}

⌨️ 快捷键说明

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