32
32
#define JSONB_MAX_ELEMS (Min(MaxAllocSize / sizeof(JsonbValue), JB_CMASK))
33
33
#define JSONB_MAX_PAIRS (Min(MaxAllocSize / sizeof(JsonbPair), JB_CMASK))
34
34
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
-
45
35
static void fillJsonbValue (JEntry * array , int index , char * base_addr ,
46
36
JsonbValue * result );
47
37
static int compareJsonbScalarValue (JsonbValue * a , JsonbValue * b );
48
38
static int lexicalCompareJsonbStringValue (const void * a , const void * b );
49
39
static 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 );
54
44
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 );
59
49
60
50
static JsonbIterator * iteratorFromContainer (JsonbContainer * container , JsonbIterator * parent );
61
51
static JsonbIterator * freeAndGetParent (JsonbIterator * it );
@@ -1175,44 +1165,46 @@ lexicalCompareJsonbStringValue(const void *a, const void *b)
1175
1165
1176
1166
/*
1177
1167
* 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().
1180
1170
*/
1181
1171
static int
1182
- reserveFromBuffer (convertState * buffer , int len )
1172
+ reserveFromBuffer (StringInfo buffer , int len )
1183
1173
{
1184
1174
int offset ;
1185
1175
1186
1176
/* 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 );
1192
1178
1193
1179
/* remember current offset */
1194
1180
offset = buffer -> len ;
1195
1181
1196
1182
/* reserve the space */
1197
1183
buffer -> len += len ;
1198
1184
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
+
1199
1191
return offset ;
1200
1192
}
1201
1193
1202
1194
/*
1203
1195
* Copy 'len' bytes to a previously reserved area in buffer.
1204
1196
*/
1205
1197
static void
1206
- copyToBuffer (convertState * buffer , int offset , char * data , int len )
1198
+ copyToBuffer (StringInfo buffer , int offset , const char * data , int len )
1207
1199
{
1208
- memcpy (buffer -> buffer + offset , data , len );
1200
+ memcpy (buffer -> data + offset , data , len );
1209
1201
}
1210
1202
1211
1203
/*
1212
1204
* A shorthand for reserveFromBuffer + copyToBuffer.
1213
1205
*/
1214
1206
static void
1215
- appendToBuffer (convertState * buffer , char * data , int len )
1207
+ appendToBuffer (StringInfo buffer , const char * data , int len )
1216
1208
{
1217
1209
int offset ;
1218
1210
@@ -1226,17 +1218,19 @@ appendToBuffer(convertState *buffer, char *data, int len)
1226
1218
* Returns the number of padding bytes appended.
1227
1219
*/
1228
1220
static short
1229
- padBufferToInt (convertState * buffer )
1221
+ padBufferToInt (StringInfo buffer )
1230
1222
{
1231
- short padlen ,
1232
- p ;
1233
- int offset ;
1223
+ int padlen ,
1224
+ p ,
1225
+ offset ;
1234
1226
1235
1227
padlen = INTALIGN (buffer -> len ) - buffer -> len ;
1236
1228
1237
1229
offset = reserveFromBuffer (buffer , padlen );
1230
+
1231
+ /* padlen must be small, so this is probably faster than a memset */
1238
1232
for (p = 0 ; p < padlen ; p ++ )
1239
- buffer -> buffer [offset + p ] = 0 ;
1233
+ buffer -> data [offset + p ] = '\0' ;
1240
1234
1241
1235
return padlen ;
1242
1236
}
@@ -1247,17 +1241,15 @@ padBufferToInt(convertState *buffer)
1247
1241
static Jsonb *
1248
1242
convertToJsonb (JsonbValue * val )
1249
1243
{
1250
- convertState buffer ;
1244
+ StringInfoData buffer ;
1251
1245
JEntry jentry ;
1252
1246
Jsonb * res ;
1253
1247
1254
1248
/* Should not already have binary representation */
1255
1249
Assert (val -> type != jbvBinary );
1256
1250
1257
1251
/* 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 );
1261
1253
1262
1254
/* Make room for the varlena header */
1263
1255
reserveFromBuffer (& buffer , sizeof (VARHDRSZ ));
@@ -1270,7 +1262,7 @@ convertToJsonb(JsonbValue *val)
1270
1262
* kind of value it is.
1271
1263
*/
1272
1264
1273
- res = (Jsonb * ) buffer .buffer ;
1265
+ res = (Jsonb * ) buffer .data ;
1274
1266
1275
1267
SET_VARSIZE (res , buffer .len );
1276
1268
@@ -1289,7 +1281,7 @@ convertToJsonb(JsonbValue *val)
1289
1281
* for debugging purposes.
1290
1282
*/
1291
1283
static void
1292
- convertJsonbValue (convertState * buffer , JEntry * header , JsonbValue * val , int level )
1284
+ convertJsonbValue (StringInfo buffer , JEntry * header , JsonbValue * val , int level )
1293
1285
{
1294
1286
check_stack_depth ();
1295
1287
@@ -1307,7 +1299,7 @@ convertJsonbValue(convertState *buffer, JEntry *header, JsonbValue *val, int lev
1307
1299
}
1308
1300
1309
1301
static void
1310
- convertJsonbArray (convertState * buffer , JEntry * pheader , JsonbValue * val , int level )
1302
+ convertJsonbArray (StringInfo buffer , JEntry * pheader , JsonbValue * val , int level )
1311
1303
{
1312
1304
int offset ;
1313
1305
int metaoffset ;
@@ -1366,7 +1358,7 @@ convertJsonbArray(convertState *buffer, JEntry *pheader, JsonbValue *val, int le
1366
1358
}
1367
1359
1368
1360
static void
1369
- convertJsonbObject (convertState * buffer , JEntry * pheader , JsonbValue * val , int level )
1361
+ convertJsonbObject (StringInfo buffer , JEntry * pheader , JsonbValue * val , int level )
1370
1362
{
1371
1363
uint32 header ;
1372
1364
int offset ;
@@ -1431,7 +1423,7 @@ convertJsonbObject(convertState *buffer, JEntry *pheader, JsonbValue *val, int l
1431
1423
}
1432
1424
1433
1425
static void
1434
- convertJsonbScalar (convertState * buffer , JEntry * jentry , JsonbValue * scalarVal )
1426
+ convertJsonbScalar (StringInfo buffer , JEntry * jentry , JsonbValue * scalarVal )
1435
1427
{
1436
1428
int numlen ;
1437
1429
short padlen ;
0 commit comments