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_dtrans.hxx"
30 
31 //------------------------------------------------------------------------
32 // includes
33 //------------------------------------------------------------------------
34 #include <rtl/ustring.h>
35 #include <osl/diagnose.h>
36 #include "DTransHelper.hxx"
37 
38 //------------------------------------------------------------------------
39 // implementation
40 //------------------------------------------------------------------------
41 
42 CStgTransferHelper::CStgTransferHelper( sal_Bool bAutoInit,
43 										HGLOBAL hGlob,
44 										sal_Bool bDelStgOnRelease ) :
45 	m_lpStream( NULL ),
46 	m_bDelStgOnRelease( bDelStgOnRelease )
47 {
48 	if ( bAutoInit )
49 		init( hGlob, m_bDelStgOnRelease );
50 }
51 
52 //------------------------------------------------------------------------
53 // dtor
54 //------------------------------------------------------------------------
55 
56 
57 CStgTransferHelper::~CStgTransferHelper( )
58 {
59 	if ( m_lpStream )
60 		m_lpStream->Release( );
61 }
62 
63 //------------------------------------------------------------------------
64 // TransferData into the
65 //------------------------------------------------------------------------
66 
67 void SAL_CALL CStgTransferHelper::write( const void* lpData, ULONG cb, ULONG* cbWritten )
68 {
69 	HRESULT hr = E_FAIL;
70 
71 	if ( m_lpStream )
72 		hr = m_lpStream->Write( lpData, cb, cbWritten );
73 
74 	if ( FAILED( hr ) )
75 		throw CStgTransferException( hr );
76 
77 #if OSL_DEBUG_LEVEL > 0
78 	HGLOBAL hGlob;
79 	hr = GetHGlobalFromStream( m_lpStream, &hGlob );
80 	OSL_ASSERT( SUCCEEDED( hr ) );
81 
82 	/*DWORD dwSize =*/ GlobalSize( hGlob );
83 	/*LPVOID lpdbgData =*/ GlobalLock( hGlob );
84 	GlobalUnlock( hGlob );
85 #endif
86 }
87 
88 //------------------------------------------------------------------------
89 // read
90 //------------------------------------------------------------------------
91 
92 void SAL_CALL CStgTransferHelper::read( LPVOID pv, ULONG cb, ULONG* pcbRead )
93 {
94 	HRESULT hr = E_FAIL;
95 
96 	if ( m_lpStream )
97 		hr = m_lpStream->Read( pv, cb , pcbRead );
98 
99 	if ( FAILED( hr ) )
100 		throw CStgTransferException( hr );
101 }
102 
103 //------------------------------------------------------------------------
104 // GetHGlobal
105 //------------------------------------------------------------------------
106 
107 HGLOBAL SAL_CALL CStgTransferHelper::getHGlobal( ) const
108 {
109 	OSL_ASSERT( m_lpStream );
110 
111 	HGLOBAL hGlob = NULL;
112 
113 	if ( m_lpStream )
114 	{
115 		HRESULT hr = GetHGlobalFromStream( m_lpStream, &hGlob );
116 		if ( FAILED( hr ) )
117 			hGlob = NULL;
118 	}
119 
120 	return hGlob;
121 }
122 
123 //------------------------------------------------------------------------
124 // getIStream
125 //------------------------------------------------------------------------
126 
127 void SAL_CALL CStgTransferHelper::getIStream( LPSTREAM* ppStream )
128 {
129 	OSL_ASSERT( ppStream );
130 	*ppStream = m_lpStream;
131 	if ( *ppStream )
132 		static_cast< LPUNKNOWN >( *ppStream )->AddRef( );
133 }
134 
135 //------------------------------------------------------------------------
136 // Init
137 //------------------------------------------------------------------------
138 
139 void SAL_CALL CStgTransferHelper::init( SIZE_T newSize,
140 									    sal_uInt32 uiFlags,
141 										sal_Bool bDelStgOnRelease )
142 {
143 	cleanup( );
144 
145 	m_bDelStgOnRelease      = bDelStgOnRelease;
146 
147 	HGLOBAL hGlob = GlobalAlloc( uiFlags, newSize );
148 	if ( NULL == hGlob )
149 		throw CStgTransferException( STG_E_MEDIUMFULL );
150 
151 	HRESULT hr = CreateStreamOnHGlobal( hGlob, m_bDelStgOnRelease, &m_lpStream );
152 	if ( FAILED( hr ) )
153 	{
154 		GlobalFree( hGlob );
155 		m_lpStream = NULL;
156 		throw CStgTransferException( hr );
157 	}
158 
159 #if OSL_DEBUG_LEVEL > 0
160 	STATSTG statstg;
161 	hr = m_lpStream->Stat( &statstg, STATFLAG_DEFAULT );
162 	OSL_ASSERT( SUCCEEDED( hr ) );
163 #endif
164 }
165 
166 //------------------------------------------------------------------------
167 // Init
168 //------------------------------------------------------------------------
169 
170 void SAL_CALL CStgTransferHelper::init( HGLOBAL hGlob,
171 						 			    sal_Bool bDelStgOnRelease )
172 {
173 	cleanup( );
174 
175 	m_bDelStgOnRelease      = bDelStgOnRelease;
176 
177 	HRESULT hr = CreateStreamOnHGlobal( hGlob, m_bDelStgOnRelease, &m_lpStream );
178 	if ( FAILED( hr ) )
179 		throw CStgTransferException( hr );
180 }
181 
182 //------------------------------------------------------------------------
183 // free the global memory and invalidate the stream pointer
184 //------------------------------------------------------------------------
185 
186 void SAL_CALL CStgTransferHelper::cleanup( )
187 {
188 	if ( m_lpStream && !m_bDelStgOnRelease )
189 	{
190 		HGLOBAL hGlob;
191 		GetHGlobalFromStream( m_lpStream, &hGlob );
192 		GlobalFree( hGlob );
193 	}
194 
195 	if ( m_lpStream )
196 	{
197 		m_lpStream->Release( );
198 		m_lpStream = NULL;
199 	}
200 }
201 
202 //------------------------------------------------------------------------
203 // return the size of memory we point to
204 //------------------------------------------------------------------------
205 
206 sal_uInt32 SAL_CALL CStgTransferHelper::memSize( CLIPFORMAT cf ) const
207 {
208 	DWORD dwSize = 0;
209 
210 	if ( NULL != m_lpStream )
211 	{
212 		HGLOBAL hGlob;
213 		GetHGlobalFromStream( m_lpStream, &hGlob );
214 
215 		if ( CF_TEXT == cf || RegisterClipboardFormat( "HTML Format" ) == cf )
216 		{
217 			sal_Char* pText = static_cast< sal_Char* >( GlobalLock( hGlob ) );
218 			if ( pText )
219 			{
220 				dwSize = strlen(pText) + 1; // strlen + trailing '\0'
221 				GlobalUnlock( hGlob );
222 			}
223 		}
224 		else if ( CF_UNICODETEXT == cf )
225 		{
226 			sal_Unicode* pText = static_cast< sal_Unicode* >( GlobalLock( hGlob ) );
227 			if ( pText )
228 			{
229 				dwSize = rtl_ustr_getLength( pText ) * sizeof( sal_Unicode );
230 				GlobalUnlock( hGlob );
231 			}
232 		}
233 		else
234 			dwSize = GlobalSize( hGlob );
235 	}
236 
237 	return dwSize;
238 }
239 
240