File: diskfile.h

package info (click to toggle)
mixviews 1.20-10.1
  • links: PTS
  • area: main
  • in suites: potato
  • size: 2,928 kB
  • ctags: 5,960
  • sloc: cpp: 32,879; ansic: 2,110; makefile: 445; sh: 17
file content (254 lines) | stat: -rw-r--r-- 6,893 bytes parent folder | download | duplicates (2)
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
// diskfile.h 

/******************************************************************************
 *
 *  MiXViews - an X window system based sound & data editor/processor
 *
 *  Copyright (c) 1993, 1994 Regents of the University of California
 *
 *  Author:     Douglas Scott
 *  Date:       December 13, 1994
 *
 *  Permission to use, copy and modify this software and its documentation
 *  for research and/or educational purposes and without fee is hereby granted,
 *  provided that the above copyright notice appear in all copies and that
 *  both that copyright notice and this permission notice appear in
 *  supporting documentation. The author reserves the right to distribute this
 *  software and its documentation.  The University of California and the author
 *  make no representations about the suitability of this software for any 
 *  purpose, and in no event shall University of California be liable for any
 *  damage, loss of data, or profits resulting from its use.
 *  It is provided "as is" without express or implied warranty.
 *
 ******************************************************************************/


// DiskFile is the class wrapper for on-disk files or files to be written to
// disk.  It is a modification of the old File class from the Gnu libg++
// distribution.

#ifndef DISKFILE_H
#ifdef __GNUG__
#pragma interface
#endif
#define DISKFILE_H

#include <builtin.h>
#include <stdio.h>
#include <stddef.h>
#include <sys/ioctl.h>
#include <InterViews/resource.h>

// The following should allow the use of the State_value vars instead of
// the integer versions found on the SGI machine

#if defined(sgi) && !defined(__GNUG__)
#define _eof INT_eof
#define _fail INT_fail
#define _bad INT_bad
#include <unistd.h>
#include <fcntl.h>
#endif	/* sgi && !__GNUG__ */

enum State_value                // File states
{ 
  _good         = 0,            // all is well
  _eof          = 1,            // at eof
  _fail         = 2,            // logical or physical IO error
  _bad          = 4             // unopened/corrupted
};

enum io_mode                    // known unix file IO modes
{
  io_readonly   = 0,            
  io_writeonly  = 1,
  io_readwrite  = 2, 
  io_appendonly = 3,
  io_append     = 4            // append, plus allow reads
};

enum access_mode                // ways to open a file
{
  a_createonly  = 0,            // create, fail if file exists
  a_create      = 1,            // create if doesn't exist, else truncate
  a_useonly     = 2,            // use (no truncate)  fail if doesn't exist
  a_use         = 3            // use (no truncate), create if doesn't exist
};

class DiskFile : virtual public Resource {
protected:
	FILE*		fp;              // _iobuf file pointer
	char*		nm;		// file name (dynamically allocated)
	char		rw;		//  1 = read; 2 = write; 3 = readwrite
	State_value	state;		// _good/_eof/_fail/_bad
	MXINT32		stat;		// last read/write/... return value

	void	initialize();
	void	reinitialize(const char*);
	static char* fopen_cmd_arg(io_mode);
public:
	DiskFile();
	virtual		~DiskFile();

// binding, rebinding, unbinding to physical files

	virtual DiskFile&	open(const char* filename, io_mode m, access_mode a);
	virtual DiskFile&	open(const char* filename, const char* m);
	DiskFile& 			reOpen(const char* m);

	virtual DiskFile&	close();
	virtual DiskFile&	remove();
	virtual DiskFile&	rename(const char* newname);

	operator FILE *() { return fp; }
	int	fdesc() const;
	virtual const char*	name();
	void		setname(const char* newname);
	int		iocount();
	int		rdstate();
	int		eof();
	int		fail();
	int		bad();
	int		good();
	
	// other status queries
	
	virtual int	readable() const;
	virtual int	writable();
	virtual int	is_open();
	
	static int exists(const char* filename);
	
	virtual		operator void*();
	
	// error handling
	
	void		error();
	void		clear(State_value f = _good); // poorly named
	void		set(State_value f); // set corresponding but
	void		unset(State_value f); // clear corresponding bit
	DiskFile&		failif(int cond);
	virtual void	check_state();
	
	// binary IO
	
	virtual DiskFile&	read(void* b, int bytes);
	virtual DiskFile&	write(const void* b, int bytes);

	// buffer control

	DiskFile&    setbuf(int buffer_kind); // legal vals: _IONBF, _IOFBF, _IOLBF
	DiskFile&    setbuf(int size, char* buf);
	DiskFile&    raw();
	
	// position control
	
	virtual DiskFile&	seek(MXINT32 pos, int seek_mode=0);
	virtual MXINT32	tell();
};

// error handlers

extern void  verbose_File_error_handler(const char*);
extern void  quiet_File_error_handler(const char*);
extern void  fatal_File_error_handler(const char*);
extern one_arg_error_handler_t File_error_handler;
extern one_arg_error_handler_t set_File_error_handler(one_arg_error_handler_t);

inline int DiskFile::fdesc() const {
	return (fp != 0) ? fileno(fp) : 0;
}

inline const char* DiskFile::name() { 
	return nm; 
}

inline int DiskFile::iocount() { 
	return stat; 
}

inline void DiskFile::clear(State_value flag) { 
	state = flag;
}

inline void DiskFile::set(State_value flag) { 
	state = State_value(int(state) | int(flag));
}

inline void DiskFile::unset(State_value flag) { 
	state = State_value(int(state) & ~int(flag));
}

inline DiskFile& DiskFile::failif(int cond) { 
	if (cond) set(_fail);  return *this; 
}

inline int DiskFile::is_open() { 
	return (fp != 0);
}

inline int DiskFile::rdstate() { 
	check_state();  return state; // check_state is necessary in rare but
}				      // possible circumstances

inline DiskFile::operator void*() { 
	check_state(); return (int(state) & (int(_bad)|int(_fail)))? 0 : this ; 
}

inline int DiskFile::eof() { 
	check_state(); return state & _eof; 
}

inline int DiskFile::fail() { 
	check_state(); return state & _fail; 
}

inline int DiskFile::bad() { 
 	check_state(); return state & _bad; 
}

inline int DiskFile::good() { 
	check_state(); return rdstate() == _good; 
}

inline int DiskFile::readable() const
{ 
  if (fp != 0) {
      if (feof(fp))
	  ((DiskFile &)(*this)).set(_eof); // ugh
      if (ferror(fp))
	  ((DiskFile &)(*this)).set(_bad); // ugh
  }
  return (state == _good && (rw & 01));
}

inline int DiskFile::writable()
{ 
  if (fp != 0 && ferror(fp)) set(_bad);
  return ((int(state) & (int(_fail)|int(_bad))) == 0 && (rw & 02));
}

inline DiskFile& DiskFile::seek(MXINT32 pos, int seek_mode) { 
	return failif(!is_open() || fseek(fp, pos, seek_mode) < 0); 
}

inline MXINT32 DiskFile::tell() { 
	failif(!is_open() || ((stat = ftell(fp)) < 0));
	return stat;
}

inline DiskFile& DiskFile::raw()
{ 
  return this->DiskFile::setbuf(_IONBF); 
}

inline DiskFile& DiskFile::read(void* buf, int bytes) {
	return failif (!readable() || (stat = fread((char *)buf, bytes, 1, fp)) != 1);
}

inline DiskFile& DiskFile::write(const void* buf, int bytes) { 
	return failif (!writable() || (stat = fwrite((const char *)buf, bytes, 1, fp)) != 1);
}

#endif /* DISKFILE_H */