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_comphelper.hxx"
26 #include <comphelper/streamsection.hxx>
27 #include <osl/diagnose.h>
28 
29 namespace comphelper
30 {
31 
32 //-------------------------------------------------------------------------
OStreamSection(const staruno::Reference<stario::XDataInputStream> & _rxInput)33 OStreamSection::OStreamSection(const staruno::Reference< stario::XDataInputStream >& _rxInput)
34 	:m_xMarkStream(_rxInput, ::com::sun::star::uno::UNO_QUERY)
35 	,m_xInStream(_rxInput)
36 	,m_nBlockStart(-1)
37 	,m_nBlockLen(-1)
38 {
39 	OSL_ENSURE(m_xInStream.is() && m_xMarkStream.is(), "OStreamSection::OStreamSection : invalid argument !");
40 	if (m_xInStream.is() && m_xMarkStream.is())
41 	{
42 		m_nBlockLen = _rxInput->readLong();
43 		m_nBlockStart = m_xMarkStream->createMark();
44 	}
45 }
46 
47 //-------------------------------------------------------------------------
OStreamSection(const staruno::Reference<stario::XDataOutputStream> & _rxOutput,sal_Int32 _nPresumedLength)48 OStreamSection::OStreamSection(const staruno::Reference< stario::XDataOutputStream >& _rxOutput, sal_Int32 _nPresumedLength)
49 	:m_xMarkStream(_rxOutput, ::com::sun::star::uno::UNO_QUERY)
50 	,m_xOutStream(_rxOutput)
51 	,m_nBlockStart(-1)
52 	,m_nBlockLen(-1)
53 {
54 	OSL_ENSURE(m_xOutStream.is() && m_xMarkStream.is(), "OStreamSection::OStreamSection : invalid argument !");
55 	if (m_xOutStream.is() && m_xMarkStream.is())
56 	{
57 		m_nBlockStart = m_xMarkStream->createMark();
58 		// a placeholder where we will write the overall length (within the destructor)
59 		if (_nPresumedLength > 0)
60 			m_nBlockLen = _nPresumedLength + sizeof(m_nBlockLen);
61 			// as the caller did not consider - of course - the placeholder we are going to write
62 		else
63 			m_nBlockLen = 0;
64 		m_xOutStream->writeLong(m_nBlockLen);
65 	}
66 }
67 
68 //-------------------------------------------------------------------------
~OStreamSection()69 OStreamSection::~OStreamSection()
70 {
71 	try
72 	{	// don't allow any exceptions to leave this block, this may be called during the stack unwinding of an exception
73 		// handling routing
74 		if (m_xInStream.is() &&  m_xMarkStream.is())
75 		{	// we're working on an input stream
76 			m_xMarkStream->jumpToMark(m_nBlockStart);
77 			m_xInStream->skipBytes(m_nBlockLen);
78 			m_xMarkStream->deleteMark(m_nBlockStart);
79 		}
80 		else if (m_xOutStream.is() && m_xMarkStream.is())
81 		{
82 			sal_Int32 nRealBlockLength = m_xMarkStream->offsetToMark(m_nBlockStart) - sizeof(m_nBlockLen);
83 			if (m_nBlockLen && (m_nBlockLen == nRealBlockLength))
84 				// nothing to do : the estimation the caller gave us (in the ctor) was correct
85 				m_xMarkStream->deleteMark(m_nBlockStart);
86 			else
87 			{	// the estimation was wrong (or we didn't get one)
88 				m_nBlockLen = nRealBlockLength;
89 				m_xMarkStream->jumpToMark(m_nBlockStart);
90 				m_xOutStream->writeLong(m_nBlockLen);
91 				m_xMarkStream->jumpToFurthest();
92 				m_xMarkStream->deleteMark(m_nBlockStart);
93 			}
94 		}
95 	}
96 	catch(const staruno::Exception&)
97 	{
98 	}
99 }
100 // -----------------------------------------------------------------------------
available()101 sal_Int32 OStreamSection::available()
102 {
103 	sal_Int32 nBytes = 0;
104 	try
105 	{	// don't allow any exceptions to leave this block, this may be called during the stack unwinding of an exception
106 		if (m_xInStream.is() &&  m_xMarkStream.is())
107 			nBytes = m_xMarkStream->offsetToMark(m_nBlockStart) - sizeof(m_nBlockLen);
108 	}
109 	catch(const staruno::Exception&)
110 	{
111 	}
112 	return nBytes;
113 }
114 // -----------------------------------------------------------------------------
115 
116 }	// namespace comphelper
117 
118 
119