Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * pqformat.h
4 : : * Definitions for formatting and parsing frontend/backend messages
5 : : *
6 : : * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7 : : * Portions Copyright (c) 1994, Regents of the University of California
8 : : *
9 : : * src/include/libpq/pqformat.h
10 : : *
11 : : *-------------------------------------------------------------------------
12 : : */
13 : : #ifndef PQFORMAT_H
14 : : #define PQFORMAT_H
15 : :
16 : : #include "lib/stringinfo.h"
17 : : #include "mb/pg_wchar.h"
18 : : #include "port/pg_bswap.h"
19 : :
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);
24 : :
25 : : extern void pq_sendbytes(StringInfo buf, const void *data, int datalen);
26 : : extern void pq_sendcountedtext(StringInfo buf, const char *str, int slen);
27 : : extern void pq_sendtext(StringInfo buf, const char *str, int slen);
28 : : extern void pq_sendstring(StringInfo buf, const char *str);
29 : : extern void pq_send_ascii_string(StringInfo buf, const char *str);
30 : : extern void pq_sendfloat4(StringInfo buf, float4 f);
31 : : extern void pq_sendfloat8(StringInfo buf, float8 f);
32 : :
33 : : /*
34 : : * Append a [u]int8 to a StringInfo buffer, which already has enough space
35 : : * preallocated.
36 : : *
37 : : * The use of pg_restrict allows the compiler to optimize the code based on
38 : : * the assumption that buf, buf->len, buf->data and *buf->data don't
39 : : * overlap. Without the annotation buf->len etc cannot be kept in a register
40 : : * over subsequent pq_writeintN calls.
41 : : *
42 : : * The use of StringInfoData * rather than StringInfo is due to MSVC being
43 : : * overly picky and demanding a * before a restrict.
44 : : */
45 : : static inline void
2119 andres@anarazel.de 46 :CBC 2339184 : pq_writeint8(StringInfoData *pg_restrict buf, uint8 i)
47 : : {
48 : 2339184 : uint8 ni = i;
49 : :
50 [ - + ]: 2339184 : Assert(buf->len + (int) sizeof(uint8) <= buf->maxlen);
51 : 2339184 : memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint8));
52 : 2339184 : buf->len += sizeof(uint8);
2377 53 : 2339184 : }
54 : :
55 : : /*
56 : : * Append a [u]int16 to a StringInfo buffer, which already has enough space
57 : : * preallocated.
58 : : */
59 : : static inline void
2119 60 : 5104599 : pq_writeint16(StringInfoData *pg_restrict buf, uint16 i)
61 : : {
62 : 5104599 : uint16 ni = pg_hton16(i);
63 : :
64 [ - + ]: 5104599 : Assert(buf->len + (int) sizeof(uint16) <= buf->maxlen);
65 : 5104599 : memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint16));
66 : 5104599 : buf->len += sizeof(uint16);
2377 67 : 5104599 : }
68 : :
69 : : /*
70 : : * Append a [u]int32 to a StringInfo buffer, which already has enough space
71 : : * preallocated.
72 : : */
73 : : static inline void
2119 74 : 16363552 : pq_writeint32(StringInfoData *pg_restrict buf, uint32 i)
75 : : {
76 : 16363552 : uint32 ni = pg_hton32(i);
77 : :
78 [ - + ]: 16363552 : Assert(buf->len + (int) sizeof(uint32) <= buf->maxlen);
79 : 16363552 : memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint32));
80 : 16363552 : buf->len += sizeof(uint32);
2377 81 : 16363552 : }
82 : :
83 : : /*
84 : : * Append a [u]int64 to a StringInfo buffer, which already has enough space
85 : : * preallocated.
86 : : */
87 : : static inline void
2119 88 : 1297359 : pq_writeint64(StringInfoData *pg_restrict buf, uint64 i)
89 : : {
90 : 1297359 : uint64 ni = pg_hton64(i);
91 : :
92 [ - + ]: 1297359 : Assert(buf->len + (int) sizeof(uint64) <= buf->maxlen);
93 : 1297359 : memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint64));
94 : 1297359 : buf->len += sizeof(uint64);
2377 95 : 1297359 : }
96 : :
97 : : /*
98 : : * Append a null-terminated text string (with conversion) to a buffer with
99 : : * preallocated space.
100 : : *
101 : : * NB: The pre-allocated space needs to be sufficient for the string after
102 : : * converting to client encoding.
103 : : *
104 : : * NB: passed text string must be null-terminated, and so is the data
105 : : * sent to the frontend.
106 : : */
107 : : static inline void
2376 108 : 404185 : pq_writestring(StringInfoData *pg_restrict buf, const char *pg_restrict str)
109 : : {
2377 110 : 404185 : int slen = strlen(str);
111 : : char *p;
112 : :
113 : 404185 : p = pg_server_to_client(str, slen);
114 [ + + ]: 404185 : if (p != str) /* actual conversion has been done? */
115 : 16 : slen = strlen(p);
116 : :
117 [ - + ]: 404185 : Assert(buf->len + slen + 1 <= buf->maxlen);
118 : :
2376 119 : 404185 : memcpy(((char *pg_restrict) buf->data + buf->len), p, slen + 1);
2377 120 : 404185 : buf->len += slen + 1;
121 : :
122 [ + + ]: 404185 : if (p != str)
123 : 16 : pfree(p);
124 : 404185 : }
125 : :
126 : : /* append a binary [u]int8 to a StringInfo buffer */
127 : : static inline void
2119 128 : 2339184 : pq_sendint8(StringInfo buf, uint8 i)
129 : : {
130 : 2339184 : enlargeStringInfo(buf, sizeof(uint8));
2377 131 : 2339184 : pq_writeint8(buf, i);
132 : 2339184 : }
133 : :
134 : : /* append a binary [u]int16 to a StringInfo buffer */
135 : : static inline void
2119 136 : 3892044 : pq_sendint16(StringInfo buf, uint16 i)
137 : : {
138 : 3892044 : enlargeStringInfo(buf, sizeof(uint16));
2377 139 : 3892044 : pq_writeint16(buf, i);
140 : 3892044 : }
141 : :
142 : : /* append a binary [u]int32 to a StringInfo buffer */
143 : : static inline void
2119 144 : 15150997 : pq_sendint32(StringInfo buf, uint32 i)
145 : : {
146 : 15150997 : enlargeStringInfo(buf, sizeof(uint32));
2377 147 : 15150997 : pq_writeint32(buf, i);
148 : 15150997 : }
149 : :
150 : : /* append a binary [u]int64 to a StringInfo buffer */
151 : : static inline void
2119 152 : 1297359 : pq_sendint64(StringInfo buf, uint64 i)
153 : : {
154 : 1297359 : enlargeStringInfo(buf, sizeof(uint64));
2377 155 : 1297359 : pq_writeint64(buf, i);
156 : 1297359 : }
157 : :
158 : : /* append a binary byte to a StringInfo buffer */
159 : : static inline void
2119 160 : 2339160 : pq_sendbyte(StringInfo buf, uint8 byt)
161 : : {
2377 162 : 2339160 : pq_sendint8(buf, byt);
163 : 2339160 : }
164 : :
165 : : /*
166 : : * Append a binary integer to a StringInfo buffer
167 : : *
168 : : * This function is deprecated; prefer use of the functions above.
169 : : */
170 : : static inline void
2119 171 : 115165 : pq_sendint(StringInfo buf, uint32 i, int b)
172 : : {
2377 173 [ - - + - ]: 115165 : switch (b)
174 : : {
2377 andres@anarazel.de 175 :UBC 0 : case 1:
2119 176 : 0 : pq_sendint8(buf, (uint8) i);
2377 177 : 0 : break;
178 : 0 : case 2:
2119 179 : 0 : pq_sendint16(buf, (uint16) i);
2377 180 : 0 : break;
2377 andres@anarazel.de 181 :CBC 115165 : case 4:
2119 182 : 115165 : pq_sendint32(buf, (uint32) i);
2377 183 : 115165 : break;
2377 andres@anarazel.de 184 :UBC 0 : default:
185 [ # # ]: 0 : elog(ERROR, "unsupported integer size %d", b);
186 : : break;
187 : : }
2377 andres@anarazel.de 188 :CBC 115165 : }
189 : :
190 : :
191 : : extern void pq_begintypsend(StringInfo buf);
192 : : extern bytea *pq_endtypsend(StringInfo buf);
193 : :
194 : : extern void pq_puttextmessage(char msgtype, const char *str);
195 : : extern void pq_putemptymessage(char msgtype);
196 : :
197 : : extern int pq_getmsgbyte(StringInfo msg);
198 : : extern unsigned int pq_getmsgint(StringInfo msg, int b);
199 : : extern int64 pq_getmsgint64(StringInfo msg);
200 : : extern float4 pq_getmsgfloat4(StringInfo msg);
201 : : extern float8 pq_getmsgfloat8(StringInfo msg);
202 : : extern const char *pq_getmsgbytes(StringInfo msg, int datalen);
203 : : extern void pq_copymsgbytes(StringInfo msg, char *buf, int datalen);
204 : : extern char *pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes);
205 : : extern const char *pq_getmsgstring(StringInfo msg);
206 : : extern const char *pq_getmsgrawstring(StringInfo msg);
207 : : extern void pq_getmsgend(StringInfo msg);
208 : :
209 : : #endif /* PQFORMAT_H */
|