pqformat.h 5.8 KB

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