File: mediablocklist.h

package info (click to toggle)
libzypp 17.36.7-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 26,380 kB
  • sloc: cpp: 132,576; xml: 2,587; sh: 486; makefile: 26; python: 23
file content (164 lines) | stat: -rw-r--r-- 4,824 bytes parent folder | download | duplicates (2)
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