1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
26 #include <system_error>
29 #include <com/sun/star/io/XSeekable.hpp>
31 using namespace com::sun::star::uno
;
32 using namespace com::sun::star::io
;
36 std::pair
<sal_Int32
, char const *> readInt32(char const * begin
, char const * end
) {
38 auto const [ptr
, ec
] = std::from_chars(begin
, end
, n
, 16);
39 return {std::max(n
, sal_Int32(0)), ec
== std::errc
{} && n
>= 0 ? ptr
: begin
};
44 namespace helpdatafileproxy
{
46 void HDFData::copyToBuffer( const char* pSrcData
, int nSize
)
49 m_pBuffer
.reset( new char[m_nSize
+1] );
50 memcpy( m_pBuffer
.get(), pSrcData
, m_nSize
);
51 m_pBuffer
[m_nSize
] = 0;
57 bool Hdf::implReadLenAndData( const char* pData
, char const * end
, int& riPos
, HDFData
& rValue
)
59 bool bSuccess
= false;
62 const char* pStartPtr
= pData
+ riPos
;
63 auto [nKeyLen
, pEndPtr
] = readInt32(pStartPtr
, end
);
64 if( pEndPtr
== pStartPtr
)
66 riPos
+= (pEndPtr
- pStartPtr
) + 1;
68 const char* pKeySrc
= pData
+ riPos
;
69 rValue
.copyToBuffer( pKeySrc
, nKeyLen
);
76 void Hdf::createHashMap( bool bOptimizeForPerformance
)
79 if( bOptimizeForPerformance
)
81 if( m_pStringToDataMap
!= nullptr )
83 m_pStringToDataMap
.reset(new StringToDataMap
);
87 if( m_pStringToValPosMap
!= nullptr )
89 m_pStringToValPosMap
.reset(new StringToValPosMap
);
92 Reference
< XInputStream
> xIn
= m_xSFA
->openFileRead( m_aFileURL
);
96 Sequence
< sal_Int8
> aData
;
97 sal_Int32 nSize
= m_xSFA
->getSize( m_aFileURL
);
98 sal_Int32 nRead
= xIn
->readBytes( aData
, nSize
);
100 const char* pData
= reinterpret_cast<const char*>(aData
.getConstArray());
101 auto const end
= pData
+ nRead
;
103 while( iPos
< nRead
)
106 if( !implReadLenAndData( pData
, end
, iPos
, aDBKey
) )
109 OString aOKeyStr
= aDBKey
.getData();
112 const char* pStartPtr
= pData
+ iPos
;
113 auto [nValLen
, pEndPtr
] = readInt32(pStartPtr
, end
);
114 if( pEndPtr
== pStartPtr
)
117 iPos
+= (pEndPtr
- pStartPtr
) + 1;
119 if( bOptimizeForPerformance
)
121 const char* pValSrc
= pData
+ iPos
;
122 (*m_pStringToDataMap
)[aOKeyStr
] = OString(pValSrc
, nValLen
);
126 // store value start position
127 (*m_pStringToValPosMap
)[aOKeyStr
] = std::pair
<int,int>( iPos
, nValLen
);
135 void Hdf::releaseHashMap()
137 m_pStringToDataMap
.reset();
138 m_pStringToValPosMap
.reset();
146 bool Hdf::getValueForKey( const OString
& rKey
, HDFData
& rValue
)
148 bool bSuccess
= false;
155 if( m_pStringToDataMap
== nullptr && m_pStringToValPosMap
== nullptr )
157 createHashMap( false/*bOptimizeForPerformance*/ );
160 if( m_pStringToValPosMap
!= nullptr )
162 StringToValPosMap::const_iterator it
= m_pStringToValPosMap
->find( rKey
);
163 if( it
!= m_pStringToValPosMap
->end() )
165 const std::pair
<int,int>& rValPair
= it
->second
;
166 int iValuePos
= rValPair
.first
;
167 int nValueLen
= rValPair
.second
;
169 Reference
< XInputStream
> xIn
= m_xSFA
->openFileRead( m_aFileURL
);
172 Reference
< XSeekable
> xXSeekable( xIn
, UNO_QUERY
);
173 if( xXSeekable
.is() )
175 xXSeekable
->seek( iValuePos
);
177 Sequence
< sal_Int8
> aData
;
178 sal_Int32 nRead
= xIn
->readBytes( aData
, nValueLen
);
179 if( nRead
== nValueLen
)
181 const char* pData
= reinterpret_cast<const char*>(aData
.getConstArray());
182 rValue
.copyToBuffer( pData
, nValueLen
);
191 else if( m_pStringToDataMap
!= nullptr )
193 StringToDataMap::const_iterator it
= m_pStringToDataMap
->find( rKey
);
194 if( it
!= m_pStringToDataMap
->end() )
196 const OString
& rValueStr
= it
->second
;
197 int nValueLen
= rValueStr
.getLength();
198 const char* pData
= rValueStr
.getStr();
199 rValue
.copyToBuffer( pData
, nValueLen
);
213 bool Hdf::startIteration()
215 bool bSuccess
= false;
217 sal_Int32 nSize
= m_xSFA
->getSize( m_aFileURL
);
219 Reference
< XInputStream
> xIn
= m_xSFA
->openFileRead( m_aFileURL
);
222 m_nItRead
= xIn
->readBytes( m_aItData
, nSize
);
223 if( m_nItRead
== nSize
)
237 bool Hdf::getNextKeyAndValue( HDFData
& rKey
, HDFData
& rValue
)
239 bool bSuccess
= false;
241 if( m_iItPos
< m_nItRead
)
243 auto const p
= reinterpret_cast<const char*>(m_aItData
.getConstArray());
244 if( implReadLenAndData( p
, p
+ m_aItData
.size(), m_iItPos
, rKey
) )
246 if( implReadLenAndData( p
, p
+ m_aItData
.size(), m_iItPos
, rValue
) )
254 void Hdf::stopIteration()
256 m_aItData
= Sequence
<sal_Int8
>();
261 } // end of namespace helpdatafileproxy
263 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */