12#include <com/sun/star/packages/zip/XZipFileAccess2.hpp>
13#include <com/sun/star/uno/XComponentContext.hpp>
18#include <rtl/string.hxx>
31#include <unordered_map>
48 explicit PositionHolder(
const Reference<XSeekable>& rxSeekable);
50 PositionHolder(
const PositionHolder&) =
delete;
51 PositionHolder& operator=(
const PositionHolder&) =
delete;
58PositionHolder::PositionHolder(
const Reference<XSeekable>& rxSeekable)
64PositionHolder::~PositionHolder()
79OUString lcl_normalizeSubStreamPath(
const OUString& rPath)
83 if (rPath.startsWith(
"/") && rPath.getLength() >= 2)
91OUString concatPath(std::u16string_view lhs,
const OUString& rhs)
95 return OUString::Concat(lhs) +
"/" + rhs;
100 OLEStreamData(OString
aName, OString rvngName);
118typedef std::unordered_map<OUString, std::size_t> NameMap_t;
119typedef std::unordered_map<OUString, tools::SvRef<SotStorage>> OLEStorageMap_t;
141 void initialize(std::unique_ptr<SvStream> pStream);
159OLEStreamData::OLEStreamData(OString
aName, OString rvngName)
165OLEStorageImpl::OLEStorageImpl()
170void OLEStorageImpl::initialize(std::unique_ptr<SvStream> pStream)
184 const OUString aPath(lcl_normalizeSubStreamPath(rPath));
185 NameMap_t::iterator aIt =
maNameMap.find(aPath);
195 = createStream(OStringToOUString(
maStreams[aIt->second].name, RTL_TEXTENCODING_UTF8));
204 = createStream(OStringToOUString(
maStreams[nId].
name, RTL_TEXTENCODING_UTF8));
213 rStorage->FillInfoList(&infos);
215 for (
const auto& info : infos)
219 OUString baseName = info.GetName(), rvngName = baseName;
221 if (!rvngName.isEmpty() && rvngName.toChar() < 32)
222 rvngName = rvngName.copy(1);
228 else if (info.IsStorage())
230 const OUString aPath = concatPath(rPath, info.GetName());
232 = rStorage->OpenSotStorage(info.GetName(), StreamMode::STD_READ);
236 traverse(aStorage, aPath);
241 "OLEStorageImpl::traverse: invalid storage entry, neither stream nor file");
248 const sal_Int32 nDelim = rPath.lastIndexOf(u
'/');
251 return mxRootStorage->OpenSotStream(rPath, StreamMode::STD_READ);
253 const OUString aDir = rPath.copy(0, nDelim);
254 const OUString
aName = rPath.copy(nDelim + 1);
256 const OLEStorageMap_t::const_iterator aIt =
maStorageMap.find(aDir);
261 return aIt->second->OpenSotStream(
aName, StreamMode::STD_READ);
269 explicit ZipStreamData(OString
aName);
288 explicit ZipStorageImpl(
const Reference<container::XNameAccess>& rxContainer);
298 Reference<XInputStream> getStream(
const OUString& rPath);
299 Reference<XInputStream>
const& getStream(std::size_t
nId);
302 void traverse(
const Reference<container::XNameAccess>& rxEnum);
304 Reference<XInputStream> createStream(
const OUString& rPath);
313ZipStreamData::ZipStreamData(OString _aName)
318ZipStorageImpl::ZipStorageImpl(
const Reference<container::XNameAccess>& rxContainer)
325void ZipStorageImpl::initialize()
332Reference<XInputStream> ZipStorageImpl::getStream(
const OUString& rPath)
334 const OUString aPath(lcl_normalizeSubStreamPath(rPath));
335 NameMap_t::iterator aIt =
maNameMap.find(aPath);
341 return Reference<XInputStream>();
343 if (!
maStreams[aIt->second].xStream.is())
344 maStreams[aIt->second].xStream = createStream(aPath);
349Reference<XInputStream>
const& ZipStorageImpl::getStream(
const std::size_t nId)
353 = createStream(OStringToOUString(
maStreams[nId].
aName, RTL_TEXTENCODING_UTF8));
358void ZipStorageImpl::traverse(
const Reference<container::XNameAccess>& rxContainer)
360 const Sequence<OUString> lNames = rxContainer->getElementNames();
364 for (
const auto& rName : lNames)
366 if (!rName.endsWith(
"/"))
374Reference<XInputStream> ZipStorageImpl::createStream(
const OUString& rPath)
376 Reference<XInputStream>
xStream;
380 const Reference<XInputStream> xInputStream(
mxContainer->getByName(rPath), UNO_QUERY_THROW);
381 const Reference<XSeekable> xSeekable(xInputStream, UNO_QUERY);
389 catch (
const Exception&)
404 unsigned subStreamCount();
405 const char* subStreamName(
unsigned id);
406 bool existsSubStream(
const char*
name);
407 librevenge::RVNGInputStream* getSubStreamByName(
const char*
name);
408 librevenge::RVNGInputStream* getSubStreamById(
unsigned id);
410 const unsigned char* read(
unsigned long numBytes,
unsigned long& numBytesRead);
415 void invalidateReadBuffer();
419 void ensureOLEIsInitialized();
422 void ensureZipIsInitialized();
424 static librevenge::RVNGInputStream*
429 css::uno::Reference<css::io::XInputStream>
mxStream;
448 , mbCheckedOLE(false)
449 , mbCheckedZip(false)
451 , mpReadBuffer(nullptr)
452 , mnReadBufferLength(0)
471 SAL_WARN(
"writerperfect",
"mnLength = mxSeekable->getLength() threw exception");
482 if (numBytes == 0 ||
isEnd())
486 if (numBytesRead == 0)
489 return reinterpret_cast<const unsigned char*
>(
maData.getConstArray());
498 const sal_Int64 tmpPosition =
mxSeekable->getPosition();
499 if ((tmpPosition < 0) || (tmpPosition >
LONG_MAX))
510 const sal_Int64 tmpPosition =
mxSeekable->getPosition();
511 if ((tmpPosition < 0) || (tmpPosition >
LONG_MAX))
521 SAL_WARN(
"writerperfect",
"mxSeekable->seek(offset) threw exception");
620 const OUString
aName(OStringToOUString(std::string_view(
name), RTL_TEXTENCODING_UTF8));
650 const OUString
aName(OStringToOUString(std::string_view(
name), RTL_TEXTENCODING_UTF8));
728librevenge::RVNGInputStream*
739librevenge::RVNGInputStream*
775 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
776 "com.sun.star.packages.zip.ZipFileAccess", { Any(mxStream) }, xContext),
814#define BUFFER_MAX 65536
820 if (numBytes == 0 || numBytes > std::numeric_limits<unsigned long>::max() / 2)
825 if ((
mpImpl->mnReadBufferPos + numBytes >
mpImpl->mnReadBufferPos)
826 && (
mpImpl->mnReadBufferPos + numBytes <= mpImpl->mnReadBufferLength))
828 const unsigned char* pTmp =
mpImpl->mpReadBuffer +
mpImpl->mnReadBufferPos;
829 mpImpl->mnReadBufferPos += numBytes;
830 numBytesRead = numBytes;
834 mpImpl->invalidateReadBuffer();
837 unsigned long curpos =
static_cast<unsigned long>(
mpImpl->tell());
838 if (curpos ==
static_cast<unsigned long>(-1))
841 if ((curpos + numBytes < curpos)
842 || (curpos + numBytes
845 numBytes =
mpImpl->mnLength - curpos;
850 if (BUFFER_MAX < mpImpl->mnLength - curpos)
856 mpImpl->mnReadBufferLength = numBytes;
858 unsigned long tmpNumBytes(0);
860 if (tmpNumBytes !=
mpImpl->mnReadBufferLength)
861 mpImpl->mnReadBufferLength = tmpNumBytes;
863 mpImpl->mnReadBufferPos = 0;
864 if (!
mpImpl->mnReadBufferLength)
867 if (numBytes <= mpImpl->mnReadBufferLength)
868 numBytesRead = numBytes;
870 numBytesRead =
mpImpl->mnReadBufferLength;
872 mpImpl->mnReadBufferPos += numBytesRead;
873 return mpImpl->mpReadBuffer;
885 sal_Int64 tmpOffset = offset;
886 if (seekType == librevenge::RVNG_SEEK_CUR)
888 if (seekType == librevenge::RVNG_SEEK_END)
889 tmpOffset +=
mpImpl->mnLength;
897 if (tmpOffset >
mpImpl->mnLength)
899 tmpOffset =
mpImpl->mnLength;
903 if (tmpOffset < mpImpl->
tell()
905 >=
static_cast<unsigned long>(
mpImpl->tell()) -
mpImpl->mnReadBufferLength)
907 mpImpl->mnReadBufferPos =
static_cast<unsigned long>(
912 mpImpl->invalidateReadBuffer();
914 if (
mpImpl->seek(tmpOffset))
926 mpImpl->invalidateReadBuffer();
927 return mpImpl->isStructured();
932 mpImpl->invalidateReadBuffer();
933 return mpImpl->subStreamCount();
938 mpImpl->invalidateReadBuffer();
939 return mpImpl->subStreamName(
id);
944 mpImpl->invalidateReadBuffer();
950 mpImpl->invalidateReadBuffer();
956 mpImpl->invalidateReadBuffer();
957 return mpImpl->getSubStreamById(
id);
bool IsOLEStorage() const
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
#define SAL_WARN(area, stream)
std::vector< sal_Int8, boost::noinit_adaptor< std::allocator< sal_Int8 > > > maData
Reference< XComponentContext > getProcessComponentContext()
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
std::vector< SvStorageInfo > SvStorageInfoList