| /************************************************************** |
| * |
| * 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 <rtl/alloc.h> |
| #include <cstring> |
| |
| #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<int,int>( 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<int,int>& 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<sal_Int8>(); |
| m_pItData = NULL; |
| m_nItRead = -1; |
| m_iItPos = -1; |
| } |
| } // end of namespace helpdatafileproxy |