File indexing completed on 2024-11-24 04:31:15

0001 /*
0002     SPDX-FileCopyrightText: 2008 Joris Guisson <joris.guisson@gmail.com>
0003     SPDX-FileCopyrightText: 2008 Ivan Vasic <ivasic@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 #include "piecedata.h"
0008 #include <klocalizedstring.h>
0009 #include <util/log.h>
0010 #ifndef Q_WS_WIN
0011 #include <util/signalcatcher.h>
0012 #endif
0013 #include "chunk.h"
0014 #include <util/error.h>
0015 #include <util/file.h>
0016 #include <util/sha1hashgen.h>
0017 
0018 namespace bt
0019 {
0020 PieceData::PieceData(bt::Chunk *chunk, bt::Uint32 off, bt::Uint32 len, bt::Uint8 *ptr, bt::CacheFile::Ptr cache_file, bool read_only)
0021     : chunk(chunk)
0022     , off(off)
0023     , len(len)
0024     , ptr(ptr)
0025     , cache_file(cache_file)
0026     , read_only(read_only)
0027 {
0028 }
0029 
0030 PieceData::~PieceData()
0031 {
0032     unload();
0033 }
0034 
0035 void PieceData::unload()
0036 {
0037     if (!ptr)
0038         return;
0039 
0040     if (!mapped())
0041         delete[] ptr;
0042     else
0043         cache_file->unmap(ptr, len);
0044     ptr = nullptr;
0045 }
0046 
0047 Uint32 PieceData::write(const bt::Uint8 *buf, Uint32 buf_size, Uint32 off)
0048 {
0049     if (off + buf_size > len || !ptr)
0050         return 0;
0051 
0052     if (read_only)
0053         throw bt::Error(i18n("Unable to write to a piece mapped read only"));
0054 
0055 #ifndef Q_WS_WIN
0056     BUS_ERROR_WPROTECT();
0057 #endif
0058     memcpy(ptr + off, buf, buf_size);
0059     return buf_size;
0060 }
0061 
0062 Uint32 PieceData::read(Uint8 *buf, Uint32 to_read, Uint32 off)
0063 {
0064     if (off + to_read > len || !ptr)
0065         return 0;
0066 
0067 #ifndef Q_WS_WIN
0068     BUS_ERROR_RPROTECT();
0069 #endif
0070     memcpy(buf, ptr + off, to_read);
0071     return to_read;
0072 }
0073 
0074 Uint32 PieceData::writeToFile(File &file, Uint32 size, Uint32 off)
0075 {
0076     if (off + size > len || !ptr)
0077         return 0;
0078 
0079 #ifndef Q_WS_WIN
0080     BUS_ERROR_RPROTECT();
0081 #endif
0082     return file.write(ptr + off, size);
0083 }
0084 
0085 Uint32 PieceData::readFromFile(File &file, Uint32 size, Uint32 off)
0086 {
0087     if (off + size > len || !ptr)
0088         return 0;
0089 
0090     if (read_only)
0091         throw bt::Error(i18n("Unable to write to a piece mapped read only"));
0092 
0093 #ifndef Q_WS_WIN
0094     BUS_ERROR_WPROTECT();
0095 #endif
0096     return file.read(ptr + off, size);
0097 }
0098 
0099 void PieceData::updateHash(SHA1HashGen &hg)
0100 {
0101     if (!ptr)
0102         return;
0103 
0104 #ifndef Q_WS_WIN
0105     BUS_ERROR_RPROTECT();
0106 #endif
0107     hg.update(ptr, len);
0108 }
0109 
0110 SHA1Hash PieceData::generateHash() const
0111 {
0112     if (!ptr)
0113         return SHA1Hash();
0114 
0115 #ifndef Q_WS_WIN
0116     BUS_ERROR_RPROTECT();
0117 #endif
0118     return SHA1Hash::generate(ptr, len);
0119 }
0120 
0121 void PieceData::unmapped()
0122 {
0123     ptr = nullptr;
0124 }
0125 }