1//
2// This file is part of the aMule Project.
3//
4// Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5// Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6//
7// Any parts of this program derived from the xMule, lMule or eMule project,
8// or contributed by third-party developers are copyrighted by their
9// respective authors.
10//
11// This program is free software; you can redistribute it and/or modify
12// it under the terms of the GNU General Public License as published by
13// the Free Software Foundation; either version 2 of the License, or
14// (at your option) any later version.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
24//
25
26#ifndef MEMFILE_H
27#define MEMFILE_H
28
29#include "SafeFile.h"	// Needed for CFileDataIO
30
31
32/**
33 * CMemFile handles virtual files stored in memory.
34 *
35 * This class allows for manipulation of binary data in memory such
36 * as data sent over networks. Using this class rather than writing
37 * the stream onto a struct confers the following advantages:
38 *  - Contents may be read dynamically in case of various versions
39 *    of the same packet.
40 *  - Endian correction is handled transparently. When reading and
41 *    writing values, CMemFile converts to and from little-endian,
42 *    so that no explicit endian convertions are nescesarry.
43 *  - Strings of dynamic length can be read.
44 *
45 * Most of these advantages also hold for writing packets.
46 *
47 * @see CFileDataIO
48 */
49class CMemFile : public CFileDataIO
50{
51public:
52	/**
53	 * Creates a dynamic file object.
54	 *
55	 * @param growthRate The growth-rate of the buffer.
56	 *
57	 * The growth-rate specified by how much the buffer-size will
58	 * be increased when the memfile runs out of space. Normally
59	 * this means that the amount of re-allocations is cut down
60	 * at the expence of slightly higher mem-usage.
61	 *
62	 * If the size of the entire file to be written is known
63	 * in advance, one can avoid needless re-allocations by
64	 * specifying the exact length as the growth-rate.
65	 *
66	 * If the growth-rate is set to zero, the memfile will allocate
67	 * exactly the needed amount of memory and no more when resizing.
68	 */
69	CMemFile(unsigned int growthRate = 1024);
70
71	/**
72	 * Creates a mem-file attached to an already existing buffer.
73	 *
74	 * @param buffer A pre-existing buffer.
75	 * @param bufferSize The size of the buffer.
76	 *
77	 * A buffer attached to a memfile is assumed to already contain
78	 * data and therefore the file-size is set to match the size of
79	 * of the buffer.
80	 *
81	 * Note that while it is valid to resize the buffer to a length
82	 * between zero and 'bufferSize', it is not valid to resize it
83	 * to a length greater than the length specified in the
84	 * constructor. This also holds for writes that would increase
85	 * the length.
86	 *
87	 * The buffer is _not_ freed by CMemFile upon destruction.
88	 *
89	 * If the buffer is a const byte*, the memfile is read-only.
90	 */
91	CMemFile(byte* buffer, size_t bufferSize);
92	CMemFile(const byte* buffer, size_t bufferSize);
93
94	/** Destructor. */
95	virtual ~CMemFile();
96
97
98	/** @see CFileDataIO::GetPosition */
99	virtual uint64 GetPosition() const;
100
101	/** @see CFileDataIO::GetLength */
102	virtual uint64 GetLength() const;
103
104
105	/**
106	 * Changes the length of the file, possibly resizing the buffer.
107	 *
108	 * @param newLen The new length of the file.
109	 *
110	 * If the current position is greater than the new length, it
111	 * will be set to the end of the file.
112	 *
113	 * Note that changing the lenght of a file with an attached buffer
114	 * to a value greater than the actual buffer size is an illegal
115	 * operation.
116	 */
117	virtual void SetLength(size_t newLen);
118
119	/**
120	 * Resets the memfile to the start.
121	 */
122	virtual void Reset() const { doSeek(0); }
123
124	/**
125	 * Returns the bytes available to read before EOF
126	 */
127	virtual sint64 GetAvailable() const { return GetLength() - GetPosition(); }
128
129	/**
130	 * Resets the memfile to the starting values.
131	 */
132	virtual void ResetData();
133
134	// Sometimes it's useful to get the buffer and do stuff with it.
135	byte* GetRawBuffer() const { return m_buffer; }
136
137protected:
138	/** @see CFileDataIO::doRead */
139	virtual sint64 doRead(void* buffer, size_t count) const;
140
141	/** @see CFileDataIO::doWrite */
142	virtual sint64 doWrite(const void* buffer, size_t count);
143
144	/** @see CFileDataIO::doSeek */
145	virtual sint64 doSeek(sint64 offset) const;
146
147private:
148	//! A CMemFile is neither copyable nor assignable.
149	//@{
150	CMemFile(const CMemFile&);
151	CMemFile& operator=(const CMemFile&);
152	//@}
153
154	/** Enlarges the buffer to at least 'size' length. */
155	void enlargeBuffer(size_t size);
156
157	//! The growth-rate for the buffer.
158	unsigned int m_growthRate;
159	//! The current position in the file.
160	mutable size_t m_position;
161	//! The actual size of the buffer.
162	size_t	m_BufferSize;
163	//! The size of the virtual file, may be less than the buffer-size.
164	size_t	m_fileSize;
165	//! If true, the buffer will be freed upon termination.
166	bool	m_delete;
167	//! read-only mark.
168	bool	m_readonly;
169	//! The actual buffer.
170	byte*	m_buffer;
171};
172
173#endif // MEMFILE_H
174// File_checked_for_headers
175