Fix crash when importing partfiles with the "Preallocate space for new files" prefere...
[amule.git] / src / PartFile.h
blobed222131de513196904b7105ea57b4caef9c65cb
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.
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.
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.
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
26 #ifndef PARTFILE_H
27 #define PARTFILE_H
30 #include "KnownFile.h" // Needed for CKnownFile
31 #include "FileAutoClose.h" // Needed for CFileAutoClose
33 #include "OtherStructs.h" // Needed for Requested_Block_Struct
34 #include "DeadSourceList.h" // Needed for CDeadSourceList
35 #include "GapList.h"
37 class CSearchFile;
38 class CMemFile;
39 class CFileDataIO;
40 class CED2KFileLink;
42 //#define BUFFER_SIZE_LIMIT 500000 // Max bytes before forcing a flush
43 #define BUFFER_TIME_LIMIT 60000 // Max milliseconds before forcing a flush
45 // Ok, eMule and aMule are building incompatible backup files because
46 // of the different name. aMule was using ".BAK" and eMule ".bak".
47 // This should fix it.
48 #define PARTMET_BAK_EXT wxT(".bak")
50 enum EPartFileFormat {
51 PMT_UNKNOWN = 0,
52 PMT_DEFAULTOLD,
53 PMT_SPLITTED,
54 PMT_NEWOLD,
55 PMT_SHAREAZA,
56 PMT_BADFORMAT
60 class SFileRating
62 public:
63 wxString UserName;
64 wxString FileName;
65 sint16 Rating;
66 wxString Comment;
67 public:
68 SFileRating(const wxString &u, const wxString &f, sint16 r, const wxString &c);
69 SFileRating(const SFileRating &fr);
70 SFileRating(const CUpDownClient &client);
71 ~SFileRating();
74 typedef std::list<SFileRating> FileRatingList;
76 class SourcenameItem
78 public:
79 wxString name;
80 int count;
81 public:
82 SourcenameItem(const wxString &n = EmptyString, int c = 0)
84 name(n), count(c) {}
87 typedef std::map<uint32,SourcenameItem> SourcenameItemMap;
89 class CPartFile : public CKnownFile {
90 public:
91 typedef std::list<Requested_Block_Struct*> CReqBlockPtrList;
93 CPartFile();
94 #ifdef CLIENT_GUI
95 CPartFile(const CEC_PartFile_Tag *tag);
96 #else
97 virtual void SetFileName(const CPath& filename);
98 #endif
99 CPartFile(CSearchFile* searchresult); //used when downloading a new file
100 CPartFile(const CED2KFileLink* fileLink);
101 virtual ~CPartFile();
103 virtual bool LoadFromFile(const CFileDataIO* WXUNUSED(file)) { return false; }
104 bool WriteToFile(CFileDataIO* WXUNUSED(file)) { return false; }
106 // virtual functions for CKnownFile and CPartFile:
107 bool IsPartFile() const { return status != PS_COMPLETE; } // true if not completed
108 bool IsCompleted() const { return status == PS_COMPLETE; } // true if completed
109 bool IsCPartFile() const { return true; } // true if it's a CPartFile
111 uint32 Process(uint32 reducedownload, uint8 m_icounter);
112 uint8 LoadPartFile(const CPath& in_directory, const CPath& filename, bool from_backup = false, bool getsizeonly = false);
113 bool SavePartFile(bool Initial = false);
114 void PartFileHashFinished(CKnownFile* result);
115 bool HashSinglePart(uint16 partnumber); // true = ok , false = corrupted
117 bool CheckShowItemInGivenCat(int inCategory);
119 bool IsComplete(uint64 start, uint64 end) { return m_gaplist.IsComplete(start, end); }
120 bool IsComplete(uint16 part) { return m_gaplist.IsComplete(part); }
122 void UpdateCompletedInfos();
124 bool GetNextRequestedBlock(CUpDownClient* sender, std::vector<Requested_Block_Struct*>& toadd, uint16& count);
125 void WritePartStatus(CMemFile* file);
126 void WriteCompleteSourcesCount(CMemFile* file);
127 static bool CanAddSource(uint32 userid, uint16 port, uint32 serverip, uint16 serverport, uint8* pdebug_lowiddropped = NULL, bool ed2kID = true);
128 void AddSources(CMemFile& sources, uint32 serverip, uint16 serverport, unsigned origin, bool bWithObfuscationAndHash);
129 #ifdef CLIENT_GUI
130 uint8 GetStatus() const { return status; }
131 uint8 GetStatus(bool /*ignorepause = false*/) const { return status; }
132 #else
133 uint8 GetStatus(bool ignorepause = false) const;
134 #endif
135 virtual void UpdatePartsInfo();
136 const CPath& GetPartMetFileName() const { return m_partmetfilename; }
137 uint16 GetPartMetNumber() const;
138 uint64 GetTransferred() const { return transferred; }
139 const CPath& GetFullName() const { return m_fullname; }
140 float GetKBpsDown() const { return kBpsDown; }
141 double GetPercentCompleted() const { return percentcompleted; }
143 #ifndef CLIENT_GUI
144 uint16 GetSourceCount() const { return (uint16)m_SrcList.size(); }
145 uint16 GetSrcA4AFCount() const { return (uint16)m_A4AFsrclist.size(); }
146 #else
147 uint16 m_source_count, m_a4af_source_count;
148 uint16 GetSourceCount() const { return m_source_count; }
149 uint16 GetSrcA4AFCount() const { return m_a4af_source_count; }
150 #endif
151 uint16 GetTransferingSrcCount() const { return transferingsrc; }
152 uint16 GetNotCurrentSourcesCount() const { return m_notCurrentSources; };
153 uint16 GetValidSourcesCount() const { return m_validSources; };
155 uint64 GetNeededSpace();
157 virtual wxString GetFeedback() const;
159 wxString getPartfileStatus() const; //<<--9/21/02
160 sint32 getTimeRemaining() const; //<<--9/21/02
161 time_t lastseencomplete;
162 int getPartfileStatusRang() const;
164 // Barry - Added as replacement for BlockReceived to buffer data before writing to disk
165 uint32 WriteToBuffer(uint32 transize, byte *data, uint64 start, uint64 end, Requested_Block_Struct *block, const CUpDownClient* client);
166 void FlushBuffer(bool fromAICHRecoveryDataAvailable = false);
168 // Barry - Added to prevent list containing deleted blocks on shutdown
169 void RemoveAllRequestedBlocks(void);
171 void RemoveBlockFromList(uint64 start,uint64 end);
172 void RemoveAllSources(bool bTryToSwap);
173 void Delete();
174 void StopFile(bool bCancel = false);
175 void PauseFile(bool bInsufficient = false);
176 void ResumeFile();
178 virtual CPacket* CreateSrcInfoPacket(const CUpDownClient* forClient, uint8 byRequestedVersion, uint16 nRequestedOptions);
179 void AddClientSources(CMemFile* sources, unsigned nSourceFrom, uint8 uClientSXVersion, bool bSourceExchange2, const CUpDownClient* pClient = NULL);
181 bool PreviewAvailable();
182 uint16 GetAvailablePartCount() const { return m_availablePartsCount; }
183 uint32 GetLastAnsweredTime() const { return m_ClientSrcAnswered; }
184 void SetLastAnsweredTime();
185 void SetLastAnsweredTimeTimeout();
186 uint64 GetLostDueToCorruption() const { return m_iLostDueToCorruption; }
187 uint64 GetGainDueToCompression() const { return m_iGainDueToCompression; }
188 uint32 TotalPacketsSavedDueToICH()const{ return m_iTotalPacketsSavedDueToICH; }
189 bool IsStopped() const { return this ? m_stopped : true; }
190 bool IsPaused() const { return m_paused; }
191 void UpdateFileRatingCommentAvail();
193 int GetCommonFilePenalty();
194 void UpdateDisplayedInfo(bool force = false);
196 uint8 GetCategory() const { return m_category; }
197 void SetCategory(uint8 cat);
198 void RemoveCategory(uint8 cat);
200 void SetDownPriority(uint8 newDownPriority, bool bSave = true, bool bRefresh = true);
201 bool IsAutoDownPriority() const { return m_bAutoDownPriority; }
202 void SetAutoDownPriority(bool flag) { m_bAutoDownPriority = flag; }
203 void UpdateAutoDownPriority();
204 uint8 GetDownPriority() const { return m_iDownPriority; }
205 void SetActive(bool bActive);
206 uint32 GetDlActiveTime() const;
207 bool GetInsufficient() const { return m_insufficient; }
209 void CompleteFileEnded(bool errorOccured, const CPath& newname);
211 bool RemoveSource(CUpDownClient* toremove, bool updatewindow = true, bool bDoStatsUpdate = true);
213 void RequestAICHRecovery(uint16 nPart);
214 void AICHRecoveryDataAvailable(uint16 nPart);
217 * This function is used to update source-counts.
219 * @param oldState The old state of the client, or -1 to ignore.
220 * @param newState The new state of the client, or -1 to ignore.
222 * Call this function for a client belonging to this file, which has changed
223 * its state. The value -1 can be used to make the function ignore one of
224 * the two states.
226 * AddSource and DelSource takes care of calling this function when a source is
227 * removed, so there's no need to call this function when calling either of those.
229 void ClientStateChanged( int oldState, int newState );
231 bool AddSource( CUpDownClient* client );
232 bool DelSource( CUpDownClient* client );
235 * Updates the requency of avilable parts from with the data the client provides.
237 * @param client The clients whoose available parts should be considered.
238 * @param increment If true, the counts are incremented, otherwise they are decremented.
240 * This functions updates the frequency list of file-parts, using the clients
241 * parts-status. This function should be called by clients every time they update their
242 * parts-status, or when they are added or removed from the file.
244 void UpdatePartsFrequency( CUpDownClient* client, bool increment );
246 ArrayOfUInts16 m_SrcpartFrequency;
248 const SourceSet& GetSourceList() const { return m_SrcList; }
249 const SourceSet& GetA4AFList() const { return m_A4AFsrclist; }
250 void ClearA4AFList() { m_A4AFsrclist.clear(); }
252 const CReqBlockPtrList GetRequestedBlockList() const { return m_requestedblocks_list; }
254 const CGapList& GetGapList() const { return m_gaplist; }
257 * Adds a source to the list of dead sources.
259 * @param client The source to be recorded as dead for this file.
261 void AddDeadSource(const CUpDownClient* client);
264 * Set the current progress of hashing and display it in the download list control.
266 * @param part Number of part currently being hashed. 0 for no hashing in progress.
268 virtual void SetHashingProgress(uint16 part) const;
271 * Checks if a source is recorded as being dead for this file.
273 * @param client The client to evaluate.
274 * @return True if dead, false otherwise.
276 * Sources that are dead are not to be considered valid
277 * sources and should not be added to the partfile.
279 bool IsDeadSource(const CUpDownClient* client);
281 /* Kad Stuff */
282 uint16 GetMaxSources() const;
283 uint16 GetMaxSourcePerFileSoft() const;
284 uint16 GetMaxSourcePerFileUDP() const;
286 void GetRatingAndComments(FileRatingList & list) const;
288 void AllocationFinished();
289 private:
290 #ifndef CLIENT_GUI
291 // partfile handle (opened on demand)
292 CFileAutoClose m_hpartfile;
293 //! A local list of sources that are invalid for this file.
294 CDeadSourceList m_deadSources;
296 class CCorruptionBlackBox* m_CorruptionBlackBox;
297 #endif
299 uint16 m_notCurrentSources;
301 uint32 m_validSources;
303 void AddGap(uint64 start, uint64 end);
304 void AddGap(uint16 part);
305 void FillGap(uint64 start, uint64 end);
306 void FillGap(uint16 part);
307 bool GetNextEmptyBlockInPart(uint16 partnumber,Requested_Block_Struct* result);
308 bool IsAlreadyRequested(uint64 start, uint64 end);
309 void CompleteFile(bool hashingdone);
310 void CreatePartFile(bool isImporting = false);
311 void Init();
313 bool CheckFreeDiskSpace( uint64 neededSpace = 0 );
315 bool IsCorruptedPart(uint16 partnumber);
317 uint32 m_iLastPausePurge;
318 uint16 m_count;
319 uint16 transferingsrc;
320 uint64 completedsize;
321 uint64 transferred;
323 uint64 m_iLostDueToCorruption;
324 uint64 m_iGainDueToCompression;
325 uint32 m_iTotalPacketsSavedDueToICH;
326 float kBpsDown;
327 CPath m_fullname; // path/name of the met file
328 CPath m_partmetfilename; // name of the met file
329 CPath m_PartPath; // path/name of the partfile
330 bool m_paused;
331 bool m_stopped;
332 bool m_insufficient;
333 uint8 m_iDownPriority;
334 bool m_bAutoDownPriority;
335 uint8 status;
336 uint32 lastpurgetime;
337 uint32 m_LastNoNeededCheck;
338 CGapList m_gaplist;
339 CReqBlockPtrList m_requestedblocks_list;
340 double percentcompleted;
341 std::list<uint16> m_corrupted_list;
342 uint16 m_availablePartsCount;
343 uint32 m_ClientSrcAnswered;
344 bool m_bPercentUpdated;
346 void PerformFileComplete();
348 uint32 m_lastRefreshedDLDisplay;
350 // Buffered data to be written
351 std::list<class PartFileBufferedData*> m_BufferedData_list;
353 uint32 m_nTotalBufferData;
354 uint32 m_nLastBufferFlushTime;
356 uint8 m_category;
357 uint32 m_nDlActiveTime;
358 time_t m_tActivated;
359 bool m_is_A4AF_auto;
361 SourceSet m_SrcList;
362 SourceSet m_A4AFsrclist;
363 bool m_hashsetneeded;
364 uint32 m_lastsearchtime;
365 bool m_localSrcReqQueued;
367 #ifdef CLIENT_GUI
368 FileRatingList m_FileRatingList;
369 const FileRatingList &GetFileRatingList() { return m_FileRatingList; }
370 void ClearFileRatingList() { m_FileRatingList.clear(); }
371 void AddFileRatingList(const wxString & u, const wxString & f, sint16 r, const wxString & c) {
372 m_FileRatingList.push_back(SFileRating(u, f, r, c)); }
374 uint32 m_kbpsDown;
375 uint8 m_iDownPriorityEC;
376 bool m_isShared;
377 SourcenameItemMap m_SourcenameItemMap;
379 ListOfUInts32 m_A4AFClientIDs;
380 ListOfUInts32 & GetA4AFClientIDs() { return m_A4AFClientIDs; }
381 public:
382 bool IsShared() const { return m_isShared; }
383 SourcenameItemMap &GetSourcenameItemMap() { return m_SourcenameItemMap; }
384 PartFileEncoderData m_PartFileEncoderData;
385 #endif
386 public:
387 bool IsHashSetNeeded() const { return m_hashsetneeded; }
388 void SetHashSetNeeded(bool value) { m_hashsetneeded = value; }
390 uint64 GetCompletedSize() const { return completedsize; }
391 void SetCompletedSize(uint64 size) { completedsize = size; }
393 bool IsLocalSrcRequestQueued() const { return m_localSrcReqQueued; }
394 void SetLocalSrcRequestQueued(bool value) { m_localSrcReqQueued = value; }
396 void AddA4AFSource(CUpDownClient* src) { m_A4AFsrclist.insert(CCLIENTREF(src, wxT("A4AFSource"))); }
397 bool RemoveA4AFSource(CUpDownClient* src) { return (m_A4AFsrclist.erase(CCLIENTREF(src, wxEmptyString)) > 0); }
399 uint32 GetLastSearchTime() const { return m_lastsearchtime; }
400 void SetLastSearchTime(uint32 time) { m_lastsearchtime = time; }
402 void AddDownloadingSource(CUpDownClient* client);
404 void RemoveDownloadingSource(CUpDownClient* client);
405 void SetStatus(uint8 in);
406 void StopPausedFile();
408 // [sivka / Tarod] Imported from eMule 0.30c (Creteil) ...
409 void SetA4AFAuto(bool in) { m_is_A4AF_auto = in; }
410 bool IsA4AFAuto() const { return m_is_A4AF_auto; }
412 // Kry -Sources seeds
413 void SaveSourceSeeds();
414 void LoadSourceSeeds();
416 // Dropping slow sources
417 CUpDownClient* GetSlowerDownloadingClient(uint32 speed, CUpDownClient* caller);
419 // Read data for sharing
420 bool ReadData(class CFileArea & area, uint64 offset, uint32 toread);
422 private:
423 /* downloading sources list */
424 CClientRefList m_downloadingSourcesList;
426 /* Kad Stuff */
427 uint32 m_LastSearchTimeKad;
428 uint8 m_TotalSearchesKad;
430 friend class CKnownFilesRem;
431 friend class CPartFileConvert;
434 #endif // PARTFILE_H
435 // File_checked_for_headers