Coverage Report

Created: 2026-07-20 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libe-book/src/lib/ZVRParser.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 libe-book 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 <algorithm>
11
12
#include <librevenge/librevenge.h>
13
#include <librevenge-stream/librevenge-stream.h>
14
15
#include "libebook_utils.h"
16
#include "EBOOKMemoryStream.h"
17
#include "ZVRParser.h"
18
19
using std::shared_ptr;
20
21
using std::string;
22
23
namespace libebook
24
{
25
26
namespace
27
{
28
29
const char ZVR_SIGNATURE[] = "!!Compressed!!\n";
30
31
}
32
33
ZVRParser::ZVRParser(librevenge::RVNGInputStream *input, librevenge::RVNGTextInterface *document)
34
21.1k
  : m_input(input)
35
21.1k
  , m_document(document)
36
21.1k
{
37
  // ignore the trailing \0
38
21.1k
  const size_t length = EBOOK_NUM_ELEMENTS(ZVR_SIGNATURE) - 1;
39
21.1k
  input->seek(0, librevenge::RVNG_SEEK_SET);
40
21.1k
  const auto *const sig = reinterpret_cast<const char *>(readNBytes(input, length));
41
21.1k
  if (!std::equal(sig, sig + length, ZVR_SIGNATURE))
42
19.6k
    throw UnsupportedFormat();
43
21.1k
}
44
45
bool ZVRParser::parse()
46
96
{
47
96
  readReplacementTable();
48
49
96
  const std::shared_ptr<librevenge::RVNGInputStream> input = uncompress();
50
51
96
  m_document->startDocument(librevenge::RVNGPropertyList());
52
96
  m_document->openPageSpan(getDefaultPageSpanPropList());
53
54
96
  writeText(input);
55
56
96
  m_document->closePageSpan();
57
96
  m_document->endDocument();
58
59
96
  return false;
60
96
}
61
62
void ZVRParser::readReplacementTable()
63
96
{
64
24.5k
  for (size_t i = 1; i != EBOOK_NUM_ELEMENTS(m_replacementTable); ++i)
65
24.4k
  {
66
24.4k
    string replacement;
67
68
156k
    while (!m_input->isEnd())
69
146k
    {
70
146k
      unsigned char c = readU8(m_input);
71
146k
      if ('\n' == c)
72
14.6k
      {
73
14.6k
        if (replacement.empty())
74
11.6k
          m_replacementTable[i] = static_cast<char>(i);
75
2.95k
        else
76
2.95k
        {
77
2.95k
          m_replacementTable[i] = replacement;
78
2.95k
          replacement.clear();
79
2.95k
        }
80
14.6k
        break;
81
14.6k
      }
82
132k
      else
83
132k
        replacement.push_back(char(c));
84
146k
    }
85
24.4k
  }
86
96
}
87
88
shared_ptr<librevenge::RVNGInputStream> ZVRParser::uncompress()
89
96
{
90
96
  string text;
91
92
6.57k
  while (!m_input->isEnd())
93
6.48k
  {
94
6.48k
    const unsigned char c = readU8(m_input);
95
6.48k
    text.append(m_replacementTable[c]);
96
6.48k
  }
97
98
96
  shared_ptr<librevenge::RVNGInputStream> strm(new EBOOKMemoryStream(reinterpret_cast<const unsigned char *>(text.data()), (unsigned) text.size()));
99
96
  return strm;
100
96
}
101
102
void ZVRParser::writeText(const shared_ptr<librevenge::RVNGInputStream> input)
103
96
{
104
96
  string text;
105
106
44.7k
  while (!input->isEnd())
107
44.6k
  {
108
44.6k
    const unsigned char c = readU8(input.get());
109
44.6k
    if ('\n' == c)
110
2.91k
    {
111
2.91k
      m_document->openParagraph(librevenge::RVNGPropertyList());
112
2.91k
      if (!text.empty())
113
481
      {
114
481
        m_document->openSpan(librevenge::RVNGPropertyList());
115
481
        m_document->insertText(librevenge::RVNGString(text.c_str()));
116
481
        m_document->closeSpan();
117
118
481
        text.clear();
119
481
      }
120
2.91k
      m_document->closeParagraph();
121
2.91k
    }
122
41.7k
    else
123
41.7k
      text.push_back((char) c);
124
44.6k
  }
125
96
}
126
127
}
128
129
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */