@@ -1502,7 +1502,98 @@ bool GzUnpacker::gzExpander( fs::FS sourceFS, const char* sourceFile, fs::FS des
1502
1502
return true ;
1503
1503
}
1504
1504
1505
+ bool GzUnpacker::gzStreamExpander ( Stream* sourceStream, fs::FS destFS, const char * destFile ) {
1506
+ tarGzClearError ();
1507
+ initFSCallbacks ();
1508
+ if (!tgzLogger ) {
1509
+ setLoggerCallback ( targzPrintLoggerCallback );
1510
+ }
1511
+ bool isupdate = false ;
1512
+ bool stream_to_tar = false ;
1513
+ bool gz_use_dict = true ;
1514
+ bool needs_free = false ;
1515
+
1516
+ if ( nodict == true ) {
1517
+ gz_use_dict = false ;
1518
+ } else if ( HEAP_AVAILABLE () < GZIP_DICT_SIZE+GZIP_BUFF_SIZE ) {
1519
+ size_t free_min_heap_blocks = HEAP_AVAILABLE () / 512 ; // leave 1k heap, eat all the rest !
1520
+ if ( free_min_heap_blocks <1 ) {
1521
+ setError ( ESP32_TARGZ_HEAP_TOO_LOW );
1522
+ return false ;
1523
+ }
1524
+ min_output_buffer_size = free_min_heap_blocks * 512 ;
1525
+ if ( min_output_buffer_size > GZIP_BUFF_SIZE ) min_output_buffer_size = GZIP_BUFF_SIZE;
1526
+ log_w (" Disabling GZIP Dictionary (heap wanted:%d, available: %d, buffer: %d bytes), writes will be slow" , HEAP_AVAILABLE (), GZIP_DICT_SIZE+GZIP_BUFF_SIZE, min_output_buffer_size );
1527
+ gz_use_dict = false ;
1528
+ //
1529
+ } else {
1530
+ log_d (" Current heap budget (available:%d, needed:%d)" , HEAP_AVAILABLE (), GZIP_DICT_SIZE+GZIP_BUFF_SIZE );
1531
+ }
1532
+
1533
+ if ( destFile == nullptr ) {
1534
+ return false ;
1535
+ }
1536
+
1537
+ tgzLogger (" [GZ] Expanding Stream to %s\n " , destFile );
1538
+
1539
+ if ( !gzProgressCallback ) {
1540
+ setGzProgressCallback ( defaultProgressCallback );
1541
+ }
1542
+
1543
+ size_t size = sourceStream->available ();
1544
+ if ( ! size ) {
1545
+ log_e (" Bad stream, aborting" );
1546
+ setError ( ESP32_TARGZ_STREAM_ERROR );
1547
+ return false ;
1548
+ }
1549
+
1550
+ if ( destFS.exists ( destFile ) ) {
1551
+ log_v (" [GZ INFO] Deleting %s as it is in the way" , destFile);
1552
+ destFS.remove ( destFile );
1553
+ }
1554
+ fs::File outFile = destFS.open (destFile, " w+" );
1555
+ if (!outFile) {
1556
+ log_e (" [GZ ERROR] in gzExpander: cannot create destination file, no space left on device ?" );
1557
+ setError ( ESP32_TARGZ_UZLIB_INVALID_FILE );
1558
+ return false ;
1559
+ }
1560
+
1561
+ tarGzIO.gz = sourceStream;
1562
+ tarGzIO.output = &outFile;
1563
+
1564
+ if ( gzWriteCallback == nullptr ) {
1565
+ setStreamWriter ( gzStreamWriteCallback );
1566
+ }
1567
+ // gzWriteCallback = &gzStreamWriteCallback; // for regular unzipping
1568
+
1569
+ int ret = gzUncompress ( isupdate, stream_to_tar, gz_use_dict );
1570
+
1571
+ outFile.close ();
1572
+
1573
+ if ( ret!=0 ) {
1574
+ log_e (" gzUncompress returned error code %d" , ret);
1575
+ if ( needs_free ) free ( (char *)destFile );
1576
+ setError ( (tarGzErrorCode)ret );
1577
+ return false ;
1578
+ }
1579
+ log_v (" uzLib expander finished!" );
1505
1580
1581
+ /*
1582
+ outfile = destFS.open( destFile, FILE_READ );
1583
+ log_d("Expanded %s to %s (%d bytes)", sourceFile, destFile, outfile.size() );
1584
+ outfile.close();
1585
+ */
1586
+ if ( gzMessageCallback ) {
1587
+ gzMessageCallback (" %s" , destFile );
1588
+ }
1589
+
1590
+ if ( needs_free ) free ( (char *)destFile );
1591
+
1592
+ if ( fstotalBytes && fsfreeBytes ) {
1593
+ log_d (" [GZ Info] FreeBytes after expansion=%d" , fsfreeBytes () );
1594
+ }
1595
+ return true ;
1596
+ }
1506
1597
1507
1598
// uncompress gz stream (file or HTTP) to any destination (see setStreamWriter)
1508
1599
bool GzUnpacker::gzStreamExpander ( Stream *stream, size_t gz_size )
0 commit comments