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-2023, 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  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);
33 
34 /*
35  * Append a [u]int8 to a StringInfo buffer, which already has enough space
36  * preallocated.
37  *
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.
42  *
43  * The use of StringInfoData * rather than StringInfo is due to MSVC being
44  * overly picky and demanding a * before a restrict.
45  */
46 static inline void
48 {
49  uint8 ni = i;
50 
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);
54 }
55 
56 /*
57  * Append a [u]int16 to a StringInfo buffer, which already has enough space
58  * preallocated.
59  */
60 static inline void
62 {
63  uint16 ni = pg_hton16(i);
64 
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);
68 }
69 
70 /*
71  * Append a [u]int32 to a StringInfo buffer, which already has enough space
72  * preallocated.
73  */
74 static inline void
76 {
77  uint32 ni = pg_hton32(i);
78 
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);
82 }
83 
84 /*
85  * Append a [u]int64 to a StringInfo buffer, which already has enough space
86  * preallocated.
87  */
88 static inline void
89 pq_writeint64(StringInfoData *pg_restrict buf, uint64 i)
90 {
91  uint64 ni = pg_hton64(i);
92 
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);
96 }
97 
98 /*
99  * Append a null-terminated text string (with conversion) to a buffer with
100  * preallocated space.
101  *
102  * NB: The pre-allocated space needs to be sufficient for the string after
103  * converting to client encoding.
104  *
105  * NB: passed text string must be null-terminated, and so is the data
106  * sent to the frontend.
107  */
108 static inline void
109 pq_writestring(StringInfoData *pg_restrict buf, const char *pg_restrict str)
110 {
111  int slen = strlen(str);
112  char *p;
113 
114  p = pg_server_to_client(str, slen);
115  if (p != str) /* actual conversion has been done? */
116  slen = strlen(p);
117 
118  Assert(buf->len + slen + 1 <= buf->maxlen);
119 
120  memcpy(((char *pg_restrict) buf->data + buf->len), p, slen + 1);
121  buf->len += slen + 1;
122 
123  if (p != str)
124  pfree(p);
125 }
126 
127 /* append a binary [u]int8 to a StringInfo buffer */
128 static inline void
130 {
131  enlargeStringInfo(buf, sizeof(uint8));
132  pq_writeint8(buf, i);
133 }
134 
135 /* append a binary [u]int16 to a StringInfo buffer */
136 static inline void
138 {
139  enlargeStringInfo(buf, sizeof(uint16));
140  pq_writeint16(buf, i);
141 }
142 
143 /* append a binary [u]int32 to a StringInfo buffer */
144 static inline void
146 {
147  enlargeStringInfo(buf, sizeof(uint32));
148  pq_writeint32(buf, i);
149 }
150 
151 /* append a binary [u]int64 to a StringInfo buffer */
152 static inline void
154 {
155  enlargeStringInfo(buf, sizeof(uint64));
156  pq_writeint64(buf, i);
157 }
158 
159 /* append a binary byte to a StringInfo buffer */
160 static inline void
162 {
163  pq_sendint8(buf, byt);
164 }
165 
166 /*
167  * Append a binary integer to a StringInfo buffer
168  *
169  * This function is deprecated; prefer use of the functions above.
170  */
171 static inline void
173 {
174  switch (b)
175  {
176  case 1:
177  pq_sendint8(buf, (uint8) i);
178  break;
179  case 2:
180  pq_sendint16(buf, (uint16) i);
181  break;
182  case 4:
183  pq_sendint32(buf, (uint32) i);
184  break;
185  default:
186  elog(ERROR, "unsupported integer size %d", b);
187  break;
188  }
189 }
190 
191 
192 extern void pq_begintypsend(StringInfo buf);
194 
195 extern void pq_puttextmessage(char msgtype, const char *str);
196 extern void pq_putemptymessage(char msgtype);
197 
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);
209 
210 #endif /* PQFORMAT_H */
unsigned short uint16
Definition: c.h:494
unsigned int uint32
Definition: c.h:495
double float8
Definition: c.h:619
float float4
Definition: c.h:618
unsigned char uint8
Definition: c.h:493
#define ERROR
Definition: elog.h:39
int b
Definition: isn.c:70
int i
Definition: isn.c:73
Assert(fmt[strlen(fmt) - 1] !='\n')
char * pg_server_to_client(const char *s, int len)
Definition: mbutils.c:739
void pfree(void *pointer)
Definition: mcxt.c:1456
#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:67
static void pq_writeint8(StringInfoData *pg_restrict buf, uint8 i)
Definition: pqformat.h:47
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:418
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145
float4 pq_getmsgfloat4(StringInfo msg)
Definition: pqformat.c:472
static void pq_sendbyte(StringInfo buf, uint8 byt)
Definition: pqformat.h:161
static void pq_writeint64(StringInfoData *pg_restrict buf, uint64 i)
Definition: pqformat.h:89
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:175
const char * pq_getmsgstring(StringInfo msg)
Definition: pqformat.c:582
void pq_getmsgend(StringInfo msg)
Definition: pqformat.c:638
void pq_copymsgbytes(StringInfo msg, char *buf, int datalen)
Definition: pqformat.c:531
const char * pq_getmsgbytes(StringInfo msg, int datalen)
Definition: pqformat.c:511
void pq_putemptymessage(char msgtype)
Definition: pqformat.c:391
float8 pq_getmsgfloat8(StringInfo msg)
Definition: pqformat.c:491
void pq_puttextmessage(char msgtype, const char *str)
Definition: pqformat.c:370
void pq_sendstring(StringInfo buf, const char *str)
Definition: pqformat.c:198
static void pq_sendint64(StringInfo buf, uint64 i)
Definition: pqformat.h:153
void pq_endmessage(StringInfo buf)
Definition: pqformat.c:299
static void pq_writestring(StringInfoData *pg_restrict buf, const char *pg_restrict str)
Definition: pqformat.h:109
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:549
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:329
static void pq_sendint8(StringInfo buf, uint8 i)
Definition: pqformat.h:129
int pq_getmsgbyte(StringInfo msg)
Definition: pqformat.c:402
void pq_beginmessage(StringInfo buf, char msgtype)
Definition: pqformat.c:88
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:456
static void pq_writeint32(StringInfoData *pg_restrict buf, uint32 i)
Definition: pqformat.h:75
void pq_sendfloat4(StringInfo buf, float4 f)
Definition: pqformat.c:255
static void pq_sendint16(StringInfo buf, uint16 i)
Definition: pqformat.h:137
const char * pq_getmsgrawstring(StringInfo msg)
Definition: pqformat.c:611
static void pq_writeint16(StringInfoData *pg_restrict buf, uint16 i)
Definition: pqformat.h:61
void pq_beginmessage_reuse(StringInfo buf, char msgtype)
Definition: pqformat.c:109
void pq_sendcountedtext(StringInfo buf, const char *str, int slen, bool countincludesself)
Definition: pqformat.c:143
void pq_send_ascii_string(StringInfo buf, const char *str)
Definition: pqformat.c:230
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:349
static void pq_sendint(StringInfo buf, uint32 i, int b)
Definition: pqformat.h:172
void pq_sendfloat8(StringInfo buf, float8 f)
Definition: pqformat.c:279
void pq_endmessage_reuse(StringInfo buf)
Definition: pqformat.c:317
void enlargeStringInfo(StringInfo str, int needed)
Definition: stringinfo.c:283
Definition: c.h:676