Coverage Report

Created: 2026-07-30 07:17

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