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 #include "oox/helper/binarystreambase.hxx"
25 
26 #include <com/sun/star/io/XSeekable.hpp>
27 #include <osl/diagnose.h>
28 
29 namespace oox {
30 
31 // ============================================================================
32 
33 using namespace ::com::sun::star::io;
34 using namespace ::com::sun::star::uno;
35 
36 // ============================================================================
37 
~BinaryStreamBase()38 BinaryStreamBase::~BinaryStreamBase()
39 {
40 }
41 
getRemaining() const42 sal_Int64 BinaryStreamBase::getRemaining() const
43 {
44     // do not use isSeekable(), implementations may provide stream position and size even if not seekable
45     sal_Int64 nPos = tell();
46     sal_Int64 nLen = size();
47     return ((nPos >= 0) && (nLen >= 0)) ? ::std::max< sal_Int64 >( nLen - nPos, 0 ) : -1;
48 }
49 
alignToBlock(sal_Int32 nBlockSize,sal_Int64 nAnchorPos)50 void BinaryStreamBase::alignToBlock( sal_Int32 nBlockSize, sal_Int64 nAnchorPos )
51 {
52     sal_Int64 nStrmPos = tell();
53     // nothing to do, if stream is at anchor position
54     if( mbSeekable && (0 <= nAnchorPos) && (nAnchorPos != nStrmPos) && (nBlockSize > 1) )
55     {
56         // prevent modulo with negative arguments...
57         sal_Int64 nSkipSize = (nAnchorPos < nStrmPos) ?
58             (nBlockSize - ((nStrmPos - nAnchorPos - 1) % nBlockSize) - 1) :
59             ((nAnchorPos - nStrmPos) % nBlockSize);
60         seek( nStrmPos + nSkipSize );
61     }
62 }
63 
64 // ============================================================================
65 
BinaryXSeekableStream(const Reference<XSeekable> & rxSeekable)66 BinaryXSeekableStream::BinaryXSeekableStream( const Reference< XSeekable >& rxSeekable ) :
67     BinaryStreamBase( mxSeekable.is() ),
68     mxSeekable( rxSeekable )
69 {
70 }
71 
~BinaryXSeekableStream()72 BinaryXSeekableStream::~BinaryXSeekableStream()
73 {
74 }
75 
size() const76 sal_Int64 BinaryXSeekableStream::size() const
77 {
78     if( mxSeekable.is() ) try
79     {
80         return mxSeekable->getLength();
81     }
82     catch( Exception& )
83     {
84         OSL_ENSURE( false, "BinaryXSeekableStream::size - exception caught" );
85     }
86     return -1;
87 }
88 
tell() const89 sal_Int64 BinaryXSeekableStream::tell() const
90 {
91     if( mxSeekable.is() ) try
92     {
93         return mxSeekable->getPosition();
94     }
95     catch( Exception& )
96     {
97         OSL_ENSURE( false, "BinaryXSeekableStream::tell - exception caught" );
98     }
99     return -1;
100 }
101 
seek(sal_Int64 nPos)102 void BinaryXSeekableStream::seek( sal_Int64 nPos )
103 {
104     if( mxSeekable.is() ) try
105     {
106         mbEof = false;
107         mxSeekable->seek( nPos );
108     }
109     catch( Exception& )
110     {
111         mbEof = true;
112     }
113 }
114 
close()115 void BinaryXSeekableStream::close()
116 {
117     mxSeekable.clear();
118     mbEof = true;
119 }
120 
121 // ============================================================================
122 
SequenceSeekableStream(const StreamDataSequence & rData)123 SequenceSeekableStream::SequenceSeekableStream( const StreamDataSequence& rData ) :
124     BinaryStreamBase( true ),
125     mpData( &rData ),
126     mnPos( 0 )
127 {
128 }
129 
size() const130 sal_Int64 SequenceSeekableStream::size() const
131 {
132     return mpData ? mpData->getLength() : -1;
133 }
134 
tell() const135 sal_Int64 SequenceSeekableStream::tell() const
136 {
137     return mpData ? mnPos : -1;
138 }
139 
seek(sal_Int64 nPos)140 void SequenceSeekableStream::seek( sal_Int64 nPos )
141 {
142     if( mpData )
143     {
144         mnPos = getLimitedValue< sal_Int32, sal_Int64 >( nPos, 0, mpData->getLength() );
145         mbEof = mnPos != nPos;
146     }
147 }
148 
close()149 void SequenceSeekableStream::close()
150 {
151     mpData = 0;
152     mbEof = true;
153 }
154 
155 // ============================================================================
156 
157 } // namespace oox
158