1 /*-------------------------------------------------------------------------
4 * Routines for formatting and parsing frontend/backend messages
6 * Outgoing messages are built up in a StringInfo buffer (which is expansible)
7 * and then sent in a single call to pq_putmessage. This module provides data
8 * formatting/conversion routines that are needed to produce valid messages.
9 * Note in particular the distinction between "raw data" and "text"; raw data
10 * is message protocol characters and binary values that are not subject to
11 * character set conversion, while text is converted by character encoding
14 * Incoming messages are similarly read into a StringInfo buffer, via
15 * pq_getmessage, and then parsed and converted from that using the routines
18 * These same routines support reading and writing of external binary formats
19 * (typsend/typreceive routines). The conversion routines for individual
20 * data types are exactly the same, only initialization and completion
24 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
25 * Portions Copyright (c) 1994, Regents of the University of California
29 *-------------------------------------------------------------------------
33 * Message assembly and output:
34 * pq_beginmessage - initialize StringInfo buffer
35 * pq_sendbyte - append a raw byte to a StringInfo buffer
36 * pq_sendint - append a binary integer to a StringInfo buffer
37 * pq_sendint64 - append a binary 8-byte int to a StringInfo buffer
38 * pq_sendfloat4 - append a float4 to a StringInfo buffer
39 * pq_sendfloat8 - append a float8 to a StringInfo buffer
40 * pq_sendbytes - append raw data to a StringInfo buffer
41 * pq_sendcountedtext - append a counted text string (with character set conversion)
42 * pq_sendtext - append a text string (with conversion)
43 * pq_sendstring - append a null-terminated text string (with conversion)
44 * pq_send_ascii_string - append a null-terminated text string (without conversion)
45 * pq_endmessage - send the completed message to the frontend
46 * Note: it is also possible to append data to the StringInfo buffer using
47 * the regular StringInfo routines, but this is discouraged since required
48 * character set conversion may not occur.
50 * typsend support (construct a bytea value containing external binary data):
51 * pq_begintypsend - initialize StringInfo buffer
52 * pq_endtypsend - return the completed string as a "bytea*"
54 * Special-case message output:
55 * pq_puttextmessage - generate a character set-converted message in one step
56 * pq_putemptymessage - convenience routine for message with empty body
58 * Message parsing after input:
59 * pq_getmsgbyte - get a raw byte from a message buffer
60 * pq_getmsgint - get a binary integer from a message buffer
61 * pq_getmsgint64 - get a binary 8-byte int from a message buffer
62 * pq_getmsgfloat4 - get a float4 from a message buffer
63 * pq_getmsgfloat8 - get a float8 from a message buffer
64 * pq_getmsgbytes - get raw data from a message buffer
65 * pq_copymsgbytes - copy raw data from a message buffer
66 * pq_getmsgtext - get a counted text string (with conversion)
67 * pq_getmsgstring - get a null-terminated text string (with conversion)
68 * pq_getmsgend - verify message fully consumed
73 #include <sys/param.h>
74 #include <netinet/in.h>
75 #include <arpa/inet.h>
77 #include "libpq/libpq.h"
78 #include "libpq/pqformat.h"
79 #include "mb/pg_wchar.h"
82 /* --------------------------------
83 * pq_beginmessage - initialize for sending a message
84 * --------------------------------
87 pq_beginmessage(StringInfo buf
, char msgtype
)
92 * We stash the message type into the buffer's cursor field, expecting
93 * that the pq_sendXXX routines won't touch it. We could alternatively
94 * make it the first byte of the buffer contents, but this seems easier.
96 buf
->cursor
= msgtype
;
99 /* --------------------------------
100 * pq_sendbyte - append a raw byte to a StringInfo buffer
101 * --------------------------------
104 pq_sendbyte(StringInfo buf
, int byt
)
106 appendStringInfoCharMacro(buf
, byt
);
109 /* --------------------------------
110 * pq_sendbytes - append raw data to a StringInfo buffer
111 * --------------------------------
114 pq_sendbytes(StringInfo buf
, const char *data
, int datalen
)
116 appendBinaryStringInfo(buf
, data
, datalen
);
119 /* --------------------------------
120 * pq_sendcountedtext - append a counted text string (with character set conversion)
122 * The data sent to the frontend by this routine is a 4-byte count field
123 * followed by the string. The count includes itself or not, as per the
124 * countincludesself flag (pre-3.0 protocol requires it to include itself).
125 * The passed text string need not be null-terminated, and the data sent
126 * to the frontend isn't either.
127 * --------------------------------
130 pq_sendcountedtext(StringInfo buf
, const char *str
, int slen
,
131 bool countincludesself
)
133 int extra
= countincludesself
? 4 : 0;
136 p
= pg_server_to_client(str
, slen
);
137 if (p
!= str
) /* actual conversion has been done? */
140 pq_sendint(buf
, slen
+ extra
, 4);
141 appendBinaryStringInfo(buf
, p
, slen
);
146 pq_sendint(buf
, slen
+ extra
, 4);
147 appendBinaryStringInfo(buf
, str
, slen
);
151 /* --------------------------------
152 * pq_sendtext - append a text string (with conversion)
154 * The passed text string need not be null-terminated, and the data sent
155 * to the frontend isn't either. Note that this is not actually useful
156 * for direct frontend transmissions, since there'd be no way for the
157 * frontend to determine the string length. But it is useful for binary
158 * format conversions.
159 * --------------------------------
162 pq_sendtext(StringInfo buf
, const char *str
, int slen
)
166 p
= pg_server_to_client(str
, slen
);
167 if (p
!= str
) /* actual conversion has been done? */
170 appendBinaryStringInfo(buf
, p
, slen
);
174 appendBinaryStringInfo(buf
, str
, slen
);
177 /* --------------------------------
178 * pq_sendstring - append a null-terminated text string (with conversion)
180 * NB: passed text string must be null-terminated, and so is the data
181 * sent to the frontend.
182 * --------------------------------
185 pq_sendstring(StringInfo buf
, const char *str
)
187 int slen
= strlen(str
);
190 p
= pg_server_to_client(str
, slen
);
191 if (p
!= str
) /* actual conversion has been done? */
194 appendBinaryStringInfo(buf
, p
, slen
+ 1);
198 appendBinaryStringInfo(buf
, str
, slen
+ 1);
201 /* --------------------------------
202 * pq_send_ascii_string - append a null-terminated text string (without conversion)
204 * This function intentionally bypasses encoding conversion, instead just
205 * silently replacing any non-7-bit-ASCII characters with question marks.
206 * It is used only when we are having trouble sending an error message to
207 * the client with normal localization and encoding conversion. The caller
208 * should already have taken measures to ensure the string is just ASCII;
209 * the extra work here is just to make certain we don't send a badly encoded
210 * string to the client (which might or might not be robust about that).
212 * NB: passed text string must be null-terminated, and so is the data
213 * sent to the frontend.
214 * --------------------------------
217 pq_send_ascii_string(StringInfo buf
, const char *str
)
223 if (IS_HIGHBIT_SET(ch
))
225 appendStringInfoCharMacro(buf
, ch
);
227 appendStringInfoChar(buf
, '\0');
230 /* --------------------------------
231 * pq_sendint - append a binary integer to a StringInfo buffer
232 * --------------------------------
235 pq_sendint(StringInfo buf
, int i
, int b
)
244 n8
= (unsigned char) i
;
245 appendBinaryStringInfo(buf
, (char *) &n8
, 1);
248 n16
= htons((uint16
) i
);
249 appendBinaryStringInfo(buf
, (char *) &n16
, 2);
252 n32
= htonl((uint32
) i
);
253 appendBinaryStringInfo(buf
, (char *) &n32
, 4);
256 elog(ERROR
, "unsupported integer size %d", b
);
261 /* --------------------------------
262 * pq_sendint64 - append a binary 8-byte int to a StringInfo buffer
264 * It is tempting to merge this with pq_sendint, but we'd have to make the
265 * argument int64 for all data widths --- that could be a big performance
266 * hit on machines where int64 isn't efficient.
267 * --------------------------------
270 pq_sendint64(StringInfo buf
, int64 i
)
274 /* High order half first, since we're doing MSB-first */
275 #ifdef INT64_IS_BUSTED
276 /* don't try a right shift of 32 on a 32-bit word */
277 n32
= (i
< 0) ? -1 : 0;
279 n32
= (uint32
) (i
>> 32);
282 appendBinaryStringInfo(buf
, (char *) &n32
, 4);
284 /* Now the low order half */
287 appendBinaryStringInfo(buf
, (char *) &n32
, 4);
290 /* --------------------------------
291 * pq_sendfloat4 - append a float4 to a StringInfo buffer
293 * The point of this routine is to localize knowledge of the external binary
294 * representation of float4, which is a component of several datatypes.
296 * We currently assume that float4 should be byte-swapped in the same way
297 * as int4. This rule is not perfect but it gives us portability across
298 * most IEEE-float-using architectures.
299 * --------------------------------
302 pq_sendfloat4(StringInfo buf
, float4 f
)
311 swap
.i
= htonl(swap
.i
);
313 appendBinaryStringInfo(buf
, (char *) &swap
.i
, 4);
316 /* --------------------------------
317 * pq_sendfloat8 - append a float8 to a StringInfo buffer
319 * The point of this routine is to localize knowledge of the external binary
320 * representation of float8, which is a component of several datatypes.
322 * We currently assume that float8 should be byte-swapped in the same way
323 * as int8. This rule is not perfect but it gives us portability across
324 * most IEEE-float-using architectures.
325 * --------------------------------
328 pq_sendfloat8(StringInfo buf
, float8 f
)
330 #ifdef INT64_IS_BUSTED
338 swap
.h
[0] = htonl(swap
.h
[0]);
339 swap
.h
[1] = htonl(swap
.h
[1]);
341 #ifdef WORDS_BIGENDIAN
342 /* machine seems to be big-endian, send h[0] first */
343 appendBinaryStringInfo(buf
, (char *) &swap
.h
[0], 4);
344 appendBinaryStringInfo(buf
, (char *) &swap
.h
[1], 4);
346 /* machine seems to be little-endian, send h[1] first */
347 appendBinaryStringInfo(buf
, (char *) &swap
.h
[1], 4);
348 appendBinaryStringInfo(buf
, (char *) &swap
.h
[0], 4);
350 #else /* INT64 works */
358 pq_sendint64(buf
, swap
.i
);
362 /* --------------------------------
363 * pq_endmessage - send the completed message to the frontend
365 * The data buffer is pfree()d, but if the StringInfo was allocated with
366 * makeStringInfo then the caller must still pfree it.
367 * --------------------------------
370 pq_endmessage(StringInfo buf
)
372 /* msgtype was saved in cursor field */
373 (void) pq_putmessage(buf
->cursor
, buf
->data
, buf
->len
);
374 /* no need to complain about any failure, since pqcomm.c already did */
380 /* --------------------------------
381 * pq_begintypsend - initialize for constructing a bytea result
382 * --------------------------------
385 pq_begintypsend(StringInfo buf
)
388 /* Reserve four bytes for the bytea length word */
389 appendStringInfoCharMacro(buf
, '\0');
390 appendStringInfoCharMacro(buf
, '\0');
391 appendStringInfoCharMacro(buf
, '\0');
392 appendStringInfoCharMacro(buf
, '\0');
395 /* --------------------------------
396 * pq_endtypsend - finish constructing a bytea result
398 * The data buffer is returned as the palloc'd bytea value. (We expect
399 * that it will be suitably aligned for this because it has been palloc'd.)
400 * We assume the StringInfoData is just a local variable in the caller and
401 * need not be pfree'd.
402 * --------------------------------
405 pq_endtypsend(StringInfo buf
)
407 bytea
*result
= (bytea
*) buf
->data
;
409 /* Insert correct length into bytea length word */
410 Assert(buf
->len
>= VARHDRSZ
);
411 SET_VARSIZE(result
, buf
->len
);
417 /* --------------------------------
418 * pq_puttextmessage - generate a character set-converted message in one step
420 * This is the same as the pqcomm.c routine pq_putmessage, except that
421 * the message body is a null-terminated string to which encoding
422 * conversion applies.
423 * --------------------------------
426 pq_puttextmessage(char msgtype
, const char *str
)
428 int slen
= strlen(str
);
431 p
= pg_server_to_client(str
, slen
);
432 if (p
!= str
) /* actual conversion has been done? */
434 (void) pq_putmessage(msgtype
, p
, strlen(p
) + 1);
438 (void) pq_putmessage(msgtype
, str
, slen
+ 1);
442 /* --------------------------------
443 * pq_putemptymessage - convenience routine for message with empty body
444 * --------------------------------
447 pq_putemptymessage(char msgtype
)
449 (void) pq_putmessage(msgtype
, NULL
, 0);
453 /* --------------------------------
454 * pq_getmsgbyte - get a raw byte from a message buffer
455 * --------------------------------
458 pq_getmsgbyte(StringInfo msg
)
460 if (msg
->cursor
>= msg
->len
)
462 (errcode(ERRCODE_PROTOCOL_VIOLATION
),
463 errmsg("no data left in message")));
464 return (unsigned char) msg
->data
[msg
->cursor
++];
467 /* --------------------------------
468 * pq_getmsgint - get a binary integer from a message buffer
470 * Values are treated as unsigned.
471 * --------------------------------
474 pq_getmsgint(StringInfo msg
, int b
)
484 pq_copymsgbytes(msg
, (char *) &n8
, 1);
488 pq_copymsgbytes(msg
, (char *) &n16
, 2);
492 pq_copymsgbytes(msg
, (char *) &n32
, 4);
496 elog(ERROR
, "unsupported integer size %d", b
);
497 result
= 0; /* keep compiler quiet */
503 /* --------------------------------
504 * pq_getmsgint64 - get a binary 8-byte int from a message buffer
506 * It is tempting to merge this with pq_getmsgint, but we'd have to make the
507 * result int64 for all data widths --- that could be a big performance
508 * hit on machines where int64 isn't efficient.
509 * --------------------------------
512 pq_getmsgint64(StringInfo msg
)
518 pq_copymsgbytes(msg
, (char *) &h32
, 4);
519 pq_copymsgbytes(msg
, (char *) &l32
, 4);
523 #ifdef INT64_IS_BUSTED
524 /* error out if incoming value is wider than 32 bits */
526 if ((result
< 0) ? (h32
!= -1) : (h32
!= 0))
528 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE
),
529 errmsg("binary value is out of range for type bigint")));
539 /* --------------------------------
540 * pq_getmsgfloat4 - get a float4 from a message buffer
542 * See notes for pq_sendfloat4.
543 * --------------------------------
546 pq_getmsgfloat4(StringInfo msg
)
554 swap
.i
= pq_getmsgint(msg
, 4);
558 /* --------------------------------
559 * pq_getmsgfloat8 - get a float8 from a message buffer
561 * See notes for pq_sendfloat8.
562 * --------------------------------
565 pq_getmsgfloat8(StringInfo msg
)
567 #ifdef INT64_IS_BUSTED
574 #ifdef WORDS_BIGENDIAN
575 /* machine seems to be big-endian, receive h[0] first */
576 swap
.h
[0] = pq_getmsgint(msg
, 4);
577 swap
.h
[1] = pq_getmsgint(msg
, 4);
579 /* machine seems to be little-endian, receive h[1] first */
580 swap
.h
[1] = pq_getmsgint(msg
, 4);
581 swap
.h
[0] = pq_getmsgint(msg
, 4);
584 #else /* INT64 works */
591 swap
.i
= pq_getmsgint64(msg
);
596 /* --------------------------------
597 * pq_getmsgbytes - get raw data from a message buffer
599 * Returns a pointer directly into the message buffer; note this
600 * may not have any particular alignment.
601 * --------------------------------
604 pq_getmsgbytes(StringInfo msg
, int datalen
)
608 if (datalen
< 0 || datalen
> (msg
->len
- msg
->cursor
))
610 (errcode(ERRCODE_PROTOCOL_VIOLATION
),
611 errmsg("insufficient data left in message")));
612 result
= &msg
->data
[msg
->cursor
];
613 msg
->cursor
+= datalen
;
617 /* --------------------------------
618 * pq_copymsgbytes - copy raw data from a message buffer
620 * Same as above, except data is copied to caller's buffer.
621 * --------------------------------
624 pq_copymsgbytes(StringInfo msg
, char *buf
, int datalen
)
626 if (datalen
< 0 || datalen
> (msg
->len
- msg
->cursor
))
628 (errcode(ERRCODE_PROTOCOL_VIOLATION
),
629 errmsg("insufficient data left in message")));
630 memcpy(buf
, &msg
->data
[msg
->cursor
], datalen
);
631 msg
->cursor
+= datalen
;
634 /* --------------------------------
635 * pq_getmsgtext - get a counted text string (with conversion)
637 * Always returns a pointer to a freshly palloc'd result.
638 * The result has a trailing null, *and* we return its strlen in *nbytes.
639 * --------------------------------
642 pq_getmsgtext(StringInfo msg
, int rawbytes
, int *nbytes
)
647 if (rawbytes
< 0 || rawbytes
> (msg
->len
- msg
->cursor
))
649 (errcode(ERRCODE_PROTOCOL_VIOLATION
),
650 errmsg("insufficient data left in message")));
651 str
= &msg
->data
[msg
->cursor
];
652 msg
->cursor
+= rawbytes
;
654 p
= pg_client_to_server(str
, rawbytes
);
655 if (p
!= str
) /* actual conversion has been done? */
659 p
= (char *) palloc(rawbytes
+ 1);
660 memcpy(p
, str
, rawbytes
);
667 /* --------------------------------
668 * pq_getmsgstring - get a null-terminated text string (with conversion)
670 * May return a pointer directly into the message buffer, or a pointer
671 * to a palloc'd conversion result.
672 * --------------------------------
675 pq_getmsgstring(StringInfo msg
)
680 str
= &msg
->data
[msg
->cursor
];
683 * It's safe to use strlen() here because a StringInfo is guaranteed to
684 * have a trailing null byte. But check we found a null inside the
688 if (msg
->cursor
+ slen
>= msg
->len
)
690 (errcode(ERRCODE_PROTOCOL_VIOLATION
),
691 errmsg("invalid string in message")));
692 msg
->cursor
+= slen
+ 1;
694 return pg_client_to_server(str
, slen
);
697 /* --------------------------------
698 * pq_getmsgend - verify message fully consumed
699 * --------------------------------
702 pq_getmsgend(StringInfo msg
)
704 if (msg
->cursor
!= msg
->len
)
706 (errcode(ERRCODE_PROTOCOL_VIOLATION
),
707 errmsg("invalid message format")));