Coverage Report

Created: 2026-08-14 10:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/writerperfect/source/writer/EPUBPackage.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice 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 "EPUBPackage.hxx"
11
12
#include <com/sun/star/embed/ElementModes.hpp>
13
#include <com/sun/star/embed/XStorage.hpp>
14
#include <com/sun/star/embed/XTransactedObject.hpp>
15
#include <com/sun/star/io/XSeekable.hpp>
16
#include <com/sun/star/xml/sax/Writer.hpp>
17
#include <com/sun/star/beans/XPropertySet.hpp>
18
#include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
19
20
#include <rtl/ref.hxx>
21
#include <sal/log.hxx>
22
#include <comphelper/attributelist.hxx>
23
#include <comphelper/sequenceashashmap.hxx>
24
#include <comphelper/storagehelper.hxx>
25
#include <unotools/mediadescriptor.hxx>
26
27
using namespace com::sun::star;
28
29
namespace writerperfect
30
{
31
EPUBPackage::EPUBPackage(uno::Reference<uno::XComponentContext> xContext,
32
                         const uno::Sequence<beans::PropertyValue>& rDescriptor)
33
0
    : mxContext(std::move(xContext))
34
0
{
35
    // Extract the output stream from the descriptor.
36
0
    comphelper::SequenceAsHashMap aMediaDesc(rDescriptor);
37
0
    auto xStream = aMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_STREAMFOROUTPUT,
38
0
                                                        uno::Reference<io::XStream>());
39
0
    const sal_Int32 nOpenMode = embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE;
40
0
    mxStorage.set(comphelper::OStorageHelper::GetStorageOfFormatFromStream(
41
0
                      ZIP_STORAGE_FORMAT_STRING, xStream, nOpenMode, mxContext),
42
0
                  uno::UNO_QUERY);
43
44
    // The zipped content represents an EPUB Publication.
45
0
    mxOutputStream.set(mxStorage->openStreamElementByHierarchicalName(
46
0
                           u"mimetype"_ustr, embed::ElementModes::READWRITE),
47
0
                       uno::UNO_QUERY);
48
0
    static constexpr OString aMimeType("application/epub+zip"_ostr);
49
0
    uno::Sequence<sal_Int8> aData(reinterpret_cast<const sal_Int8*>(aMimeType.getStr()),
50
0
                                  aMimeType.getLength());
51
0
    mxOutputStream->writeBytes(aData);
52
0
    uno::Reference<embed::XTransactedObject> xTransactedObject(mxOutputStream, uno::UNO_QUERY);
53
0
    xTransactedObject->commit();
54
55
    // MIME type must be uncompressed.
56
0
    uno::Reference<beans::XPropertySet> xPropertySet(mxOutputStream, uno::UNO_QUERY);
57
0
    xPropertySet->setPropertyValue(u"Compressed"_ustr, uno::Any(false));
58
0
    mxOutputStream.clear();
59
0
}
60
61
EPUBPackage::~EPUBPackage()
62
0
{
63
0
    uno::Reference<embed::XTransactedObject> xTransactedObject(mxStorage, uno::UNO_QUERY);
64
0
    xTransactedObject->commit();
65
0
}
66
67
void EPUBPackage::openXMLFile(const char* pName)
68
0
{
69
0
    assert(pName);
70
0
    assert(!mxOutputStream.is());
71
0
    assert(!mxOutputWriter.is());
72
73
0
    mxOutputStream.set(mxStorage->openStreamElementByHierarchicalName(
74
0
                           OUString::fromUtf8(pName), embed::ElementModes::READWRITE),
75
0
                       uno::UNO_QUERY);
76
0
    mxOutputWriter = xml::sax::Writer::create(mxContext);
77
0
    mxOutputWriter->setOutputStream(mxOutputStream);
78
0
    mxOutputWriter->startDocument();
79
0
}
80
81
void EPUBPackage::openElement(const char* pName, const librevenge::RVNGPropertyList& rAttributes)
82
0
{
83
0
    assert(mxOutputWriter.is());
84
85
0
    rtl::Reference<comphelper::AttributeList> pAttributeList(new comphelper::AttributeList());
86
87
0
    librevenge::RVNGPropertyList::Iter it(rAttributes);
88
0
    for (it.rewind(); it.next();)
89
0
        pAttributeList->AddAttribute(OUString::fromUtf8(it.key()),
90
0
                                     OUString::fromUtf8(it()->getStr().cstr()));
91
92
0
    mxOutputWriter->startElement(OUString::fromUtf8(pName), pAttributeList);
93
0
}
94
95
void EPUBPackage::closeElement(const char* pName)
96
0
{
97
0
    assert(mxOutputWriter.is());
98
99
0
    mxOutputWriter->endElement(OUString::fromUtf8(pName));
100
0
}
101
102
void EPUBPackage::insertCharacters(const librevenge::RVNGString& rCharacters)
103
0
{
104
0
    mxOutputWriter->characters(OUString::fromUtf8(rCharacters.cstr()));
105
0
}
106
107
void EPUBPackage::closeXMLFile()
108
0
{
109
0
    assert(mxOutputWriter.is());
110
0
    assert(mxOutputStream.is());
111
112
0
    mxOutputWriter->endDocument();
113
0
    mxOutputWriter.clear();
114
115
0
    uno::Reference<embed::XTransactedObject> xTransactedObject(mxOutputStream, uno::UNO_QUERY);
116
0
    xTransactedObject->commit();
117
0
    mxOutputStream.clear();
118
0
}
119
120
void EPUBPackage::openCSSFile(const char* pName)
121
0
{
122
0
    assert(pName);
123
0
    assert(!mxOutputStream.is());
124
125
0
    mxOutputStream.set(mxStorage->openStreamElementByHierarchicalName(
126
0
                           OUString::fromUtf8(pName), embed::ElementModes::READWRITE),
127
0
                       uno::UNO_QUERY);
128
0
}
129
130
void EPUBPackage::insertRule(const librevenge::RVNGString& rSelector,
131
                             const librevenge::RVNGPropertyList& rProperties)
132
0
{
133
0
    assert(mxOutputStream.is());
134
135
0
    uno::Reference<io::XSeekable> xSeekable(mxOutputStream, uno::UNO_QUERY);
136
0
    std::stringstream aStream;
137
0
    if (xSeekable->getPosition() != 0)
138
0
        aStream << '\n';
139
0
    aStream << rSelector.cstr() << " {\n";
140
141
0
    librevenge::RVNGPropertyList::Iter it(rProperties);
142
0
    for (it.rewind(); it.next();)
143
0
    {
144
0
        if (it() && it.key() != std::string_view("direction"))
145
0
            aStream << "  " << it.key() << ": " << it()->getStr().cstr() << ";\n";
146
0
    }
147
148
0
    aStream << "}\n";
149
0
    std::string aString = aStream.str();
150
0
    uno::Sequence<sal_Int8> aData(reinterpret_cast<const sal_Int8*>(aString.c_str()),
151
0
                                  aString.size());
152
0
    mxOutputStream->writeBytes(aData);
153
0
}
154
155
void EPUBPackage::closeCSSFile()
156
0
{
157
0
    assert(mxOutputStream.is());
158
159
0
    uno::Reference<embed::XTransactedObject> xTransactedObject(mxOutputStream, uno::UNO_QUERY);
160
0
    xTransactedObject->commit();
161
0
    mxOutputStream.clear();
162
0
}
163
164
void EPUBPackage::openBinaryFile(const char* pName)
165
0
{
166
0
    assert(pName);
167
0
    assert(!mxOutputStream.is());
168
169
0
    mxOutputStream.set(mxStorage->openStreamElementByHierarchicalName(
170
0
                           OUString::fromUtf8(pName), embed::ElementModes::READWRITE),
171
0
                       uno::UNO_QUERY);
172
0
}
173
174
void EPUBPackage::insertBinaryData(const librevenge::RVNGBinaryData& rData)
175
0
{
176
0
    assert(mxOutputStream.is());
177
178
0
    if (rData.empty())
179
0
        return;
180
181
0
    uno::Sequence<sal_Int8> aData(reinterpret_cast<const sal_Int8*>(rData.getDataBuffer()),
182
0
                                  rData.size());
183
0
    mxOutputStream->writeBytes(aData);
184
0
}
185
186
void EPUBPackage::closeBinaryFile()
187
0
{
188
0
    assert(mxOutputStream.is());
189
190
0
    uno::Reference<embed::XTransactedObject> xTransactedObject(mxOutputStream, uno::UNO_QUERY);
191
0
    xTransactedObject->commit();
192
0
    mxOutputStream.clear();
193
0
}
194
195
void EPUBPackage::openTextFile(const char* pName)
196
0
{
197
0
    SAL_WARN("writerperfect", "EPUBPackage::openTextFile, " << pName << ": implement me");
198
0
}
199
200
void EPUBPackage::insertText(const librevenge::RVNGString& /*rCharacters*/)
201
0
{
202
0
    SAL_WARN("writerperfect", "EPUBPackage::insertText: implement me");
203
0
}
204
205
void EPUBPackage::insertLineBreak()
206
0
{
207
0
    SAL_WARN("writerperfect", "EPUBPackage::insertLineBreak: implement me");
208
0
}
209
210
void EPUBPackage::closeTextFile()
211
0
{
212
0
    SAL_WARN("writerperfect", "EPUBPackage::closeTextFile: implement me");
213
0
}
214
215
} // namespace writerperfect
216
217
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */