Coverage Report

Created: 2026-09-28 08:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poppler/glib/poppler-cached-file-loader.cc
Line
Count
Source
1
/* poppler-cached-file-loader.h: glib interface to poppler
2
 *
3
 * Copyright (C) 2012 Carlos Garcia Campos <carlosgc@gnome.org>
4
 * Copyright (C) 2022 Albert Astals Cid <aacid@kde.org>
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 2, or (at your option)
9
 * any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
19
 */
20
21
#include "config.h"
22
#include "poppler-cached-file-loader.h"
23
24
PopplerCachedFileLoader::PopplerCachedFileLoader(GInputStream *inputStreamA, GCancellable *cancellableA, goffset lengthA)
25
0
{
26
0
    inputStream = static_cast<GInputStream *> g_object_ref(inputStreamA);
27
0
    cancellable = cancellableA ? static_cast<GCancellable *> g_object_ref(cancellableA) : nullptr;
28
0
    length = lengthA;
29
0
    cachedFile = nullptr;
30
0
}
31
32
PopplerCachedFileLoader::~PopplerCachedFileLoader()
33
0
{
34
0
    g_object_unref(inputStream);
35
0
    if (cancellable) {
36
0
        g_object_unref(cancellable);
37
0
    }
38
0
}
39
40
size_t PopplerCachedFileLoader::init(CachedFile *cachedFileA)
41
0
{
42
0
    size_t size;
43
0
    gssize bytesRead;
44
0
    char buf[CachedFileChunkSize];
45
46
0
    cachedFile = cachedFileA;
47
48
0
    if (length != static_cast<goffset>(-1)) {
49
0
        return length;
50
0
    }
51
52
0
    if (G_IS_FILE_INPUT_STREAM(inputStream)) {
53
0
        GFileInfo *info;
54
55
0
        info = g_file_input_stream_query_info(G_FILE_INPUT_STREAM(inputStream), G_FILE_ATTRIBUTE_STANDARD_SIZE, cancellable, nullptr);
56
0
        if (!info) {
57
0
            error(errInternal, -1, "Failed to get size.");
58
0
            return static_cast<size_t>(-1);
59
0
        }
60
61
0
        length = g_file_info_get_size(info);
62
0
        g_object_unref(info);
63
64
0
        return length;
65
0
    }
66
67
    // Unknown stream length, read the whole stream and return the size.
68
0
    CachedFileWriter writer = CachedFileWriter(cachedFile, nullptr);
69
0
    size = 0;
70
0
    do {
71
0
        bytesRead = g_input_stream_read(inputStream, buf, CachedFileChunkSize, cancellable, nullptr);
72
0
        if (bytesRead == -1) {
73
0
            break;
74
0
        }
75
76
0
        writer.write(buf, bytesRead);
77
0
        size += bytesRead;
78
0
    } while (bytesRead > 0);
79
80
0
    return size;
81
0
}
82
83
int PopplerCachedFileLoader::load(const std::vector<ByteRange> &ranges, CachedFileWriter *writer)
84
0
{
85
0
    char buf[CachedFileChunkSize];
86
0
    gssize bytesRead;
87
0
    size_t rangeBytesRead, bytesToRead;
88
89
0
    if (length == static_cast<goffset>(-1)) {
90
0
        return 0;
91
0
    }
92
93
0
    for (const ByteRange &range : ranges) {
94
0
        bytesToRead = MIN(CachedFileChunkSize, range.length);
95
0
        rangeBytesRead = 0;
96
0
        g_seekable_seek(G_SEEKABLE(inputStream), range.offset, G_SEEK_SET, cancellable, nullptr);
97
0
        do {
98
0
            bytesRead = g_input_stream_read(inputStream, buf, bytesToRead, cancellable, nullptr);
99
0
            if (bytesRead == -1) {
100
0
                return -1;
101
0
            }
102
103
0
            writer->write(buf, bytesRead);
104
0
            rangeBytesRead += bytesRead;
105
0
            bytesToRead = range.length - rangeBytesRead;
106
0
        } while (bytesRead > 0 && bytesToRead > 0);
107
0
    }
108
109
0
    return 0;
110
0
}