1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #include "EPUBPackage.hxx"
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>
20 #include <sal/log.hxx>
21 #include <comphelper/attributelist.hxx>
22 #include <comphelper/storagehelper.hxx>
23 #include <unotools/mediadescriptor.hxx>
25 using namespace com::sun::star
;
27 namespace writerperfect
29 EPUBPackage::EPUBPackage(uno::Reference
<uno::XComponentContext
> xContext
,
30 const uno::Sequence
<beans::PropertyValue
>& rDescriptor
)
31 : mxContext(std::move(xContext
))
33 // Extract the output stream from the descriptor.
34 utl::MediaDescriptor
aMediaDesc(rDescriptor
);
35 auto xStream
= aMediaDesc
.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_STREAMFOROUTPUT
,
36 uno::Reference
<io::XStream
>());
37 const sal_Int32 nOpenMode
= embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
;
38 mxStorage
.set(comphelper::OStorageHelper::GetStorageOfFormatFromStream(
39 ZIP_STORAGE_FORMAT_STRING
, xStream
, nOpenMode
, mxContext
),
42 // The zipped content represents an EPUB Publication.
44 mxStorage
->openStreamElementByHierarchicalName("mimetype", embed::ElementModes::READWRITE
),
46 static constexpr OString
aMimeType("application/epub+zip"_ostr
);
47 uno::Sequence
<sal_Int8
> aData(reinterpret_cast<const sal_Int8
*>(aMimeType
.getStr()),
48 aMimeType
.getLength());
49 mxOutputStream
->writeBytes(aData
);
50 uno::Reference
<embed::XTransactedObject
> xTransactedObject(mxOutputStream
, uno::UNO_QUERY
);
51 xTransactedObject
->commit();
53 // MIME type must be uncompressed.
54 uno::Reference
<beans::XPropertySet
> xPropertySet(mxOutputStream
, uno::UNO_QUERY
);
55 xPropertySet
->setPropertyValue("Compressed", uno::Any(false));
56 mxOutputStream
.clear();
59 EPUBPackage::~EPUBPackage()
61 uno::Reference
<embed::XTransactedObject
> xTransactedObject(mxStorage
, uno::UNO_QUERY
);
62 xTransactedObject
->commit();
65 void EPUBPackage::openXMLFile(const char* pName
)
68 assert(!mxOutputStream
.is());
69 assert(!mxOutputWriter
.is());
71 mxOutputStream
.set(mxStorage
->openStreamElementByHierarchicalName(
72 OUString::fromUtf8(pName
), embed::ElementModes::READWRITE
),
74 mxOutputWriter
= xml::sax::Writer::create(mxContext
);
75 mxOutputWriter
->setOutputStream(mxOutputStream
);
76 mxOutputWriter
->startDocument();
79 void EPUBPackage::openElement(const char* pName
, const librevenge::RVNGPropertyList
& rAttributes
)
81 assert(mxOutputWriter
.is());
83 rtl::Reference
<comphelper::AttributeList
> pAttributeList(new comphelper::AttributeList());
85 librevenge::RVNGPropertyList::Iter
it(rAttributes
);
86 for (it
.rewind(); it
.next();)
87 pAttributeList
->AddAttribute(OUString::fromUtf8(it
.key()),
88 OUString::fromUtf8(it()->getStr().cstr()));
90 mxOutputWriter
->startElement(OUString::fromUtf8(pName
), pAttributeList
);
93 void EPUBPackage::closeElement(const char* pName
)
95 assert(mxOutputWriter
.is());
97 mxOutputWriter
->endElement(OUString::fromUtf8(pName
));
100 void EPUBPackage::insertCharacters(const librevenge::RVNGString
& rCharacters
)
102 mxOutputWriter
->characters(OUString::fromUtf8(rCharacters
.cstr()));
105 void EPUBPackage::closeXMLFile()
107 assert(mxOutputWriter
.is());
108 assert(mxOutputStream
.is());
110 mxOutputWriter
->endDocument();
111 mxOutputWriter
.clear();
113 uno::Reference
<embed::XTransactedObject
> xTransactedObject(mxOutputStream
, uno::UNO_QUERY
);
114 xTransactedObject
->commit();
115 mxOutputStream
.clear();
118 void EPUBPackage::openCSSFile(const char* pName
)
121 assert(!mxOutputStream
.is());
123 mxOutputStream
.set(mxStorage
->openStreamElementByHierarchicalName(
124 OUString::fromUtf8(pName
), embed::ElementModes::READWRITE
),
128 void EPUBPackage::insertRule(const librevenge::RVNGString
& rSelector
,
129 const librevenge::RVNGPropertyList
& rProperties
)
131 assert(mxOutputStream
.is());
133 uno::Reference
<io::XSeekable
> xSeekable(mxOutputStream
, uno::UNO_QUERY
);
134 std::stringstream aStream
;
135 if (xSeekable
->getPosition() != 0)
137 aStream
<< rSelector
.cstr() << " {\n";
139 librevenge::RVNGPropertyList::Iter
it(rProperties
);
140 for (it
.rewind(); it
.next();)
143 aStream
<< " " << it
.key() << ": " << it()->getStr().cstr() << ";\n";
147 std::string aString
= aStream
.str();
148 uno::Sequence
<sal_Int8
> aData(reinterpret_cast<const sal_Int8
*>(aString
.c_str()),
150 mxOutputStream
->writeBytes(aData
);
153 void EPUBPackage::closeCSSFile()
155 assert(mxOutputStream
.is());
157 uno::Reference
<embed::XTransactedObject
> xTransactedObject(mxOutputStream
, uno::UNO_QUERY
);
158 xTransactedObject
->commit();
159 mxOutputStream
.clear();
162 void EPUBPackage::openBinaryFile(const char* pName
)
165 assert(!mxOutputStream
.is());
167 mxOutputStream
.set(mxStorage
->openStreamElementByHierarchicalName(
168 OUString::fromUtf8(pName
), embed::ElementModes::READWRITE
),
172 void EPUBPackage::insertBinaryData(const librevenge::RVNGBinaryData
& rData
)
174 assert(mxOutputStream
.is());
179 uno::Sequence
<sal_Int8
> aData(reinterpret_cast<const sal_Int8
*>(rData
.getDataBuffer()),
181 mxOutputStream
->writeBytes(aData
);
184 void EPUBPackage::closeBinaryFile()
186 assert(mxOutputStream
.is());
188 uno::Reference
<embed::XTransactedObject
> xTransactedObject(mxOutputStream
, uno::UNO_QUERY
);
189 xTransactedObject
->commit();
190 mxOutputStream
.clear();
193 void EPUBPackage::openTextFile(const char* pName
)
195 SAL_WARN("writerperfect", "EPUBPackage::openTextFile, " << pName
<< ": implement me");
198 void EPUBPackage::insertText(const librevenge::RVNGString
& /*rCharacters*/)
200 SAL_WARN("writerperfect", "EPUBPackage::insertText: implement me");
203 void EPUBPackage::insertLineBreak()
205 SAL_WARN("writerperfect", "EPUBPackage::insertLineBreak: implement me");
208 void EPUBPackage::closeTextFile()
210 SAL_WARN("writerperfect", "EPUBPackage::closeTextFile: implement me");
213 } // namespace writerperfect
215 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */