Merge branch 'main' of feistymeow.org:feisty_meow
[feisty_meow.git] / filesystem / byte_filer.h
1 #ifndef BYTE_FILER_CLASS
2 #define BYTE_FILER_CLASS
3
4 /*****************************************************************************\
5 *                                                                             *
6 *  Name   : byte_filer                                                        *
7 *  Author : Chris Koeritz                                                     *
8 *                                                                             *
9 *******************************************************************************
10 * Copyright (c) 2000-$now By Author.  This program is free software; you can  *
11 * redistribute it and/or modify it under the terms of the GNU General Public  *
12 * License as published by the Free Software Foundation; either version 2 of   *
13 * the License or (at your option) any later version.  This is online at:      *
14 *     http://www.fsf.org/copyleft/gpl.html                                    *
15 * Please send any updates to: fred@gruntose.com                               *
16 \*****************************************************************************/
17
18 #include <basis/astring.h>
19 #include <basis/byte_array.h>
20 #include <basis/definitions.h>
21
22 #include "filename.h"
23
24 namespace filesystem {
25
26 // forward declarations.
27 class file_hider;
28
29 //! Provides file managment services using the standard I/O support.
30
31 class byte_filer
32 {
33 public:
34   byte_filer();
35     //!< constructs an object that doesn't access a file yet.
36     /*!< use open() to make the object valid. */
37
38   byte_filer(const basis::astring &fname, const basis::astring &permissions);
39     //!< opens a file "fname" as specified in "permissions".
40     /*!< these are identical to the standard I/O permissions:
41
42     - "r"  - opens text file for reading.
43     - "w"  - opens text file for writing and discards any previous contents.
44     - "a"  - opens text file for writing at end; appends to contents.
45     - "r+" - opens text file for update (both reading and writing).
46     - "w+" - creates a text file for update; any previous contents are lost.
47     - "a+" - opens or creates a text file for update, appending at end.
48
49     a "b" can be added to the end of these to indicate a binary file should
50     be used instead of a text file. */
51
52   byte_filer(const char *fname, const char *permissions);
53     //!< synonym for above but takes char pointers.
54
55   byte_filer(bool auto_close, void *opened);
56     //!< uses a previously "opened" stdio FILE handle.  be careful!
57     /*!< the "opened" object must be a valid FILE pointer; void * is used to
58     avoid pulling in the stdio header.  this method will not close the file
59     handle if "auto_close" is false. */
60
61   ~byte_filer();
62
63   static size_t file_size_limit();
64     //!< returns the maximum size that seek and length can support.
65     /*!< use the huge_file class if you need to exceed the stdio limits. */
66
67   bool open(const basis::astring &fname, const basis::astring &permissions);
68     //!< opens a file with "fname" and "permissions" as in the constructor.
69     /*!< if a different file had already been opened, it is closed. */
70
71   void close();
72     //!< shuts down the open file, if any.
73     /*!< open() will have to be invoked before this object can be used again. */
74
75   const basis::astring &name() const;
76     //!< returns the file name that the object is operating on.
77
78   bool good();
79     //!< returns true if the file seems to be in the appropriate desired state.
80
81   size_t length();
82     //!< returns the file's total length, in bytes.
83     /*!< this cannot accurately report a file length if it is file_size_limit()
84     or greater. */
85
86   size_t tell();
87     //!< returns the current position within the file, in terms of bytes.
88     /*!< this is also limited to file_size_limit(). */
89
90   void flush();
91     //!< forces any pending writes to actually be saved to the file.
92
93   enum origins {
94     FROM_START,    //!< offset is from the beginning of the file.
95     FROM_END,      //!< offset is from the end of the file.
96     FROM_CURRENT   //!< offset is from current cursor position.
97   };
98
99   bool seek(int where, origins origin = FROM_START);
100     //!< places the cursor in the file at "where", based on the "origin".
101     /*!< note that if the origin is FROM_END, then the offset "where" should
102     be a negative number if you're trying to access the interior of the file;
103     positive offsets indicate places after the actual end of the file. */
104
105   bool eof();
106     //!< returns true if the cursor is at (or after) the end of the file.
107
108   int read(basis::abyte *buffer, int buffer_size);
109     //!< reads "buffer_size" bytes from the file into "buffer".
110     /*!< for all of the read and write operations, the number of bytes that
111     is actually processed for the file is returned. */
112   int write(const basis::abyte *buffer, int buffer_size);
113     //!< writes "buffer_size" bytes into the file from "buffer".
114
115   int read(basis::byte_array &buffer, int desired_size);
116     //!< reads "buffer_size" bytes from the file into "buffer".
117   int write(const basis::byte_array &buffer);
118     //!< writes the "buffer" into the file.
119
120   int read(basis::astring &buffer, int desired_size);
121     //!< read() pulls up to "desired_size" bytes from the file into "buffer".
122     /*!< since the read() will grab as much data as is available given that it
123     fits in "desired_size".  null characters embedded in the file are a bad
124     issue here; some other method must be used to read the file instead (such
125     as the byte_array read above).  the "buffer" is shrunk to fit the zero
126     terminator that we automatically add. */
127
128   int write(const basis::astring &buffer, bool add_null = false);
129     //!< stores the string in "buffer" into the file at the current position.
130     /*!< if "add_null" is true, then write() adds a zero terminator to what
131     is written into the file.  otherwise just the string's non-null contents
132     are written. */
133
134   int getline(basis::abyte *buffer, int desired_size);
135     //!< reads a line of text (terminated by a return) into the "buffer".
136   int getline(basis::byte_array &buffer, int desired_size);
137     //!< reads a line of text (terminated by a return) into the "buffer".
138   int getline(basis::astring &buffer, int desired_size);
139     //!< reads a line of text (terminated by a return) into the "buffer".
140
141   bool truncate();
142     //!< truncates the file after the current position.
143
144   void *file_handle();
145     //!< provides a hook to get at the operating system's file handle.
146     /*!< this is of the type FILE *, as defined by <stdio.h>. */
147
148 private:
149   file_hider *_handle;  //!< the standard I/O support that we rely upon.
150   filename *_filename;  //!< holds onto our current filename.
151   bool _auto_close;  //!< true if the object should close the file.
152
153   // not to be called.
154   byte_filer(const byte_filer &);
155   byte_filer &operator =(const byte_filer &);
156 };
157
158 } //namespace.
159
160 #endif
161