blob: faf9164c80f92461cdd272f884b2f9c8826bec9f (
plain) (
blame)
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
|
#include <util/ysaveload.h>
#include "chunked_helpers.h"
TBlob GetBlock(const TBlob& blob, size_t index) {
TChunkedDataReader reader(blob);
if (index >= reader.GetBlocksCount())
ythrow yexception() << "index " << index << " is >= than block count " << reader.GetBlocksCount();
size_t begin = (const char*)reader.GetBlock(index) - (const char*)blob.Data();
return blob.SubBlob(begin, begin + reader.GetBlockLen(index));
}
/*************************** TNamedChunkedDataReader ***************************/
static const char* NamedChunkedDataMagic = "NamedChunkedData";
TNamedChunkedDataReader::TNamedChunkedDataReader(const TBlob& blob)
: TChunkedDataReader(blob)
{
if (TChunkedDataReader::GetBlocksCount() < 1)
throw yexception() << "Too few blocks";
size_t block = TChunkedDataReader::GetBlocksCount() - 1;
size_t magicLen = strlen(NamedChunkedDataMagic);
if (GetBlockLen(block) < magicLen || memcmp(GetBlock(block), NamedChunkedDataMagic, magicLen) != 0)
throw yexception() << "Not a valid named chunked data file";
TMemoryInput input(static_cast<const char*>(GetBlock(block)) + magicLen, GetBlockLen(block) - magicLen);
Load(&input, Names);
size_t index = 0;
for (TVector<TString>::const_iterator it = Names.begin(); it != Names.end(); ++it, ++index) {
if (!it->empty())
NameToIndex[*it] = index;
}
}
/*************************** TNamedChunkedDataWriter ***************************/
TNamedChunkedDataWriter::TNamedChunkedDataWriter(IOutputStream& slave)
: TChunkedDataWriter(slave)
{
}
TNamedChunkedDataWriter::~TNamedChunkedDataWriter() {
}
void TNamedChunkedDataWriter::NewBlock() {
NewBlock("");
}
void TNamedChunkedDataWriter::NewBlock(const TString& name) {
if (!name.empty()) {
if (NameToIndex.count(name) != 0)
throw yexception() << "Block name is not unique";
NameToIndex[name] = Names.size();
}
Names.push_back(name);
TChunkedDataWriter::NewBlock();
}
void TNamedChunkedDataWriter::WriteFooter() {
NewBlock("");
Write(NamedChunkedDataMagic);
Save(this, Names);
TChunkedDataWriter::WriteFooter();
}
|