File: pfile.h

package info (click to toggle)
kobodeluxe 0.5.1-8
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 4,356 kB
  • ctags: 4,910
  • sloc: ansic: 18,747; cpp: 18,203; sh: 3,192; makefile: 160
file content (136 lines) | stat: -rw-r--r-- 4,754 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*(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