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