mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2026-10-23 12:52:51 +00:00
changed TorrentFile from struct to class
This commit is contained in:
1 parent
52ee907ab2
commit
13ca01b35f
4 files changed
+75
-57
No files matched your search
+37
-35
@@ -176,10 +176,10 @@ namespace torrents
|
||||
bool TorrentFile::Save (size_t offset, const uint8_t * buf, size_t len)
|
||||
{
|
||||
Open ();
|
||||
if (f)
|
||||
if (m_File)
|
||||
{
|
||||
f.seekp (offset, std::ios::beg);
|
||||
f.write ((const char *)buf, len);
|
||||
m_File.seekp (offset, std::ios::beg);
|
||||
m_File.write ((const char *)buf, len);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
@@ -189,10 +189,10 @@ namespace torrents
|
||||
bool TorrentFile::Load (size_t offset, uint8_t * buf, size_t len)
|
||||
{
|
||||
Open ();
|
||||
if (f)
|
||||
if (m_File)
|
||||
{
|
||||
f.seekg (offset, std::ios::beg);
|
||||
f.read ((char *)buf, len);
|
||||
m_File.seekg (offset, std::ios::beg);
|
||||
m_File.read ((char *)buf, len);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
@@ -201,35 +201,40 @@ namespace torrents
|
||||
|
||||
void TorrentFile::Complete ()
|
||||
{
|
||||
isPart = false;
|
||||
m_IsPart = false;
|
||||
Close ();
|
||||
}
|
||||
|
||||
void TorrentFile::Open ()
|
||||
{
|
||||
if (!f.is_open ())
|
||||
if (!m_File.is_open ())
|
||||
{
|
||||
auto mode = std::ios::binary | std::ios::in;
|
||||
auto filePath = fullFilePath;
|
||||
if (isPart)
|
||||
auto filePath = m_FullFilePath;
|
||||
if (m_IsPart)
|
||||
{
|
||||
filePath += ".part";
|
||||
mode |= std::ios::out;
|
||||
}
|
||||
f.open (filePath, mode);
|
||||
m_File.open (filePath, mode);
|
||||
}
|
||||
auto ts = i2p::util::GetMonotonicSeconds ();
|
||||
if (ts > lastFlushTime + TORRENT_FILE_FLUSH_INTERVAL)
|
||||
if (ts > m_LastFlushTime + TORRENT_FILE_FLUSH_INTERVAL)
|
||||
{
|
||||
f.flush ();
|
||||
lastFlushTime = ts;
|
||||
m_File.flush ();
|
||||
m_LastFlushTime = ts;
|
||||
}
|
||||
lastAccessTime = ts;
|
||||
m_LastAccessTime = ts;
|
||||
}
|
||||
|
||||
void TorrentFile::Close ()
|
||||
{
|
||||
f.close ();
|
||||
m_File.close ();
|
||||
}
|
||||
|
||||
void TorrentFile::UpdateFullPath (const std::filesystem::path& rootDir)
|
||||
{
|
||||
m_FullFilePath = rootDir/m_FullFilePath;
|
||||
}
|
||||
|
||||
Piece::Piece (size_t size, const uint8_t * hash):
|
||||
@@ -307,7 +312,7 @@ namespace torrents
|
||||
if (m_Data && fragment.fragmentOffset + fragment.fragmentSize <= m_Size)
|
||||
{
|
||||
if (fragment.file->Save (fragment.fileOffset, m_Data + fragment.fragmentOffset, fragment.fragmentSize))
|
||||
LogPrint (eLogDebug, "Torrents: Saved bytes ", fragment.fileOffset, " - ", fragment.fileOffset + fragment.fragmentSize - 1, " to ", fragment.file->fullFilePath);
|
||||
LogPrint (eLogDebug, "Torrents: Saved bytes ", fragment.fileOffset, " - ", fragment.fileOffset + fragment.fragmentSize - 1, " to ", fragment.file->GetFullFilePath ());
|
||||
}
|
||||
m_IsSending = false;
|
||||
}
|
||||
@@ -321,12 +326,12 @@ namespace torrents
|
||||
UpdateDataBuffer (data);
|
||||
if (success)
|
||||
{
|
||||
LogPrint (eLogDebug, "Torrents: Loaded bytes ", fragment.fileOffset, " - ", fragment.fileOffset + fragment.fragmentSize - 1, " from ", fragment.file->fullFilePath);
|
||||
LogPrint (eLogDebug, "Torrents: Loaded bytes ", fragment.fileOffset, " - ", fragment.fileOffset + fragment.fragmentSize - 1, " from ", fragment.file->GetFullFilePath ());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint (eLogError, "Torrents: Failed to load bytes ", fragment.fileOffset, " - ", fragment.fileOffset + fragment.fragmentSize - 1, " from ", fragment.file->fullFilePath);
|
||||
LogPrint (eLogError, "Torrents: Failed to load bytes ", fragment.fileOffset, " - ", fragment.fileOffset + fragment.fragmentSize - 1, " from ", fragment.file->GetFullFilePath ());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -640,13 +645,10 @@ namespace torrents
|
||||
if (len && fileLength && !filePath.empty ())
|
||||
{
|
||||
m_Files.emplace_back (std::make_shared<TorrentFile> (filePath, fileLength));
|
||||
m_Length += fileLength;
|
||||
if (m_Length > MAX_TORRENT_LENGTH)
|
||||
{
|
||||
LogPrint (eLogError, "Torrents: Invalid torent's overall length ", m_Length);
|
||||
if (m_Length + fileLength <= MAX_TORRENT_LENGTH)
|
||||
m_Length += fileLength;
|
||||
else
|
||||
m_Error = eTorrentErrorMalformedMetaInfo;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_Error = eTorrentErrorMalformedMetaInfo;
|
||||
@@ -966,8 +968,8 @@ namespace torrents
|
||||
auto it = m_Files.begin ();
|
||||
while (it != m_Files.end ())
|
||||
{
|
||||
if (offset < (*it)->fileLength) break;
|
||||
offset -= (*it)->fileLength;
|
||||
if (offset < (*it)->GetFileLength ()) break;
|
||||
offset -= (*it)->GetFileLength ();
|
||||
it++;
|
||||
}
|
||||
if (it != m_Files.end ())
|
||||
@@ -977,8 +979,8 @@ namespace torrents
|
||||
while (size > 0)
|
||||
{
|
||||
auto file = *it;
|
||||
file->isPart = !IsComplete ();
|
||||
if (offset + size <= file->fileLength)
|
||||
file->SetIsPart (!IsComplete ());
|
||||
if (offset + size <= file->GetFileLength ())
|
||||
{
|
||||
// last fragment
|
||||
ret.emplace_back (file, offset, fragmentOffset, size);
|
||||
@@ -986,7 +988,7 @@ namespace torrents
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t l = file->fileLength - offset;
|
||||
size_t l = file->GetFileLength () - offset;
|
||||
ret.emplace_back (file, offset, fragmentOffset, l);
|
||||
size -= l; fragmentOffset += l;
|
||||
offset = 0; it++;
|
||||
@@ -1008,22 +1010,22 @@ namespace torrents
|
||||
size_t currentSize = 0, currentCompletedSize = 0;
|
||||
for (const auto& piece: m_Pieces)
|
||||
{
|
||||
if (currentSize + m_PieceLength < (*filesIT)->fileLength)
|
||||
if (currentSize + m_PieceLength < (*filesIT)->GetFileLength ())
|
||||
{
|
||||
currentSize += m_PieceLength;
|
||||
if (piece.IsComplete ()) currentCompletedSize += m_PieceLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t leftoverSize = (*filesIT)->fileLength - currentSize;
|
||||
size_t leftoverSize = (*filesIT)->GetFileLength () - currentSize;
|
||||
if (piece.IsComplete ()) currentCompletedSize += leftoverSize;
|
||||
completed.push_back (currentCompletedSize);
|
||||
currentSize = m_PieceLength - leftoverSize;
|
||||
filesIT++;
|
||||
while (filesIT != m_Files.end () && (*filesIT)->fileLength <= currentSize)
|
||||
while (filesIT != m_Files.end () && (*filesIT)->GetFileLength () <= currentSize)
|
||||
{
|
||||
completed.push_back ((*filesIT)->fileLength);
|
||||
currentSize -= (*filesIT)->fileLength;
|
||||
completed.push_back ((*filesIT)->GetFileLength ());
|
||||
currentSize -= (*filesIT)->GetFileLength ();
|
||||
filesIT++;
|
||||
}
|
||||
currentCompletedSize = piece.IsComplete () ? currentSize : 0;
|
||||
|
||||
+26
-13
@@ -95,21 +95,34 @@ namespace torrents
|
||||
eMessageTypeExtended = 20
|
||||
};
|
||||
|
||||
struct TorrentFile
|
||||
class TorrentFile
|
||||
{
|
||||
std::filesystem::path fullFilePath;
|
||||
size_t fileLength;
|
||||
bool isPart = true;
|
||||
std::fstream f;
|
||||
uint64_t lastAccessTime = 0, lastFlushTime = 0; // monotonic seconds
|
||||
public:
|
||||
|
||||
TorrentFile (const std::filesystem::path & fullFilePath1, size_t fileLength1):
|
||||
fullFilePath (fullFilePath1), fileLength (fileLength1) {};
|
||||
bool Save (size_t offset, const uint8_t * buf, size_t len);
|
||||
bool Load (size_t offset, uint8_t * buf, size_t len);
|
||||
void Complete ();
|
||||
void Open ();
|
||||
void Close ();
|
||||
TorrentFile (const std::filesystem::path & fullFilePath, size_t fileLength):
|
||||
m_FullFilePath (fullFilePath), m_FileLength (fileLength), m_IsPart (true),
|
||||
m_LastAccessTime (0), m_LastFlushTime (0) {};
|
||||
|
||||
bool Save (size_t offset, const uint8_t * buf, size_t len);
|
||||
bool Load (size_t offset, uint8_t * buf, size_t len);
|
||||
void Complete ();
|
||||
void Open ();
|
||||
void Close ();
|
||||
|
||||
const std::filesystem::path& GetFullFilePath () const { return m_FullFilePath; }
|
||||
void SetFullPath (const std::filesystem::path& p) { m_FullFilePath = p; }
|
||||
size_t GetFileLength () const { return m_FileLength; }
|
||||
uint64_t GetLastAccessTime () const { return m_LastAccessTime; }
|
||||
void SetIsPart (bool isPart) { m_IsPart = isPart; }
|
||||
void UpdateFullPath (const std::filesystem::path& rootDir);
|
||||
|
||||
private:
|
||||
|
||||
std::filesystem::path m_FullFilePath;
|
||||
size_t m_FileLength;
|
||||
bool m_IsPart;
|
||||
std::fstream m_File;
|
||||
uint64_t m_LastAccessTime, m_LastFlushTime; // monotonic seconds
|
||||
};
|
||||
|
||||
struct PieceFileFragment // fragment to save to/load from file
|
||||
|
||||
@@ -525,8 +525,8 @@ namespace torrents
|
||||
for (const auto& it: torrentFiles)
|
||||
{
|
||||
boost::json::object file;
|
||||
file["name"] = std::filesystem::relative (it->fullFilePath, torrentsDir).string ();
|
||||
file["length"] = it->fileLength;
|
||||
file["name"] = std::filesystem::relative (it->GetFullFilePath (), torrentsDir).string ();
|
||||
file["length"] = it->GetFileLength ();
|
||||
file["bytesCompleted"] = (ind < filesCompleted.size ()) ? filesCompleted[ind] : 0;
|
||||
files.push_back (file);
|
||||
ind++;
|
||||
|
||||
@@ -167,12 +167,15 @@ namespace torrents
|
||||
bool completed = true;
|
||||
for (auto it: torrent->GetFiles ())
|
||||
{
|
||||
it->fullFilePath = torrent->IsSingleFile () ? torrent->GetFullPath () : torrent->GetFullPath ()/it->fullFilePath;
|
||||
if (!std::filesystem::exists (it->fullFilePath))
|
||||
if (torrent->IsSingleFile ())
|
||||
it->SetFullPath (torrent->GetFullPath ());
|
||||
else
|
||||
it->UpdateFullPath (torrent->GetFullPath ());
|
||||
if (!std::filesystem::exists (it->GetFullFilePath ()))
|
||||
{
|
||||
auto partFilePath = it->fullFilePath; partFilePath += ".part";
|
||||
auto partFilePath = it->GetFullFilePath (); partFilePath += ".part";
|
||||
if (!std::filesystem::exists (partFilePath))
|
||||
CreateAndReserveFile (partFilePath, it->fileLength);
|
||||
CreateAndReserveFile (partFilePath, it->GetFileLength ());
|
||||
completed = false;
|
||||
}
|
||||
}
|
||||
@@ -247,11 +250,11 @@ namespace torrents
|
||||
bool completed = true;
|
||||
for (auto it: torrent->GetFiles ())
|
||||
{
|
||||
auto partFilePath = it->fullFilePath; partFilePath += ".part";
|
||||
auto partFilePath = it->GetFullFilePath (); partFilePath += ".part";
|
||||
if (std::filesystem::exists (partFilePath))
|
||||
{
|
||||
std::error_code ec;
|
||||
std::filesystem::rename (partFilePath, it->fullFilePath, ec);
|
||||
std::filesystem::rename (partFilePath, it->GetFullFilePath (), ec);
|
||||
if (ec)
|
||||
{
|
||||
completed = false;
|
||||
@@ -855,7 +858,7 @@ namespace torrents
|
||||
boost::asio::post (GetDiskIOService (), [torrent = it.second, ts]()
|
||||
{
|
||||
for (auto it: torrent->GetFiles ())
|
||||
if (ts > it->lastAccessTime + TORRENT_FILE_INACTIVITY_TIMEOUT)
|
||||
if (ts > it->GetLastAccessTime () + TORRENT_FILE_INACTIVITY_TIMEOUT)
|
||||
it->Close ();
|
||||
});
|
||||
it.second->SetNextUpdateStatusTime (ts + TORRENTS_STATUS_UPDATE_INTERVAL + GetLocalDestination ()->GetRng ()() % TORRENTS_STATUS_UPDATE_INTERVAL_VARIANCE);
|
||||
|
||||
Reference in new issue
Block a user