1 /*
2  * Copyright (C) 2008-2020 by the Widelands Development Team
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  *
18  */
19 
20 #ifndef WL_IO_FILEWRITE_H
21 #define WL_IO_FILEWRITE_H
22 
23 #include <limits>
24 
25 #include "io/streamwrite.h"
26 
27 class FileSystem;
28 
29 /// Mirror of \ref FileRead : all writes are first stored in a block of memory
30 /// and finally written out when write() is called.
31 class FileWrite : public StreamWrite {
32 public:
33 	struct Pos {
posPos34 		Pos(size_t const p = 0) : pos(p) {
35 		}
36 
37 		/// Returns a special value indicating invalidity.
nullPos38 		static Pos null() {
39 			return std::numeric_limits<size_t>::max();
40 		}
41 
is_nullPos42 		bool is_null() const {
43 			return *this == null();
44 		}
size_tPos45 		operator size_t() const {
46 			return pos;
47 		}
48 		Pos operator++() {
49 			return ++pos;
50 		}
51 		Pos operator+=(const Pos& other) {
52 			return pos += other.pos;
53 		}
54 
55 	private:
56 		size_t pos;
57 	};
58 
59 	struct Exception {};
60 	struct BufferOverflow : public Exception {};
61 
62 	/// Set the buffer to empty.
63 	FileWrite();
64 
65 	/// Clear any remaining allocated data.
66 	~FileWrite() override;
67 
68 	/// Clears the object's buffer.
69 	void clear();
70 
71 	/// Write the file out to disk. If successful, this clears the buffers.
72 	/// Otherwise, an exception is thrown but the buffer remains intact (don't
73 	/// worry, it will be cleared by the destructor).
74 	void write(FileSystem& fs, const std::string& filename);
75 
76 	/// Get the position that will be written to in the next write operation that
77 	/// does not specify a position.
78 	Pos get_pos() const;
79 
80 	/// Set the file pointer to a new location. The position can be beyond the
81 	/// current end of file.
82 	void set_pos(const Pos& pos);
83 
84 	/// Write data at the given location.
85 	void data(const void* src, size_t size, Pos pos);
86 
87 	/// Write data at the current file pointer and advance it.
88 	void data(void const* src, size_t size) override;
89 
90 	/// Returns the current buffer. Use this for in_memory operations.
91 	std::string get_data() const;
92 
93 private:
94 	char* data_;
95 	size_t length_;
96 	size_t max_size_;
97 	Pos filepos_;
98 };
99 
100 #endif  // end of include guard: WL_IO_FILEWRITE_H
101