bump product version to 4.1.6.2
[LibreOffice.git] / writerperfect / source / common / WPXSvStream.cxx
blobe0c8d8c19a85188598a1735764ec84789a3b3920
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include "WPXSvStream.hxx"
11 #include <tools/stream.hxx>
12 #include <unotools/streamwrap.hxx>
13 #include <unotools/ucbstreamhelper.hxx>
14 #include <limits>
15 #include <vector>
17 using namespace ::com::sun::star::uno;
18 using namespace ::com::sun::star::io;
20 namespace
22 static void splitPath( std::vector<OUString> &rElems, const OUString &rPath )
24 for (sal_Int32 i = 0; i >= 0;)
25 rElems.push_back( rPath.getToken( 0, '/', i ) );
28 } // anonymous namespace
30 typedef struct
32 SotStorageRef ref;
33 } SotStorageRefWrapper;
35 typedef struct
37 SotStorageStreamRef ref;
38 } SotStorageStreamRefWrapper;
40 class WPXSvInputStreamImpl : public WPXInputStream
42 public :
43 WPXSvInputStreamImpl( ::com::sun::star::uno::Reference<
44 ::com::sun::star::io::XInputStream > xStream );
45 ~WPXSvInputStreamImpl();
47 bool isOLEStream();
48 WPXInputStream * getDocumentOLEStream(const char *name);
50 const unsigned char *read(unsigned long numBytes, unsigned long &numBytesRead);
51 int seek(long offset, WPX_SEEK_TYPE seekType);
52 long tell();
53 bool atEOS();
54 private:
55 ::std::vector< SotStorageRefWrapper > mxChildrenStorages;
56 ::std::vector< SotStorageStreamRefWrapper > mxChildrenStreams;
57 ::com::sun::star::uno::Reference<
58 ::com::sun::star::io::XInputStream > mxStream;
59 ::com::sun::star::uno::Reference<
60 ::com::sun::star::io::XSeekable > mxSeekable;
61 ::com::sun::star::uno::Sequence< sal_Int8 > maData;
62 sal_Int64 mnLength;
65 WPXSvInputStreamImpl::WPXSvInputStreamImpl( Reference< XInputStream > xStream ) :
66 WPXInputStream(),
67 mxChildrenStorages(),
68 mxChildrenStreams(),
69 mxStream(xStream),
70 mxSeekable(xStream, UNO_QUERY),
71 maData(0)
73 if (!xStream.is() || !mxStream.is())
74 mnLength = 0;
75 else
77 if (!mxSeekable.is())
78 mnLength = 0;
79 else
81 try
83 mnLength = mxSeekable->getLength();
85 catch ( ... )
87 SAL_WARN("writerperfect", "mnLength = mxSeekable->getLength() threw exception");
88 mnLength = 0;
94 WPXSvInputStreamImpl::~WPXSvInputStreamImpl()
98 const unsigned char *WPXSvInputStreamImpl::read(unsigned long numBytes, unsigned long &numBytesRead)
100 numBytesRead = 0;
102 if (numBytes == 0 || atEOS())
103 return 0;
105 numBytesRead = mxStream->readSomeBytes (maData, numBytes);
106 if (numBytesRead == 0)
107 return 0;
109 return (const unsigned char *)maData.getConstArray();
112 long WPXSvInputStreamImpl::tell()
114 if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
115 return -1L;
116 else
118 sal_Int64 tmpPosition = mxSeekable->getPosition();
119 if ((tmpPosition < 0) || (tmpPosition > (std::numeric_limits<long>::max)()))
120 return -1L;
121 return (long)tmpPosition;
125 int WPXSvInputStreamImpl::seek(long offset, WPX_SEEK_TYPE seekType)
127 if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
128 return -1;
130 sal_Int64 tmpPosition = mxSeekable->getPosition();
131 if ((tmpPosition < 0) || (tmpPosition > (std::numeric_limits<long>::max)()))
132 return -1;
134 sal_Int64 tmpOffset = offset;
135 if (seekType == WPX_SEEK_CUR)
136 tmpOffset += tmpPosition;
137 if (seekType == WPX_SEEK_END)
138 tmpOffset += mnLength;
140 int retVal = 0;
141 if (tmpOffset < 0)
143 tmpOffset = 0;
144 retVal = -1;
146 if (offset > mnLength)
148 tmpOffset = mnLength;
149 retVal = -1;
154 mxSeekable->seek(tmpOffset);
155 return retVal;
157 catch (...)
159 SAL_WARN("writerperfect", "mxSeekable->seek(offset) threw exception");
160 return -1;
164 bool WPXSvInputStreamImpl::atEOS()
166 if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
167 return true;
168 return (mxSeekable->getPosition() >= mnLength);
171 bool WPXSvInputStreamImpl::isOLEStream()
173 if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
174 return false;
176 sal_Int64 tmpPosition = mxSeekable->getPosition();
177 mxSeekable->seek(0);
179 SvStream *pStream = utl::UcbStreamHelper::CreateStream( mxStream );
180 bool bAns = pStream && SotStorage::IsOLEStorage( pStream );
181 if (pStream)
182 delete pStream;
184 mxSeekable->seek(tmpPosition);
186 return bAns;
189 WPXInputStream *WPXSvInputStreamImpl::getDocumentOLEStream(const char *name)
191 if (!name)
192 return 0;
193 OUString rPath(name,strlen(name),RTL_TEXTENCODING_UTF8);
194 std::vector<OUString> aElems;
195 splitPath( aElems, rPath );
197 if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
198 return 0;
200 sal_Int64 tmpPosition = mxSeekable->getPosition();
201 mxSeekable->seek(0);
203 SvStream *pStream = utl::UcbStreamHelper::CreateStream( mxStream );
205 if (!pStream || !SotStorage::IsOLEStorage( pStream ))
207 mxSeekable->seek(tmpPosition);
208 return 0;
211 SotStorageRefWrapper storageRefWrapper;
212 storageRefWrapper.ref = new SotStorage( pStream, sal_True );
213 mxChildrenStorages.push_back( storageRefWrapper );
215 unsigned i = 0;
216 while (i < aElems.size())
218 if( mxChildrenStorages.back().ref->IsStream(aElems[i]))
219 break;
220 else if (mxChildrenStorages.back().ref->IsStorage(aElems[i]))
222 SotStorageRef tmpParent(mxChildrenStorages.back().ref);
223 storageRefWrapper.ref = tmpParent->OpenSotStorage(aElems[i++], STREAM_STD_READ);
224 mxChildrenStorages.push_back(storageRefWrapper);
226 else
227 // should not happen
228 return 0;
231 // For the while don't return stream in this situation.
232 // Later, given how libcdr's zip stream implementation behaves,
233 // return the first stream in the storage if there is one.
234 if (i >= aElems.size())
235 return 0;
237 SotStorageStreamRefWrapper storageStreamRefWrapper;
238 storageStreamRefWrapper.ref = mxChildrenStorages.back().ref->OpenSotStream( aElems[i], STREAM_STD_READ );
239 mxChildrenStreams.push_back( storageStreamRefWrapper );
241 mxSeekable->seek(tmpPosition);
243 if ( !mxChildrenStreams.back().ref.Is() || mxChildrenStreams.back().ref->GetError() )
245 mxSeekable->seek(tmpPosition);
246 return 0;
249 Reference < XInputStream > xContents(new utl::OSeekableInputStreamWrapper( mxChildrenStreams.back().ref ));
250 mxSeekable->seek(tmpPosition);
251 if (xContents.is())
252 return new WPXSvInputStream( xContents );
253 else
254 return 0;
258 WPXSvInputStream::WPXSvInputStream( Reference< XInputStream > xStream ) :
259 mpImpl(new WPXSvInputStreamImpl(xStream))
263 WPXSvInputStream::~WPXSvInputStream()
265 delete mpImpl;
268 const unsigned char *WPXSvInputStream::read(unsigned long numBytes, unsigned long &numBytesRead)
270 return mpImpl->read(numBytes, numBytesRead);
273 long WPXSvInputStream::tell()
275 return mpImpl->tell();
278 int WPXSvInputStream::seek(long offset, WPX_SEEK_TYPE seekType)
280 return mpImpl->seek(offset, seekType);
283 bool WPXSvInputStream::atEOS()
285 return mpImpl->atEOS();
288 bool WPXSvInputStream::isOLEStream()
290 return mpImpl->isOLEStream();
293 WPXInputStream *WPXSvInputStream::getDocumentOLEStream(const char *name)
295 return mpImpl->getDocumentOLEStream(name);
298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */