doc: 1-byte varlena headers can be used for user PLAIN storage
[pgsql.git] / src / backend / utils / mb / stringinfo_mb.c
blob67a958d72bee16f617c2d2bb06bb56b473fe53d4
1 /*-------------------------------------------------------------------------
3 * stringinfo_mb.c
4 * Multibyte encoding-aware additional StringInfo facilities
6 * This is separate from common/stringinfo.c so that frontend users
7 * of that file need not pull in unnecessary multibyte-encoding support
8 * code.
11 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
12 * Portions Copyright (c) 1994, Regents of the University of California
15 * IDENTIFICATION
16 * src/backend/utils/mb/stringinfo_mb.c
18 *-------------------------------------------------------------------------
20 #include "postgres.h"
22 #include "mb/stringinfo_mb.h"
23 #include "mb/pg_wchar.h"
27 * appendStringInfoStringQuoted
29 * Append up to maxlen bytes from s to str, or the whole input string if
30 * maxlen < 0, adding single quotes around it and doubling all single quotes.
31 * Add an ellipsis if the copy is incomplete.
33 void
34 appendStringInfoStringQuoted(StringInfo str, const char *s, int maxlen)
36 char *copy = NULL;
37 const char *chunk_search_start,
38 *chunk_copy_start,
39 *chunk_end;
40 int slen;
41 bool ellipsis;
43 Assert(str != NULL);
45 slen = strlen(s);
46 if (maxlen >= 0 && maxlen < slen)
48 int finallen = pg_mbcliplen(s, slen, maxlen);
50 copy = pnstrdup(s, finallen);
51 chunk_search_start = copy;
52 chunk_copy_start = copy;
54 ellipsis = true;
56 else
58 chunk_search_start = s;
59 chunk_copy_start = s;
61 ellipsis = false;
64 appendStringInfoCharMacro(str, '\'');
66 while ((chunk_end = strchr(chunk_search_start, '\'')) != NULL)
68 /* copy including the found delimiting ' */
69 appendBinaryStringInfoNT(str,
70 chunk_copy_start,
71 chunk_end - chunk_copy_start + 1);
73 /* in order to double it, include this ' into the next chunk as well */
74 chunk_copy_start = chunk_end;
75 chunk_search_start = chunk_end + 1;
78 /* copy the last chunk and terminate */
79 if (ellipsis)
80 appendStringInfo(str, "%s...'", chunk_copy_start);
81 else
82 appendStringInfo(str, "%s'", chunk_copy_start);
84 if (copy)
85 pfree(copy);