/************************************************************** * * 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 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmlhelp.hxx" #include "db.hxx" #include #include #include "com/sun/star/io/XSeekable.hpp" 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; delete [] m_pBuffer; m_pBuffer = new char[m_nSize+1]; memcpy( m_pBuffer, 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 != NULL ) return; m_pStringToDataMap = new StringToDataMap(); } else { if( m_pStringToValPosMap != NULL ) return; m_pStringToValPosMap = 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 = (const char*)aData.getConstArray(); int iPos = 0; while( iPos < nRead ) { HDFData aDBKey; if( !implReadLenAndData( pData, iPos, aDBKey ) ) break; rtl::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; rtl::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( void ) { if( m_pStringToDataMap != NULL ) { delete m_pStringToDataMap; m_pStringToDataMap = NULL; } if( m_pStringToValPosMap != NULL ) { delete m_pStringToValPosMap; m_pStringToValPosMap = NULL; } } bool Hdf::getValueForKey( const rtl::OString& rKey, HDFData& rValue ) { bool bSuccess = false; if( !m_xSFA.is() ) return bSuccess; try { if( m_pStringToDataMap == NULL && m_pStringToValPosMap == NULL ) { bool bOptimizeForPerformance = false; createHashMap( bOptimizeForPerformance ); } if( m_pStringToValPosMap != NULL ) { 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 = (const sal_Char*)aData.getConstArray(); rValue.copyToBuffer( pData, nValueLen ); bSuccess = true; } } xIn->closeInput(); } } } else if( m_pStringToDataMap != NULL ) { StringToDataMap::const_iterator it = m_pStringToDataMap->find( rKey ); if( it != m_pStringToDataMap->end() ) { const rtl::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( void ) { 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 = (const char*)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( void ) { m_aItData = Sequence(); m_pItData = NULL; m_nItRead = -1; m_iItPos = -1; } } // end of namespace helpdatafileproxy