1 #include "WPXSvStream.h"
2 #include "filter/FilterInternal.hxx"
3 #include <tools/stream.hxx>
4 #include <unotools/streamwrap.hxx>
5 #include <unotools/ucbstreamhelper.hxx>
6 #include <limits>
7 
8 using namespace ::com::sun::star::uno;
9 using namespace ::com::sun::star::io;
10 
WPXSvInputStream(Reference<XInputStream> xStream)11 WPXSvInputStream::WPXSvInputStream( Reference< XInputStream > xStream ) :
12 		WPXInputStream(true),
13 		mxChildStorage(),
14 		mxChildStream(),
15 		mxStream(xStream),
16 		mxSeekable(xStream, UNO_QUERY),
17 		maData(0)
18 {
19 	if (!xStream.is() || !mxStream.is())
20 		mnLength = 0;
21 	else
22 	{
23 		if (!mxSeekable.is())
24 			mnLength = 0;
25 		else
26 		{
27 			try
28 			{
29 				mnLength = mxSeekable->getLength();
30 			}
31 			catch ( ... )
32 			{
33 				WRITER_DEBUG_MSG(("mnLength = mxSeekable->getLength() threw exception\n"));
34 				mnLength = 0;
35 			}
36 		}
37 	}
38 }
39 
~WPXSvInputStream()40 WPXSvInputStream::~WPXSvInputStream()
41 {
42 }
43 
read(size_t numBytes,size_t & numBytesRead)44 const uint8_t * WPXSvInputStream::read(size_t numBytes, size_t &numBytesRead)
45 {
46 	numBytesRead = 0;
47 
48 	if (numBytes == 0 || atEOS())
49 		return 0;
50 
51 	numBytesRead = mxStream->readSomeBytes (maData, numBytes);
52 	if (numBytesRead == 0)
53 		return 0;
54 
55 	return (const uint8_t *)maData.getConstArray();
56 }
57 
tell()58 long WPXSvInputStream::tell()
59 {
60 	if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
61 		return -1L;
62 	else
63 	{
64 		sal_Int64 tmpPosition = mxSeekable->getPosition();
65 		if ((tmpPosition < 0) || (tmpPosition > (std::numeric_limits<long>::max)()))
66 			return -1L;
67 		return (long)tmpPosition;
68 	}
69 }
70 
seek(long offset,WPX_SEEK_TYPE seekType)71 int WPXSvInputStream::seek(long offset, WPX_SEEK_TYPE seekType)
72 {
73 	if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
74 		return -1;
75 
76 	sal_Int64 tmpPosition = mxSeekable->getPosition();
77 	if ((tmpPosition < 0) || (tmpPosition > (std::numeric_limits<long>::max)()))
78 		return -1;
79 
80 	sal_Int64 tmpOffset = offset;
81 	if (seekType == WPX_SEEK_CUR)
82 		tmpOffset += tmpPosition;
83 
84 	int retVal = 0;
85 	if (tmpOffset < 0)
86 	{
87 		tmpOffset = 0;
88 		retVal = -1;
89 	}
90 	if (offset > mnLength)
91 	{
92 		tmpOffset = mnLength;
93 		retVal = -1;
94 	}
95 
96 	try
97 	{
98 		mxSeekable->seek(tmpOffset);
99 		return retVal;
100 	}
101 	catch (...)
102 	{
103 		WRITER_DEBUG_MSG(("mxSeekable->seek(offset) threw exception\n"));
104 		return -1;
105 	}
106 }
107 
atEOS()108 bool WPXSvInputStream::atEOS()
109 {
110 	if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
111 		return true;
112 	return (mxSeekable->getPosition() >= mnLength);
113 }
114 
isOLEStream()115 bool WPXSvInputStream::isOLEStream()
116 {
117 	if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
118 		return false;
119 
120 	sal_Int64 tmpPosition = mxSeekable->getPosition();
121 	mxSeekable->seek(0);
122 
123 	SvStream *pStream = utl::UcbStreamHelper::CreateStream( mxStream );
124 	bool bAns = pStream && SotStorage::IsOLEStorage( pStream );
125 	if (pStream)
126 		delete pStream;
127 
128 	mxSeekable->seek(tmpPosition);
129 
130 	return bAns;
131 }
132 
getDocumentOLEStream(const char * name)133 WPXInputStream * WPXSvInputStream::getDocumentOLEStream(const char * name)
134 {
135 	if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
136 		return 0;
137 
138 	sal_Int64 tmpPosition = mxSeekable->getPosition();
139 	mxSeekable->seek(0);
140 
141 	SvStream *pStream = utl::UcbStreamHelper::CreateStream( mxStream );
142 
143 	if (!pStream || !SotStorage::IsOLEStorage( pStream ))
144 	{
145 		mxSeekable->seek(tmpPosition);
146 		return 0;
147 	}
148 
149 	mxChildStorage = new SotStorage( pStream, sal_True );
150 
151 	mxChildStream = mxChildStorage->OpenSotStream(
152 			rtl::OUString::createFromAscii( name ),
153 			STREAM_STD_READ );
154 
155 	mxSeekable->seek(tmpPosition);
156 
157 	if ( !mxChildStream.Is() || mxChildStream->GetError() )
158 	{
159 		mxSeekable->seek(tmpPosition);
160 		return 0;
161 	}
162 
163 	Reference < XInputStream > xContents(new utl::OSeekableInputStreamWrapper( mxChildStream ));
164 	mxSeekable->seek(tmpPosition);
165 	if (xContents.is())
166 		return new WPXSvInputStream( xContents );
167 	else
168 		return 0;
169 }
170 
getDocumentOLEStream()171 WPXInputStream * WPXSvInputStream::getDocumentOLEStream()
172 {
173 	return getDocumentOLEStream( "PerfectOffice_MAIN" );
174 }
175