001 #include "WPXSvStream.h"
002 #include "filter/FilterInternal.hxx"
003 #include <tools/stream.hxx>
004 #include <unotools/streamwrap.hxx>
005 #include <unotools/ucbstreamhelper.hxx>
006 #include <limits>
007
008 using namespace ::com::sun::star::uno;
009 using namespace ::com::sun::star::io;
010
011 WPXSvInputStream::WPXSvInputStream( Reference< XInputStream > xStream ) :
012 WPXInputStream(true),
013 mxChildStorage(),
014 mxChildStream(),
015 mxStream(xStream),
016 mxSeekable(xStream, UNO_QUERY),
017 maData(0)
018 {
019 if (!xStream.is() || !mxStream.is())
020 mnLength = 0;
021 else
022 {
023 if (!mxSeekable.is())
024 mnLength = 0;
025 else
026 {
027 try
028 {
029 mnLength = mxSeekable->getLength();
030 }
031 catch ( ... )
032 {
033 WRITER_DEBUG_MSG(("mnLength = mxSeekable->getLength() threw exception\n"));
034 mnLength = 0;
035 }
036 }
037 }
038 }
039
040 WPXSvInputStream::~WPXSvInputStream()
041 {
042 }
043
044 const uint8_t * WPXSvInputStream::read(size_t numBytes, size_t &numBytesRead)
045 {
046 numBytesRead = 0;
047
048 if (numBytes == 0 || atEOS())
049 return 0;
050
051 numBytesRead = mxStream->readSomeBytes (maData, numBytes);
052 if (numBytesRead == 0)
053 return 0;
054
055 return (const uint8_t *)maData.getConstArray();
056 }
057
058 long WPXSvInputStream::tell()
059 {
060 if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
061 return -1L;
062 else
063 {
064 sal_Int64 tmpPosition = mxSeekable->getPosition();
065 if ((tmpPosition < 0) || (tmpPosition > (std::numeric_limits<long>::max)()))
066 return -1L;
067 return (long)tmpPosition;
068 }
069 }
070
071 int WPXSvInputStream::seek(long offset, WPX_SEEK_TYPE seekType)
072 {
073 if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
074 return -1;
075
076 sal_Int64 tmpPosition = mxSeekable->getPosition();
077 if ((tmpPosition < 0) || (tmpPosition > (std::numeric_limits<long>::max)()))
078 return -1;
079
080 sal_Int64 tmpOffset = offset;
081 if (seekType == WPX_SEEK_CUR)
082 tmpOffset += tmpPosition;
083
084 int retVal = 0;
085 if (tmpOffset < 0)
086 {
087 tmpOffset = 0;
088 retVal = -1;
089 }
090 if (offset > mnLength)
091 {
092 tmpOffset = mnLength;
093 retVal = -1;
094 }
095
096 try
097 {
098 mxSeekable->seek(tmpOffset);
099 return retVal;
100 }
101 catch (...)
102 {
103 WRITER_DEBUG_MSG(("mxSeekable->seek(offset) threw exception\n"));
104 return -1;
105 }
106 }
107
108 bool WPXSvInputStream::atEOS()
109 {
110 if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
111 return true;
112 return (mxSeekable->getPosition() >= mnLength);
113 }
114
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
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, 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
171 WPXInputStream * WPXSvInputStream::getDocumentOLEStream()
172 {
173 return getDocumentOLEStream( "PerfectOffice_MAIN" );
174 }