From 940b4d1848e8c70ab7642901a68594e8016caffc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 18:51:28 +0200 Subject: Adding upstream version 1:7.0.4. Signed-off-by: Daniel Baumann --- xmlhelp/source/cxxhelp/provider/db.cxx | 252 +++++++++++++++++++++++++++++++++ 1 file changed, 252 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 000000000..f8a38ecd8 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/db.cxx @@ -0,0 +1,252 @@ +/* -*- 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 + +using namespace com::sun::star::uno; +using namespace com::sun::star::io; + +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, int& riPos, HDFData& rValue ) +{ + bool bSuccess = false; + + // Read key len + const char* pStartPtr = pData + riPos; + char* pEndPtr; + sal_Int32 nKeyLen = strtol( pStartPtr, &pEndPtr, 16 ); + 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() ) + { + 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()); + int iPos = 0; + while( iPos < nRead ) + { + HDFData aDBKey; + if( !implReadLenAndData( pData, iPos, aDBKey ) ) + break; + + OString aOKeyStr = aDBKey.getData(); + + // Read val len + const char* pStartPtr = pData + iPos; + char* pEndPtr; + sal_Int32 nValLen = strtol( pStartPtr, &pEndPtr, 16 ); + 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_pItData = reinterpret_cast(m_aItData.getConstArray()); + m_iItPos = 0; + } + else + { + stopIteration(); + } + } + + return bSuccess; +} + +bool Hdf::getNextKeyAndValue( HDFData& rKey, HDFData& rValue ) +{ + bool bSuccess = false; + + if( m_iItPos < m_nItRead ) + { + if( implReadLenAndData( m_pItData, m_iItPos, rKey ) ) + { + if( implReadLenAndData( m_pItData, m_iItPos, rValue ) ) + bSuccess = true; + } + } + + return bSuccess; +} + +void Hdf::stopIteration() +{ + m_aItData = Sequence(); + m_pItData = nullptr; + m_nItRead = -1; + m_iItPos = -1; +} + +} // end of namespace helpdatafileproxy + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3