Coverage Report

Created: 2026-03-12 06:42

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
5.76k
#define CHUNK 16384
17
18
libcdr::CDRInternalStream::CDRInternalStream(const std::vector<unsigned char> &buffer) :
19
3.57k
  librevenge::RVNGInputStream(),
20
3.57k
  m_offset(0),
21
3.57k
  m_buffer(buffer)
22
3.57k
{
23
3.57k
}
24
25
libcdr::CDRInternalStream::CDRInternalStream(librevenge::RVNGInputStream *input, unsigned long size, bool compressed) :
26
22.9k
  librevenge::RVNGInputStream(),
27
22.9k
  m_offset(0),
28
22.9k
  m_buffer()
29
22.9k
{
30
22.9k
  if (!size)
31
199
    return;
32
33
22.7k
  if (!compressed)
34
22.4k
  {
35
22.4k
    unsigned long tmpNumBytesRead = 0;
36
22.4k
    const unsigned char *tmpBuffer = input->read(size, tmpNumBytesRead);
37
38
22.4k
    if (size != tmpNumBytesRead)
39
3.28k
      return;
40
41
19.1k
    m_buffer = std::vector<unsigned char>(size);
42
19.1k
    memcpy(&m_buffer[0], tmpBuffer, size);
43
19.1k
  }
44
300
  else
45
300
  {
46
300
    int ret;
47
300
    z_stream strm;
48
300
    unsigned char out[CHUNK];
49
50
    /* allocate inflate state */
51
300
    strm.zalloc = Z_NULL;
52
300
    strm.zfree = Z_NULL;
53
300
    strm.opaque = Z_NULL;
54
300
    strm.avail_in = 0;
55
300
    strm.next_in = Z_NULL;
56
300
    ret = inflateInit(&strm);
57
300
    if (ret != Z_OK)
58
0
      return;
59
60
300
    unsigned long tmpNumBytesRead = 0;
61
300
    const unsigned char *tmpBuffer = input->read(size, tmpNumBytesRead);
62
63
300
    if (size != tmpNumBytesRead)
64
0
    {
65
0
      (void)inflateEnd(&strm);
66
0
      return;
67
0
    }
68
69
300
    strm.avail_in = (uInt)tmpNumBytesRead;
70
300
    strm.next_in = const_cast<Bytef *>(tmpBuffer);
71
72
300
    do
73
2.93k
    {
74
2.93k
      strm.avail_out = CHUNK;
75
2.93k
      strm.next_out = out;
76
2.93k
      ret = inflate(&strm, Z_NO_FLUSH);
77
2.93k
      switch (ret)
78
2.93k
      {
79
0
      case Z_NEED_DICT:
80
108
      case Z_DATA_ERROR:
81
108
      case Z_MEM_ERROR:
82
108
        (void)inflateEnd(&strm);
83
108
        m_buffer.clear();
84
108
        return;
85
2.82k
      default:
86
2.82k
        break;
87
2.93k
      }
88
89
2.82k
      unsigned have = CHUNK - strm.avail_out;
90
91
43.3M
      for (unsigned long i=0; i<have; i++)
92
43.3M
        m_buffer.push_back(out[i]);
93
94
2.82k
    }
95
2.82k
    while (strm.avail_out == 0);
96
192
    (void)inflateEnd(&strm);
97
192
  }
98
22.7k
}
99
100
const unsigned char *libcdr::CDRInternalStream::read(unsigned long numBytes, unsigned long &numBytesRead)
101
1.57M
{
102
1.57M
  numBytesRead = 0;
103
104
1.57M
  if (numBytes == 0)
105
0
    return nullptr;
106
107
1.57M
  unsigned long numBytesToRead;
108
109
1.57M
  if ((m_offset+numBytes) < m_buffer.size())
110
1.56M
    numBytesToRead = numBytes;
111
4.54k
  else
112
4.54k
    numBytesToRead = m_buffer.size() - m_offset;
113
114
1.57M
  numBytesRead = numBytesToRead; // about as paranoid as we can be..
115
116
1.57M
  if (numBytesToRead == 0)
117
0
    return nullptr;
118
119
1.57M
  long oldOffset = m_offset;
120
1.57M
  m_offset += numBytesToRead;
121
122
1.57M
  return &m_buffer[oldOffset];
123
1.57M
}
124
125
int libcdr::CDRInternalStream::seek(long offset, librevenge::RVNG_SEEK_TYPE seekType)
126
330k
{
127
330k
  if (seekType == librevenge::RVNG_SEEK_CUR)
128
135k
    m_offset += offset;
129
194k
  else if (seekType == librevenge::RVNG_SEEK_SET)
130
156k
    m_offset = offset;
131
37.4k
  else if (seekType == librevenge::RVNG_SEEK_END)
132
37.4k
    m_offset = long(static_cast<unsigned long>(m_buffer.size())) + offset;
133
134
330k
  if (m_offset < 0)
135
0
  {
136
0
    m_offset = 0;
137
0
    return 1;
138
0
  }
139
330k
  if ((long)m_offset > (long)m_buffer.size())
140
54.8k
  {
141
54.8k
    m_offset = m_buffer.size();
142
54.8k
    return 1;
143
54.8k
  }
144
145
275k
  return 0;
146
330k
}
147
148
long libcdr::CDRInternalStream::tell()
149
213k
{
150
213k
  return m_offset;
151
213k
}
152
153
bool libcdr::CDRInternalStream::isEnd()
154
2.78M
{
155
2.78M
  if ((long)m_offset >= (long)m_buffer.size())
156
27.6k
    return true;
157
158
2.75M
  return false;
159
2.78M
}
160
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */