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