From 13ca01b35ffac54b1982c38c444ef904c105194b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 19 Sep 2026 10:57:55 -0400 Subject: [PATCH] changed TorrentFile from struct to class --- libi2pd_client/Torrents.cpp | 72 ++++++++++++++++--------------- libi2pd_client/Torrents.h | 39 +++++++++++------ libi2pd_client/TorrentsRPC.cpp | 4 +- libi2pd_client/TorrentsTunnel.cpp | 17 +++++--- 4 files changed, 75 insertions(+), 57 deletions(-) diff --git a/libi2pd_client/Torrents.cpp b/libi2pd_client/Torrents.cpp index 6e5b24bd..c1c67526 100644 --- a/libi2pd_client/Torrents.cpp +++ b/libi2pd_client/Torrents.cpp @@ -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 (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; diff --git a/libi2pd_client/Torrents.h b/libi2pd_client/Torrents.h index dabea4bd..e4e1c212 100644 --- a/libi2pd_client/Torrents.h +++ b/libi2pd_client/Torrents.h @@ -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 diff --git a/libi2pd_client/TorrentsRPC.cpp b/libi2pd_client/TorrentsRPC.cpp index ab7373ec..665d610e 100644 --- a/libi2pd_client/TorrentsRPC.cpp +++ b/libi2pd_client/TorrentsRPC.cpp @@ -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++; diff --git a/libi2pd_client/TorrentsTunnel.cpp b/libi2pd_client/TorrentsTunnel.cpp index 4ded6f3e..1e53d314 100644 --- a/libi2pd_client/TorrentsTunnel.cpp +++ b/libi2pd_client/TorrentsTunnel.cpp @@ -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);