LCOV - code coverage report
Current view: top level - source/ps - FileIo.h (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 2 9 22.2 %
Date: 2023-01-19 00:18:29 Functions: 1 15 6.7 %

          Line data    Source code
       1             : /* Copyright (C) 2021 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : /*
      19             :  * endian-safe binary file IO helpers.
      20             :  */
      21             : 
      22             : // the file format has passing similarity to IFF. note however that
      23             : // "chunks" aren't identified by FOURCCs; only the file header is
      24             : // so marked.
      25             : // all > 8-bit integers are stored in little-endian format
      26             : // (hence the _le suffix). however, the caller is responsible for
      27             : // swapping their raw data before passing it to PackRaw. a convenience
      28             : // routine is provided for the common case of storing size_t.
      29             : 
      30             : #ifndef INCLUDED_FILEPACKER
      31             : #define INCLUDED_FILEPACKER
      32             : 
      33             : #include "lib/file/vfs/vfs_path.h"
      34             : #include "ps/CStrForward.h"
      35             : #include "ps/Errors.h"
      36             : #include "ps/Filesystem.h"    // WriteBuffer
      37             : 
      38           0 : ERROR_GROUP(File);
      39           0 : ERROR_TYPE(File, OpenFailed);
      40           0 : ERROR_TYPE(File, WriteFailed);
      41           0 : ERROR_TYPE(File, InvalidType);
      42           0 : ERROR_TYPE(File, InvalidVersion);
      43           0 : ERROR_TYPE(File, ReadFailed);
      44           0 : ERROR_TYPE(File, UnexpectedEOF);
      45             : 
      46             : 
      47             : /**
      48             :  * helper class for writing binary files. this is basically a
      49             :  * resizable buffer that allows adding raw data and strings;
      50             :  * upon calling Write(), everything is written out to disk.
      51             :  **/
      52             : class CFilePacker
      53             : {
      54             : public:
      55             :     /**
      56             :      * adds version and signature (i.e. the header) to the buffer.
      57             :      * this means Write() can write the entire buffer to file in one go,
      58             :      * which is simpler and more efficient than writing in pieces.
      59             :      **/
      60             :     CFilePacker(u32 version, const char magic[4]);
      61             : 
      62             :     ~CFilePacker();
      63             : 
      64             :     /**
      65             :      * write out to file all packed data added so far.
      66             :      * it's safe to call this multiple times, but typically would
      67             :      * only be done once.
      68             :      **/
      69             :     void Write(const VfsPath& filename);
      70             : 
      71             :     /**
      72             :      * pack given number of bytes onto the end of the data stream
      73             :      **/
      74             :     void PackRaw(const void* rawData, size_t rawDataSize);
      75             : 
      76             :     /**
      77             :      * convenience: convert a number (almost always a size type) to
      78             :      * little-endian u32 and pack that.
      79             :      **/
      80             :     void PackSize(size_t value);
      81             : 
      82             :     /**
      83             :      * pack a string onto the end of the data stream
      84             :      * (encoded as a 32-bit length followed by the characters)
      85             :      **/
      86             :     void PackString(const CStr8& str);
      87             : 
      88             : private:
      89             :     /**
      90             :      * the output data stream built during pack operations.
      91             :      * contains the header, so we can write this out in one go.
      92             :      **/
      93             :     WriteBuffer m_writeBuffer;
      94             : };
      95             : 
      96             : 
      97             : /**
      98             :  * helper class for reading binary files
      99             :  **/
     100             : class CFileUnpacker
     101             : {
     102             : public:
     103             :     CFileUnpacker();
     104             :     ~CFileUnpacker();
     105             : 
     106             :     /**
     107             :      * open and read in given file, check magic bits against those given;
     108             :      * throw variety of exceptions if open failed / version incorrect, etc.
     109             :      **/
     110             :     void Read(const VfsPath& filename, const char magic[4]);
     111             : 
     112             :     /**
     113             :      * @return version number that was stored in the file's header.
     114             :      **/
     115          30 :     u32 GetVersion() const
     116             :     {
     117          30 :         return m_version;
     118             :     }
     119             : 
     120             :     /**
     121             :      * unpack given number of bytes from the input into the given array.
     122             :      * throws PSERROR_File_UnexpectedEOF if the end of the data stream is
     123             :      * reached before the given number of bytes have been read.
     124             :      **/
     125             :     void UnpackRaw(void* rawData, size_t rawDataSize);
     126             : 
     127             :     /**
     128             :      * use UnpackRaw to retrieve 32-bits; returns their value as size_t
     129             :      * after converting from little endian to native byte order.
     130             :      **/
     131             :     size_t UnpackSize();
     132             : 
     133             :     /**
     134             :      * unpack a string from the raw data stream.
     135             :      * @param result is assigned a newly constructed CStr8 holding the
     136             :      * string read from the input stream.
     137             :      **/
     138             :     void UnpackString(CStr8& result);
     139             : 
     140             : private:
     141             :     // the data read from file and used during unpack operations
     142             :     std::shared_ptr<u8> m_buf;
     143             :     size_t m_bufSize;
     144             : 
     145             :     size_t m_unpackPos; /// current unpack position in stream
     146             :     u32 m_version;  /// version that was stored in the file header
     147             : };
     148             : 
     149             : #endif

Generated by: LCOV version 1.13