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 311 : StgInternalStream::StgInternalStream( BaseStorage& rStg, const OUString& rName, bool bWr )
30 : {
31 311 : bIsWritable = true;
32 : sal_uInt16 nMode = bWr
33 : ? STREAM_WRITE | STREAM_SHARE_DENYALL
34 311 : : STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE;
35 311 : pStrm = rStg.OpenStream( rName, nMode );
36 :
37 : // set the error code right here in the stream
38 311 : SetError( rStg.GetError() );
39 311 : SetBufferSize( 1024 );
40 311 : }
41 :
42 622 : StgInternalStream::~StgInternalStream()
43 : {
44 311 : delete pStrm;
45 311 : }
46 :
47 265 : sal_uLong StgInternalStream::GetData( void* pData, sal_uLong nSize )
48 : {
49 265 : if( pStrm )
50 : {
51 265 : nSize = pStrm->Read( pData, nSize );
52 265 : SetError( pStrm->GetError() );
53 265 : return nSize;
54 : }
55 : else
56 0 : return 0;
57 : }
58 :
59 46 : sal_uLong StgInternalStream::PutData( const void* pData, sal_uLong nSize )
60 : {
61 46 : if( pStrm )
62 : {
63 46 : nSize = pStrm->Write( pData, nSize );
64 46 : SetError( pStrm->GetError() );
65 46 : return nSize;
66 : }
67 : else
68 0 : return 0;
69 : }
70 :
71 576 : sal_uInt64 StgInternalStream::SeekPos(sal_uInt64 const nPos)
72 : {
73 576 : return pStrm ? pStrm->Seek( nPos ) : 0;
74 : }
75 :
76 46 : void StgInternalStream::FlushData()
77 : {
78 46 : if( pStrm )
79 : {
80 46 : pStrm->Flush();
81 46 : SetError( pStrm->GetError() );
82 : }
83 46 : }
84 :
85 46 : void StgInternalStream::Commit()
86 : {
87 46 : Flush();
88 46 : pStrm->Commit();
89 46 : }
90 :
91 : ///////////////////////// class StgCompObjStream
92 :
93 288 : StgCompObjStream::StgCompObjStream( BaseStorage& rStg, bool bWr )
94 288 : : StgInternalStream( rStg, OUString("\1CompObj"), bWr )
95 : {
96 288 : memset( &aClsId, 0, sizeof( ClsId ) );
97 288 : nCbFormat = 0;
98 288 : }
99 :
100 265 : bool StgCompObjStream::Load()
101 : {
102 265 : memset( &aClsId, 0, sizeof( ClsId ) );
103 265 : nCbFormat = 0;
104 265 : aUserName = "";
105 265 : if( GetError() != SVSTREAM_OK )
106 0 : return false;
107 265 : Seek( 8L ); // skip the first part
108 265 : sal_Int32 nMarker = 0;
109 265 : ReadInt32( nMarker );
110 265 : if( nMarker == -1L )
111 : {
112 265 : ReadClsId( *this, aClsId );
113 265 : sal_Int32 nLen1 = 0;
114 265 : ReadInt32( nLen1 );
115 265 : if ( nLen1 > 0 )
116 : {
117 : // higher bits are ignored
118 265 : sal_uLong nStrLen = ::std::min( nLen1, (sal_Int32)0xFFFE );
119 :
120 265 : sal_Char* p = new sal_Char[ nStrLen+1 ];
121 265 : p[nStrLen] = 0;
122 265 : 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 265 : aUserName = nStrLen ? OUString( p, nStrLen, RTL_TEXTENCODING_MS_1252 ) : OUString();
131 265 : nCbFormat = ReadClipboardFormat( *this );
132 : }
133 : else
134 0 : SetError( SVSTREAM_GENERALERROR );
135 265 : delete [] p;
136 : }
137 : }
138 265 : return GetError() == SVSTREAM_OK;
139 : }
140 :
141 23 : bool StgCompObjStream::Store()
142 : {
143 23 : if( GetError() != SVSTREAM_OK )
144 0 : return false;
145 23 : Seek( 0L );
146 23 : OString aAsciiUserName(OUStringToOString(aUserName, RTL_TEXTENCODING_MS_1252));
147 23 : WriteInt16( (sal_Int16) 1 ); // Version?
148 23 : WriteInt16( (sal_Int16) -2 ); // 0xFFFE = Byte Order Indicator
149 23 : WriteInt32( (sal_Int32) 0x0A03 ); // Windows 3.10
150 23 : WriteInt32( (sal_Int32) -1L );
151 23 : WriteClsId( *this, aClsId ); // Class ID
152 23 : WriteInt32( (sal_Int32) (aAsciiUserName.getLength() + 1) );
153 23 : WriteCharPtr( (const char *)aAsciiUserName.getStr() );
154 23 : WriteUChar( (sal_uInt8) 0 ); // string terminator
155 23 : WriteClipboardFormat( *this, nCbFormat );
156 23 : WriteInt32( (sal_Int32) 0 ); // terminator
157 23 : Commit();
158 23 : return GetError() == SVSTREAM_OK;
159 : }
160 :
161 : /////////////////////////// class StgOleStream
162 :
163 23 : StgOleStream::StgOleStream( BaseStorage& rStg, bool bWr )
164 23 : : StgInternalStream( rStg, OUString("\1Ole"), bWr )
165 : {
166 23 : nFlags = 0;
167 23 : }
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 23 : bool StgOleStream::Store()
182 : {
183 23 : if( GetError() != SVSTREAM_OK )
184 0 : return false;
185 :
186 23 : Seek( 0L );
187 23 : WriteInt32( (sal_Int32) 0x02000001 ); // OLE version, format
188 23 : WriteInt32( (sal_Int32) nFlags ); // Object flags
189 23 : WriteInt32( (sal_Int32) 0 ); // Update Options
190 23 : WriteInt32( (sal_Int32) 0 ); // reserved
191 23 : WriteInt32( (sal_Int32) 0 ); // Moniker 1
192 23 : Commit();
193 23 : return GetError() == SVSTREAM_OK;
194 : }
195 :
196 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|