1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_extensions.hxx"
26 
27 #include "xmxtrct.hxx"
28 
29 #include <rtl/memory.h>
30 #include <tools/zcodec.hxx>
31 #include <unotools/streamhelper.hxx>
32 #include <sot/storage.hxx>
33 
34 // ----------------
35 // - XMXLockBytes -
36 // ----------------
37 
38 class XMXLockBytes : public SvLockBytes
39 {
40 	REF( NMSP_IO::XInputStream ) 	mxIStm;
41 	SEQ( sal_Int8 )					maSeq;
42 
43 									XMXLockBytes();
44 
45 public:
46 
47 									XMXLockBytes( const REF( NMSP_IO::XInputStream )& rxIStm );
48 	virtual							~XMXLockBytes();
49 
50 	virtual ErrCode					ReadAt( sal_Size nPos, void* pBuffer, sal_Size nCount, sal_Size* pRead ) const;
51 	virtual ErrCode					WriteAt( sal_Size nPos, const void* pBuffer, sal_Size nCount, sal_Size* pWritten );
52 	virtual ErrCode					Flush() const;
53 	virtual ErrCode					SetSize( sal_Size nSize );
54 	virtual ErrCode					Stat( SvLockBytesStat*, SvLockBytesStatFlag ) const;
55 };
56 
57 // ------------------------------------------------------------------------
58 
XMXLockBytes(const REF (NMSP_IO::XInputStream)& rxIStm)59 XMXLockBytes::XMXLockBytes( const REF( NMSP_IO::XInputStream )& rxIStm ) :
60 	mxIStm( rxIStm )
61 {
62 	if( mxIStm.is() )
63 	{
64 		const sal_uInt32	nBytesToRead = 65535;
65 		sal_uInt32			nRead;
66 
67 		do
68 		{
69 			SEQ( sal_Int8 ) aReadSeq;
70 
71 			nRead = mxIStm->readSomeBytes( aReadSeq, nBytesToRead );
72 
73 			if( nRead )
74 			{
75 				const sal_uInt32 nOldLength = maSeq.getLength();
76 				maSeq.realloc( nOldLength + nRead );
77 				rtl_copyMemory( maSeq.getArray() + nOldLength, aReadSeq.getConstArray(), aReadSeq.getLength() );
78 			}
79 		}
80 		while( nBytesToRead == nRead );
81 	}
82 }
83 
84 // ------------------------------------------------------------------------
85 
~XMXLockBytes()86 XMXLockBytes::~XMXLockBytes()
87 {
88 }
89 
90 // ------------------------------------------------------------------------
91 
ReadAt(sal_Size nPos,void * pBuffer,sal_Size nCount,sal_Size * pRead) const92 ErrCode XMXLockBytes::ReadAt( sal_Size nPos, void* pBuffer, sal_Size nCount, sal_Size* pRead ) const
93 {
94 	const sal_Size		nSeqLen = maSeq.getLength();
95 	ErrCode				nErr = ERRCODE_NONE;
96 
97 	if( nPos < nSeqLen )
98 	{
99 		if( ( nPos + nCount ) > nSeqLen )
100 			nCount = nSeqLen - nPos;
101 
102 		rtl_copyMemory( pBuffer, maSeq.getConstArray() + nPos, nCount );
103 		*pRead = nCount;
104 	}
105 	else
106 		*pRead = 0UL;
107 
108 	return nErr;
109 }
110 
111 // ------------------------------------------------------------------------
112 
WriteAt(sal_Size,const void *,sal_Size,sal_Size *)113 ErrCode XMXLockBytes::WriteAt( sal_Size /*nPos*/, const void* /*pBuffer*/, sal_Size /*nCount*/, sal_Size* /*pWritten*/ )
114 {
115 	return ERRCODE_IO_CANTWRITE;
116 }
117 
118 // ------------------------------------------------------------------------
119 
Flush() const120 ErrCode XMXLockBytes::Flush() const
121 {
122 	return ERRCODE_NONE;
123 }
124 
125 // ------------------------------------------------------------------------
126 
SetSize(sal_Size)127 ErrCode XMXLockBytes::SetSize( sal_Size /*nSize*/ )
128 {
129 	return ERRCODE_IO_CANTWRITE;
130 }
131 
132 // ------------------------------------------------------------------------
133 
Stat(SvLockBytesStat * pStat,SvLockBytesStatFlag) const134 ErrCode XMXLockBytes::Stat( SvLockBytesStat* pStat, SvLockBytesStatFlag /*eFlag*/ ) const
135 {
136 	pStat->nSize = maSeq.getLength();
137 	return ERRCODE_NONE;
138 }
139 
140 // ----------------
141 // - XMLExtractor -
142 // ----------------
143 
XMLExtractor(const REF (NMSP_LANG::XMultiServiceFactory)& rxMgr)144 XMLExtractor::XMLExtractor( const REF( NMSP_LANG::XMultiServiceFactory )& rxMgr ) :
145 	mxFact( rxMgr )
146 {
147 }
148 
149 // -----------------------------------------------------------------------------
150 
~XMLExtractor()151 XMLExtractor::~XMLExtractor()
152 {
153 }
154 
155 // -----------------------------------------------------------------------------
156 
REF(NMSP_IO::XInputStream)157 REF( NMSP_IO::XInputStream ) SAL_CALL XMLExtractor::extract( const REF( NMSP_IO::XInputStream )& rxIStm ) throw( NMSP_UNO::RuntimeException )
158 {
159 	REF( NMSP_IO::XInputStream ) xRet;
160 
161 	if( rxIStm.is() )
162 	{
163 		SvStream		aIStm( new XMXLockBytes( rxIStm ) );
164 		SvStorageRef	aStorage( new SvStorage( aIStm ) );
165 		String			aStmName;
166 		const String	aFormat1( String::CreateFromAscii( "XMLFormat" ) );
167 		const String	aFormat2( String::CreateFromAscii( "XMLFormat2" ) );
168 
169 		if( aStorage->IsContained( aFormat2 ) )
170 			aStmName = aFormat2;
171 		else if( aStorage->IsContained( aFormat1 ) )
172 			aStmName = aFormat1;
173 
174 		if( !aStorage->GetError() && aStmName.Len() && aStorage->IsStream( aStmName ) )
175 		{
176             SvStorageStreamRef xStream( aStorage->OpenSotStream( aStmName ) );
177 
178 			if( xStream.Is() )
179 			{
180 				SvMemoryStream*	pMemStm = new SvMemoryStream( 65535, 65535 );
181 				ZCodec			aCodec;
182 
183 				aCodec.BeginCompression( ZCODEC_BEST_COMPRESSION );
184 				aCodec.Decompress( *xStream, *pMemStm );
185 				aCodec.EndCompression();
186 
187 				xRet = new ::utl::OInputStreamHelper( new SvLockBytes( pMemStm, sal_True ), 65535 );
188 			}
189 		}
190 	}
191 
192 	return xRet;
193 }
194