1 /*------------------------------------------------------------------------- 2 * 3 * stringinfo.h 4 * Declarations/definitions for "StringInfo" functions. 5 * 6 * StringInfo provides an indefinitely-extensible string data type. 7 * It can be used to buffer either ordinary C strings (null-terminated text) 8 * or arbitrary binary data. All storage is allocated with palloc(). 9 * 10 * Portions Copyright (c) 2003-2018, PgPool Global Development Group 11 * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group 12 * Portions Copyright (c) 1994, Regents of the University of California 13 * 14 * src/include/lib/stringinfo.h 15 * 16 *------------------------------------------------------------------------- 17 */ 18 #ifndef STRINGINFO_H 19 #define STRINGINFO_H 20 21 #include <stdio.h> 22 #include <stdarg.h> 23 #include "parser/pg_config_manual.h" 24 #include "pool_parser.h" 25 26 /* port.h */ 27 28 #ifdef USE_REPL_SNPRINTF 29 extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args); 30 31 /* 32 * The GCC-specific code below prevents the __attribute__(... 'printf') 33 * above from being replaced, and this is required because gcc doesn't 34 * know anything about pg_printf. 35 */ 36 #ifndef vsnprintf 37 38 #ifdef __GNUC__ 39 #define vsnprintf(...) pg_vsnprintf(__VA_ARGS__) 40 #else 41 #define vsnprintf pg_vsnprintf 42 #endif 43 #endif 44 45 #endif /* USE_REPL_SNPRINTF */ 46 47 /* utils.memutils.h */ 48 49 /* 50 * MaxAllocSize, MaxAllocHugeSize 51 * Quasi-arbitrary limits on size of allocations. 52 * 53 * Note: 54 * There is no guarantee that smaller allocations will succeed, but 55 * larger requests will be summarily denied. 56 * 57 * palloc() enforces MaxAllocSize, chosen to correspond to the limiting size 58 * of varlena objects under TOAST. See VARSIZE_4B() and related macros in 59 * postgres.h. Many datatypes assume that any allocatable size can be 60 * represented in a varlena header. This limit also permits a caller to use 61 * an "int" variable for an index into or length of an allocation. Callers 62 * careful to avoid these hazards can access the higher limit with 63 * MemoryContextAllocHuge(). Both limits permit code to assume that it may 64 * compute twice an allocation's size without overflow. 65 */ 66 #define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */ 67 68 69 /*------------------------- 70 * StringInfoData holds information about an extensible string. 71 * data is the current buffer for the string (allocated with palloc). 72 * len is the current string length. There is guaranteed to be 73 * a terminating '\0' at data[len], although this is not very 74 * useful when the string holds binary data rather than text. 75 * maxlen is the allocated size in bytes of 'data', i.e. the maximum 76 * string size (including the terminating '\0' char) that we can 77 * currently store in 'data' without having to reallocate 78 * more space. We must always have maxlen > len. 79 * cursor is initialized to zero by makeStringInfo or initStringInfo, 80 * but is not otherwise touched by the stringinfo.c routines. 81 * Some routines use it to scan through a StringInfo. 82 *------------------------- 83 */ 84 typedef struct StringInfoData 85 { 86 char *data; 87 int len; 88 int maxlen; 89 int cursor; 90 } StringInfoData; 91 92 typedef StringInfoData *StringInfo; 93 94 95 /*------------------------ 96 * There are two ways to create a StringInfo object initially: 97 * 98 * StringInfo stringptr = makeStringInfo(); 99 * Both the StringInfoData and the data buffer are palloc'd. 100 * 101 * StringInfoData string; 102 * initStringInfo(&string); 103 * The data buffer is palloc'd but the StringInfoData is just local. 104 * This is the easiest approach for a StringInfo object that will 105 * only live as long as the current routine. 106 * 107 * To destroy a StringInfo, pfree() the data buffer, and then pfree() the 108 * StringInfoData if it was palloc'd. There's no special support for this. 109 * 110 * NOTE: some routines build up a string using StringInfo, and then 111 * release the StringInfoData but return the data string itself to their 112 * caller. At that point the data string looks like a plain palloc'd 113 * string. 114 *------------------------- 115 */ 116 117 /*------------------------ 118 * makeStringInfo 119 * Create an empty 'StringInfoData' & return a pointer to it. 120 */ 121 extern StringInfo makeStringInfo(void); 122 123 /*------------------------ 124 * initStringInfo 125 * Initialize a StringInfoData struct (with previously undefined contents) 126 * to describe an empty string. 127 */ 128 extern void initStringInfo(StringInfo str); 129 130 /*------------------------ 131 * resetStringInfo 132 * Clears the current content of the StringInfo, if any. The 133 * StringInfo remains valid. 134 */ 135 extern void resetStringInfo(StringInfo str); 136 137 /*------------------------ 138 * appendStringInfo 139 * Format text data under the control of fmt (an sprintf-style format string) 140 * and append it to whatever is already in str. More space is allocated 141 * to str if necessary. This is sort of like a combination of sprintf and 142 * strcat. 143 */ 144 extern void appendStringInfo(StringInfo str, const char *fmt,...) pg_attribute_printf(2, 3); 145 146 /*------------------------ 147 * appendStringInfoVA 148 * Attempt to format text data under the control of fmt (an sprintf-style 149 * format string) and append it to whatever is already in str. If successful 150 * return zero; if not (because there's not enough space), return an estimate 151 * of the space needed, without modifying str. Typically the caller should 152 * pass the return value to enlargeStringInfo() before trying again; see 153 * appendStringInfo for standard usage pattern. 154 */ 155 extern int appendStringInfoVA(StringInfo str, const char *fmt, va_list args) pg_attribute_printf(2, 0); 156 157 /*------------------------ 158 * appendStringInfoString 159 * Append a null-terminated string to str. 160 * Like appendStringInfo(str, "%s", s) but faster. 161 */ 162 extern void appendStringInfoString(StringInfo str, const char *s); 163 164 /*------------------------ 165 * appendStringInfoChar 166 * Append a single byte to str. 167 * Like appendStringInfo(str, "%c", ch) but much faster. 168 */ 169 extern void appendStringInfoChar(StringInfo str, char ch); 170 171 /*------------------------ 172 * appendStringInfoCharMacro 173 * As above, but a macro for even more speed where it matters. 174 * Caution: str argument will be evaluated multiple times. 175 */ 176 #define appendStringInfoCharMacro(str,ch) \ 177 (((str)->len + 1 >= (str)->maxlen) ? \ 178 appendStringInfoChar(str, ch) : \ 179 (void)((str)->data[(str)->len] = (ch), (str)->data[++(str)->len] = '\0')) 180 181 /*------------------------ 182 * appendStringInfoSpaces 183 * Append a given number of spaces to str. 184 */ 185 extern void appendStringInfoSpaces(StringInfo str, int count); 186 187 /*------------------------ 188 * appendBinaryStringInfo 189 * Append arbitrary binary data to a StringInfo, allocating more space 190 * if necessary. 191 */ 192 extern void appendBinaryStringInfo(StringInfo str, 193 const char *data, int datalen); 194 195 /*------------------------ 196 * appendBinaryStringInfoNT 197 * Append arbitrary binary data to a StringInfo, allocating more space 198 * if necessary. Does not ensure a trailing null-byte exists. 199 */ 200 extern void appendBinaryStringInfoNT(StringInfo str, 201 const char *data, int datalen); 202 203 /*------------------------ 204 * enlargeStringInfo 205 * Make sure a StringInfo's buffer can hold at least 'needed' more bytes. 206 */ 207 extern void enlargeStringInfo(StringInfo str, int needed); 208 209 #endif /* STRINGINFO_H */ 210