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>
137 lines
4.6 KiB
C++
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
|