1 /*-------------------------------------------------------------------------
4 * Definitions for formatting and parsing frontend/backend messages
6 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
9 * src/include/libpq/pqformat.h
11 *-------------------------------------------------------------------------
16 #include "lib/stringinfo.h"
17 #include "mb/pg_wchar.h"
18 #include "port/pg_bswap.h"
20 extern void pq_beginmessage(StringInfo buf
, char msgtype
);
21 extern void pq_beginmessage_reuse(StringInfo buf
, char msgtype
);
22 extern void pq_endmessage(StringInfo buf
);
23 extern void pq_endmessage_reuse(StringInfo buf
);
25 extern void pq_sendbytes(StringInfo buf
, const char *data
, int datalen
);
26 extern void pq_sendcountedtext(StringInfo buf
, const char *str
, int slen
,
27 bool countincludesself
);
28 extern void pq_sendtext(StringInfo buf
, const char *str
, int slen
);
29 extern void pq_sendstring(StringInfo buf
, const char *str
);
30 extern void pq_send_ascii_string(StringInfo buf
, const char *str
);
31 extern void pq_sendfloat4(StringInfo buf
, float4 f
);
32 extern void pq_sendfloat8(StringInfo buf
, float8 f
);
35 * Append a [u]int8 to a StringInfo buffer, which already has enough space
38 * The use of pg_restrict allows the compiler to optimize the code based on
39 * the assumption that buf, buf->len, buf->data and *buf->data don't
40 * overlap. Without the annotation buf->len etc cannot be kept in a register
41 * over subsequent pq_writeintN calls.
43 * The use of StringInfoData * rather than StringInfo is due to MSVC being
44 * overly picky and demanding a * before a restrict.
47 pq_writeint8(StringInfoData
*pg_restrict buf
, uint8 i
)
51 Assert(buf
->len
+ (int) sizeof(uint8
) <= buf
->maxlen
);
52 memcpy((char *pg_restrict
) (buf
->data
+ buf
->len
), &ni
, sizeof(uint8
));
53 buf
->len
+= sizeof(uint8
);
57 * Append a [u]int16 to a StringInfo buffer, which already has enough space
61 pq_writeint16(StringInfoData
*pg_restrict buf
, uint16 i
)
63 uint16 ni
= pg_hton16(i
);
65 Assert(buf
->len
+ (int) sizeof(uint16
) <= buf
->maxlen
);
66 memcpy((char *pg_restrict
) (buf
->data
+ buf
->len
), &ni
, sizeof(uint16
));
67 buf
->len
+= sizeof(uint16
);
71 * Append a [u]int32 to a StringInfo buffer, which already has enough space
75 pq_writeint32(StringInfoData
*pg_restrict buf
, uint32 i
)
77 uint32 ni
= pg_hton32(i
);
79 Assert(buf
->len
+ (int) sizeof(uint32
) <= buf
->maxlen
);
80 memcpy((char *pg_restrict
) (buf
->data
+ buf
->len
), &ni
, sizeof(uint32
));
81 buf
->len
+= sizeof(uint32
);
85 * Append a [u]int64 to a StringInfo buffer, which already has enough space
89 pq_writeint64(StringInfoData
*pg_restrict buf
, uint64 i
)
91 uint64 ni
= pg_hton64(i
);
93 Assert(buf
->len
+ (int) sizeof(uint64
) <= buf
->maxlen
);
94 memcpy((char *pg_restrict
) (buf
->data
+ buf
->len
), &ni
, sizeof(uint64
));
95 buf
->len
+= sizeof(uint64
);
99 * Append a null-terminated text string (with conversion) to a buffer with
100 * preallocated space.
102 * NB: The pre-allocated space needs to be sufficient for the string after
103 * converting to client encoding.
105 * NB: passed text string must be null-terminated, and so is the data
106 * sent to the frontend.
109 pq_writestring(StringInfoData
*pg_restrict buf
, const char *pg_restrict str
)
111 int slen
= strlen(str
);
114 p
= pg_server_to_client(str
, slen
);
115 if (p
!= str
) /* actual conversion has been done? */
118 Assert(buf
->len
+ slen
+ 1 <= buf
->maxlen
);
120 memcpy(((char *pg_restrict
) buf
->data
+ buf
->len
), p
, slen
+ 1);
121 buf
->len
+= slen
+ 1;
127 /* append a binary [u]int8 to a StringInfo buffer */
129 pq_sendint8(StringInfo buf
, uint8 i
)
131 enlargeStringInfo(buf
, sizeof(uint8
));
132 pq_writeint8(buf
, i
);
135 /* append a binary [u]int16 to a StringInfo buffer */
137 pq_sendint16(StringInfo buf
, uint16 i
)
139 enlargeStringInfo(buf
, sizeof(uint16
));
140 pq_writeint16(buf
, i
);
143 /* append a binary [u]int32 to a StringInfo buffer */
145 pq_sendint32(StringInfo buf
, uint32 i
)
147 enlargeStringInfo(buf
, sizeof(uint32
));
148 pq_writeint32(buf
, i
);
151 /* append a binary [u]int64 to a StringInfo buffer */
153 pq_sendint64(StringInfo buf
, uint64 i
)
155 enlargeStringInfo(buf
, sizeof(uint64
));
156 pq_writeint64(buf
, i
);
159 /* append a binary byte to a StringInfo buffer */
161 pq_sendbyte(StringInfo buf
, uint8 byt
)
163 pq_sendint8(buf
, byt
);
167 * Append a binary integer to a StringInfo buffer
169 * This function is deprecated; prefer use of the functions above.
172 pq_sendint(StringInfo buf
, uint32 i
, int b
)
177 pq_sendint8(buf
, (uint8
) i
);
180 pq_sendint16(buf
, (uint16
) i
);
183 pq_sendint32(buf
, (uint32
) i
);
186 elog(ERROR
, "unsupported integer size %d", b
);
192 extern void pq_begintypsend(StringInfo buf
);
193 extern bytea
*pq_endtypsend(StringInfo buf
);
195 extern void pq_puttextmessage(char msgtype
, const char *str
);
196 extern void pq_putemptymessage(char msgtype
);
198 extern int pq_getmsgbyte(StringInfo msg
);
199 extern unsigned int pq_getmsgint(StringInfo msg
, int b
);
200 extern int64
pq_getmsgint64(StringInfo msg
);
201 extern float4
pq_getmsgfloat4(StringInfo msg
);
202 extern float8
pq_getmsgfloat8(StringInfo msg
);
203 extern const char *pq_getmsgbytes(StringInfo msg
, int datalen
);
204 extern void pq_copymsgbytes(StringInfo msg
, char *buf
, int datalen
);
205 extern char *pq_getmsgtext(StringInfo msg
, int rawbytes
, int *nbytes
);
206 extern const char *pq_getmsgstring(StringInfo msg
);
207 extern const char *pq_getmsgrawstring(StringInfo msg
);
208 extern void pq_getmsgend(StringInfo msg
);
210 #endif /* PQFORMAT_H */