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 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 53 CStgTransferHelper::~CStgTransferHelper( ) 54 { 55 if ( m_lpStream ) 56 m_lpStream->Release( ); 57 } 58 59 //------------------------------------------------------------------------ 60 // TransferData into the 61 //------------------------------------------------------------------------ 62 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 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 103 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 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 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 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 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 202 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