@@ -105,6 +105,32 @@ struct VarkShardInfo
105105 const uint8_t * pCompressedData; // pointer to start of compressed chunks (mmap only, nullptr for FP)
106106};
107107
108+ // Simple RAII for conditional FILE* ownership
109+ struct VarkFP {
110+ FILE* fp = nullptr ;
111+ bool owns = false ;
112+ VarkFP () = default ;
113+ VarkFP ( FILE* f, bool own ) : fp(f), owns(own) {}
114+ ~VarkFP () { if ( owns && fp ) fclose ( fp ); }
115+ operator FILE*() const { return fp; }
116+ explicit operator bool () const { return fp != nullptr ; }
117+ };
118+
119+ // Acquires read FP from vark. Returns empty handle if MMAP mode.
120+ static VarkFP VarkAcquireReadFP ( Vark& vark )
121+ {
122+ if ( (vark.flags & VARK_MMAP) && vark.mmapHandle ) return {};
123+ if ( (vark.flags & VARK_PERSISTENT_FP) && vark.fp ) return { vark.fp , false };
124+ return { fopen ( vark.path .string ().c_str (), " rb" ), true };
125+ }
126+
127+ // Acquires read/write FP from vark for append operations.
128+ static VarkFP VarkAcquireWriteFP ( Vark& vark )
129+ {
130+ if ( (vark.flags & VARK_PERSISTENT_FP) && vark.fp ) return { vark.fp , false };
131+ return { fopen ( vark.path .string ().c_str (), " r+b" ), true };
132+ }
133+
108134// For MMAP: parses VSHF from memory, returns header. pOffsets points into mmap via tempShardBuffer copy.
109135static bool VarkParseVSHF_MMAP ( Vark& vark, const uint8_t * ptr, size_t entrySize, VarkShardInfo& out )
110136{
@@ -361,11 +387,8 @@ void VarkCloseArchive( Vark& vark )
361387bool VarkDecompressFile ( Vark& vark, const std::string& file, std::vector< uint8_t >& data )
362388{
363389 const VarkFile* entry = nullptr ;
364- FILE* fp = nullptr ;
365- std::vector< uint8_t >* pCompressedData = nullptr ;
366390 uint64_t uncompressedSize = 0 ;
367391 uint64_t compressedSize = 0 ;
368- bool ownFP = false ;
369392
370393 if ( vark.flags & VARK_WRITE ) return false ;
371394
@@ -375,37 +398,36 @@ bool VarkDecompressFile( Vark& vark, const std::string& file, std::vector< uint8
375398
376399 if ( entry->shardSize > 0 )
377400 {
378- if ( (vark.flags & VARK_MMAP) && vark.mmapHandle )
401+ VarkFP fp = VarkAcquireReadFP ( vark );
402+ mio::mmap_source* mmap = (vark.flags & VARK_MMAP) ? (mio::mmap_source*)vark.mmapHandle : nullptr ;
403+
404+ VarkShardInfo hdr;
405+ uint64_t dataStartPos = 0 ;
406+
407+ if ( mmap )
379408 {
380- mio::mmap_source* mmap = (mio::mmap_source*)vark.mmapHandle ;
381409 if ( !mmap->is_open () ) return false ;
382-
383- VarkShardInfo hdr;
384410 if ( !VarkParseVSHF_MMAP ( vark, (const uint8_t *)mmap->data () + entry->offset , (size_t )entry->size , hdr ) ) return false ;
385- return VarkDecompressShards ( vark, nullptr , hdr, entry->shardSize , 0 , 0 , hdr.totalUncompressedSize , data );
386411 }
387412 else
388413 {
389- if ( (vark.flags & VARK_PERSISTENT_FP) && vark.fp ) fp = vark.fp ;
390- else { fp = fopen ( vark.path .string ().c_str (), " rb" ); if ( !fp ) return false ; ownFP = true ; }
391-
392- if ( VARK_FSEEK ( fp, (long long )entry->offset , SEEK_SET ) != 0 ) goto error1;
393-
394- VarkShardInfo hdr;
395- if ( !VarkParseVSHF_Fp ( vark, fp, hdr ) ) goto error1;
396- if ( !VarkDecompressShards ( vark, fp, hdr, entry->shardSize , VARK_FTELL ( fp ), 0 , hdr.totalUncompressedSize , data ) ) goto error1;
397-
398- if ( ownFP ) fclose ( fp );
399- return true ;
414+ if ( !fp ) return false ;
415+ if ( VARK_FSEEK ( fp, (long long )entry->offset , SEEK_SET ) != 0 ) return false ;
416+ if ( !VarkParseVSHF_Fp ( vark, fp, hdr ) ) return false ;
417+ dataStartPos = VARK_FTELL ( fp );
400418 }
419+
420+ return VarkDecompressShards ( vark, fp, hdr, entry->shardSize , dataStartPos, 0 , hdr.totalUncompressedSize , data );
401421 }
402422
403423 if ( entry->size < 8 ) return false ;
404424 compressedSize = entry->size - 8 ;
405425
406- if ( (vark.flags & VARK_MMAP) && vark.mmapHandle )
426+ VarkFP fp = VarkAcquireReadFP ( vark );
427+ mio::mmap_source* mmap = (vark.flags & VARK_MMAP) ? (mio::mmap_source*)vark.mmapHandle : nullptr ;
428+
429+ if ( mmap )
407430 {
408- mio::mmap_source* mmap = (mio::mmap_source*)vark.mmapHandle ;
409431 if ( !mmap->is_open () ) return false ;
410432 if ( entry->offset + 8 + compressedSize > mmap->size () ) return false ;
411433
@@ -421,36 +443,24 @@ bool VarkDecompressFile( Vark& vark, const std::string& file, std::vector< uint8
421443 return true ;
422444 }
423445
424- if ( (vark.flags & VARK_PERSISTENT_FP) && vark.fp ) fp = vark.fp ;
425- else { fp = fopen ( vark.path .string ().c_str (), " rb" ); if ( !fp ) goto error0; ownFP = true ; }
426-
427- if ( VARK_FSEEK ( fp, (long long )entry->offset , SEEK_SET ) != 0 ) goto error1;
428- if ( fread ( &uncompressedSize, sizeof (uncompressedSize), 1 , fp ) != 1 ) goto error1;
446+ if ( !fp ) return false ;
447+ if ( VARK_FSEEK ( fp, (long long )entry->offset , SEEK_SET ) != 0 ) return false ;
448+ if ( fread ( &uncompressedSize, sizeof (uncompressedSize), 1 , fp ) != 1 ) return false ;
429449
430- compressedSize = entry->size - 8 ;
431- pCompressedData = &vark.tempBuffer ;
432- pCompressedData->resize ( (size_t )compressedSize );
433-
450+ vark.tempBuffer .resize ( (size_t )compressedSize );
434451 if ( compressedSize > 0 )
435452 {
436- if ( fread ( pCompressedData-> data (), 1 , (size_t )compressedSize, fp ) != compressedSize ) goto error1 ;
453+ if ( fread ( vark. tempBuffer . data (), 1 , (size_t )compressedSize, fp ) != compressedSize ) return false ;
437454 }
438455
439- if ( ownFP ) fclose ( fp );
440-
441456 data.resize ( (size_t )uncompressedSize );
442457 if ( uncompressedSize > 0 )
443458 {
444- int res = lzav::lzav_decompress ( pCompressedData-> data (), data.data (), (int )compressedSize, (int )uncompressedSize );
459+ int res = lzav::lzav_decompress ( vark. tempBuffer . data (), data.data (), (int )compressedSize, (int )uncompressedSize );
445460 if ( res < 0 || (uint64_t )res != uncompressedSize ) return false ;
446461 }
447462
448463 return true ;
449-
450- error1:
451- if ( ownFP && fp ) fclose ( fp );
452- error0:
453- return false ;
454464}
455465
456466bool VarkDecompressFileSharded ( Vark& vark, const std::string& file, uint64_t offset, uint64_t size, std::vector< uint8_t >& data )
@@ -464,48 +474,32 @@ bool VarkDecompressFileSharded( Vark& vark, const std::string& file, uint64_t of
464474
465475 if ( entry->shardSize == 0 ) return false ;
466476
467- FILE* fp = nullptr ;
468- bool ownFP = false ;
477+ VarkFP fp = VarkAcquireReadFP ( vark ) ;
478+ mio::mmap_source* mmap = (vark. flags & VARK_MMAP) ? (mio::mmap_source*)vark. mmapHandle : nullptr ;
469479
470- if ( ( vark.flags & VARK_MMAP ) && vark.mmapHandle )
480+ VarkShardInfo hdr;
481+ uint64_t dataStartPos = 0 ;
482+
483+ if ( mmap )
471484 {
472- mio::mmap_source* mmap = ( mio::mmap_source* ) vark.mmapHandle ;
473485 if ( !mmap->is_open () ) return false ;
474-
475- VarkShardInfo hdr;
476- if ( !VarkParseVSHF_MMAP ( vark, ( const uint8_t * ) mmap->data () + entry->offset , (size_t )entry->size , hdr ) ) return false ;
477- if ( offset + size > hdr.totalUncompressedSize ) return false ;
478-
479- return VarkDecompressShards ( vark, nullptr , hdr, entry->shardSize , 0 , offset, size, data );
486+ if ( !VarkParseVSHF_MMAP ( vark, (const uint8_t *)mmap->data () + entry->offset , (size_t )entry->size , hdr ) ) return false ;
480487 }
481488 else
482489 {
483- if ( ( vark.flags & VARK_PERSISTENT_FP ) && vark.fp ) fp = vark.fp ;
484- else { fp = fopen ( vark.path .string ().c_str (), " rb" ); if ( !fp ) return false ; ownFP = true ; }
485-
486- if ( VARK_FSEEK ( fp, ( long long ) entry->offset , SEEK_SET ) != 0 ) goto error1;
487-
488- VarkShardInfo hdr;
489- if ( !VarkParseVSHF_Fp ( vark, fp, hdr ) ) goto error1;
490- if ( offset + size > hdr.totalUncompressedSize ) goto error1;
491-
492- uint64_t dataStartPos = VARK_FTELL ( fp );
493- if ( !VarkDecompressShards ( vark, fp, hdr, entry->shardSize , dataStartPos, offset, size, data ) ) goto error1;
494-
495- if ( ownFP ) fclose ( fp );
496- return true ;
490+ if ( !fp ) return false ;
491+ if ( VARK_FSEEK ( fp, (long long )entry->offset , SEEK_SET ) != 0 ) return false ;
492+ if ( !VarkParseVSHF_Fp ( vark, fp, hdr ) ) return false ;
493+ dataStartPos = VARK_FTELL ( fp );
497494 }
498495
499- error1:
500- if ( ownFP && fp ) fclose ( fp );
501- return false ;
496+ if ( offset + size > hdr. totalUncompressedSize ) return false ;
497+
498+ return VarkDecompressShards ( vark, fp, hdr, entry-> shardSize , dataStartPos, offset, size, data ) ;
502499}
503500
504501bool VarkCompressAppendFile ( Vark& vark, const std::string& file, uint32_t flags )
505502{
506- FILE* srcFp = nullptr ;
507- FILE* fp = nullptr ;
508- std::vector< uint8_t > srcData;
509503 VarkFile newFile;
510504 long long srcLen = 0 ;
511505 uint64_t tableOffset = 0 ;
@@ -515,26 +509,29 @@ bool VarkCompressAppendFile( Vark& vark, const std::string& file, uint32_t flags
515509
516510 if ( !( vark.flags & VARK_WRITE ) ) return false ;
517511
518- srcFp = fopen ( file.c_str (), " rb" );
519- if ( !srcFp ) goto error0;
520-
521- VARK_FSEEK ( srcFp, 0 , SEEK_END );
522- srcLen = VARK_FTELL ( srcFp );
523- VARK_FSEEK ( srcFp, 0 , SEEK_SET );
524-
525- srcData.resize ( (size_t )srcLen );
526- if ( srcLen > 0 )
512+ // Read source file
513+ std::vector< uint8_t > srcData;
527514 {
528- if ( fread ( srcData.data (), 1 , (size_t )srcLen, srcFp ) != (size_t )srcLen ) goto error1;
529- }
530- fclose ( srcFp );
515+ VarkFP srcFp ( fopen ( file.c_str (), " rb" ), true );
516+ if ( !srcFp ) return false ;
517+
518+ VARK_FSEEK ( srcFp, 0 , SEEK_END );
519+ srcLen = VARK_FTELL ( srcFp );
520+ VARK_FSEEK ( srcFp, 0 , SEEK_SET );
531521
532- if ( (vark.flags & VARK_PERSISTENT_FP) && vark.fp ) fp = vark.fp ;
533- else { fp = fopen ( vark.path .string ().c_str (), " r+b" ); if ( !fp ) goto error0; }
522+ srcData.resize ( (size_t )srcLen );
523+ if ( srcLen > 0 )
524+ {
525+ if ( fread ( srcData.data (), 1 , (size_t )srcLen, srcFp ) != (size_t )srcLen ) return false ;
526+ }
527+ } // srcFp closes automatically here
528+
529+ VarkFP fp = VarkAcquireWriteFP ( vark );
530+ if ( !fp ) return false ;
534531
535- if ( VARK_FSEEK ( fp, 4 , SEEK_SET ) != 0 ) goto error2 ;
536- if ( fread ( &tableOffset, sizeof (tableOffset), 1 , fp ) != 1 ) goto error2 ;
537- if ( VARK_FSEEK ( fp, (long long )tableOffset, SEEK_SET ) != 0 ) goto error2 ;
532+ if ( VARK_FSEEK ( fp, 4 , SEEK_SET ) != 0 ) return false ;
533+ if ( fread ( &tableOffset, sizeof (tableOffset), 1 , fp ) != 1 ) return false ;
534+ if ( VARK_FSEEK ( fp, (long long )tableOffset, SEEK_SET ) != 0 ) return false ;
538535
539536 newFile.offset = tableOffset;
540537 newFile.path = file;
@@ -583,13 +580,13 @@ bool VarkCompressAppendFile( Vark& vark, const std::string& file, uint32_t flags
583580 int bound = lzav::lzav_compress_bound ( (int )srcLen );
584581 std::vector< uint8_t > dstData ( bound );
585582 int compressedLen = lzav::lzav_compress_default ( srcData.data (), dstData.data (), (int )srcLen, bound );
586- if ( compressedLen == 0 && srcLen > 0 ) goto error2 ;
583+ if ( compressedLen == 0 && srcLen > 0 ) return false ;
587584
588585 uncompressedSize = (uint64_t )srcLen;
589- if ( fwrite ( &uncompressedSize, sizeof (uncompressedSize), 1 , fp ) != 1 ) goto error2 ;
586+ if ( fwrite ( &uncompressedSize, sizeof (uncompressedSize), 1 , fp ) != 1 ) return false ;
590587 if ( compressedLen > 0 )
591588 {
592- if ( fwrite ( dstData.data (), 1 , compressedLen, fp ) != (size_t )compressedLen ) goto error2 ;
589+ if ( fwrite ( dstData.data (), 1 , compressedLen, fp ) != (size_t )compressedLen ) return false ;
593590 }
594591 newFile.size = 8 + compressedLen;
595592 }
@@ -599,7 +596,7 @@ bool VarkCompressAppendFile( Vark& vark, const std::string& file, uint32_t flags
599596
600597 newTableOffset = (uint64_t )VARK_FTELL ( fp );
601598 count = vark.files .size ();
602- if ( fwrite ( &count, sizeof (count), 1 , fp ) != 1 ) goto error2 ;
599+ if ( fwrite ( &count, sizeof (count), 1 , fp ) != 1 ) return false ;
603600
604601 for ( const auto & f : vark.files )
605602 {
@@ -614,22 +611,13 @@ bool VarkCompressAppendFile( Vark& vark, const std::string& file, uint32_t flags
614611 fwrite ( &count, sizeof (count), 1 , fp );
615612 for ( const auto & f : vark.files ) fwrite ( &f.shardSize , sizeof (uint32_t ), 1 , fp );
616613
617- if ( VARK_FSEEK ( fp, 4 , SEEK_SET ) != 0 ) goto error2 ;
618- if ( fwrite ( &newTableOffset, sizeof (newTableOffset), 1 , fp ) != 1 ) goto error2 ;
614+ if ( VARK_FSEEK ( fp, 4 , SEEK_SET ) != 0 ) return false ;
615+ if ( fwrite ( &newTableOffset, sizeof (newTableOffset), 1 , fp ) != 1 ) return false ;
619616
620617 VARK_FSEEK ( fp, 0 , SEEK_END );
621618 vark.size = (uint64_t )VARK_FTELL ( fp );
622619
623- if ( fp != vark.fp ) fclose ( fp );
624620 return true ;
625-
626- error2:
627- if ( fp != vark.fp ) fclose ( fp );
628- return false ;
629- error1:
630- fclose ( srcFp );
631- error0:
632- return false ;
633621}
634622
635623#endif // VARK_IMPLEMENTATION
0 commit comments