From 267c6f2ac71f92999e969232431ba04678e7437e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 07:54:39 +0200 Subject: Adding upstream version 4:24.2.0. Signed-off-by: Daniel Baumann --- xmlhelp/source/cxxhelp/provider/db.cxx | 264 +++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 xmlhelp/source/cxxhelp/provider/db.cxx (limited to 'xmlhelp/source/cxxhelp/provider/db.cxx') diff --git a/xmlhelp/source/cxxhelp/provider/db.cxx b/xmlhelp/source/cxxhelp/provider/db.cxx new file mode 100644 index 0000000000..d60bff78ee --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/db.cxx @@ -0,0 +1,264 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include "db.hxx" + +#include +#include +#include +#include +#include + +#include + +using namespace com::sun::star::uno; +using namespace com::sun::star::io; + +namespace { + +std::pair readInt32(char const * begin, char const * end) { + sal_Int32 n = 0; + auto const [ptr, ec] = std::from_chars(begin, end, n, 16); + return {std::max(n, sal_Int32(0)), ec == std::errc{} && n >= 0 ? ptr : begin}; +} + +} + +namespace helpdatafileproxy { + +void HDFData::copyToBuffer( const char* pSrcData, int nSize ) +{ + m_nSize = nSize; + m_pBuffer.reset( new char[m_nSize+1] ); + memcpy( m_pBuffer.get(), pSrcData, m_nSize ); + m_pBuffer[m_nSize] = 0; +} + + +// Hdf + +bool Hdf::implReadLenAndData( const char* pData, char const * end, int& riPos, HDFData& rValue ) +{ + bool bSuccess = false; + + // Read key len + const char* pStartPtr = pData + riPos; + auto [nKeyLen, pEndPtr] = readInt32(pStartPtr, end); + if( pEndPtr == pStartPtr ) + return bSuccess; + riPos += (pEndPtr - pStartPtr) + 1; + + const char* pKeySrc = pData + riPos; + rValue.copyToBuffer( pKeySrc, nKeyLen ); + riPos += nKeyLen + 1; + + bSuccess = true; + return bSuccess; +} + +void Hdf::createHashMap( bool bOptimizeForPerformance ) +{ + releaseHashMap(); + if( bOptimizeForPerformance ) + { + if( m_pStringToDataMap != nullptr ) + return; + m_pStringToDataMap.reset(new StringToDataMap); + } + else + { + if( m_pStringToValPosMap != nullptr ) + return; + m_pStringToValPosMap.reset(new StringToValPosMap); + } + + Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL ); + if( !xIn.is() ) + return; + + Sequence< sal_Int8 > aData; + sal_Int32 nSize = m_xSFA->getSize( m_aFileURL ); + sal_Int32 nRead = xIn->readBytes( aData, nSize ); + + const char* pData = reinterpret_cast(aData.getConstArray()); + auto const end = pData + nRead; + int iPos = 0; + while( iPos < nRead ) + { + HDFData aDBKey; + if( !implReadLenAndData( pData, end, iPos, aDBKey ) ) + break; + + OString aOKeyStr = aDBKey.getData(); + + // Read val len + const char* pStartPtr = pData + iPos; + auto [nValLen, pEndPtr] = readInt32(pStartPtr, end); + if( pEndPtr == pStartPtr ) + break; + + iPos += (pEndPtr - pStartPtr) + 1; + + if( bOptimizeForPerformance ) + { + const char* pValSrc = pData + iPos; + OString aValStr( pValSrc, nValLen ); + (*m_pStringToDataMap)[aOKeyStr] = aValStr; + } + else + { + // store value start position + (*m_pStringToValPosMap)[aOKeyStr] = std::pair( iPos, nValLen ); + } + iPos += nValLen + 1; + } + + xIn->closeInput(); +} + +void Hdf::releaseHashMap() +{ + m_pStringToDataMap.reset(); + m_pStringToValPosMap.reset(); +} + + +Hdf::~Hdf() +{ +} + +bool Hdf::getValueForKey( const OString& rKey, HDFData& rValue ) +{ + bool bSuccess = false; + if( !m_xSFA.is() ) + return bSuccess; + + try + { + + if( m_pStringToDataMap == nullptr && m_pStringToValPosMap == nullptr ) + { + createHashMap( false/*bOptimizeForPerformance*/ ); + } + + if( m_pStringToValPosMap != nullptr ) + { + StringToValPosMap::const_iterator it = m_pStringToValPosMap->find( rKey ); + if( it != m_pStringToValPosMap->end() ) + { + const std::pair& rValPair = it->second; + int iValuePos = rValPair.first; + int nValueLen = rValPair.second; + + Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL ); + if( xIn.is() ) + { + Reference< XSeekable > xXSeekable( xIn, UNO_QUERY ); + if( xXSeekable.is() ) + { + xXSeekable->seek( iValuePos ); + + Sequence< sal_Int8 > aData; + sal_Int32 nRead = xIn->readBytes( aData, nValueLen ); + if( nRead == nValueLen ) + { + const char* pData = reinterpret_cast(aData.getConstArray()); + rValue.copyToBuffer( pData, nValueLen ); + bSuccess = true; + } + } + xIn->closeInput(); + } + } + } + + else if( m_pStringToDataMap != nullptr ) + { + StringToDataMap::const_iterator it = m_pStringToDataMap->find( rKey ); + if( it != m_pStringToDataMap->end() ) + { + const OString& rValueStr = it->second; + int nValueLen = rValueStr.getLength(); + const char* pData = rValueStr.getStr(); + rValue.copyToBuffer( pData, nValueLen ); + bSuccess = true; + } + } + + } + catch( Exception & ) + { + bSuccess = false; + } + + return bSuccess; +} + +bool Hdf::startIteration() +{ + bool bSuccess = false; + + sal_Int32 nSize = m_xSFA->getSize( m_aFileURL ); + + Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL ); + if( xIn.is() ) + { + m_nItRead = xIn->readBytes( m_aItData, nSize ); + if( m_nItRead == nSize ) + { + bSuccess = true; + m_iItPos = 0; + } + else + { + stopIteration(); + } + } + + return bSuccess; +} + +bool Hdf::getNextKeyAndValue( HDFData& rKey, HDFData& rValue ) +{ + bool bSuccess = false; + + if( m_iItPos < m_nItRead ) + { + auto const p = reinterpret_cast(m_aItData.getConstArray()); + if( implReadLenAndData( p, p + m_aItData.size(), m_iItPos, rKey ) ) + { + if( implReadLenAndData( p, p + m_aItData.size(), m_iItPos, rValue ) ) + bSuccess = true; + } + } + + return bSuccess; +} + +void Hdf::stopIteration() +{ + m_aItData = Sequence(); + m_nItRead = -1; + m_iItPos = -1; +} + +} // end of namespace helpdatafileproxy + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3