diff options
Diffstat (limited to 'src/include/lib/stringinfo.h')
-rw-r--r-- | src/include/lib/stringinfo.h | 93 |
1 files changed, 84 insertions, 9 deletions
diff --git a/src/include/lib/stringinfo.h b/src/include/lib/stringinfo.h index 36a416f8e0a..598ed093dc8 100644 --- a/src/include/lib/stringinfo.h +++ b/src/include/lib/stringinfo.h @@ -20,17 +20,27 @@ /*------------------------- * StringInfoData holds information about an extensible string. - * data is the current buffer for the string (allocated with palloc). - * len is the current string length. There is guaranteed to be - * a terminating '\0' at data[len], although this is not very - * useful when the string holds binary data rather than text. + * data is the current buffer for the string. + * len is the current string length. Except in the case of read-only + * strings described below, there is guaranteed to be a + * terminating '\0' at data[len]. * maxlen is the allocated size in bytes of 'data', i.e. the maximum * string size (including the terminating '\0' char) that we can * currently store in 'data' without having to reallocate - * more space. We must always have maxlen > len. - * cursor is initialized to zero by makeStringInfo or initStringInfo, - * but is not otherwise touched by the stringinfo.c routines. - * Some routines use it to scan through a StringInfo. + * more space. We must always have maxlen > len, except + * in the read-only case described below. + * cursor is initialized to zero by makeStringInfo, initStringInfo, + * initReadOnlyStringInfo and initStringInfoFromString but is not + * otherwise touched by the stringinfo.c routines. Some routines + * use it to scan through a StringInfo. + * + * As a special case, a StringInfoData can be initialized with a read-only + * string buffer. In this case "data" does not necessarily point at a + * palloc'd chunk, and management of the buffer storage is the caller's + * responsibility. maxlen is set to zero to indicate that this is the case. + * Read-only StringInfoDatas cannot be appended to or reset. + * Also, it is caller's option whether a read-only string buffer has a + * terminating '\0' or not. This depends on the intended usage. *------------------------- */ typedef struct StringInfoData @@ -45,7 +55,7 @@ typedef StringInfoData *StringInfo; /*------------------------ - * There are two ways to create a StringInfo object initially: + * There are four ways to create a StringInfo object initially: * * StringInfo stringptr = makeStringInfo(); * Both the StringInfoData and the data buffer are palloc'd. @@ -56,8 +66,31 @@ typedef StringInfoData *StringInfo; * This is the easiest approach for a StringInfo object that will * only live as long as the current routine. * + * StringInfoData string; + * initReadOnlyStringInfo(&string, existingbuf, len); + * The StringInfoData's data field is set to point directly to the + * existing buffer and the StringInfoData's len is set to the given len. + * The given buffer can point to memory that's not managed by palloc or + * is pointing partway through a palloc'd chunk. The maxlen field is set + * to 0. A read-only StringInfo cannot be appended to using any of the + * appendStringInfo functions or reset with resetStringInfo(). The given + * buffer can optionally omit the trailing NUL. + * + * StringInfoData string; + * initStringInfoFromString(&string, palloced_buf, len); + * The StringInfoData's data field is set to point directly to the given + * buffer and the StringInfoData's len is set to the given len. This + * method of initialization is useful when the buffer already exists. + * StringInfos initialized this way can be appended to using the + * appendStringInfo functions and reset with resetStringInfo(). The + * given buffer must be NUL-terminated. The palloc'd buffer is assumed + * to be len + 1 in size. + * * To destroy a StringInfo, pfree() the data buffer, and then pfree() the * StringInfoData if it was palloc'd. There's no special support for this. + * However, if the StringInfo was initialized using initReadOnlyStringInfo() + * then the caller will need to consider if it is safe to pfree the data + * buffer. * * NOTE: some routines build up a string using StringInfo, and then * release the StringInfoData but return the data string itself to their @@ -80,6 +113,48 @@ extern StringInfo makeStringInfo(void); extern void initStringInfo(StringInfo str); /*------------------------ + * initReadOnlyStringInfo + * Initialize a StringInfoData struct from an existing string without copying + * the string. The caller is responsible for ensuring the given string + * remains valid as long as the StringInfoData does. Calls to this are used + * in performance critical locations where allocating a new buffer and copying + * would be too costly. Read-only StringInfoData's may not be appended to + * using any of the appendStringInfo functions or reset with + * resetStringInfo(). + * + * 'data' does not need to point directly to a palloc'd chunk of memory and may + * omit the NUL termination character at data[len]. + */ +static inline void +initReadOnlyStringInfo(StringInfo str, char *data, int len) +{ + str->data = data; + str->len = len; + str->maxlen = 0; /* read-only */ + str->cursor = 0; +} + +/*------------------------ + * initStringInfoFromString + * Initialize a StringInfoData struct from an existing string without copying + * the string. 'data' must be a valid palloc'd chunk of memory that can have + * repalloc() called should more space be required during a call to any of the + * appendStringInfo functions. + * + * 'data' must be NUL terminated at 'len' bytes. + */ +static inline void +initStringInfoFromString(StringInfo str, char *data, int len) +{ + Assert(data[len] == '\0'); + + str->data = data; + str->len = len; + str->maxlen = len + 1; + str->cursor = 0; +} + +/*------------------------ * resetStringInfo * Clears the current content of the StringInfo, if any. The * StringInfo remains valid. |