1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
30 
31 #include "xmxtrct.hxx"
32 
33 #include <rtl/memory.h>
34 #include <tools/zcodec.hxx>
35 #include <unotools/streamhelper.hxx>
36 #include <sot/storage.hxx>
37 
38 // ----------------
39 // - XMXLockBytes -
40 // ----------------
41 
42 class XMXLockBytes : public SvLockBytes
43 {
44 	REF( NMSP_IO::XInputStream ) 	mxIStm;
45 	SEQ( sal_Int8 )					maSeq;
46 
47 									XMXLockBytes();
48 
49 public:
50 
51 									XMXLockBytes( const REF( NMSP_IO::XInputStream )& rxIStm );
52 	virtual							~XMXLockBytes();
53 
54 	virtual ErrCode					ReadAt( sal_Size nPos, void* pBuffer, sal_Size nCount, sal_Size* pRead ) const;
55 	virtual ErrCode					WriteAt( sal_Size nPos, const void* pBuffer, sal_Size nCount, sal_Size* pWritten );
56 	virtual ErrCode					Flush() const;
57 	virtual ErrCode					SetSize( sal_Size nSize );
58 	virtual ErrCode					Stat( SvLockBytesStat*, SvLockBytesStatFlag ) const;
59 };
60 
61 // ------------------------------------------------------------------------
62 
63 XMXLockBytes::XMXLockBytes( const REF( NMSP_IO::XInputStream )& rxIStm ) :
64 	mxIStm( rxIStm )
65 {
66 	if( mxIStm.is() )
67 	{
68 		const sal_uInt32	nBytesToRead = 65535;
69 		sal_uInt32			nRead;
70 
71 		do
72 		{
73 			SEQ( sal_Int8 ) aReadSeq;
74 
75 			nRead = mxIStm->readSomeBytes( aReadSeq, nBytesToRead );
76 
77 			if( nRead )
78 			{
79 				const sal_uInt32 nOldLength = maSeq.getLength();
80 				maSeq.realloc( nOldLength + nRead );
81 				rtl_copyMemory( maSeq.getArray() + nOldLength, aReadSeq.getConstArray(), aReadSeq.getLength() );
82 			}
83 		}
84 		while( nBytesToRead == nRead );
85 	}
86 }
87 
88 // ------------------------------------------------------------------------
89 
90 XMXLockBytes::~XMXLockBytes()
91 {
92 }
93 
94 // ------------------------------------------------------------------------
95 
96 ErrCode XMXLockBytes::ReadAt( sal_Size nPos, void* pBuffer, sal_Size nCount, sal_Size* pRead ) const
97 {
98 	const sal_Size		nSeqLen = maSeq.getLength();
99 	ErrCode				nErr = ERRCODE_NONE;
100 
101 	if( nPos < nSeqLen )
102 	{
103 		if( ( nPos + nCount ) > nSeqLen )
104 			nCount = nSeqLen - nPos;
105 
106 		rtl_copyMemory( pBuffer, maSeq.getConstArray() + nPos, nCount );
107 		*pRead = nCount;
108 	}
109 	else
110 		*pRead = 0UL;
111 
112 	return nErr;
113 }
114 
115 // ------------------------------------------------------------------------
116 
117 ErrCode XMXLockBytes::WriteAt( sal_Size /*nPos*/, const void* /*pBuffer*/, sal_Size /*nCount*/, sal_Size* /*pWritten*/ )
118 {
119 	return ERRCODE_IO_CANTWRITE;
120 }
121 
122 // ------------------------------------------------------------------------
123 
124 ErrCode XMXLockBytes::Flush() const
125 {
126 	return ERRCODE_NONE;
127 }
128 
129 // ------------------------------------------------------------------------
130 
131 ErrCode XMXLockBytes::SetSize( sal_Size /*nSize*/ )
132 {
133 	return ERRCODE_IO_CANTWRITE;
134 }
135 
136 // ------------------------------------------------------------------------
137 
138 ErrCode XMXLockBytes::Stat( SvLockBytesStat* pStat, SvLockBytesStatFlag /*eFlag*/ ) const
139 {
140 	pStat->nSize = maSeq.getLength();
141 	return ERRCODE_NONE;
142 }
143 
144 // ----------------
145 // - XMLExtractor -
146 // ----------------
147 
148 XMLExtractor::XMLExtractor( const REF( NMSP_LANG::XMultiServiceFactory )& rxMgr ) :
149 	mxFact( rxMgr )
150 {
151 }
152 
153 // -----------------------------------------------------------------------------
154 
155 XMLExtractor::~XMLExtractor()
156 {
157 }
158 
159 // -----------------------------------------------------------------------------
160 
161 REF( NMSP_IO::XInputStream ) SAL_CALL XMLExtractor::extract( const REF( NMSP_IO::XInputStream )& rxIStm ) throw( NMSP_UNO::RuntimeException )
162 {
163 	REF( NMSP_IO::XInputStream ) xRet;
164 
165 	if( rxIStm.is() )
166 	{
167 		SvStream		aIStm( new XMXLockBytes( rxIStm ) );
168 		SvStorageRef	aStorage( new SvStorage( aIStm ) );
169 		String			aStmName;
170 		const String	aFormat1( String::CreateFromAscii( "XMLFormat" ) );
171 		const String	aFormat2( String::CreateFromAscii( "XMLFormat2" ) );
172 
173 		if( aStorage->IsContained( aFormat2 ) )
174 			aStmName = aFormat2;
175 		else if( aStorage->IsContained( aFormat1 ) )
176 			aStmName = aFormat1;
177 
178 		if( !aStorage->GetError() && aStmName.Len() && aStorage->IsStream( aStmName ) )
179 		{
180             SvStorageStreamRef xStream( aStorage->OpenSotStream( aStmName ) );
181 
182 			if( xStream.Is() )
183 			{
184 				SvMemoryStream*	pMemStm = new SvMemoryStream( 65535, 65535 );
185 				ZCodec			aCodec;
186 
187 				aCodec.BeginCompression( ZCODEC_BEST_COMPRESSION );
188 				aCodec.Decompress( *xStream, *pMemStm );
189 				aCodec.EndCompression();
190 
191 				xRet = new ::utl::OInputStreamHelper( new SvLockBytes( pMemStm, sal_True ), 65535 );
192 			}
193 		}
194 	}
195 
196 	return xRet;
197 }
198