Coverage Report

Created: 2026-08-11 07:29

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
13.3k
    : device(dev)
23
13.3k
{
24
13.3k
    const auto pdbHead = device->read(0x4e);
25
13.3k
    if (pdbHead.size() < 0x4e)
26
317
        return;
27
28
13.0k
    fileType = pdbHead.mid(0x3c, 8);
29
30
13.0k
    const auto nrecords = qFromBigEndian<quint16>(pdbHead.constData() + 0x4c);
31
13.0k
    const auto recordData = device->read(8 * nrecords);
32
13.0k
    if (recordData.size() < 8 * nrecords)
33
173
        return;
34
35
12.8k
    quint32 lastOffset = 0x4d + 8 * nrecords;
36
28.3k
    for (int i = 0; i < nrecords; i++) {
37
27.7k
        const quint32 offset = qFromBigEndian<quint32>(recordData.constData() + 8 * i);
38
27.7k
        if (offset < lastOffset) {
39
27
            return;
40
27
        }
41
27.7k
        if (offset > dev->size()) {
42
12.2k
            break;
43
12.2k
        }
44
15.4k
        recordOffsets.append(offset);
45
15.4k
        lastOffset = offset;
46
15.4k
    }
47
12.8k
    valid = true;
48
12.8k
}
49
50
13.3k
PDB::~PDB() = default;
51
52
PDB::PDB(QIODevice *device)
53
13.3k
    : d(new PDBPrivate(device))
54
13.3k
{
55
13.3k
}
56
57
QByteArray PDB::getRecord(quint16 i) const
58
32.5k
{
59
32.5k
    if (i >= d->recordOffsets.size()) {
60
5.07k
        return QByteArray();
61
5.07k
    }
62
63
27.4k
    quint32 offset = d->recordOffsets[i];
64
27.4k
    quint32 end = (i + 1 < d->recordOffsets.size()) ? d->recordOffsets[i + 1] : d->device->size();
65
66
27.4k
    if (!d->device->seek(offset))
67
0
        return QByteArray();
68
69
27.4k
    return d->device->read(end - offset);
70
27.4k
}
71
72
QByteArray PDB::fileType() const
73
0
{
74
0
    return d->fileType;
75
0
}
76
77
bool PDB::isValid() const
78
13.3k
{
79
13.3k
    return d->valid;
80
13.3k
}
81
82
quint16 PDB::recordCount() const
83
292
{
84
    // Range guaranteed by constructor/PDB field size
85
292
    return d->recordOffsets.size();
86
292
}
87
88
}