|
| 1 | +/*------------------------------------------------------------------------- |
| 2 | + * |
| 3 | + * stringinfo_mb.c |
| 4 | + * Multibyte encoding-aware additional StringInfo facilites |
| 5 | + * |
| 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. |
| 9 | + * |
| 10 | + * |
| 11 | + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 12 | + * Portions Copyright (c) 1994, Regents of the University of California |
| 13 | + * |
| 14 | + * |
| 15 | + * IDENTIFICATION |
| 16 | + * src/backend/utils/mb/stringinfo_mb.c |
| 17 | + * |
| 18 | + *------------------------------------------------------------------------- |
| 19 | + */ |
| 20 | +#include "postgres.h" |
| 21 | + |
| 22 | +#include "mb/stringinfo_mb.h" |
| 23 | +#include "mb/pg_wchar.h" |
| 24 | + |
| 25 | + |
| 26 | +/* |
| 27 | + * appendStringInfoStringQuoted |
| 28 | + * |
| 29 | + * Append up to maxlen characters 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. |
| 32 | + */ |
| 33 | +void |
| 34 | +appendStringInfoStringQuoted(StringInfo str, const char *s, int maxlen) |
| 35 | +{ |
| 36 | + char *copy = NULL; |
| 37 | + const char *chunk_search_start, |
| 38 | + *chunk_copy_start, |
| 39 | + *chunk_end; |
| 40 | + int slen; |
| 41 | + bool ellipsis; |
| 42 | + |
| 43 | + Assert(str != NULL); |
| 44 | + |
| 45 | + slen = strlen(s); |
| 46 | + if (maxlen > 0 && maxlen < slen) |
| 47 | + { |
| 48 | + int finallen = pg_mbcliplen(s, slen, maxlen); |
| 49 | + |
| 50 | + copy = pnstrdup(s, finallen); |
| 51 | + chunk_search_start = copy; |
| 52 | + chunk_copy_start = copy; |
| 53 | + |
| 54 | + ellipsis = true; |
| 55 | + } |
| 56 | + else |
| 57 | + { |
| 58 | + chunk_search_start = s; |
| 59 | + chunk_copy_start = s; |
| 60 | + |
| 61 | + ellipsis = false; |
| 62 | + } |
| 63 | + |
| 64 | + appendStringInfoCharMacro(str, '\''); |
| 65 | + |
| 66 | + while ((chunk_end = strchr(chunk_search_start, '\'')) != NULL) |
| 67 | + { |
| 68 | + /* copy including the found delimiting ' */ |
| 69 | + appendBinaryStringInfoNT(str, |
| 70 | + chunk_copy_start, |
| 71 | + chunk_end - chunk_copy_start + 1); |
| 72 | + |
| 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; |
| 76 | + } |
| 77 | + |
| 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); |
| 83 | + |
| 84 | + if (copy) |
| 85 | + pfree(copy); |
| 86 | +} |
0 commit comments