Coverage Report

Created: 2026-04-29 07:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcdr/src/lib/CDRInternalStream.cpp
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/*
3
 * This file is part of the libcdr project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 */
9
10
#include "CDRInternalStream.h"
11
12
#include <zlib.h>
13
#include <string.h>  // for memcpy
14
15
16
8.33k
#define CHUNK 16384
17
18
libcdr::CDRInternalStream::CDRInternalStream(const std::vector<unsigned char> &buffer) :
19
4.26k
  librevenge::RVNGInputStream(),
20
4.26k
  m_offset(0),
21
4.26k
  m_buffer(buffer)
22
4.26k
{
23
4.26k
}
24
25
libcdr::CDRInternalStream::CDRInternalStream(librevenge::RVNGInputStream *input, unsigned long size, bool compressed) :
26
41.8k
  librevenge::RVNGInputStream(),
27
41.8k
  m_offset(0),
28
41.8k
  m_buffer()
29
41.8k
{
30
41.8k
  if (!size)
31
290
    return;
32
33
41.5k
  if (!compressed)
34
41.0k
  {
35
41.0k
    unsigned long tmpNumBytesRead = 0;
36
41.0k
    const unsigned char *tmpBuffer = input->read(size, tmpNumBytesRead);
37
38
41.0k
    if (size != tmpNumBytesRead)
39
9.82k
      return;
40
41
31.2k
    m_buffer = std::vector<unsigned char>(size);
42
31.2k
    memcpy(&m_buffer[0], tmpBuffer, size);
43
31.2k
  }
44
548
  else
45
548
  {
46
548
    int ret;
47
548
    z_stream strm;
48
548
    unsigned char out[CHUNK];
49
50
    /* allocate inflate state */
51
548
    strm.zalloc = Z_NULL;
52
548
    strm.zfree = Z_NULL;
53
548
    strm.opaque = Z_NULL;
54
548
    strm.avail_in = 0;
55
548
    strm.next_in = Z_NULL;
56
548
    ret = inflateInit(&strm);
57
548
    if (ret != Z_OK)
58
0
      return;
59
60
548
    unsigned long tmpNumBytesRead = 0;
61
548
    const unsigned char *tmpBuffer = input->read(size, tmpNumBytesRead);
62
63
548
    if (size != tmpNumBytesRead)
64
0
    {
65
0
      (void)inflateEnd(&strm);
66
0
      return;
67
0
    }
68
69
548
    strm.avail_in = (uInt)tmpNumBytesRead;
70
548
    strm.next_in = const_cast<Bytef *>(tmpBuffer);
71
72
548
    do
73
4.24k
    {
74
4.24k
      strm.avail_out = CHUNK;
75
4.24k
      strm.next_out = out;
76
4.24k
      ret = inflate(&strm, Z_NO_FLUSH);
77
4.24k
      switch (ret)
78
4.24k
      {
79
0
      case Z_NEED_DICT:
80
152
      case Z_DATA_ERROR:
81
152
      case Z_MEM_ERROR:
82
152
        (void)inflateEnd(&strm);
83
152
        m_buffer.clear();
84
152
        return;
85
4.09k
      default:
86
4.09k
        break;
87
4.24k
      }
88
89
4.09k
      unsigned have = CHUNK - strm.avail_out;
90
91
60.7M
      for (unsigned long i=0; i<have; i++)
92
60.7M
        m_buffer.push_back(out[i]);
93
94
4.09k
    }
95
4.09k
    while (strm.avail_out == 0);
96
396
    (void)inflateEnd(&strm);
97
396
  }
98
41.5k
}
99
100
const unsigned char *libcdr::CDRInternalStream::read(unsigned long numBytes, unsigned long &numBytesRead)
101
2.06M
{
102
2.06M
  numBytesRead = 0;
103
104
2.06M
  if (numBytes == 0)
105
0
    return nullptr;
106
107
2.06M
  unsigned long numBytesToRead;
108
109
2.06M
  if ((m_offset+numBytes) < m_buffer.size())
110
2.05M
    numBytesToRead = numBytes;
111
6.87k
  else
112
6.87k
    numBytesToRead = m_buffer.size() - m_offset;
113
114
2.06M
  numBytesRead = numBytesToRead; // about as paranoid as we can be..
115
116
2.06M
  if (numBytesToRead == 0)
117
0
    return nullptr;
118
119
2.06M
  long oldOffset = m_offset;
120
2.06M
  m_offset += numBytesToRead;
121
122
2.06M
  return &m_buffer[oldOffset];
123
2.06M
}
124
125
int libcdr::CDRInternalStream::seek(long offset, librevenge::RVNG_SEEK_TYPE seekType)
126
496k
{
127
496k
  if (seekType == librevenge::RVNG_SEEK_CUR)
128
192k
    m_offset += offset;
129
303k
  else if (seekType == librevenge::RVNG_SEEK_SET)
130
243k
    m_offset = offset;
131
60.1k
  else if (seekType == librevenge::RVNG_SEEK_END)
132
60.1k
    m_offset = long(static_cast<unsigned long>(m_buffer.size())) + offset;
133
134
496k
  if (m_offset < 0)
135
0
  {
136
0
    m_offset = 0;
137
0
    return 1;
138
0
  }
139
496k
  if ((long)m_offset > (long)m_buffer.size())
140
85.0k
  {
141
85.0k
    m_offset = m_buffer.size();
142
85.0k
    return 1;
143
85.0k
  }
144
145
411k
  return 0;
146
496k
}
147
148
long libcdr::CDRInternalStream::tell()
149
329k
{
150
329k
  return m_offset;
151
329k
}
152
153
bool libcdr::CDRInternalStream::isEnd()
154
3.55M
{
155
3.55M
  if ((long)m_offset >= (long)m_buffer.size())
156
49.3k
    return true;
157
158
3.50M
  return false;
159
3.55M
}
160
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */