3232#define JSONB_MAX_ELEMS (Min(MaxAllocSize / sizeof(JsonbValue), JB_CMASK))
3333#define JSONB_MAX_PAIRS (Min(MaxAllocSize / sizeof(JsonbPair), JB_CMASK))
3434
35- /*
36- * convertState: a resizeable buffer used when constructing a Jsonb datum
37- */
38- typedef struct
39- {
40- char * buffer ;
41- int len ;
42- int allocatedsz ;
43- }convertState ;
44-
4535static void fillJsonbValue (JEntry * array ,int index ,char * base_addr ,
4636JsonbValue * result );
4737static int compareJsonbScalarValue (JsonbValue * a ,JsonbValue * b );
4838static int lexicalCompareJsonbStringValue (const void * a ,const void * b );
4939static Jsonb * convertToJsonb (JsonbValue * val );
50- static void convertJsonbValue (convertState * buffer ,JEntry * header ,JsonbValue * val ,int level );
51- static void convertJsonbArray (convertState * buffer ,JEntry * header ,JsonbValue * val ,int level );
52- static void convertJsonbObject (convertState * buffer ,JEntry * header ,JsonbValue * val ,int level );
53- static void convertJsonbScalar (convertState * buffer ,JEntry * header ,JsonbValue * scalarVal );
40+ static void convertJsonbValue (StringInfo buffer ,JEntry * header ,JsonbValue * val ,int level );
41+ static void convertJsonbArray (StringInfo buffer ,JEntry * header ,JsonbValue * val ,int level );
42+ static void convertJsonbObject (StringInfo buffer ,JEntry * header ,JsonbValue * val ,int level );
43+ static void convertJsonbScalar (StringInfo buffer ,JEntry * header ,JsonbValue * scalarVal );
5444
55- static int reserveFromBuffer (convertState * buffer ,int len );
56- static void appendToBuffer (convertState * buffer ,char * data ,int len );
57- static void copyToBuffer (convertState * buffer ,int offset ,char * data ,int len );
58- static short padBufferToInt (convertState * buffer );
45+ static int reserveFromBuffer (StringInfo buffer ,int len );
46+ static void appendToBuffer (StringInfo buffer ,const char * data ,int len );
47+ static void copyToBuffer (StringInfo buffer ,int offset ,const char * data ,int len );
48+ static short padBufferToInt (StringInfo buffer );
5949
6050static JsonbIterator * iteratorFromContainer (JsonbContainer * container ,JsonbIterator * parent );
6151static JsonbIterator * freeAndGetParent (JsonbIterator * it );
@@ -1175,44 +1165,46 @@ lexicalCompareJsonbStringValue(const void *a, const void *b)
11751165
11761166/*
11771167 * Reserve 'len' bytes, at the end of the buffer, enlarging it if necessary.
1178- * Returns the offset to the reserved area. The caller is expected tocopy
1179- * thedata to the reserved area later with copyToBuffer()
1168+ * Returns the offset to the reserved area. The caller is expected tofill
1169+ * the reserved area later with copyToBuffer().
11801170 */
11811171static int
1182- reserveFromBuffer (convertState * buffer ,int len )
1172+ reserveFromBuffer (StringInfo buffer ,int len )
11831173{
11841174int offset ;
11851175
11861176/* Make more room if needed */
1187- if (buffer -> len + len > buffer -> allocatedsz )
1188- {
1189- buffer -> allocatedsz *=2 ;
1190- buffer -> buffer = repalloc (buffer -> buffer ,buffer -> allocatedsz );
1191- }
1177+ enlargeStringInfo (buffer ,len );
11921178
11931179/* remember current offset */
11941180offset = buffer -> len ;
11951181
11961182/* reserve the space */
11971183buffer -> len += len ;
11981184
1185+ /*
1186+ * Keep a trailing null in place, even though it's not useful for us;
1187+ * it seems best to preserve the invariants of StringInfos.
1188+ */
1189+ buffer -> data [buffer -> len ]= '\0' ;
1190+
11991191return offset ;
12001192}
12011193
12021194/*
12031195 * Copy 'len' bytes to a previously reserved area in buffer.
12041196 */
12051197static void
1206- copyToBuffer (convertState * buffer ,int offset ,char * data ,int len )
1198+ copyToBuffer (StringInfo buffer ,int offset ,const char * data ,int len )
12071199{
1208- memcpy (buffer -> buffer + offset ,data ,len );
1200+ memcpy (buffer -> data + offset ,data ,len );
12091201}
12101202
12111203/*
12121204 * A shorthand for reserveFromBuffer + copyToBuffer.
12131205 */
12141206static void
1215- appendToBuffer (convertState * buffer ,char * data ,int len )
1207+ appendToBuffer (StringInfo buffer ,const char * data ,int len )
12161208{
12171209int offset ;
12181210
@@ -1226,17 +1218,19 @@ appendToBuffer(convertState *buffer, char *data, int len)
12261218 * Returns the number of padding bytes appended.
12271219 */
12281220static short
1229- padBufferToInt (convertState * buffer )
1221+ padBufferToInt (StringInfo buffer )
12301222{
1231- short padlen ,
1232- p ;
1233- int offset ;
1223+ int padlen ,
1224+ p ,
1225+ offset ;
12341226
12351227padlen = INTALIGN (buffer -> len )- buffer -> len ;
12361228
12371229offset = reserveFromBuffer (buffer ,padlen );
1230+
1231+ /* padlen must be small, so this is probably faster than a memset */
12381232for (p = 0 ;p < padlen ;p ++ )
1239- buffer -> buffer [offset + p ]= 0 ;
1233+ buffer -> data [offset + p ]= '\0' ;
12401234
12411235return padlen ;
12421236}
@@ -1247,17 +1241,15 @@ padBufferToInt(convertState *buffer)
12471241static Jsonb *
12481242convertToJsonb (JsonbValue * val )
12491243{
1250- convertState buffer ;
1244+ StringInfoData buffer ;
12511245JEntry jentry ;
12521246Jsonb * res ;
12531247
12541248/* Should not already have binary representation */
12551249Assert (val -> type != jbvBinary );
12561250
12571251/* Allocate an output buffer. It will be enlarged as needed */
1258- buffer .buffer = palloc (128 );
1259- buffer .len = 0 ;
1260- buffer .allocatedsz = 128 ;
1252+ initStringInfo (& buffer );
12611253
12621254/* Make room for the varlena header */
12631255reserveFromBuffer (& buffer ,sizeof (VARHDRSZ ));
@@ -1270,7 +1262,7 @@ convertToJsonb(JsonbValue *val)
12701262 * kind of value it is.
12711263 */
12721264
1273- res = (Jsonb * )buffer .buffer ;
1265+ res = (Jsonb * )buffer .data ;
12741266
12751267SET_VARSIZE (res ,buffer .len );
12761268
@@ -1289,7 +1281,7 @@ convertToJsonb(JsonbValue *val)
12891281 * for debugging purposes.
12901282 */
12911283static void
1292- convertJsonbValue (convertState * buffer ,JEntry * header ,JsonbValue * val ,int level )
1284+ convertJsonbValue (StringInfo buffer ,JEntry * header ,JsonbValue * val ,int level )
12931285{
12941286check_stack_depth ();
12951287
@@ -1307,7 +1299,7 @@ convertJsonbValue(convertState *buffer, JEntry *header, JsonbValue *val, int lev
13071299}
13081300
13091301static void
1310- convertJsonbArray (convertState * buffer ,JEntry * pheader ,JsonbValue * val ,int level )
1302+ convertJsonbArray (StringInfo buffer ,JEntry * pheader ,JsonbValue * val ,int level )
13111303{
13121304int offset ;
13131305int metaoffset ;
@@ -1366,7 +1358,7 @@ convertJsonbArray(convertState *buffer, JEntry *pheader, JsonbValue *val, int le
13661358}
13671359
13681360static void
1369- convertJsonbObject (convertState * buffer ,JEntry * pheader ,JsonbValue * val ,int level )
1361+ convertJsonbObject (StringInfo buffer ,JEntry * pheader ,JsonbValue * val ,int level )
13701362{
13711363uint32 header ;
13721364int offset ;
@@ -1431,7 +1423,7 @@ convertJsonbObject(convertState *buffer, JEntry *pheader, JsonbValue *val, int l
14311423}
14321424
14331425static void
1434- convertJsonbScalar (convertState * buffer ,JEntry * jentry ,JsonbValue * scalarVal )
1426+ convertJsonbScalar (StringInfo buffer ,JEntry * jentry ,JsonbValue * scalarVal )
14351427{
14361428int numlen ;
14371429short padlen ;