xref: /trunk/main/dtrans/source/win32/dtobj/DTransHelper.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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