1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #ifndef __I4FILE_HPP
|
---|
10 | #define __I4FILE_HPP
|
---|
11 |
|
---|
12 | #include "arch.hh"
|
---|
13 | #include "isllist.hh"
|
---|
14 |
|
---|
15 |
|
---|
16 | enum { I4_FILE_STATUS_DIRECTORY=1};
|
---|
17 | struct i4_file_status_struct
|
---|
18 | {
|
---|
19 | w32 last_modified;
|
---|
20 | w32 last_accessed;
|
---|
21 | w32 created;
|
---|
22 | w32 flags;
|
---|
23 | } ;
|
---|
24 |
|
---|
25 | // Summary
|
---|
26 | // A file (i4_file_class) is a purely virtual file
|
---|
27 | // which should allow much flexability.
|
---|
28 | // A i4_file_class is opened through the i4_file_manager_class::open().
|
---|
29 |
|
---|
30 | // A file manager defaults going through the operating system's open(), but
|
---|
31 | // like the unix model other file managers can be mounted on top of directories.
|
---|
32 | // When a file is accessed in this directory, the open call will be transfered
|
---|
33 | // to this file manager.
|
---|
34 |
|
---|
35 | // This allows for redirection, tar-like-files, memory-files, and other goodies.
|
---|
36 |
|
---|
37 | // One particular instance this is useful, might be running game off of a cdrom.
|
---|
38 | // the data directory can be linked to the cdrom and the savegame data can
|
---|
39 | // be linked to somewhere on the hard-drive.
|
---|
40 |
|
---|
41 | // i.e.
|
---|
42 |
|
---|
43 | // i4_file_man.mount_dir("/cdrom",new file_redirector("d:\\"));
|
---|
44 | // i4_file_class *fp=i4_file_man.open("/cdrom/art/picture.pcx");
|
---|
45 |
|
---|
46 |
|
---|
47 | // TODO : test mounting, now that all string are i4_const_str instead of char *
|
---|
48 |
|
---|
49 | class i4_const_str;
|
---|
50 | class i4_str;
|
---|
51 |
|
---|
52 | class i4_file_class
|
---|
53 | {
|
---|
54 | public:
|
---|
55 | virtual w32 read (void *buffer, w32 size) = 0;
|
---|
56 | virtual w32 write(const void *buffer, w32 size) = 0;
|
---|
57 | virtual w32 seek (w32 offset) = 0;
|
---|
58 | virtual w32 size () = 0;
|
---|
59 | virtual w32 tell () = 0;
|
---|
60 |
|
---|
61 | i4_bool eof() { return tell()==size(); }
|
---|
62 |
|
---|
63 | typedef void (*async_callback)(w32 count, void *context);
|
---|
64 |
|
---|
65 | // returns i4_F if an immediate error occured
|
---|
66 | virtual i4_bool async_read (void *buffer, w32 size,
|
---|
67 | async_callback call,
|
---|
68 | void *context=0);
|
---|
69 |
|
---|
70 | virtual i4_bool async_write(const void *buffer, w32 size,
|
---|
71 | async_callback call,
|
---|
72 | void *context=0);
|
---|
73 |
|
---|
74 | // abort current operation
|
---|
75 | virtual void abort() {}
|
---|
76 |
|
---|
77 | // Nice Read Methods
|
---|
78 | w8 read_8 ()
|
---|
79 | {
|
---|
80 | w8 buf;
|
---|
81 | if (read(&buf,1)!=1)
|
---|
82 | return 0xff;
|
---|
83 | else return buf;
|
---|
84 | }
|
---|
85 |
|
---|
86 | w16 read_16 () // loads and converts to LSB (intel-format)
|
---|
87 | {
|
---|
88 | w16 buf;
|
---|
89 | if (read(&buf,2)!=2)
|
---|
90 | return 0xffff;
|
---|
91 | else return s_to_lsb(buf);
|
---|
92 | }
|
---|
93 |
|
---|
94 | w32 read_32 () // loads and converts to LSB (intel-format)
|
---|
95 | {
|
---|
96 | w32 buf;
|
---|
97 | if (read(&buf,4)!=4)
|
---|
98 | return 0xffffffff;
|
---|
99 | else return l_to_lsb(buf);
|
---|
100 | }
|
---|
101 |
|
---|
102 | float read_float() // loads and converts to LSB (intel-format)
|
---|
103 | {
|
---|
104 | w32 buf;
|
---|
105 | if (read(&buf,4)!=4)
|
---|
106 | return (float)0xffff;
|
---|
107 |
|
---|
108 | buf = l_to_lsb(buf);
|
---|
109 |
|
---|
110 | return *((float*)&buf);
|
---|
111 | }
|
---|
112 |
|
---|
113 | i4_str* read_str(w32 len);
|
---|
114 | i4_str* read_counted_str();
|
---|
115 |
|
---|
116 | // C++ stream operators
|
---|
117 | i4_file_class& operator>>(w32& v) { v = (w32) read_32(); return *this; }
|
---|
118 | i4_file_class& operator>>(sw32& v) { v = (sw32)read_32(); return *this; }
|
---|
119 | i4_file_class& operator>>(w16& v) { v = (w16) read_16(); return *this; }
|
---|
120 | i4_file_class& operator>>(sw16& v) { v = (sw16)read_16(); return *this; }
|
---|
121 | i4_file_class& operator>>(w8& v) { v = (w8) read_8(); return *this; }
|
---|
122 | i4_file_class& operator>>(sw8& v) { v = (sw8) read_8(); return *this; }
|
---|
123 | i4_file_class& operator>>(float& v) { v = read_float(); return *this; }
|
---|
124 |
|
---|
125 | // Nice Write Methods
|
---|
126 | w32 write_8 (w8 num)
|
---|
127 | {
|
---|
128 | return (write(&num,1));
|
---|
129 | }
|
---|
130 |
|
---|
131 | w32 write_16 (w16 num) // loads and converts to LSB (intel-format)
|
---|
132 | {
|
---|
133 | num = s_to_lsb(num);
|
---|
134 | return (write(&num,2));
|
---|
135 | }
|
---|
136 |
|
---|
137 | w32 write_32 (w32 num) // loads and converts to LSB (intel-format)
|
---|
138 | {
|
---|
139 | num = l_to_lsb(num);
|
---|
140 | return (write(&num,4));
|
---|
141 | }
|
---|
142 |
|
---|
143 | w32 write_float(float num) // loads and converts to LSB (intel-format)
|
---|
144 | {
|
---|
145 | w32 tmp = l_to_lsb( *((w32*)&num) );
|
---|
146 | return (write(&tmp,4));
|
---|
147 | }
|
---|
148 |
|
---|
149 | w32 write_str(const i4_const_str &str);
|
---|
150 | w32 write_counted_str(const i4_const_str &str);
|
---|
151 |
|
---|
152 | // same as fprintf, but with the addition %S is a i4_const_str *
|
---|
153 | int printf(char *format, ...);
|
---|
154 |
|
---|
155 | // write_format takes a different set of % symbols than the typical printf to elimante
|
---|
156 | // confusion with sizes and be easily usuable with readf_binary
|
---|
157 | // writef_binary("124fS", &a_w8_var, &a_w16_var, &a_w32_var,
|
---|
158 | // &a_float_var, &a_i4_const_str_pointer);
|
---|
159 | int write_format(char *format, ...);
|
---|
160 |
|
---|
161 | // format is same as write_format
|
---|
162 | int read_format(char *format, ...);
|
---|
163 |
|
---|
164 |
|
---|
165 |
|
---|
166 | // C++ stream operators
|
---|
167 | i4_file_class& operator<<(w32 v) { write_32(v); return *this; }
|
---|
168 | i4_file_class& operator<<(sw32 v) { write_32((w32)v); return *this; }
|
---|
169 | i4_file_class& operator<<(w16 v) { write_16(v); return *this; }
|
---|
170 | i4_file_class& operator<<(sw16 v) { write_16((w16)v); return *this; }
|
---|
171 | i4_file_class& operator<<(w8 v) { write_8(v); return *this; }
|
---|
172 | i4_file_class& operator<<(sw8 v) { write_8((w8)v); return *this; }
|
---|
173 | i4_file_class& operator<<(float v) { write_float(v); return *this; }
|
---|
174 |
|
---|
175 | virtual ~i4_file_class() {}
|
---|
176 | };
|
---|
177 |
|
---|
178 |
|
---|
179 | // open flags
|
---|
180 | enum { I4_READ=1,
|
---|
181 | I4_WRITE=2,
|
---|
182 | I4_APPEND=4,
|
---|
183 | I4_NO_BUFFER=8,
|
---|
184 | I4_SUPPORT_ASYNC=16 // this flag is needed if you intend to call async_read/write
|
---|
185 | };
|
---|
186 |
|
---|
187 | // returns NULL if unable to open file
|
---|
188 | i4_file_class *i4_open(const i4_const_str &name, w32 flags=I4_READ);
|
---|
189 |
|
---|
190 | // return i4_F on failure
|
---|
191 | i4_bool i4_unlink(const i4_const_str &name);
|
---|
192 |
|
---|
193 | // returns i4_F if file does not exsist
|
---|
194 | i4_bool i4_get_status(const i4_const_str &filename,
|
---|
195 | i4_file_status_struct &return_stat);
|
---|
196 |
|
---|
197 | // return i4_F on failure
|
---|
198 | i4_bool i4_mkdir(const i4_const_str &path);
|
---|
199 | i4_bool i4_rmdir(const i4_const_str &path);
|
---|
200 | i4_bool i4_chdir(const i4_const_str &path);
|
---|
201 |
|
---|
202 | struct i4_directory_struct
|
---|
203 | {
|
---|
204 | i4_str **files;
|
---|
205 | w32 tfiles;
|
---|
206 |
|
---|
207 | i4_str **dirs;
|
---|
208 | w32 tdirs;
|
---|
209 |
|
---|
210 | i4_file_status_struct *file_status; // array of file stats coresponding to above files
|
---|
211 |
|
---|
212 | i4_directory_struct() { tfiles=tdirs=0; files=dirs=0; file_status=0; }
|
---|
213 | ~i4_directory_struct();
|
---|
214 | };
|
---|
215 |
|
---|
216 | // returns i4_F if path is bad (tfiles and tdirs will be 0 as well)
|
---|
217 | // you are responsible for deleting both the array of strings and each string in the array
|
---|
218 | // file_status is a pointer to an array of file_status's that will be created, you
|
---|
219 | // must free these as well. file_status may be 0 (default), in which case no array is created
|
---|
220 | class i4_status_class;
|
---|
221 | i4_bool i4_get_directory(const i4_const_str &path,
|
---|
222 | i4_directory_struct &dir_struct,
|
---|
223 | i4_bool get_status=i4_F,
|
---|
224 | i4_status_class *status=0);
|
---|
225 |
|
---|
226 |
|
---|
227 |
|
---|
228 | struct i4_filename_struct
|
---|
229 | {
|
---|
230 | char path[256];
|
---|
231 | char filename[256];
|
---|
232 | char extension[256];
|
---|
233 |
|
---|
234 | i4_filename_struct() { path[0]=0; filename[0]=0; extension[0]=0; }
|
---|
235 | };
|
---|
236 |
|
---|
237 | // returns i4_F if path cannot be split
|
---|
238 | i4_bool i4_split_path(const i4_const_str &name, i4_filename_struct &fname_struct);
|
---|
239 |
|
---|
240 | // return 0 if full path cannot be determined
|
---|
241 | i4_str *i4_full_path(const i4_const_str &relative_name);
|
---|
242 |
|
---|
243 | // returns the shortest relative path
|
---|
244 | i4_str *i4_relative_path(const i4_const_str &path);
|
---|
245 |
|
---|
246 |
|
---|
247 |
|
---|
248 | #endif
|
---|
249 |
|
---|