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