aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/vespa/searchlib/util/filesizecalculator.cpp
blob: 7b5ef8ec1bad0746cc8b548da64709305d0b2847 (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
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "filesizecalculator.h"
#include <vespa/vespalib/data/fileheader.h>
#include <cinttypes>
#include <vespa/log/log.h>
LOG_SETUP(".searchlib.util.filesizecalculator");


namespace search {

namespace {

const vespalib::string fileBitSizeTag = "fileBitSize";

bool byteAligned(uint64_t bitSize)
{
    return ((bitSize % 8) == 0);
}

}

bool
FileSizeCalculator::extractFileSize(const vespalib::GenericHeader &header,
                                    size_t headerLen,
                                    vespalib::string fileName, uint64_t &fileSize)
{
    if (!header.hasTag(fileBitSizeTag)) {
        return true;
    }
    uint64_t fileBitSize = header.getTag(fileBitSizeTag).asInteger();
    uint64_t fileByteSize = fileBitSize / 8;
    if (!byteAligned(fileBitSize)) {
        LOG(error,
            "Bad header file size tag for %s, fileBitSize=%" PRIu64 " which is not a multiple of 8",
            fileName.c_str(), fileBitSize);
        return false;
    }
    if (fileByteSize < headerLen) {
        LOG(error,
            "Bad header file size tag for %s, fileBitSize=%" PRIu64 " but header is %zu bits",
            fileName.c_str(), fileBitSize, headerLen * 8);
        return false;
    }
    if (fileByteSize > fileSize) {
        LOG(error,
            "Bad header file size tag for %s, fileBitSize=%" PRIu64 " but whole file size is %" PRIu64 " bits",
            fileName.c_str(), fileBitSize, fileSize * 8);
        return false;
    }
    fileSize = fileByteSize;
    return true;
}

}