-
Notifications
You must be signed in to change notification settings - Fork 4
/
OpenCompressedFile.cc
51 lines (39 loc) · 1.23 KB
/
OpenCompressedFile.cc
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
#include "OpenCompressedFile.h"
#include "BlockCache.h"
#include <cstring>
OpenCompressedFile::OpenCompressedFile(const CompressedFile *file,
int openFlags) : mFile(file), mFH(file->path(), openFlags) { }
void OpenCompressedFile::decompressBlock(const Block& b, Buffer& ubuf) const {
mFile->decompressBlock(mFH, b, ubuf);
}
namespace {
class Callback : public BlockCache::Callback {
Mutex mMutex;
off_t& max;
char *buf;
size_t size;
off_t offset;
public:
Callback(off_t& m, char *b, size_t s, off_t o)
: max(m), buf(b), size(s), offset(o) { }
virtual void operator()(const Block& block,
BlockCache::BufPtr& ubuf) {
off_t omin = std::max(offset, off_t(block.uoff)),
omax = std::min(offset + size, block.uoff + block.usize);
size_t bstart = omin - block.uoff,
bsize = omax - omin;
memcpy(buf + omin - offset, &(*ubuf)[bstart], bsize);
Lock lock(mMutex);
if (max < omax)
max = omax;
}
};
}
ssize_t OpenCompressedFile::read(BlockCache& cache,
char *buf, size_t size, off_t offset) const {
off_t max = offset;
CompressedFile::BlockIterator biter = mFile->findBlock(offset);
Callback cb(max, buf, size, offset);
cache.getBlocks(*this, biter, offset + size, cb);
return max - offset;
}