@@ -1265,3 +1265,86 @@ func TestPeekableDecoder(t *testing.T) {
1265
1265
}
1266
1266
}
1267
1267
}
1268
+
1269
+ // TestDecoderReset tests that the decoder preserves its internal
1270
+ // buffer between Reset calls to avoid frequent allocations when reusing the decoder.
1271
+ // It ensures that the buffer capacity is maintained while avoiding aliasing
1272
+ // issues with bytes.Buffer.
1273
+ func TestDecoderReset (t * testing.T ) {
1274
+ // Create a decoder with a reasonably large JSON input to ensure buffer growth
1275
+ largeJSON := `{"key1":"value1","key2":"value2","key3":"value3","key4":"value4","key5":"value5"}`
1276
+ dec := NewDecoder (strings .NewReader (largeJSON ))
1277
+
1278
+ t .Run ("Test capacity preservation" , func (t * testing.T ) {
1279
+ // Read the first JSON value to grow the internal buffer
1280
+ val1 , err := dec .ReadValue ()
1281
+ if err != nil {
1282
+ t .Fatalf ("first ReadValue failed: %v" , err )
1283
+ }
1284
+ if string (val1 ) != largeJSON {
1285
+ t .Fatalf ("first ReadValue = %q, want %q" , val1 , largeJSON )
1286
+ }
1287
+
1288
+ // Get the buffer capacity after first use
1289
+ initialCapacity := cap (dec .s .buf )
1290
+ if initialCapacity == 0 {
1291
+ t .Fatalf ("expected non-zero buffer capacity after first use" )
1292
+ }
1293
+
1294
+ // Reset with a new reader - this should preserve the buffer capacity
1295
+ dec .Reset (strings .NewReader (largeJSON ))
1296
+
1297
+ // Verify the buffer capacity is preserved (or at least not smaller)
1298
+ preservedCapacity := cap (dec .s .buf )
1299
+ if preservedCapacity < initialCapacity {
1300
+ t .Fatalf ("buffer capacity reduced after Reset: got %d, want at least %d" , preservedCapacity , initialCapacity )
1301
+ }
1302
+
1303
+ // Read the second JSON value to ensure the decoder still works correctly
1304
+ val2 , err := dec .ReadValue ()
1305
+ if err != nil {
1306
+ t .Fatalf ("second ReadValue failed: %v" , err )
1307
+ }
1308
+ if string (val2 ) != largeJSON {
1309
+ t .Fatalf ("second ReadValue = %q, want %q" , val2 , largeJSON )
1310
+ }
1311
+ })
1312
+
1313
+ var bbBuf []byte
1314
+ t .Run ("Test aliasing with bytes.Buffer" , func (t * testing.T ) {
1315
+ // Test with bytes.Buffer to verify proper aliasing behavior.
1316
+ bb := bytes .NewBufferString (largeJSON )
1317
+ dec .Reset (bb )
1318
+ bbBuf = bb .Bytes ()
1319
+
1320
+ // Read the third JSON value to ensure functionality with bytes.Buffer
1321
+ val3 , err := dec .ReadValue ()
1322
+ if err != nil {
1323
+ t .Fatalf ("fourth ReadValue failed: %v" , err )
1324
+ }
1325
+ if string (val3 ) != largeJSON {
1326
+ t .Fatalf ("fourth ReadValue = %q, want %q" , val3 , largeJSON )
1327
+ }
1328
+ // The decoder buffer should alias bytes.Buffer's internal buffer.
1329
+ if len (dec .s .buf ) == 0 || len (bbBuf ) == 0 || & dec .s .buf [0 ] != & bbBuf [0 ] {
1330
+ t .Fatalf ("decoder buffer does not alias bytes.Buffer" )
1331
+ }
1332
+ })
1333
+
1334
+ t .Run ("Test aliasing removed after Reset" , func (t * testing.T ) {
1335
+ // Reset with a new reader and verify the buffer is not aliased.
1336
+ dec .Reset (strings .NewReader (largeJSON ))
1337
+ val4 , err := dec .ReadValue ()
1338
+ if err != nil {
1339
+ t .Fatalf ("fifth ReadValue failed: %v" , err )
1340
+ }
1341
+ if string (val4 ) != largeJSON {
1342
+ t .Fatalf ("fourth ReadValue = %q, want %q" , val4 , largeJSON )
1343
+ }
1344
+
1345
+ // The decoder buffer should not alias the bytes.Buffer's internal buffer.
1346
+ if len (dec .s .buf ) == 0 || len (bbBuf ) == 0 || & dec .s .buf [0 ] == & bbBuf [0 ] {
1347
+ t .Fatalf ("decoder buffer aliases bytes.Buffer" )
1348
+ }
1349
+ })
1350
+ }
0 commit comments