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 ,
4636 JsonbValue * 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 to copy
1179- * the data to the reserved area later with copyToBuffer()
1168+ * Returns the offset to the reserved area. The caller is expected to fill
1169+ * the reserved area later with copyToBuffer().
11801170 */
11811171static int
1182- reserveFromBuffer (convertState * buffer , int len )
1172+ reserveFromBuffer (StringInfo buffer , int len )
11831173{
11841174 int 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 */
11941180 offset = buffer -> len ;
11951181
11961182 /* reserve the space */
11971183 buffer -> 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+
11991191 return 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{
12171209 int 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
12351227 padlen = INTALIGN (buffer -> len ) - buffer -> len ;
12361228
12371229 offset = reserveFromBuffer (buffer , padlen );
1230+
1231+ /* padlen must be small, so this is probably faster than a memset */
12381232 for (p = 0 ; p < padlen ; p ++ )
1239- buffer -> buffer [offset + p ] = 0 ;
1233+ buffer -> data [offset + p ] = '\0' ;
12401234
12411235 return padlen ;
12421236}
@@ -1247,17 +1241,15 @@ padBufferToInt(convertState *buffer)
12471241static Jsonb *
12481242convertToJsonb (JsonbValue * val )
12491243{
1250- convertState buffer ;
1244+ StringInfoData buffer ;
12511245 JEntry jentry ;
12521246 Jsonb * res ;
12531247
12541248 /* Should not already have binary representation */
12551249 Assert (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 */
12631255 reserveFromBuffer (& 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
12751267 SET_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{
12941286 check_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{
13121304 int offset ;
13131305 int 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{
13711363 uint32 header ;
13721364 int 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{
14361428 int numlen ;
14371429 short padlen ;
0 commit comments