LibreOffice Module dtrans (master)  1
DTransHelper.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <rtl/ustring.h>
21 #include <osl/diagnose.h>
22 #include "DTransHelper.hxx"
23 
24 // implementation
25 
27  HGLOBAL hGlob,
28  bool bDelStgOnRelease ) :
29  m_lpStream( nullptr ),
30  m_bDelStgOnRelease( bDelStgOnRelease )
31 {
32  if ( bAutoInit )
33  init( hGlob, m_bDelStgOnRelease );
34 }
35 
36 // dtor
37 
39 {
40  if ( m_lpStream )
41  m_lpStream->Release( );
42 }
43 
44 // TransferData into the
45 
46 void CStgTransferHelper::write( const void* lpData, ULONG cb, ULONG* cbWritten )
47 {
48  HRESULT hr = E_FAIL;
49 
50  if ( m_lpStream )
51  hr = m_lpStream->Write( lpData, cb, cbWritten );
52 
53  if ( FAILED( hr ) )
54  throw CStgTransferException( hr );
55 
56 #if OSL_DEBUG_LEVEL > 0
57  HGLOBAL hGlob;
58  hr = GetHGlobalFromStream( m_lpStream, &hGlob );
59  OSL_ASSERT( SUCCEEDED( hr ) );
60 
61  /*DWORD dwSize =*/ GlobalSize( hGlob );
62  /*LPVOID lpdbgData =*/ GlobalLock( hGlob );
63  GlobalUnlock( hGlob );
64 #endif
65 }
66 
67 // read
68 
69 void CStgTransferHelper::read( LPVOID pv, ULONG cb, ULONG* pcbRead )
70 {
71  HRESULT hr = E_FAIL;
72 
73  if ( m_lpStream )
74  hr = m_lpStream->Read( pv, cb , pcbRead );
75 
76  if ( FAILED( hr ) )
77  throw CStgTransferException( hr );
78 }
79 
80 // GetHGlobal
81 
83 {
84  OSL_ASSERT( m_lpStream );
85 
86  HGLOBAL hGlob = nullptr;
87 
88  if ( m_lpStream )
89  {
90  HRESULT hr = GetHGlobalFromStream( m_lpStream, &hGlob );
91  if ( FAILED( hr ) )
92  hGlob = nullptr;
93  }
94 
95  return hGlob;
96 }
97 
98 // getIStream
99 
100 void CStgTransferHelper::getIStream( LPSTREAM* ppStream )
101 {
102  OSL_ASSERT( ppStream );
103  *ppStream = m_lpStream;
104  if ( *ppStream )
105  static_cast< LPUNKNOWN >( *ppStream )->AddRef( );
106 }
107 
108 // Init
109 
110 void CStgTransferHelper::init( SIZE_T newSize,
111  sal_uInt32 uiFlags,
112  bool bDelStgOnRelease )
113 {
114  cleanup( );
115 
116  m_bDelStgOnRelease = bDelStgOnRelease;
117 
118  HGLOBAL hGlob = GlobalAlloc( uiFlags, newSize );
119  if ( nullptr == hGlob )
120  throw CStgTransferException( STG_E_MEDIUMFULL );
121 
122  HRESULT hr = CreateStreamOnHGlobal( hGlob, m_bDelStgOnRelease, &m_lpStream );
123  if ( FAILED( hr ) )
124  {
125  GlobalFree( hGlob );
126  m_lpStream = nullptr;
127  throw CStgTransferException( hr );
128  }
129 
130 #if OSL_DEBUG_LEVEL > 0
131  STATSTG statstg;
132  hr = m_lpStream->Stat( &statstg, STATFLAG_DEFAULT );
133  OSL_ASSERT( SUCCEEDED( hr ) );
134 #endif
135 }
136 
137 // Init
138 
139 void CStgTransferHelper::init( HGLOBAL hGlob,
140  bool bDelStgOnRelease )
141 {
142  cleanup( );
143 
144  m_bDelStgOnRelease = bDelStgOnRelease;
145 
146  HRESULT hr = CreateStreamOnHGlobal( hGlob, m_bDelStgOnRelease, &m_lpStream );
147  if ( FAILED( hr ) )
148  throw CStgTransferException( hr );
149 }
150 
151 // free the global memory and invalidate the stream pointer
152 
154 {
155  if ( m_lpStream && !m_bDelStgOnRelease )
156  {
157  HGLOBAL hGlob;
158  GetHGlobalFromStream( m_lpStream, &hGlob );
159  GlobalFree( hGlob );
160  }
161 
162  if ( m_lpStream )
163  {
164  m_lpStream->Release( );
165  m_lpStream = nullptr;
166  }
167 }
168 
169 // return the size of memory we point to
170 
171 sal_uInt32 CStgTransferHelper::memSize( CLIPFORMAT cf ) const
172 {
173  DWORD dwSize = 0;
174 
175  if ( nullptr != m_lpStream )
176  {
177  HGLOBAL hGlob;
178  GetHGlobalFromStream( m_lpStream, &hGlob );
179 
180  if ( CF_TEXT == cf || RegisterClipboardFormatW( L"HTML Format" ) == cf )
181  {
182  char* pText = static_cast< char* >( GlobalLock( hGlob ) );
183  if ( pText )
184  {
185  dwSize = strlen(pText) + 1; // strlen + trailing '\0'
186  GlobalUnlock( hGlob );
187  }
188  }
189  else if ( CF_UNICODETEXT == cf )
190  {
191  sal_Unicode* pText = static_cast< sal_Unicode* >( GlobalLock( hGlob ) );
192  if ( pText )
193  {
194  dwSize = rtl_ustr_getLength( pText ) * sizeof( sal_Unicode );
195  GlobalUnlock( hGlob );
196  }
197  }
198  else
199  dwSize = GlobalSize( hGlob );
200  }
201 
202  return dwSize;
203 }
204 
205 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
CStgTransferHelper(bool bAutoInit=false, HGLOBAL hGlob=nullptr, bool bDelStgOnRelease=false)
sal_uInt32 memSize(CLIPFORMAT cf=CF_INVALID) const
EXTERN_C BOOL BOOL const wchar_t *pProgramPath HRESULT hr
HGLOBAL getHGlobal() const
sal_uInt16 sal_Unicode
void getIStream(LPSTREAM *ppStream)
void write(const void *lpData, ULONG cb, ULONG *cbWritten=nullptr)
void init(SIZE_T newSize, sal_uInt32 uiFlags=GHND, bool bDelStgOnRelease=false)
void read(LPVOID pv, ULONG cb, ULONG *pcbRead=nullptr)