@@ -465,35 +465,28 @@ class BitStreamWriter
465
465
};
466
466
467
467
468
-
469
468
/* * Non-refcounted RAII wrapper for FILE*
470
469
*
471
470
* Will automatically close the file when it goes out of scope if not null.
472
471
* If you're returning the file pointer, return file.release().
473
472
* If you need to close the file early, use file.fclose() instead of fclose(file).
474
473
*/
475
- class CAutoFile
474
+ class AutoFile
476
475
{
477
- private:
478
- const int nType;
479
- const int nVersion;
480
-
476
+ protected:
481
477
FILE* file;
482
478
483
479
public:
484
- CAutoFile (FILE* filenew, int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn)
485
- {
486
- file = filenew;
487
- }
480
+ explicit AutoFile (FILE* filenew) : file{filenew} {}
488
481
489
- ~CAutoFile ()
482
+ ~AutoFile ()
490
483
{
491
484
fclose ();
492
485
}
493
486
494
487
// Disallow copies
495
- CAutoFile (const CAutoFile &) = delete ;
496
- CAutoFile & operator =(const CAutoFile &) = delete ;
488
+ AutoFile (const AutoFile &) = delete ;
489
+ AutoFile & operator =(const AutoFile &) = delete ;
497
490
498
491
void fclose ()
499
492
{
@@ -504,14 +497,14 @@ class CAutoFile
504
497
}
505
498
506
499
/* * Get wrapped FILE* with transfer of ownership.
507
- * @note This will invalidate the CAutoFile object, and makes it the responsibility of the caller
500
+ * @note This will invalidate the AutoFile object, and makes it the responsibility of the caller
508
501
* of this function to clean up the returned FILE*.
509
502
*/
510
503
FILE* release () { FILE* ret = file; file = nullptr ; return ret; }
511
504
512
505
/* * Get wrapped FILE* without transfer of ownership.
513
506
* @note Ownership of the FILE* will remain with this class. Use this only if the scope of the
514
- * CAutoFile outlives use of the passed pointer.
507
+ * AutoFile outlives use of the passed pointer.
515
508
*/
516
509
FILE* Get () const { return file; }
517
510
@@ -522,40 +515,62 @@ class CAutoFile
522
515
//
523
516
// Stream subset
524
517
//
525
- int GetType () const { return nType; }
526
- int GetVersion () const { return nVersion; }
527
-
528
518
void read (Span<std::byte> dst)
529
519
{
530
- if (!file)
531
- throw std::ios_base::failure (" CAutoFile::read: file handle is nullptr" );
520
+ if (!file) throw std::ios_base::failure (" AutoFile::read: file handle is nullptr" );
532
521
if (fread (dst.data (), 1 , dst.size (), file) != dst.size ()) {
533
- throw std::ios_base::failure (feof (file) ? " CAutoFile ::read: end of file" : " CAutoFile ::read: fread failed" );
522
+ throw std::ios_base::failure (feof (file) ? " AutoFile ::read: end of file" : " AutoFile ::read: fread failed" );
534
523
}
535
524
}
536
525
537
526
void ignore (size_t nSize)
538
527
{
539
- if (!file)
540
- throw std::ios_base::failure (" CAutoFile::ignore: file handle is nullptr" );
528
+ if (!file) throw std::ios_base::failure (" AutoFile::ignore: file handle is nullptr" );
541
529
unsigned char data[4096 ];
542
530
while (nSize > 0 ) {
543
531
size_t nNow = std::min<size_t >(nSize, sizeof (data));
544
532
if (fread (data, 1 , nNow, file) != nNow)
545
- throw std::ios_base::failure (feof (file) ? " CAutoFile ::ignore: end of file" : " CAutoFile ::read: fread failed" );
533
+ throw std::ios_base::failure (feof (file) ? " AutoFile ::ignore: end of file" : " AutoFile ::read: fread failed" );
546
534
nSize -= nNow;
547
535
}
548
536
}
549
537
550
538
void write (Span<const std::byte> src)
551
539
{
552
- if (!file)
553
- throw std::ios_base::failure (" CAutoFile::write: file handle is nullptr" );
540
+ if (!file) throw std::ios_base::failure (" AutoFile::write: file handle is nullptr" );
554
541
if (fwrite (src.data (), 1 , src.size (), file) != src.size ()) {
555
- throw std::ios_base::failure (" CAutoFile ::write: write failed" );
542
+ throw std::ios_base::failure (" AutoFile ::write: write failed" );
556
543
}
557
544
}
558
545
546
+ template <typename T>
547
+ AutoFile& operator <<(const T& obj)
548
+ {
549
+ if (!file) throw std::ios_base::failure (" AutoFile::operator<<: file handle is nullptr" );
550
+ ::Serialize (*this , obj);
551
+ return *this ;
552
+ }
553
+
554
+ template <typename T>
555
+ AutoFile& operator >>(T&& obj)
556
+ {
557
+ if (!file) throw std::ios_base::failure (" AutoFile::operator>>: file handle is nullptr" );
558
+ ::Unserialize (*this , obj);
559
+ return *this ;
560
+ }
561
+ };
562
+
563
+ class CAutoFile : public AutoFile
564
+ {
565
+ private:
566
+ const int nType;
567
+ const int nVersion;
568
+
569
+ public:
570
+ CAutoFile (FILE* filenew, int nTypeIn, int nVersionIn) : AutoFile{filenew}, nType(nTypeIn), nVersion(nVersionIn) {}
571
+ int GetType () const { return nType; }
572
+ int GetVersion () const { return nVersion; }
573
+
559
574
template <typename T>
560
575
CAutoFile& operator <<(const T& obj)
561
576
{
0 commit comments