1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
/*---------------------------------------------------------------------\
| ____ _ __ __ ___ |
| |__ / \ / / . \ . \ |
| / / \ V /| _/ _/ |
| / /__ | | | | | | |
| /_____||_| |_| |_| |
| |
\---------------------------------------------------------------------*/
/** \file zypp-curl/parser/MediaBlockList
*
*/
#ifndef ZYPP_CURL_PARSER_MEDIABLOCKLIST_H
#define ZYPP_CURL_PARSER_MEDIABLOCKLIST_H
#include <sys/types.h>
#include <vector>
#include <optional>
#include <zypp-core/Digest.h>
namespace zypp {
namespace media {
/**
* a single block from the blocklist, consisting of an offset and a size
**/
struct MediaBlock {
MediaBlock( off_t off_r, size_t size_r )
: off( off_r )
, size( size_r )
{}
off_t off;
size_t size;
};
class MediaBlockList {
public:
MediaBlockList(off_t filesize=off_t(-1));
/**
* do we have a blocklist describing the file?
* set to true when addBlock() is called
**/
inline bool haveBlocks() const {
return haveblocks;
}
/**
* add a block with offset off and size size to the block list. Note
* that blocks must be ordered and must not overlap. returns the
* block number.
**/
size_t addBlock(off_t off, size_t size);
/**
* return the offset/size of a block with number blkno
**/
inline const MediaBlock &getBlock(size_t blkno) const {
return blocks[blkno];
}
/**
* return the number of blocks in the blocklist
**/
inline size_t numBlocks() const {
return blocks.size();
}
/**
* set / return the size of the whole file
**/
inline void setFilesize(off_t newfilesize=off_t(-1)) {
filesize = newfilesize;
}
inline off_t getFilesize() const {
return filesize;
}
inline bool haveFilesize() const {
return filesize != off_t(-1);
}
/**
* set / verify the checksum over the whole file
**/
void setFileChecksum(std::string ctype, int cl, unsigned char *c);
std::string fileChecksumType () const;
const UByteArray &getFileChecksum( );
bool createFileDigest(Digest &digest) const;
bool verifyFileDigest(Digest &digest) const;
inline bool haveFileChecksum() const {
return !fsumtype.empty() && fsum.size();
}
/**
* set / verify the (strong) checksum over a single block
**/
void setChecksum(size_t blkno, const std::string& cstype, int csl, unsigned char *cs, size_t cspad=0);
bool checkChecksum(size_t blkno, const unsigned char *buf, size_t bufl) const;
UByteArray getChecksum( size_t blkno ) const;
std::string getChecksumType( ) const;
size_t checksumPad() const;
bool createDigest(Digest &digest) const;
bool verifyDigest(size_t blkno, Digest &digest) const;
inline bool haveChecksum(size_t blkno) const {
return chksumlen && chksums.size() >= chksumlen * (blkno + 1);
}
/**
* set / verify the (weak) rolling checksum over a single block
**/
void setRsum(size_t blkno, int rsl, unsigned int rs, size_t rspad=0);
/**
* how many blocks in sequence need to have the correct checksums to be
* considered a match
*/
void setRsumSequence( uint seq );
bool checkRsum(size_t blkno, const unsigned char *buf, size_t bufl) const;
unsigned int updateRsum(unsigned int rs, const char *bytes, size_t len) const;
bool verifyRsum(size_t blkno, unsigned int rs) const;
inline bool haveRsum(size_t blkno) const {
return rsumlen && rsums.size() >= blkno + 1;
}
/**
* scan a file for blocks from our blocklist. if we find a suitable block,
* it is removed from the list
**/
void reuseBlocksOld(FILE *wfp, const std::string& filename);
void reuseBlocks(FILE *wfp, const std::string& filename);
/**
* return block list as string
**/
std::string asString() const;
private:
void writeBlock(size_t blkno, FILE *fp, const unsigned char *buf, size_t bufl, size_t start, std::vector<bool> &found) const;
bool checkChecksumRotated(size_t blkno, const unsigned char *buf, size_t bufl, size_t start) const;
off_t filesize;
std::string fsumtype;
UByteArray fsum;
bool haveblocks;
std::vector<MediaBlock> blocks;
std::string chksumtype;
int chksumlen;
size_t chksumpad;
std::vector<unsigned char> chksums;
int rsumlen;
uint rsumseq; // < how many consecutive matches are required
size_t rsumpad;
std::vector<unsigned int> rsums;
};
inline std::ostream & operator<<(std::ostream &str, const MediaBlockList &bl)
{ return str << bl.asString(); }
} // namespace media
} // namespace zypp
#endif // ZYPP_CURL_PARSER_MEDIABLOCKLIST_H
|