kobodl/pfile.h
Ville Lindholm dbc223eb84
Initial commit
Import existing source tree; original VCS history is no longer available.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-28 16:35:31 +03:00

137 lines
4.6 KiB
C++

/*(LGPL)
---------------------------------------------------------------------------
pfile.h - Portable File Access Toolkit
---------------------------------------------------------------------------
* Copyright (C) 2002, David Olofson
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _PFILE_H_
#define _PFILE_H_
////////////////////////////////////////////////////////////
// Note that these classes can keep track of only one
// chunk at a time! Recursive chunk-inside-chunk is *NOT*
// supported.
////////////////////////////////////////////////////////////
//Create a little endian "FOURCC" ID code. (That is, 'a' will be
//first if the integer result is stored in little endian format
//in a file.)
#define MAKE_4CC(a, b, c, d) \
((a)&0xff | ((b)<<8)&0xff00 | \
((c)<<16)&0xff0000 | ((d)<<24)&0xff000000)
////////////////////////////////////////////////////////////
// pfile_t - Portable File Access Base Class
////////////////////////////////////////////////////////////
// Handles the reading and writing of data from/to file
// via the internal buffer.
//
// Reading can be done either directly from the file, or
// through the internal buffer.
//
// To read through the buffer, the desired number of
// bytes (for example, all bytes of a chunk) must be
// read into the buffer using read_buffer(). Subsequent
// reads will be from the buffer, and end-of-buffer is
// treated like EOF.
//
// Writing is always done to the buffer. To actually
// write data to file, call write_buffer().
//
// IMPORTANT:
// Written data is *lost* if the pfile object
// is destroyed before write_buffer() is called!
//
// Reading RIFF style chunks:
// Use chunk_read() to read the entire chunk into
// the internal buffer. If this succeeds,
// chunk_type() and chunk_size() will return
// information about the chunk, and subsequent
// read() calls will read from the data section of
// the chunk. Use chunk_end() to stop reading, and
// discard the buffer. The next read() will start
// at the first byte after the end of the chunk.
//
// Writing RIFF style chunks:
// Use chunk_write() to set the type of the chunk
// to write. Subsequent write()ing will be done to
// the internal buffer, which will grow as needed.
// Use chunk_end() to write the whole chunk, with
// the correct size and all data. chunk_end() will
// discard the buffer and return the object to
// "direct" operation.
//
class pfile_t
{
FILE *f; //Just a plain file handle...
int _status; // < 0 if there was an error
int bufsize; //Actual malloc()ed size of buffer
int bufused; //Current buffer write position
int bufpos; //Current buffer read position
char *buffer; //Read/write buffer
int chunk_id; //Chunk type ID
int chunk_writing; //1 if we're building a chunk for writing
// Initialize buffer for writing. Subsequent write() calls
// will write to the buffer instead of the file.
int buffer_init();
// Initialize buffer, and read 'len' bytes into it.
// Subsequent read() calls will read from the buffer
// instead of the file.
int buffer_read(int len);
//Unbuffered write operations
int write_ub(void *data, int len);
int write_ub(unsigned int x);
int write_ub(int x);
public:
pfile_t(FILE *file);
virtual ~pfile_t();
int status(); //Read and reset current status.
int status(int new_status); //Set (provided the current status
// >= 0) and return (new) status
//These return # of bytes read, or -1 in case of EOF, or an error.
int read(void *data, int len);
int read(unsigned int &x);
int read(int &x);
void buffer_close(); //Discard the buffer and return to
//"direct" operation.
//These return # of bytes written, or -1 in case of EOF, or an error.
int write(void *data, int len);
int write(unsigned int x);
int write(int x);
int buffer_write(); //Write the whole buffer to the file.
//This will flush the buffer as well.
//RIFF style chunk handling
int chunk_read();
int chunk_type() { return chunk_id; }
int chunk_size() { return bufused; }
int chunk_write(int id);
int chunk_end();
};
#endif