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