LCOV - code coverage report
Current view: top level - src/include/lib - stringinfo.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 12 12
Test Date: 2026-03-03 13:15:30 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * stringinfo.h
       4              :  *    Declarations/definitions for "StringInfo" functions.
       5              :  *
       6              :  * StringInfo provides an extensible string data type (currently limited to a
       7              :  * length of 1GB).  It can be used to buffer either ordinary C strings
       8              :  * (null-terminated text) or arbitrary binary data.  All storage is allocated
       9              :  * with palloc() (falling back to malloc in frontend code).
      10              :  *
      11              :  * Portions Copyright (c) 1996-2026, 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              : /*-------------------------
      22              :  * StringInfoData holds information about an extensible string.
      23              :  *      data    is the current buffer for the string.
      24              :  *      len     is the current string length.  Except in the case of read-only
      25              :  *              strings described below, there is guaranteed to be a
      26              :  *              terminating '\0' at data[len].
      27              :  *      maxlen  is the allocated size in bytes of 'data', i.e. the maximum
      28              :  *              string size (including the terminating '\0' char) that we can
      29              :  *              currently store in 'data' without having to reallocate
      30              :  *              more space.  We must always have maxlen > len, except
      31              :  *              in the read-only case described below.
      32              :  *      cursor  is initialized to zero by makeStringInfo, initStringInfo,
      33              :  *              initReadOnlyStringInfo and initStringInfoFromString but is not
      34              :  *              otherwise touched by the stringinfo.c routines.  Some routines
      35              :  *              use it to scan through a StringInfo.
      36              :  *
      37              :  * As a special case, a StringInfoData can be initialized with a read-only
      38              :  * string buffer.  In this case "data" does not necessarily point at a
      39              :  * palloc'd chunk, and management of the buffer storage is the caller's
      40              :  * responsibility.  maxlen is set to zero to indicate that this is the case.
      41              :  * Read-only StringInfoDatas cannot be appended to or reset.
      42              :  * Also, it is caller's option whether a read-only string buffer has a
      43              :  * terminating '\0' or not.  This depends on the intended usage.
      44              :  *-------------------------
      45              :  */
      46              : typedef struct StringInfoData
      47              : {
      48              :     char       *data;
      49              :     int         len;
      50              :     int         maxlen;
      51              :     int         cursor;
      52              : } StringInfoData;
      53              : 
      54              : typedef StringInfoData *StringInfo;
      55              : 
      56              : 
      57              : /*------------------------
      58              :  * There are six ways to create a StringInfo object initially:
      59              :  *
      60              :  * StringInfo stringptr = makeStringInfo();
      61              :  *      Both the StringInfoData and the data buffer are palloc'd.
      62              :  *
      63              :  * StringInfo stringptr = makeStringInfoExt(initsize);
      64              :  *      Same as makeStringInfo except the data buffer is allocated
      65              :  *      with size 'initsize'.
      66              :  *
      67              :  * StringInfoData string;
      68              :  * initStringInfo(&string);
      69              :  *      The data buffer is palloc'd but the StringInfoData is just local.
      70              :  *      This is the easiest approach for a StringInfo object that will
      71              :  *      only live as long as the current routine.
      72              :  *
      73              :  * StringInfoData string;
      74              :  * initStringInfoExt(&string, initsize);
      75              :  *      Same as initStringInfo except the data buffer is allocated
      76              :  *      with size 'initsize'.
      77              :  *
      78              :  * StringInfoData string;
      79              :  * initReadOnlyStringInfo(&string, existingbuf, len);
      80              :  *      The StringInfoData's data field is set to point directly to the
      81              :  *      existing buffer and the StringInfoData's len is set to the given len.
      82              :  *      The given buffer can point to memory that's not managed by palloc or
      83              :  *      is pointing partway through a palloc'd chunk.  The maxlen field is set
      84              :  *      to 0.  A read-only StringInfo cannot be appended to using any of the
      85              :  *      appendStringInfo functions or reset with resetStringInfo().  The given
      86              :  *      buffer can optionally omit the trailing NUL.
      87              :  *
      88              :  * StringInfoData string;
      89              :  * initStringInfoFromString(&string, palloced_buf, len);
      90              :  *      The StringInfoData's data field is set to point directly to the given
      91              :  *      buffer and the StringInfoData's len is set to the given len.  This
      92              :  *      method of initialization is useful when the buffer already exists.
      93              :  *      StringInfos initialized this way can be appended to using the
      94              :  *      appendStringInfo functions and reset with resetStringInfo().  The
      95              :  *      given buffer must be NUL-terminated.  The palloc'd buffer is assumed
      96              :  *      to be len + 1 in size.
      97              :  *
      98              :  * To destroy a StringInfo, pfree() the data buffer, and then pfree() the
      99              :  * StringInfoData if it was palloc'd.  For StringInfos created with
     100              :  * makeStringInfo(), destroyStringInfo() is provided for this purpose.
     101              :  * However, if the StringInfo was initialized using initReadOnlyStringInfo()
     102              :  * then the caller will need to consider if it is safe to pfree the data
     103              :  * buffer.
     104              :  *
     105              :  * NOTE: some routines build up a string using StringInfo, and then
     106              :  * release the StringInfoData but return the data string itself to their
     107              :  * caller.  At that point the data string looks like a plain palloc'd
     108              :  * string.
     109              :  *-------------------------
     110              :  */
     111              : 
     112              : #define STRINGINFO_DEFAULT_SIZE 1024    /* default initial allocation size */
     113              : 
     114              : /*------------------------
     115              :  * makeStringInfo
     116              :  * Create an empty 'StringInfoData' & return a pointer to it.
     117              :  */
     118              : extern StringInfo makeStringInfo(void);
     119              : 
     120              : /*------------------------
     121              :  * makeStringInfoExt
     122              :  * Create an empty 'StringInfoData' & return a pointer to it.
     123              :  * The data buffer is allocated with size 'initsize'.
     124              :  * The valid range for 'initsize' is 1 to MaxAllocSize.
     125              :  */
     126              : extern StringInfo makeStringInfoExt(int initsize);
     127              : 
     128              : /*------------------------
     129              :  * initStringInfo
     130              :  * Initialize a StringInfoData struct (with previously undefined contents)
     131              :  * to describe an empty string.
     132              :  */
     133              : extern void initStringInfo(StringInfo str);
     134              : 
     135              : /*------------------------
     136              :  * initStringInfoExt
     137              :  * Initialize a StringInfoData struct (with previously undefined contents) to
     138              :  * describe an empty string. The data buffer is allocated with size
     139              :  * 'initsize'. The valid range for 'initsize' is 1 to MaxAllocSize.
     140              :  */
     141              : extern void initStringInfoExt(StringInfo str, int initsize);
     142              : 
     143              : /*------------------------
     144              :  * initReadOnlyStringInfo
     145              :  * Initialize a StringInfoData struct from an existing string without copying
     146              :  * the string.  The caller is responsible for ensuring the given string
     147              :  * remains valid as long as the StringInfoData does.  Calls to this are used
     148              :  * in performance critical locations where allocating a new buffer and copying
     149              :  * would be too costly.  Read-only StringInfoData's may not be appended to
     150              :  * using any of the appendStringInfo functions or reset with
     151              :  * resetStringInfo().
     152              :  *
     153              :  * 'data' does not need to point directly to a palloc'd chunk of memory and may
     154              :  * omit the NUL termination character at data[len].
     155              :  */
     156              : static inline void
     157       475459 : initReadOnlyStringInfo(StringInfo str, char *data, int len)
     158              : {
     159       475459 :     str->data = data;
     160       475459 :     str->len = len;
     161       475459 :     str->maxlen = 0;         /* read-only */
     162       475459 :     str->cursor = 0;
     163       475459 : }
     164              : 
     165              : /*------------------------
     166              :  * initStringInfoFromString
     167              :  * Initialize a StringInfoData struct from an existing string without copying
     168              :  * the string.  'data' must be a valid palloc'd chunk of memory that can have
     169              :  * repalloc() called should more space be required during a call to any of the
     170              :  * appendStringInfo functions.
     171              :  *
     172              :  * 'data' must be NUL terminated at 'len' bytes.
     173              :  */
     174              : static inline void
     175       257647 : initStringInfoFromString(StringInfo str, char *data, int len)
     176              : {
     177              :     Assert(data[len] == '\0');
     178              : 
     179       257647 :     str->data = data;
     180       257647 :     str->len = len;
     181       257647 :     str->maxlen = len + 1;
     182       257647 :     str->cursor = 0;
     183       257647 : }
     184              : 
     185              : /*------------------------
     186              :  * resetStringInfo
     187              :  * Clears the current content of the StringInfo, if any. The
     188              :  * StringInfo remains valid.
     189              :  */
     190              : extern void resetStringInfo(StringInfo str);
     191              : 
     192              : /*------------------------
     193              :  * appendStringInfo
     194              :  * Format text data under the control of fmt (an sprintf-style format string)
     195              :  * and append it to whatever is already in str.  More space is allocated
     196              :  * to str if necessary.  This is sort of like a combination of sprintf and
     197              :  * strcat.
     198              :  */
     199              : extern void appendStringInfo(StringInfo str, const char *fmt,...) pg_attribute_printf(2, 3);
     200              : 
     201              : /*------------------------
     202              :  * appendStringInfoVA
     203              :  * Attempt to format text data under the control of fmt (an sprintf-style
     204              :  * format string) and append it to whatever is already in str.  If successful
     205              :  * return zero; if not (because there's not enough space), return an estimate
     206              :  * of the space needed, without modifying str.  Typically the caller should
     207              :  * pass the return value to enlargeStringInfo() before trying again; see
     208              :  * appendStringInfo for standard usage pattern.
     209              :  */
     210              : extern int  appendStringInfoVA(StringInfo str, const char *fmt, va_list args) pg_attribute_printf(2, 0);
     211              : 
     212              : /*------------------------
     213              :  * appendStringInfoString
     214              :  * Append a null-terminated string to str.
     215              :  * Like appendStringInfo(str, "%s", s) but faster.
     216              :  */
     217              : extern void appendStringInfoString(StringInfo str, const char *s);
     218              : 
     219              : /*------------------------
     220              :  * appendStringInfoChar
     221              :  * Append a single byte to str.
     222              :  * Like appendStringInfo(str, "%c", ch) but much faster.
     223              :  */
     224              : extern void appendStringInfoChar(StringInfo str, char ch);
     225              : 
     226              : /*------------------------
     227              :  * appendStringInfoCharMacro
     228              :  * As above, but a macro for even more speed where it matters.
     229              :  * Caution: str argument will be evaluated multiple times.
     230              :  */
     231              : #define appendStringInfoCharMacro(str,ch) \
     232              :     (((str)->len + 1 >= (str)->maxlen) ? \
     233              :      appendStringInfoChar(str, ch) : \
     234              :      (void)((str)->data[(str)->len] = (ch), (str)->data[++(str)->len] = '\0'))
     235              : 
     236              : /*------------------------
     237              :  * appendStringInfoSpaces
     238              :  * Append a given number of spaces to str.
     239              :  */
     240              : extern void appendStringInfoSpaces(StringInfo str, int count);
     241              : 
     242              : /*------------------------
     243              :  * appendBinaryStringInfo
     244              :  * Append arbitrary binary data to a StringInfo, allocating more space
     245              :  * if necessary.
     246              :  */
     247              : extern void appendBinaryStringInfo(StringInfo str,
     248              :                                    const void *data, int datalen);
     249              : 
     250              : /*------------------------
     251              :  * appendBinaryStringInfoNT
     252              :  * Append arbitrary binary data to a StringInfo, allocating more space
     253              :  * if necessary. Does not ensure a trailing null-byte exists.
     254              :  */
     255              : extern void appendBinaryStringInfoNT(StringInfo str,
     256              :                                      const void *data, int datalen);
     257              : 
     258              : /*------------------------
     259              :  * enlargeStringInfo
     260              :  * Make sure a StringInfo's buffer can hold at least 'needed' more bytes.
     261              :  */
     262              : extern void enlargeStringInfo(StringInfo str, int needed);
     263              : 
     264              : /*------------------------
     265              :  * destroyStringInfo
     266              :  * Frees a StringInfo and its buffer (opposite of makeStringInfo()).
     267              :  */
     268              : extern void destroyStringInfo(StringInfo str);
     269              : 
     270              : #endif                          /* STRINGINFO_H */
        

Generated by: LCOV version 2.0-1