Line data Source code
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/string.h"
21 : #include "stgole.hxx"
22 : #include "sot/storinfo.hxx"
23 :
24 : #ifdef _MSC_VER
25 : #pragma warning(disable: 4342)
26 : #endif
27 : ///////////////////////// class StgInternalStream
28 :
29 0 : StgInternalStream::StgInternalStream( BaseStorage& rStg, const OUString& rName, bool bWr )
30 : {
31 0 : bIsWritable = true;
32 : sal_uInt16 nMode = bWr
33 : ? STREAM_WRITE | STREAM_SHARE_DENYALL
34 0 : : STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE;
35 0 : pStrm = rStg.OpenStream( rName, nMode );
36 :
37 : // set the error code right here in the stream
38 0 : SetError( rStg.GetError() );
39 0 : SetBufferSize( 1024 );
40 0 : }
41 :
42 0 : StgInternalStream::~StgInternalStream()
43 : {
44 0 : delete pStrm;
45 0 : }
46 :
47 0 : sal_uLong StgInternalStream::GetData( void* pData, sal_uLong nSize )
48 : {
49 0 : if( pStrm )
50 : {
51 0 : nSize = pStrm->Read( pData, nSize );
52 0 : SetError( pStrm->GetError() );
53 0 : return nSize;
54 : }
55 : else
56 0 : return 0;
57 : }
58 :
59 0 : sal_uLong StgInternalStream::PutData( const void* pData, sal_uLong nSize )
60 : {
61 0 : if( pStrm )
62 : {
63 0 : nSize = pStrm->Write( pData, nSize );
64 0 : SetError( pStrm->GetError() );
65 0 : return nSize;
66 : }
67 : else
68 0 : return 0;
69 : }
70 :
71 0 : sal_uInt64 StgInternalStream::SeekPos(sal_uInt64 const nPos)
72 : {
73 0 : return pStrm ? pStrm->Seek( nPos ) : 0;
74 : }
75 :
76 0 : void StgInternalStream::FlushData()
77 : {
78 0 : if( pStrm )
79 : {
80 0 : pStrm->Flush();
81 0 : SetError( pStrm->GetError() );
82 : }
83 0 : }
84 :
85 0 : void StgInternalStream::Commit()
86 : {
87 0 : Flush();
88 0 : pStrm->Commit();
89 0 : }
90 :
91 : ///////////////////////// class StgCompObjStream
92 :
93 0 : StgCompObjStream::StgCompObjStream( BaseStorage& rStg, bool bWr )
94 0 : : StgInternalStream( rStg, OUString("\1CompObj"), bWr )
95 : {
96 0 : memset( &aClsId, 0, sizeof( ClsId ) );
97 0 : nCbFormat = 0;
98 0 : }
99 :
100 0 : bool StgCompObjStream::Load()
101 : {
102 0 : memset( &aClsId, 0, sizeof( ClsId ) );
103 0 : nCbFormat = 0;
104 0 : aUserName = "";
105 0 : if( GetError() != SVSTREAM_OK )
106 0 : return false;
107 0 : Seek( 8L ); // skip the first part
108 0 : sal_Int32 nMarker = 0;
109 0 : ReadInt32( nMarker );
110 0 : if( nMarker == -1L )
111 : {
112 0 : ReadClsId( *this, aClsId );
113 0 : sal_Int32 nLen1 = 0;
114 0 : ReadInt32( nLen1 );
115 0 : if ( nLen1 > 0 )
116 : {
117 : // higher bits are ignored
118 0 : sal_uLong nStrLen = ::std::min( nLen1, (sal_Int32)0xFFFE );
119 :
120 0 : sal_Char* p = new sal_Char[ nStrLen+1 ];
121 0 : p[nStrLen] = 0;
122 0 : if( Read( p, nStrLen ) == nStrLen )
123 : {
124 : //The encoding here is "ANSI", which is pretty useless seeing as
125 : //the actual codepage used doesn't seem to be specified/stored
126 : //anywhere :-(. Might as well pick 1252 and be consistent on
127 : //all platforms and envs
128 : //https://issues.apache.org/ooo/attachment.cgi?id=68668
129 : //for a good edge-case example
130 0 : aUserName = nStrLen ? OUString( p, nStrLen, RTL_TEXTENCODING_MS_1252 ) : OUString();
131 0 : nCbFormat = ReadClipboardFormat( *this );
132 : }
133 : else
134 0 : SetError( SVSTREAM_GENERALERROR );
135 0 : delete [] p;
136 : }
137 : }
138 0 : return GetError() == SVSTREAM_OK;
139 : }
140 :
141 0 : bool StgCompObjStream::Store()
142 : {
143 0 : if( GetError() != SVSTREAM_OK )
144 0 : return false;
145 0 : Seek( 0L );
146 0 : OString aAsciiUserName(OUStringToOString(aUserName, RTL_TEXTENCODING_MS_1252));
147 0 : WriteInt16( (sal_Int16) 1 ); // Version?
148 0 : WriteInt16( (sal_Int16) -2 ); // 0xFFFE = Byte Order Indicator
149 0 : WriteInt32( (sal_Int32) 0x0A03 ); // Windows 3.10
150 0 : WriteInt32( (sal_Int32) -1L );
151 0 : WriteClsId( *this, aClsId ); // Class ID
152 0 : WriteInt32( (sal_Int32) (aAsciiUserName.getLength() + 1) );
153 0 : WriteCharPtr( (const char *)aAsciiUserName.getStr() );
154 0 : WriteUChar( (sal_uInt8) 0 ); // string terminator
155 0 : WriteClipboardFormat( *this, nCbFormat );
156 0 : WriteInt32( (sal_Int32) 0 ); // terminator
157 0 : Commit();
158 0 : return GetError() == SVSTREAM_OK;
159 : }
160 :
161 : /////////////////////////// class StgOleStream
162 :
163 0 : StgOleStream::StgOleStream( BaseStorage& rStg, bool bWr )
164 0 : : StgInternalStream( rStg, OUString("\1Ole"), bWr )
165 : {
166 0 : nFlags = 0;
167 0 : }
168 :
169 0 : bool StgOleStream::Load()
170 : {
171 0 : nFlags = 0;
172 0 : if( GetError() != SVSTREAM_OK )
173 0 : return false;
174 :
175 0 : sal_Int32 version = 0;
176 0 : Seek( 0L );
177 0 : ReadInt32( version ).ReadUInt32( nFlags );
178 0 : return GetError() == SVSTREAM_OK;
179 : }
180 :
181 0 : bool StgOleStream::Store()
182 : {
183 0 : if( GetError() != SVSTREAM_OK )
184 0 : return false;
185 :
186 0 : Seek( 0L );
187 0 : WriteInt32( (sal_Int32) 0x02000001 ); // OLE version, format
188 0 : WriteInt32( (sal_Int32) nFlags ); // Object flags
189 0 : WriteInt32( (sal_Int32) 0 ); // Update Options
190 0 : WriteInt32( (sal_Int32) 0 ); // reserved
191 0 : WriteInt32( (sal_Int32) 0 ); // Moniker 1
192 0 : Commit();
193 0 : return GetError() == SVSTREAM_OK;
194 : }
195 :
196 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|