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_sot.hxx" 26 27 #include "rtl/string.h" 28 #include "rtl/string.h" 29 #include "stgole.hxx" 30 #include "sot/storinfo.hxx" // Read/WriteClipboardFormat() 31 32 #include <tools/debug.hxx> 33 #if defined(_MSC_VER) && (_MSC_VER>=1400) 34 #pragma warning(disable: 4342) 35 #endif 36 ///////////////////////// class StgInternalStream //////////////////////// 37 38 StgInternalStream::StgInternalStream 39 ( BaseStorage& rStg, const String& rName, sal_Bool bWr ) 40 { 41 bIsWritable = sal_True; 42 sal_uInt16 nMode = bWr 43 ? STREAM_WRITE | STREAM_SHARE_DENYALL 44 : STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE; 45 pStrm = rStg.OpenStream( rName, nMode ); 46 47 // set the error code right here in the stream 48 SetError( rStg.GetError() ); 49 SetBufferSize( 1024 ); 50 } 51 52 StgInternalStream::~StgInternalStream() 53 { 54 delete pStrm; 55 } 56 57 sal_uLong StgInternalStream::GetData( void* pData, sal_uLong nSize ) 58 { 59 if( pStrm ) 60 { 61 nSize = pStrm->Read( pData, nSize ); 62 SetError( pStrm->GetError() ); 63 return nSize; 64 } 65 else 66 return 0; 67 } 68 69 sal_uLong StgInternalStream::PutData( const void* pData, sal_uLong nSize ) 70 { 71 if( pStrm ) 72 { 73 nSize = pStrm->Write( pData, nSize ); 74 SetError( pStrm->GetError() ); 75 return nSize; 76 } 77 else 78 return 0; 79 } 80 81 sal_uLong StgInternalStream::SeekPos( sal_uLong nPos ) 82 { 83 return pStrm ? pStrm->Seek( nPos ) : 0; 84 } 85 86 void StgInternalStream::FlushData() 87 { 88 if( pStrm ) 89 { 90 pStrm->Flush(); 91 SetError( pStrm->GetError() ); 92 } 93 } 94 95 void StgInternalStream::Commit() 96 { 97 Flush(); 98 pStrm->Commit(); 99 } 100 101 ///////////////////////// class StgCompObjStream ///////////////////////// 102 103 StgCompObjStream::StgCompObjStream( BaseStorage& rStg, sal_Bool bWr ) 104 : StgInternalStream( rStg, String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1CompObj" ) ), bWr ) 105 { 106 memset( &aClsId, 0, sizeof( ClsId ) ); 107 nCbFormat = 0; 108 } 109 110 sal_Bool StgCompObjStream::Load() 111 { 112 memset( &aClsId, 0, sizeof( ClsId ) ); 113 nCbFormat = 0; 114 aUserName.Erase(); 115 if( GetError() != SVSTREAM_OK ) 116 return sal_False; 117 Seek( 8L ); // skip the first part 118 sal_Int32 nMarker = 0; 119 *this >> nMarker; 120 if( nMarker == -1L ) 121 { 122 *this >> aClsId; 123 sal_Int32 nLen1 = 0; 124 *this >> nLen1; 125 if ( nLen1 > 0 ) 126 { 127 // higher bits are ignored 128 sal_uLong nStrLen = ::std::min( nLen1, (sal_Int32)0xFFFE ); 129 130 sal_Char* p = new sal_Char[ nStrLen+1 ]; 131 p[nStrLen] = 0; 132 if( Read( p, nStrLen ) == nStrLen ) 133 { 134 aUserName = nStrLen ? String( p, gsl_getSystemTextEncoding() ) : String(); 135 nCbFormat = ReadClipboardFormat( *this ); 136 } 137 else 138 SetError( SVSTREAM_GENERALERROR ); 139 delete [] p; 140 } 141 } 142 return sal_Bool( GetError() == SVSTREAM_OK ); 143 } 144 145 sal_Bool StgCompObjStream::Store() 146 { 147 if( GetError() != SVSTREAM_OK ) 148 return sal_False; 149 Seek( 0L ); 150 ByteString aAsciiUserName( aUserName, RTL_TEXTENCODING_ASCII_US ); 151 *this << (sal_Int16) 1 // Version? 152 << (sal_Int16) -2 // 0xFFFE = Byte Order Indicator 153 << (sal_Int32) 0x0A03 // Windows 3.10 154 << (sal_Int32) -1L 155 << aClsId // Class ID 156 << (sal_Int32) (aAsciiUserName.Len() + 1) 157 << (const char *)aAsciiUserName.GetBuffer() 158 << (sal_uInt8) 0; // string terminator 159 /* // determine the clipboard format string 160 String aCbFmt; 161 if( nCbFormat > FORMAT_GDIMETAFILE ) 162 aCbFmt = Exchange::GetFormatName( nCbFormat ); 163 if( aCbFmt.Len() ) 164 *this << (sal_Int32) aCbFmt.Len() + 1 165 << (const char*) aCbFmt 166 << (sal_uInt8) 0; 167 else if( nCbFormat ) 168 *this << (sal_Int32) -1 // for Windows 169 << (sal_Int32) nCbFormat; 170 else 171 *this << (sal_Int32) 0; // no clipboard format 172 */ 173 WriteClipboardFormat( *this, nCbFormat ); 174 *this << (sal_Int32) 0; // terminator 175 Commit(); 176 return sal_Bool( GetError() == SVSTREAM_OK ); 177 } 178 179 /////////////////////////// class StgOleStream /////////////////////////// 180 181 StgOleStream::StgOleStream( BaseStorage& rStg, sal_Bool bWr ) 182 : StgInternalStream( rStg, String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole" ) ), bWr ) 183 { 184 nFlags = 0; 185 } 186 187 sal_Bool StgOleStream::Load() 188 { 189 nFlags = 0; 190 if( GetError() != SVSTREAM_OK ) 191 return sal_False; 192 sal_Int32 version = 0; 193 Seek( 0L ); 194 *this >> version >> nFlags; 195 return sal_Bool( GetError() == SVSTREAM_OK ); 196 } 197 198 sal_Bool StgOleStream::Store() 199 { 200 if( GetError() != SVSTREAM_OK ) 201 return sal_False; 202 Seek( 0L ); 203 *this << (sal_Int32) 0x02000001 // OLE version, format 204 << (sal_Int32) nFlags // Object flags 205 << (sal_Int32) 0 // Update Options 206 << (sal_Int32) 0 // reserved 207 << (sal_Int32) 0; // Moniker 1 208 Commit(); 209 return sal_Bool( GetError() == SVSTREAM_OK ); 210 } 211 212