summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/expandedstring.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/expandedstring.c')
-rw-r--r--src/backend/utils/adt/expandedstring.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/backend/utils/adt/expandedstring.c b/src/backend/utils/adt/expandedstring.c
new file mode 100644
index 0000000000..4e279a3aa1
--- /dev/null
+++ b/src/backend/utils/adt/expandedstring.c
@@ -0,0 +1,86 @@
+/*-------------------------------------------------------------------------
+ *
+ * expandedstring.c
+ * Expand a varlena into a StringInfo.
+ *
+ * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/backend/utils/adt/expandeddatum.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "fmgr.h"
+#include "utils/expandedstring.h"
+#include "utils/memutils.h"
+
+static Size ESI_get_flat_size(ExpandedObjectHeader *eohptr);
+static void ESI_flatten_into(ExpandedObjectHeader *eohptr,
+ void *result, Size allocated_size);
+
+static const ExpandedObjectMethods ESI_methods =
+{
+ ESI_get_flat_size,
+ ESI_flatten_into
+};
+
+/*
+ * Construct an expanded datum consisting of an empty StringInfo.
+ *
+ * Caller must ensure that CurrentMemoryContext points to a context with
+ * a suitable lifetime.
+ */
+ExpandedStringInfoHeader *
+GetExpandedStringInfo(void)
+{
+ ExpandedStringInfoHeader *esih;
+ MemoryContext objcxt;
+ MemoryContext oldcxt;
+
+ objcxt = AllocSetContextCreate(CurrentMemoryContext,
+ "stringinfo expanded object",
+ ALLOCSET_SMALL_MINSIZE,
+ ALLOCSET_SMALL_INITSIZE,
+ ALLOCSET_DEFAULT_MAXSIZE);
+
+ oldcxt = MemoryContextSwitchTo(objcxt);
+ esih = palloc(sizeof(ExpandedStringInfoHeader));
+ EOH_init_header(&esih->hdr, &ESI_methods, objcxt);
+ initStringInfo(&esih->buf);
+ MemoryContextSwitchTo(oldcxt);
+
+ return esih;
+}
+
+/*
+ * The space required to flatten a StringInfo back to a plain old varlena is
+ * just the number of bytes we have in the buffer, plus the size of a 4-byte
+ * header. Even if the buffer is short, we can't flatten to a packed
+ * representation.
+ */
+static Size
+ESI_get_flat_size(ExpandedObjectHeader *eohptr)
+{
+ ExpandedStringInfoHeader *esih = (ExpandedStringInfoHeader *) eohptr;
+
+ return VARHDRSZ + esih->buf.len;
+}
+
+/*
+ * Flattening a StringInfo just involves copying the data into the allocated
+ * space.
+ */
+static void
+ESI_flatten_into(ExpandedObjectHeader *eohptr,
+ void *result, Size allocated_size)
+{
+ ExpandedStringInfoHeader *esih = (ExpandedStringInfoHeader *) eohptr;
+
+ Assert(allocated_size == VARHDRSZ + esih->buf.len);
+ memcpy(VARDATA(result), esih->buf.data, esih->buf.len);
+ SET_VARSIZE(result, VARHDRSZ + esih->buf.len);
+}