Branch data Line data Source code
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 "WPXSvStream.h"
11 : : #include "filter/FilterInternal.hxx"
12 : : #include <tools/stream.hxx>
13 : : #include <unotools/streamwrap.hxx>
14 : : #include <unotools/ucbstreamhelper.hxx>
15 : : #include <limits>
16 : :
17 : : using namespace ::com::sun::star::uno;
18 : : using namespace ::com::sun::star::io;
19 : :
20 : : namespace
21 : : {
22 : 20 : static void splitPath( std::vector<rtl::OUString> &rElems, const ::rtl::OUString &rPath )
23 : : {
24 [ + + ]: 40 : for (sal_Int32 i = 0; i >= 0;)
25 [ + - ]: 20 : rElems.push_back( rPath.getToken( 0, '/', i ) );
26 : 20 : }
27 : :
28 : : } // anonymous namespace
29 : :
30 : 70 : WPXSvInputStream::WPXSvInputStream( Reference< XInputStream > xStream ) :
31 : : WPXInputStream(),
32 : : mxChildrenStorages(),
33 : : mxChildrenStreams(),
34 : : mxStream(xStream),
35 : : mxSeekable(xStream, UNO_QUERY),
36 [ + - ][ + - ]: 70 : maData(0)
[ + - ][ + - ]
37 : : {
38 [ + - ][ - + ]: 70 : if (!xStream.is() || !mxStream.is())
[ - + ]
39 : 0 : mnLength = 0;
40 : : else
41 : : {
42 [ - + ]: 70 : if (!mxSeekable.is())
43 : 0 : mnLength = 0;
44 : : else
45 : : {
46 : : try
47 : : {
48 [ + - ][ + - ]: 70 : mnLength = mxSeekable->getLength();
49 : : }
50 [ # # ]: 0 : catch ( ... )
51 : : {
52 : : WRITER_DEBUG_MSG(("mnLength = mxSeekable->getLength() threw exception\n"));
53 : 0 : mnLength = 0;
54 : : }
55 : : }
56 : : }
57 : 70 : }
58 : :
59 [ + - ]: 70 : WPXSvInputStream::~WPXSvInputStream()
60 : : {
61 [ - + ]: 70 : }
62 : :
63 : 160138 : const unsigned char *WPXSvInputStream::read(unsigned long numBytes, unsigned long &numBytesRead)
64 : : {
65 : 160138 : numBytesRead = 0;
66 : :
67 [ + - ][ - + ]: 160138 : if (numBytes == 0 || atEOS())
[ - + ]
68 : 0 : return 0;
69 : :
70 : 160138 : numBytesRead = mxStream->readSomeBytes (maData, numBytes);
71 [ - + ]: 160138 : if (numBytesRead == 0)
72 : 0 : return 0;
73 : :
74 : 160138 : return (const unsigned char *)maData.getConstArray();
75 : : }
76 : :
77 : 10 : long WPXSvInputStream::tell()
78 : : {
79 [ + - ][ + - ]: 10 : if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
[ - + ][ - + ]
80 : 0 : return -1L;
81 : : else
82 : : {
83 : 10 : sal_Int64 tmpPosition = mxSeekable->getPosition();
84 [ - + ][ - + ]: 10 : if ((tmpPosition < 0) || (tmpPosition > (std::numeric_limits<long>::max)()))
[ + - ]
85 : 0 : return -1L;
86 : 10 : return (long)tmpPosition;
87 : : }
88 : : }
89 : :
90 : 155580 : int WPXSvInputStream::seek(long offset, WPX_SEEK_TYPE seekType)
91 : : {
92 [ + - ][ + - ]: 155580 : if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
[ - + ][ - + ]
93 : 0 : return -1;
94 : :
95 : 155580 : sal_Int64 tmpPosition = mxSeekable->getPosition();
96 [ - + ][ - + ]: 155580 : if ((tmpPosition < 0) || (tmpPosition > (std::numeric_limits<long>::max)()))
[ + - ]
97 : 0 : return -1;
98 : :
99 : 155580 : sal_Int64 tmpOffset = offset;
100 [ + + ]: 155580 : if (seekType == WPX_SEEK_CUR)
101 : 155450 : tmpOffset += tmpPosition;
102 : :
103 : 155580 : int retVal = 0;
104 [ - + ]: 155580 : if (tmpOffset < 0)
105 : : {
106 : 0 : tmpOffset = 0;
107 : 0 : retVal = -1;
108 : : }
109 [ - + ]: 155580 : if (offset > mnLength)
110 : : {
111 : 0 : tmpOffset = mnLength;
112 : 0 : retVal = -1;
113 : : }
114 : :
115 : : try
116 : : {
117 [ + - ][ + - ]: 155580 : mxSeekable->seek(tmpOffset);
118 : 155580 : return retVal;
119 : : }
120 : 0 : catch (...)
121 : : {
122 : : WRITER_DEBUG_MSG(("mxSeekable->seek(offset) threw exception\n"));
123 : 0 : return -1;
124 : : }
125 : : }
126 : :
127 : 475224 : bool WPXSvInputStream::atEOS()
128 : : {
129 [ + - ][ + - ]: 475224 : if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
[ - + ][ - + ]
130 : 0 : return true;
131 : 475224 : return (mxSeekable->getPosition() >= mnLength);
132 : : }
133 : :
134 : 40 : bool WPXSvInputStream::isOLEStream()
135 : : {
136 [ + - ][ + - ]: 40 : if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
[ - + ][ - + ]
137 : 0 : return false;
138 : :
139 : 40 : sal_Int64 tmpPosition = mxSeekable->getPosition();
140 : 40 : mxSeekable->seek(0);
141 : :
142 [ + - ]: 40 : SvStream *pStream = utl::UcbStreamHelper::CreateStream( mxStream );
143 [ - + ][ + - ]: 40 : bool bAns = pStream && SotStorage::IsOLEStorage( pStream );
144 [ + - ]: 40 : if (pStream)
145 [ + - ]: 40 : delete pStream;
146 : :
147 : 40 : mxSeekable->seek(tmpPosition);
148 : :
149 : 40 : return bAns;
150 : : }
151 : :
152 : 20 : WPXInputStream *WPXSvInputStream::getDocumentOLEStream(const char *name)
153 : : {
154 [ - + ]: 20 : if (!name)
155 : 0 : return 0;
156 [ + - ]: 20 : rtl::OUString rPath(name,strlen(name),RTL_TEXTENCODING_UTF8);
157 [ + - ]: 20 : std::vector<rtl::OUString> aElems;
158 [ + - ]: 20 : splitPath( aElems, rPath );
159 : :
160 [ + - ][ + - ]: 20 : if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
[ - + ][ - + ]
161 : 0 : return 0;
162 : :
163 [ + - ][ + - ]: 20 : sal_Int64 tmpPosition = mxSeekable->getPosition();
164 [ + - ][ + - ]: 20 : mxSeekable->seek(0);
165 : :
166 [ + - ]: 20 : SvStream *pStream = utl::UcbStreamHelper::CreateStream( mxStream );
167 : :
168 [ + - ][ + - ]: 20 : if (!pStream || !SotStorage::IsOLEStorage( pStream ))
[ + - ][ + - ]
169 : : {
170 [ + - ][ + - ]: 20 : mxSeekable->seek(tmpPosition);
171 : 20 : return 0;
172 : : }
173 : :
174 [ # # ]: 0 : SotStorageRefWrapper storageRefWrapper;
175 [ # # ][ # # ]: 0 : storageRefWrapper.ref = new SotStorage( pStream, sal_True );
[ # # ]
176 [ # # ]: 0 : mxChildrenStorages.push_back( storageRefWrapper );
177 : :
178 : 0 : unsigned i = 0;
179 [ # # ]: 0 : while (i < aElems.size())
180 : : {
181 [ # # ][ # # ]: 0 : if( mxChildrenStorages.back().ref->IsStream(aElems[i]))
[ # # ][ # # ]
[ # # ]
182 : 0 : break;
183 [ # # ][ # # ]: 0 : else if (mxChildrenStorages.back().ref->IsStorage(aElems[i]))
[ # # ][ # # ]
[ # # ]
184 : : {
185 [ # # ]: 0 : SotStorageRef tmpParent(mxChildrenStorages.back().ref);
186 [ # # ][ # # ]: 0 : storageRefWrapper.ref = tmpParent->OpenSotStorage(aElems[i++], STREAM_STD_READ);
[ # # ][ # # ]
187 [ # # ][ # # ]: 0 : mxChildrenStorages.push_back(storageRefWrapper);
188 : : }
189 : : else
190 : : // should not happen
191 : 0 : return 0;
192 : : }
193 : :
194 : : // For the while don't return stream in this situation.
195 : : // Later, given how libcdr's zip stream implementation behaves,
196 : : // return the first stream in the storage if there is one.
197 [ # # ]: 0 : if (i >= aElems.size())
198 : 0 : return 0;
199 : :
200 [ # # ]: 0 : SotStorageStreamRefWrapper storageStreamRefWrapper;
201 [ # # ][ # # ]: 0 : storageStreamRefWrapper.ref = mxChildrenStorages.back().ref->OpenSotStream( aElems[i], STREAM_STD_READ );
[ # # ][ # # ]
[ # # ]
202 [ # # ]: 0 : mxChildrenStreams.push_back( storageStreamRefWrapper );
203 : :
204 [ # # ][ # # ]: 0 : mxSeekable->seek(tmpPosition);
205 : :
206 [ # # ][ # # ]: 0 : if ( !mxChildrenStreams.back().ref.Is() || mxChildrenStreams.back().ref->GetError() )
[ # # ][ # # ]
[ # # ]
207 : : {
208 [ # # ][ # # ]: 0 : mxSeekable->seek(tmpPosition);
209 : 0 : return 0;
210 : : }
211 : :
212 [ # # ][ # # ]: 0 : Reference < XInputStream > xContents(new utl::OSeekableInputStreamWrapper( mxChildrenStreams.back().ref ));
[ # # ][ # # ]
213 [ # # ][ # # ]: 0 : mxSeekable->seek(tmpPosition);
214 [ # # ]: 0 : if (xContents.is())
215 [ # # ][ # # ]: 0 : return new WPXSvInputStream( xContents );
216 : : else
217 [ # # ][ # # ]: 20 : return 0;
218 : : }
219 : :
220 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|