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