1 /*
2 * HT Editor
3 * stream.h
4 *
5 * Copyright (C) 1999-2002 Stefan Weyergraf (stefan@weyergraf.de)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #ifndef __STREAM_H__
22 #define __STREAM_H__
23
24 #include <stdarg.h>
25 #include <stdio.h>
26
27 #include "data.h"
28 #include "str.h"
29 #include "io/file.h"
30
31 class String;
32
33 /**
34 * A stream.
35 */
36 class Stream {
37 private:
38 IOAccessMode mAccessMode;
39 protected:
40 void checkAccess(IOAccessMode mask);
41 public:
42 Stream();
~Stream()43 virtual ~Stream() {};
44 /* new */
45 virtual FileOfs copyAllTo(Stream *stream);
46 virtual FileOfs copyTo(Stream *stream, FileOfs count);
47 virtual IOAccessMode getAccessMode() const;
48 virtual String & getDesc(String &result) const;
49 virtual uint read(void *buf, uint size);
50 void readx(void *buf, uint size);
51 virtual int setAccessMode(IOAccessMode mode);
52 void setAccessModex(IOAccessMode mode);
53 virtual uint write(const void *buf, uint size);
54 void writex(const void *buf, uint size);
55
56 char * readstrz();
57 bool readStringz(String &s);
58 void writestrz(const char *str);
59
60 char * readstrp();
61 void writestrp(const char *str);
62
63 char * readstrw();
64 void writestrw( const char *str);
65
66 char * readstrl();
67 void writestrl(const char *str);
68 void * readmeml(uint32 &len);
69 void writememl(void *mem, uint32 len);
70 };
71
72 /**
73 * A stream, layering a stream.
74 */
75 class StreamLayer: public Stream {
76 protected:
77 Stream *mStream;
78 bool mOwnStream;
79
80 public:
81
82 StreamLayer(Stream *stream, bool own_stream);
83 virtual ~StreamLayer();
84 /* extends Stream */
85 virtual IOAccessMode getAccessMode() const;
86 virtual String & getDesc(String &result) const;
87 virtual uint read(void *buf, uint size);
88 virtual int setAccessMode(IOAccessMode mode);
89 virtual uint write(const void *buf, uint size);
90 /* new */
91 Stream * getLayered() const;
92 virtual void setLayered(Stream *newLayered, bool ownNewLayered);
93 };
94
95
96 #define OS_FMT_DEC 0
97 #define OS_FMT_HEX 1
98
99 class GetObject;
100
101 /**
102 * A stream-layer, storing/loading |Object|s.
103 */
104 class ObjectStream: public StreamLayer {
105 public:
106 ObjectStream(Stream *stream, bool own_stream);
107 /* new */
108 virtual void getBinary(void *buf, uint size, const char *desc) = 0;
109 virtual bool getBool(const char *desc) = 0;
110 virtual uint64 getInt(uint size, const char *desc) = 0;
111 virtual Object * getObjectInternal(const char *name, ObjectID id = OBJID_INVALID) = 0;
112 GetObject getObject(const char *name, ObjectID id = OBJID_INVALID);
113 virtual char * getString(const char *desc) = 0;
114 virtual byte * getLenString(int &length, const char *desc) = 0;
115
116 virtual void putBinary(const void *mem, uint size, const char *desc) = 0;
117 virtual void putBool(bool b, const char *desc) = 0;
118 virtual void putComment(const char *comment) = 0;
119 virtual void putCommentf(const char *comment_format, ...);
120 virtual void putInt(uint64 i, uint size, const char *desc, uint int_fmt_hint = OS_FMT_DEC) = 0;
121 virtual void putObject(const Object *object, const char *name, ObjectID id = OBJID_INVALID) = 0;
122 virtual void putSeparator() = 0;
123 virtual void putString(const char *string, const char *desc) = 0;
124 virtual void putLenString(const byte *string, int length, const char *desc) = 0;
125
126 virtual void corrupt() = 0;
127 };
128
129 class GetObject {
130 private:
131 friend GetObject ObjectStream::getObject(const char *name, ObjectID id);
132
133 ObjectStream &mO;
134 const char *mName;
135 ObjectID mId;
136
137 GetObject(ObjectStream &o, const char *name, ObjectID id = OBJID_INVALID)
mO(o)138 : mO(o), mName(name), mId(id)
139 {
140 }
141
142 GetObject operator=(const GetObject &); // not implemented
143
144 public:
145 template <typename T> operator T* () const
146 {
147 return static_cast<T*>(mO.getObjectInternal(mName, mId));
148 }
149 };
150
getObject(const char * name,ObjectID id)151 inline GetObject ObjectStream::getObject(const char *name, ObjectID id)
152 {
153 return GetObject(*this, name, id);
154 }
155
156 #define PUTX_BINARY(st, d, size, dstr) (st).putBinary(d, size, dstr)
157 #define PUTX_BOOL(st, d, dstr) (st).putBool(d, dstr)
158 #define PUTX_INT(st, d, size, dstr) (st).putInt(d, size, dstr)
159 #define PUTX_INTD(st, d, size, dstr) (st).putInt(d, size, dstr, OS_FMT_DEC)
160 #define PUTX_INTX(st, d, size, dstr) (st).putInt(d, size, dstr, OS_FMT_HEX)
161 #define PUTX_INT8(st, d, dstr) (st).putInt(d, 1, dstr)
162 #define PUTX_INT8D(st, d, dstr) (st).putInt(d, 1, dstr, OS_FMT_DEC)
163 #define PUTX_INT8X(st, d, dstr) (st).putInt(d, 1, dstr, OS_FMT_HEX)
164 #define PUTX_INT16(st, d, dstr) (st).putInt(d, 2, dstr)
165 #define PUTX_INT16D(st, d, dstr) (st).putInt(d, 2, dstr, OS_FMT_DEC)
166 #define PUTX_INT16X(st, d, dstr) (st).putInt(d, 2, dstr, OS_FMT_HEX)
167 #define PUTX_INT32(st, d, dstr) (st).putInt(d, 4, dstr)
168 #define PUTX_INT32D(st, d, dstr) (st).putInt(d, 4, dstr, OS_FMT_DEC)
169 #define PUTX_INT32X(st, d, dstr) (st).putInt(d, 4, dstr, OS_FMT_HEX)
170 #define PUTX_INT64(st, d, dstr) (st).putInt(d, 8, dstr)
171 #define PUTX_INT64D(st, d, dstr) (st).putInt(d, 8, dstr, OS_FMT_DEC)
172 #define PUTX_INT64X(st, d, dstr) (st).putInt(d, 8, dstr, OS_FMT_HEX)
173 #define PUTX_OBJECT(st, d, dstr) (st).putObject(d, dstr)
174 #define PUTX_STRING(st, d, dstr) (st).putString(d, dstr)
175 #define PUTX_LSTRING(st, d, len, dstr) (st).putLenString(d, len, dstr)
176
177 #define PUT_BINARY(st, d, size) PUTX_BINARY(st, d, size, #d)
178 #define PUT_BOOL(st, d) PUTX_BOOL(st, d, #d)
179 #define PUT_INT(st, d, size) PUTX_INT(st, d, size, #d)
180 #define PUT_INTD(st, d, size) PUTX_INTD(st, d, size, #d)
181 #define PUT_INTX(st, d, size) PUTX_INTX(st, d, size, #d)
182 #define PUT_INT8(st, d) PUTX_INT8(st, d, #d)
183 #define PUT_INT8D(st, d) PUTX_INT8D(st, d, #d)
184 #define PUT_INT8X(st, d) PUTX_INT8X(st, d, #d)
185 #define PUT_INT16(st, d) PUTX_INT16(st, d, #d)
186 #define PUT_INT16D(st, d) PUTX_INT16D(st, d, #d)
187 #define PUT_INT16X(st, d) PUTX_INT16X(st, d, #d)
188 #define PUT_INT32(st, d) PUTX_INT32(st, d, #d)
189 #define PUT_INT32D(st, d) PUTX_INT32D(st, d, #d)
190 #define PUT_INT32X(st, d) PUTX_INT32X(st, d, #d)
191 #define PUT_INT64(st, d) PUTX_INT64(st, d, #d)
192 #define PUT_INT64D(st, d) PUTX_INT64D(st, d, #d)
193 #define PUT_INT64X(st, d) PUTX_INT64X(st, d, #d)
194 #define PUT_OBJECT(st, d) PUTX_OBJECT(st, d, #d)
195 #define PUT_STRING(st, d) PUTX_STRING(st, d, #d)
196 #define PUT_LSTRING(st, d, len) PUTX_LSTRING(st, d, len, #d)
197
198 #define GETX_BINARY(st, d, size, dstr) (st).getBinary(d, size, dstr)
199 #define GETX_BOOL(st, dstr) (st).getBool(dstr)
200 #define GETX_INT(st, size, dstr) (st).getInt(size, dstr)
201 #define GETX_INTD(st, size, dstr) GETX_INT(st, size, dstr)
202 #define GETX_INTX(st, size, dstr) GETX_INT(st, size, dstr)
203 #define GETX_INT8(st, dstr) (st).getInt(1, dstr)
204 #define GETX_INT8D(st, dstr) GETX_INT8(st, dstr)
205 #define GETX_INT8X(st, dstr) GETX_INT8(st, dstr)
206 #define GETX_INT16(st, dstr) (st).getInt(2, dstr)
207 #define GETX_INT16D(st, dstr) GETX_INT16(st, dstr)
208 #define GETX_INT16X(st, dstr) GETX_INT16(st, dstr)
209 #define GETX_INT32(st, dstr) (st).getInt(4, dstr)
210 #define GETX_INT32D(st, dstr) GETX_INT32(st, dstr)
211 #define GETX_INT32X(st, dstr) GETX_INT32(st, dstr)
212 #define GETX_INT64(st, dstr) (st).getInt(8, dstr)
213 #define GETX_INT64D(st, dstr) GETX_INT64(st, dstr)
214 #define GETX_INT64X(st, dstr) GETX_INT64(st, dstr)
215 #define GETX_STRING(st, dstr) (st).getString(dstr)
216 #define GETX_LSTRING(st, size, dstr) (st).getLenString(size, dstr)
217 #define GETX_OBJECT(st, dstr) (st).getObject(dstr)
218
219 #define GET_BINARY(st, d, size) GETX_BINARY(st, d, size, #d)
220 #define GET_BOOL(st, d) d=GETX_BOOL(st, #d)
221 #define GET_INT(st, d, size) d=GETX_INT(st, size, #d)
222 #define GET_INTD(st, d, size) d=GET_INT(st, d, size)
223 #define GET_INTX(st, d, size) d=GET_INT(st, d, size)
224 #define GET_INT8(st, d) d=GETX_INT8(st, #d)
225 #define GET_INT8D(st, d) d=GETX_INT8D(st, #d)
226 #define GET_INT8X(st, d) d=GETX_INT8X(st, #d)
227 #define GET_INT16(st, d) d=GETX_INT16(st, #d)
228 #define GET_INT16D(st, d) d=GETX_INT16D(st, #d)
229 #define GET_INT16X(st, d) d=GETX_INT16X(st, #d)
230 #define GET_INT32(st, d) d=GETX_INT32(st, #d)
231 #define GET_INT32D(st, d) d=GETX_INT32D(st, #d)
232 #define GET_INT32X(st, d) d=GETX_INT32X(st, #d)
233 #define GET_INT64(st, d) d=GETX_INT64(st, #d)
234 #define GET_INT64D(st, d) d=GETX_INT64D(st, #d)
235 #define GET_INT64X(st, d) d=GETX_INT64X(st, #d)
236 #define GET_STRING(st, d) d=GETX_STRING(st, #d)
237 #define GET_LSTRING(st, d, size) d=GETX_LSTRING(st, size, #d)
238 #define GET_OBJECT(st, d) d=GETX_OBJECT(st, #d)
239
240 /**
241 * A object-stream-layer.
242 */
243 class ObjectStreamLayer: public ObjectStream {
244 protected:
245 ObjectStream *mObjStream;
246 public:
247 ObjectStreamLayer(ObjectStream *aObjStream, bool own_ostream);
248 /* extends ObjectStream */
249 virtual void getBinary(void *buf, uint size, const char *desc);
250 virtual bool getBool(const char *desc);
251 virtual uint64 getInt(uint size, const char *desc);
252 virtual Object * getObjectInternal(const char *name, ObjectID id = OBJID_INVALID);
253 virtual char * getString(const char *desc);
254 virtual byte * getLenString(int &length, const char *desc);
255
256 virtual void putBinary(const void *mem, uint size, const char *desc);
257 virtual void putBool(bool b, const char *desc);
258 virtual void putComment(const char *comment);
259 virtual void putInt(uint64 i, uint size, const char *desc, uint int_fmt_hint = OS_FMT_DEC);
260 virtual void putObject(const Object *object, const char *name, ObjectID id = OBJID_INVALID);
261 virtual void putSeparator();
262 virtual void putString(const char *string, const char *desc);
263 virtual void putLenString(const byte *string, int length, const char *desc);
264 };
265
266 /* cntl cmd */
267 #define FCNTL_MODS_INVD 0x00000001
268 #define FCNTL_MODS_FLUSH 0x00000002
269 #define FCNTL_MODS_CLEAR_DIRTY_RANGE 0x00000003 // const FileOfs offset, const FileOfs range
270 #define FCNTL_MODS_IS_DIRTY 0x00000004 // const FileOfs offset, const FileOfs range, bool &isdirty
271 #define FCNTL_CACHE_INVD 0x00000005
272 #define FCNTL_FLUSH_STAT 0x00000006
273 #define FCNTL_GET_RELOC 0x00000007 // bool &enabled
274 #define FCNTL_SET_RELOC 0x00000008 // bool enable
275 #define FCNTL_GET_FD 0x00000009 // int &fd
276
277 // Return a "modification count" that changes, every time the file state
278 // ( content, size, pstat ) changes.
279 // While identical mod-counts imply identical file states,
280 // different mod-counts do not necessarily imply different file states !
281 #define FCNTL_GET_MOD_COUNT 0x00000009 // int &mcount
282
283 #define IS_DIRTY_SINGLEBIT 0x80000000
284
285 /**
286 * A file.
287 */
288 class File: public Stream {
289 protected:
290 int mcount;
291 public:
292 File();
293 /* new */
294 int cntl(uint cmd, ...);
295 virtual void cut(FileOfs size);
296 virtual void extend(FileOfs newsize);
297 virtual String & getFilename(String &result) const;
298 virtual FileOfs getSize() const;
299 virtual void insert(const void *buf, FileOfs size);
300 virtual void pstat(pstat_t &s) const;
301 virtual void seek(FileOfs offset);
302 virtual FileOfs tell() const;
303 virtual void truncate(FileOfs newsize);
304 virtual int vcntl(uint cmd, va_list vargs);
305
306 void move(FileOfs src, FileOfs dest, FileOfs size);
307 char * fgetstrz();
308 String & fgetstrz(String &result);
309 };
310
311 /**
312 * A file, layering a file.
313 */
314 class FileLayer: public File {
315 protected:
316 File *mFile;
317 bool mOwnFile;
318 public:
319 FileLayer(File *file, bool own_file);
320 virtual ~FileLayer();
321 /* extends File */
322 virtual void cut(FileOfs size);
323 virtual void extend(FileOfs newsize);
324 virtual IOAccessMode getAccessMode() const;
325 virtual String & getDesc(String &result) const;
326 virtual String & getFilename(String &result) const;
327 virtual FileOfs getSize() const;
328 virtual void insert(const void *buf, FileOfs size);
329 virtual void pstat(pstat_t &s) const;
330 virtual uint read(void *buf, uint size);
331 virtual void seek(FileOfs offset);
332 virtual int setAccessMode(IOAccessMode mode);
333 virtual FileOfs tell() const;
334 virtual void truncate(FileOfs newsize);
335 virtual int vcntl(uint cmd, va_list vargs);
336 virtual uint write(const void *buf, uint size);
337 /* new */
338 File * getLayered() const;
339 virtual void setLayered(File *newLayered, bool ownNewLayered);
340 };
341
342 /**
343 * A local file (file descriptor [fd]).
344 */
345 class LocalFileFD: public File {
346 protected:
347 String mFilename;
348 FileOpenMode mOpenMode;
349
350 int fd;
351 bool own_fd;
352
353 FileOfs offset;
354
355 int setAccessModeInternal(IOAccessMode mode);
356 public:
357
358 LocalFileFD(const String &aFilename, IOAccessMode mode, FileOpenMode aOpenMode);
359 LocalFileFD(int fd, bool own_fd, IOAccessMode mode);
360 virtual ~LocalFileFD();
361 /* extends File */
362 virtual String & getDesc(String &result) const;
363 virtual String & getFilename(String &result) const;
364 virtual FileOfs getSize() const;
365 virtual uint read(void *buf, uint size);
366 virtual void seek(FileOfs offset);
367 virtual int setAccessMode(IOAccessMode mode);
368 virtual FileOfs tell() const;
369 virtual void truncate(FileOfs newsize);
370 virtual int vcntl(uint cmd, va_list vargs);
371 virtual uint write(const void *buf, uint size);
372 };
373
374 /**
375 * A local file (file stream [FILE*]).
376 */
377 class LocalFile: public File {
378 protected:
379 String mFilename;
380 FileOpenMode mOpenMode;
381
382 SYS_FILE * file;
383 bool own_file;
384
385 FileOfs offset;
386
387 int setAccessModeInternal(IOAccessMode mode);
388 public:
389 LocalFile(const String &aFilename, IOAccessMode mode, FileOpenMode aOpenMode);
390 LocalFile(SYS_FILE *file, bool own_file, IOAccessMode mode);
391 virtual ~LocalFile();
392 /* extends File */
393 virtual String & getDesc(String &result) const;
394 virtual String & getFilename(String &result) const;
395 virtual FileOfs getSize() const;
396 virtual void pstat(pstat_t &s) const;
397 virtual uint read(void *buf, uint size);
398 virtual void seek(FileOfs offset);
399 virtual int setAccessMode(IOAccessMode mode);
400 virtual FileOfs tell() const;
401 virtual void truncate(FileOfs newsize);
402 virtual int vcntl(uint cmd, va_list vargs);
403 virtual uint write(const void *buf, uint size);
404 };
405
406 /**
407 * A temporary file.
408 */
409 class TempFile: public LocalFile {
410 public:
411 TempFile(IOAccessMode mode);
412 /* extends File */
413 virtual String & getDesc(String &result) const;
414 virtual void pstat(pstat_t &s) const;
415 };
416
417 /**
418 * A fixed-size, read-only file, mapping a area of memory.
419 */
420 class ConstMemMapFile: public File {
421 protected:
422 FileOfs ofs, pos;
423 uint size;
424 const void *buf;
425 public:
426 ConstMemMapFile(const void *buf, uint size, FileOfs ofs=0);
427 /* extends File */
428 virtual String & getDesc(String &result) const;
429 virtual FileOfs getSize() const;
430 virtual uint read(void *buf, uint size);
431 virtual void seek(FileOfs offset);
432 virtual FileOfs tell() const;
433 };
434
435 /**
436 * A fixed-size file, mapping a area of memory.
437 */
438 class MemMapFile: public ConstMemMapFile {
439 public:
440 MemMapFile(void *buf, uint size, FileOfs ofs=0);
441 /* extends Stream */
442 virtual uint write(const void *buf, uint size);
443 };
444
445 /**
446 * A (read-only) file with zero-content.
447 */
448 class NullFile: public File {
449 public:
450 NullFile();
451 /* extends File */
452 virtual void extend(FileOfs newsize);
453 virtual String & getDesc(String &result) const;
454 virtual FileOfs getSize() const;
455 virtual void pstat(pstat_t &s) const;
456 virtual uint read(void *buf, uint size);
457 virtual void seek(FileOfs offset);
458 virtual int setAccessMode(IOAccessMode mode);
459 virtual FileOfs tell() const;
460 virtual void truncate(FileOfs newsize);
461 virtual uint write(const void *buf, uint size);
462 };
463
464 /**
465 * A file, existing only in memory.
466 */
467 class MemoryFile: public File {
468 protected:
469 FileOfs ofs;
470 FileOfs pos;
471 uint bufsize, dsize, ibufsize;
472 byte *buf;
473
474 virtual uint extendBufSize(uint bufsize);
475 virtual uint shrinkBufSize(uint bufsize);
476 void extendBuf();
477 void shrinkBuf();
478 void resizeBuf(uint newsize);
479 public:
480 MemoryFile(FileOfs ofs = 0, uint size = 0, IOAccessMode mode = IOAM_READ | IOAM_WRITE);
481 virtual ~MemoryFile();
482 /* extends File */
483 virtual void extend(FileOfs newsize);
484 virtual IOAccessMode getAccessMode() const;
485 virtual String & getDesc(String &result) const;
486 virtual FileOfs getSize() const;
487 virtual void pstat(pstat_t &s) const;
488 virtual uint read(void *buf, uint size);
489 virtual void seek(FileOfs offset);
490 virtual int setAccessMode(IOAccessMode mode);
491 virtual FileOfs tell() const;
492 virtual void truncate(FileOfs newsize);
493 virtual uint write(const void *buf, uint size);
494 /* new */
495 byte * getBufPtr() const;
496 };
497
498 /**
499 * A file layer, representing a cropped version of a file
500 */
501 class CroppedFile: public FileLayer {
502 protected:
503 FileOfs mCropStart;
504 bool mHasCropSize;
505 FileOfs mCropSize;
506 public:
507 // crop [start; start+size-1]
508 CroppedFile(File *file, bool own_file, FileOfs aCropStart, FileOfs aCropSize);
509 // no size, just start
510 CroppedFile(File *file, bool own_file, FileOfs aCropStart);
511 /* extends FileLayer */
512 virtual void extend(FileOfs newsize);
513 virtual String & getDesc(String &result) const;
514 virtual FileOfs getSize() const;
515 virtual void pstat(pstat_t &s) const;
516 virtual uint read(void *buf, uint size);
517 virtual void seek(FileOfs offset);
518 virtual FileOfs tell() const;
519 virtual void truncate(FileOfs newsize);
520 virtual uint write(const void *buf, uint size);
521 };
522
523
524 #endif /* __STREAM_H__ */
525