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 SAFEFILE_H 27 #define SAFEFILE_H 28 29 30 #include <wx/filename.h> // Needed for wxFileName 31 #include <common/MuleDebug.h> // Needef for CMuleException 32 #include "Tag.h" 33 34 namespace Kademlia { 35 class CUInt128; 36 } 37 using Kademlia::CUInt128; 38 class CMD4Hash; 39 40 41 /** 42 * This class provides a interface for safe file IO. 43 * 44 * Basic IO operations will either succeed or throw an exception, 45 * so that failure cannot be ignored. There are currently 3 types 46 * of failures: Read past EOF, errors while reading, and errors 47 * while writing. 48 * 49 * Beyond basic IO, the interface provides functions for reading 50 * and writing a number of simple data-types. These are all written 51 * and read as little-endian in order to allow for communication 52 * across platforms. 53 * 54 * Note that when empty areas are created, for instance by seeking 55 * past the end, then writing, the value of bytes where no data was 56 * explicitly written is not specified. 57 */ 58 class CFileDataIO 59 { 60 public: 61 /** 62 * The Destructor does nothing, but is needed to allow 63 * for safe deletion objects via CFileDataIO pointers. 64 */ 65 virtual ~CFileDataIO(); 66 67 68 /** 69 * Must return the current position in the file. 70 */ 71 virtual uint64 GetPosition() const = 0; 72 73 /** 74 * Must return the length of the file-object in bytes. 75 */ 76 virtual uint64 GetLength() const = 0; 77 78 /** 79 * Returns true when the file-position is past or at the end of the file. 80 */ 81 virtual bool Eof() const; 82 83 84 /** 85 * Changes the file position. 86 * 87 * Note that seeking to an negative position is an illegal operation. 88 * 89 * @see wxFile::Seek 90 */ 91 virtual uint64 Seek(sint64 offset, wxSeekMode from = wxFromStart) const; 92 93 94 /** 95 * Reads 'count' bytes into 'buffer'. 96 * 97 * @param buffer The target buffer. 98 * @param count The number of bytes to read. 99 * 100 * Note that Read will read the specified number of 101 * bytes unless this would read past the end of the 102 * file. In that case, a CEOFException is thrown and 103 * the position and target buffer is left unchanged. 104 * 105 * However, it is also possible that the read will 106 * fail due to IO errors (bad hardware, ect), in which 107 * case an CIOFailureException will be thrown. 108 */ 109 virtual void Read(void* buffer, size_t count) const; 110 111 /** 112 * Write 'count' bytes from 'buffer' into the file. 113 * 114 * @param buffer The source-data buffer. 115 * @param count The number of bytes to write. 116 * 117 * Note that Write will throw a CIOFailureException 118 * if it fails to write the specified number of bytes, 119 * which can be caused by hardware failures, lack of 120 * free space, etc. 121 */ 122 virtual void Write(const void* buffer, size_t count); 123 124 125 /** 126 * Reads the given type from the file, stored as little-endian. 127 * 128 * @see CSafeFileIO::Read 129 */ 130 //@{ 131 virtual uint8 ReadUInt8() const; 132 virtual uint16 ReadUInt16() const; 133 virtual uint32 ReadUInt32() const; 134 virtual uint64 ReadUInt64() const; 135 virtual CUInt128 ReadUInt128() const; 136 virtual CMD4Hash ReadHash() const; 137 virtual float ReadFloat() const; 138 virtual unsigned char* ReadBsob(uint8* size) const; 139 //@} 140 141 /** 142 * Reads a string from the file. 143 * 144 * @param bOptUTF8 Specifies if the string is UTF8 encoded. 145 * @param lenBytes The number of bytes used to store the string length. 146 * @param SafeRead Avoids throwing CEOFException, see below. 147 * @return The resulting text-string. 148 * 149 * Note that when SafeRead is set to true, CSafeFileIO will crop the length 150 * read from the lenght-field (see lenBytes), so that at most GetLength() - 151 * GetPosition() bytes are read. 152 * 153 * @see CSafeFileIO::Read 154 */ 155 virtual wxString ReadString(bool bOptUTF8, uint8 lenBytes = 2, bool SafeRead = false) const; 156 157 /** 158 * Reads a string from the file, where the length is specified directly. 159 * 160 * @param bOptUTF8 Specifies if the string is UTF8 encoded. 161 * @param length The length of the string. 162 * @return The resulting text-string. 163 * 164 * This function is typically used when the text-fields length is not stored 165 * as an integer-field in front of the text-field. 166 */ 167 virtual wxString ReadOnlyString(bool bOptUTF8, uint16 length) const; 168 169 170 /** 171 * Writes a value of the given type to the file, storing it as little-endian. 172 * 173 * @see CSafeFileIO::Write 174 */ 175 //@{ 176 virtual void WriteUInt8(uint8 value); 177 virtual void WriteUInt16(uint16 value); 178 virtual void WriteUInt32(uint32 value); 179 virtual void WriteUInt64(uint64 value); 180 virtual void WriteUInt128(const CUInt128& value); 181 virtual void WriteHash(const CMD4Hash& value); 182 virtual void WriteFloat(float value); 183 virtual void WriteBsob( const unsigned char* val, uint8 size); 184 //@} 185 186 /** 187 * Writes a text-string to the file. 188 * 189 * @param str The string to be written. 190 * @param encoding The text-ecoding, see EUtf8Str. 191 * @param lenBytes The number of bytes used to store the string length. 192 * 193 * Valid values for the 'lenBytes' parameters is 0 bytes (no length field), 194 * 2 bytes and 4 bytes. 195 * 196 * @see CSafeFileIO::Write 197 */ 198 virtual void WriteString(const wxString& str, EUtf8Str encoding = utf8strNone, uint8 lenBytes = 2); 199 200 /* Warning: Special Kad functions, needs documentation */ 201 202 CTag* ReadTag(bool bOptACP = false) const; 203 void ReadTagPtrList(TagPtrList* taglist, bool bOptACP = false) const; 204 205 void WriteTag(const CTag& tag); 206 void WriteTagPtrList(const TagPtrList& tagList); 207 208 /* Special ED2Kv2 function */ 209 uint64 GetIntTagValue() const; 210 211 /* Some functions I added for simplicity */ 212 // Very obvious IsEmpty()213 bool IsEmpty() { return (GetLength() == 0); } 214 215 // Appends to the end Append(const uint8 * buffer,int n)216 void Append(const uint8* buffer, int n) { Seek(0, wxFromEnd); Write(buffer, n); } 217 218 protected: 219 /** 220 * The actual read / write function, as implemented by subclasses. 221 * 222 * @param buffer The buffer to read data into / write data from. 223 * @param count The number of bytes to read / written. 224 * @return The number of bytes read / written or -1 in case of errors. 225 * 226 * Note that the return value must be the actual number of bytes 227 * read or written, with the exception that in case of errors, -1 228 * may be returned. This is because the return value is used to 229 * detect if the operation succeded. 230 * 231 * This function should not throw Either of the CSafeIOExceptions, 232 * this is done by the CSafeFileIO::Read and the CSafeFileIO::Write 233 * functions. 234 */ 235 //@{ 236 virtual sint64 doRead(void* buffer, size_t count) const = 0; 237 virtual sint64 doWrite(const void* buffer, size_t count) = 0; 238 //@} 239 240 /** 241 * The actual seek function, as implemented by subclasses. 242 * 243 * @param offset The absolute offset to seek to. 244 * @return The resulting offset. 245 * 246 * This function should not throw of the CSafeIOExceptions, 247 * this is handled by the CSafeFileIO::Seek. At the moment, 248 * seeks that fail are considered a fatal error. 249 */ 250 virtual sint64 doSeek(sint64 offset) const = 0; 251 252 private: 253 /** 254 * Helper-function that does the actual writing of the string. 255 * 256 * @param str The string to be written. 257 * @param encoding The encoding of the string. 258 * @param lenBytes The number of bytes used to store the string length. 259 * 260 */ 261 void WriteStringCore(const char* str, EUtf8Str encoding, uint8 lenBytes); 262 }; 263 264 265 /** 266 * The base class of IO exceptions used by 267 * the CSafeFileIO interface and implementations 268 * of the interface. 269 */ 270 struct CSafeIOException : public CMuleException 271 { 272 CSafeIOException(const wxString& type, const wxString& desc); 273 }; 274 275 276 /** 277 * This exception is thrown when attempts are 278 * made at reading past the end of the file. 279 * 280 * This typically happens when a invalid packet 281 * is received that is shorter than expected and 282 * is not fatal. 283 */ 284 struct CEOFException : public CSafeIOException { 285 CEOFException(const wxString& desc); 286 }; 287 288 289 /** 290 * This exception reflects a failure in performing 291 * basic IO operations read and write. It will be 292 * thrown in case a read or a write fails to read 293 * or write the specified number of bytes. 294 */ 295 struct CIOFailureException : public CSafeIOException { 296 CIOFailureException(const wxString& type, const wxString& desc); 297 CIOFailureException(const wxString& desc); 298 }; 299 300 301 #endif // SAFEFILE_H 302 // File_checked_for_headers 303