Coverage Report

Created: 2026-08-25 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kdegraphics-mobipocket/lib/pdb.cpp
Line
Count
Source
1
// SPDX-FileCopyrightText: 2008 by Jakub Stachowski <qbast@go2.pl>
2
// SPDX-License-Identifier: GPL-2.0-or-later
3
4
#include "pdb_p.h"
5
6
#include <QIODevice>
7
#include <QtEndian>
8
9
namespace Mobipocket
10
{
11
12
struct PDBPrivate {
13
    PDBPrivate(QIODevice *dev);
14
15
    QIODevice *device;
16
    QByteArray fileType;
17
    QList<quint32> recordOffsets;
18
    bool valid = false;
19
};
20
21
PDBPrivate::PDBPrivate(QIODevice *dev)
22
15.2k
    : device(dev)
23
15.2k
{
24
15.2k
    const auto pdbHead = device->read(0x4e);
25
15.2k
    if (pdbHead.size() < 0x4e)
26
331
        return;
27
28
14.9k
    fileType = pdbHead.mid(0x3c, 8);
29
30
14.9k
    const auto nrecords = qFromBigEndian<quint16>(pdbHead.constData() + 0x4c);
31
14.9k
    const auto recordData = device->read(8 * nrecords);
32
14.9k
    if (recordData.size() < 8 * nrecords)
33
141
        return;
34
35
14.7k
    quint32 lastOffset = 0x4d + 8 * nrecords;
36
32.0k
    for (int i = 0; i < nrecords; i++) {
37
31.4k
        const quint32 offset = qFromBigEndian<quint32>(recordData.constData() + 8 * i);
38
31.4k
        if (offset < lastOffset) {
39
18
            return;
40
18
        }
41
31.4k
        if (offset > dev->size()) {
42
14.1k
            break;
43
14.1k
        }
44
17.2k
        recordOffsets.append(offset);
45
17.2k
        lastOffset = offset;
46
17.2k
    }
47
14.7k
    valid = true;
48
14.7k
}
49
50
15.2k
PDB::~PDB() = default;
51
52
PDB::PDB(QIODevice *device)
53
15.2k
    : d(new PDBPrivate(device))
54
15.2k
{
55
15.2k
}
56
57
QByteArray PDB::getRecord(quint16 i) const
58
37.8k
{
59
37.8k
    if (i >= d->recordOffsets.size()) {
60
6.54k
        return QByteArray();
61
6.54k
    }
62
63
31.3k
    quint32 offset = d->recordOffsets[i];
64
31.3k
    quint32 end = (i + 1 < d->recordOffsets.size()) ? d->recordOffsets[i + 1] : d->device->size();
65
66
31.3k
    if (!d->device->seek(offset))
67
0
        return QByteArray();
68
69
31.3k
    return d->device->read(end - offset);
70
31.3k
}
71
72
QByteArray PDB::fileType() const
73
0
{
74
0
    return d->fileType;
75
0
}
76
77
bool PDB::isValid() const
78
15.2k
{
79
15.2k
    return d->valid;
80
15.2k
}
81
82
quint16 PDB::recordCount() const
83
280
{
84
    // Range guaranteed by constructor/PDB field size
85
280
    return d->recordOffsets.size();
86
280
}
87
88
}