PostgreSQL Source Code  git master
pqformat.h
Go to the documentation of this file.
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);
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
47 {
48  uint8 ni = i;
49 
50  Assert(buf->len + (int) sizeof(uint8) <= buf->maxlen);
51  memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint8));
52  buf->len += sizeof(uint8);
53 }
54 
55 /*
56  * Append a [u]int16 to a StringInfo buffer, which already has enough space
57  * preallocated.
58  */
59 static inline void
61 {
62  uint16 ni = pg_hton16(i);
63 
64  Assert(buf->len + (int) sizeof(uint16) <= buf->maxlen);
65  memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint16));
66  buf->len += sizeof(uint16);
67 }
68 
69 /*
70  * Append a [u]int32 to a StringInfo buffer, which already has enough space
71  * preallocated.
72  */
73 static inline void
75 {
76  uint32 ni = pg_hton32(i);
77 
78  Assert(buf->len + (int) sizeof(uint32) <= buf->maxlen);
79  memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint32));
80  buf->len += sizeof(uint32);
81 }
82 
83 /*
84  * Append a [u]int64 to a StringInfo buffer, which already has enough space
85  * preallocated.
86  */
87 static inline void
88 pq_writeint64(StringInfoData *pg_restrict buf, uint64 i)
89 {
90  uint64 ni = pg_hton64(i);
91 
92  Assert(buf->len + (int) sizeof(uint64) <= buf->maxlen);
93  memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint64));
94  buf->len += sizeof(uint64);
95 }
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
108 pq_writestring(StringInfoData *pg_restrict buf, const char *pg_restrict str)
109 {
110  int slen = strlen(str);
111  char *p;
112 
113  p = pg_server_to_client(str, slen);
114  if (p != str) /* actual conversion has been done? */
115  slen = strlen(p);
116 
117  Assert(buf->len + slen + 1 <= buf->maxlen);
118 
119  memcpy(((char *pg_restrict) buf->data + buf->len), p, slen + 1);
120  buf->len += slen + 1;
121 
122  if (p != str)
123  pfree(p);
124 }
125 
126 /* append a binary [u]int8 to a StringInfo buffer */
127 static inline void
129 {
130  enlargeStringInfo(buf, sizeof(uint8));
131  pq_writeint8(buf, i);
132 }
133 
134 /* append a binary [u]int16 to a StringInfo buffer */
135 static inline void
137 {
138  enlargeStringInfo(buf, sizeof(uint16));
139  pq_writeint16(buf, i);
140 }
141 
142 /* append a binary [u]int32 to a StringInfo buffer */
143 static inline void
145 {
146  enlargeStringInfo(buf, sizeof(uint32));
147  pq_writeint32(buf, i);
148 }
149 
150 /* append a binary [u]int64 to a StringInfo buffer */
151 static inline void
153 {
154  enlargeStringInfo(buf, sizeof(uint64));
155  pq_writeint64(buf, i);
156 }
157 
158 /* append a binary byte to a StringInfo buffer */
159 static inline void
161 {
162  pq_sendint8(buf, byt);
163 }
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
172 {
173  switch (b)
174  {
175  case 1:
176  pq_sendint8(buf, (uint8) i);
177  break;
178  case 2:
179  pq_sendint16(buf, (uint16) i);
180  break;
181  case 4:
182  pq_sendint32(buf, (uint32) i);
183  break;
184  default:
185  elog(ERROR, "unsupported integer size %d", b);
186  break;
187  }
188 }
189 
190 
191 extern void pq_begintypsend(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 */
unsigned short uint16
Definition: c.h:505
unsigned int uint32
Definition: c.h:506
#define Assert(condition)
Definition: c.h:849
double float8
Definition: c.h:621
float float4
Definition: c.h:620
unsigned char uint8
Definition: c.h:504
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
const char * str
int b
Definition: isn.c:69
int i
Definition: isn.c:72
char * pg_server_to_client(const char *s, int len)
Definition: mbutils.c:738
void pfree(void *pointer)
Definition: mcxt.c:1521
#define pg_hton32(x)
Definition: pg_bswap.h:121
#define pg_hton64(x)
Definition: pg_bswap.h:122
#define pg_hton16(x)
Definition: pg_bswap.h:120
const void * data
static char * buf
Definition: pg_test_fsync.c:72
static void pq_writeint8(StringInfoData *pg_restrict buf, uint8 i)
Definition: pqformat.h:46
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:415
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:144
float4 pq_getmsgfloat4(StringInfo msg)
Definition: pqformat.c:469
static void pq_sendbyte(StringInfo buf, uint8 byt)
Definition: pqformat.h:160
static void pq_writeint64(StringInfoData *pg_restrict buf, uint64 i)
Definition: pqformat.h:88
void pq_sendbytes(StringInfo buf, const void *data, int datalen)
Definition: pqformat.c:126
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:172
const char * pq_getmsgstring(StringInfo msg)
Definition: pqformat.c:579
void pq_getmsgend(StringInfo msg)
Definition: pqformat.c:635
void pq_copymsgbytes(StringInfo msg, char *buf, int datalen)
Definition: pqformat.c:528
const char * pq_getmsgbytes(StringInfo msg, int datalen)
Definition: pqformat.c:508
void pq_putemptymessage(char msgtype)
Definition: pqformat.c:388
float8 pq_getmsgfloat8(StringInfo msg)
Definition: pqformat.c:488
void pq_puttextmessage(char msgtype, const char *str)
Definition: pqformat.c:367
void pq_sendstring(StringInfo buf, const char *str)
Definition: pqformat.c:195
static void pq_sendint64(StringInfo buf, uint64 i)
Definition: pqformat.h:152
void pq_endmessage(StringInfo buf)
Definition: pqformat.c:296
static void pq_writestring(StringInfoData *pg_restrict buf, const char *pg_restrict str)
Definition: pqformat.h:108
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:546
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
static void pq_sendint8(StringInfo buf, uint8 i)
Definition: pqformat.h:128
int pq_getmsgbyte(StringInfo msg)
Definition: pqformat.c:399
void pq_beginmessage(StringInfo buf, char msgtype)
Definition: pqformat.c:88
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:453
static void pq_writeint32(StringInfoData *pg_restrict buf, uint32 i)
Definition: pqformat.h:74
void pq_sendfloat4(StringInfo buf, float4 f)
Definition: pqformat.c:252
static void pq_sendint16(StringInfo buf, uint16 i)
Definition: pqformat.h:136
const char * pq_getmsgrawstring(StringInfo msg)
Definition: pqformat.c:608
static void pq_writeint16(StringInfoData *pg_restrict buf, uint16 i)
Definition: pqformat.h:60
void pq_beginmessage_reuse(StringInfo buf, char msgtype)
Definition: pqformat.c:109
void pq_send_ascii_string(StringInfo buf, const char *str)
Definition: pqformat.c:227
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
static void pq_sendint(StringInfo buf, uint32 i, int b)
Definition: pqformat.h:171
void pq_sendfloat8(StringInfo buf, float8 f)
Definition: pqformat.c:276
void pq_endmessage_reuse(StringInfo buf)
Definition: pqformat.c:314
void pq_sendcountedtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:142
void enlargeStringInfo(StringInfo str, int needed)
Definition: stringinfo.c:286
Definition: c.h:678