1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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);
}
|