1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_xmlhelp.hxx" 26 27 #include "db.hxx" 28 29 #include <rtl/alloc.h> 30 #include <cstring> 31 32 #include "com/sun/star/io/XSeekable.hpp" 33 34 using namespace com::sun::star::uno; 35 using namespace com::sun::star::io; 36 37 namespace helpdatafileproxy { 38 39 //---------------------------------------------------------------------------- 40 void HDFData::copyToBuffer( const char* pSrcData, int nSize ) 41 { 42 m_nSize = nSize; 43 delete [] m_pBuffer; 44 m_pBuffer = new char[m_nSize+1]; 45 memcpy( m_pBuffer, pSrcData, m_nSize ); 46 m_pBuffer[m_nSize] = 0; 47 } 48 49 50 // Hdf 51 52 bool Hdf::implReadLenAndData( const char* pData, int& riPos, HDFData& rValue ) 53 { 54 bool bSuccess = false; 55 56 // Read key len 57 const char* pStartPtr = pData + riPos; 58 char* pEndPtr; 59 sal_Int32 nKeyLen = strtol( pStartPtr, &pEndPtr, 16 ); 60 if( pEndPtr == pStartPtr ) 61 return bSuccess; 62 riPos += (pEndPtr - pStartPtr) + 1; 63 64 const char* pKeySrc = pData + riPos; 65 rValue.copyToBuffer( pKeySrc, nKeyLen ); 66 riPos += nKeyLen + 1; 67 68 bSuccess = true; 69 return bSuccess; 70 } 71 72 void Hdf::createHashMap( bool bOptimizeForPerformance ) 73 { 74 releaseHashMap(); 75 if( bOptimizeForPerformance ) 76 { 77 if( m_pStringToDataMap != NULL ) 78 return; 79 m_pStringToDataMap = new StringToDataMap(); 80 } 81 else 82 { 83 if( m_pStringToValPosMap != NULL ) 84 return; 85 m_pStringToValPosMap = new StringToValPosMap(); 86 } 87 88 Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL ); 89 if( xIn.is() ) 90 { 91 Sequence< sal_Int8 > aData; 92 sal_Int32 nSize = m_xSFA->getSize( m_aFileURL ); 93 sal_Int32 nRead = xIn->readBytes( aData, nSize ); 94 95 const char* pData = (const char*)aData.getConstArray(); 96 int iPos = 0; 97 while( iPos < nRead ) 98 { 99 HDFData aDBKey; 100 if( !implReadLenAndData( pData, iPos, aDBKey ) ) 101 break; 102 103 rtl::OString aOKeyStr = aDBKey.getData(); 104 105 // Read val len 106 const char* pStartPtr = pData + iPos; 107 char* pEndPtr; 108 sal_Int32 nValLen = strtol( pStartPtr, &pEndPtr, 16 ); 109 if( pEndPtr == pStartPtr ) 110 break; 111 112 iPos += (pEndPtr - pStartPtr) + 1; 113 114 if( bOptimizeForPerformance ) 115 { 116 const char* pValSrc = pData + iPos; 117 rtl::OString aValStr( pValSrc, nValLen ); 118 (*m_pStringToDataMap)[aOKeyStr] = aValStr; 119 } 120 else 121 { 122 // store value start position 123 (*m_pStringToValPosMap)[aOKeyStr] = std::pair<int,int>( iPos, nValLen ); 124 } 125 iPos += nValLen + 1; 126 } 127 128 xIn->closeInput(); 129 } 130 } 131 132 void Hdf::releaseHashMap( void ) 133 { 134 if( m_pStringToDataMap != NULL ) 135 { 136 delete m_pStringToDataMap; 137 m_pStringToDataMap = NULL; 138 } 139 if( m_pStringToValPosMap != NULL ) 140 { 141 delete m_pStringToValPosMap; 142 m_pStringToValPosMap = NULL; 143 } 144 } 145 146 147 bool Hdf::getValueForKey( const rtl::OString& rKey, HDFData& rValue ) 148 { 149 bool bSuccess = false; 150 if( !m_xSFA.is() ) 151 return bSuccess; 152 153 try 154 { 155 156 if( m_pStringToDataMap == NULL && m_pStringToValPosMap == NULL ) 157 { 158 bool bOptimizeForPerformance = false; 159 createHashMap( bOptimizeForPerformance ); 160 } 161 162 if( m_pStringToValPosMap != NULL ) 163 { 164 StringToValPosMap::const_iterator it = m_pStringToValPosMap->find( rKey ); 165 if( it != m_pStringToValPosMap->end() ) 166 { 167 const std::pair<int,int>& rValPair = it->second; 168 int iValuePos = rValPair.first; 169 int nValueLen = rValPair.second; 170 171 Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL ); 172 if( xIn.is() ) 173 { 174 Reference< XSeekable > xXSeekable( xIn, UNO_QUERY ); 175 if( xXSeekable.is() ) 176 { 177 xXSeekable->seek( iValuePos ); 178 179 Sequence< sal_Int8 > aData; 180 sal_Int32 nRead = xIn->readBytes( aData, nValueLen ); 181 if( nRead == nValueLen ) 182 { 183 const char* pData = (const sal_Char*)aData.getConstArray(); 184 rValue.copyToBuffer( pData, nValueLen ); 185 bSuccess = true; 186 } 187 } 188 xIn->closeInput(); 189 } 190 } 191 } 192 193 else if( m_pStringToDataMap != NULL ) 194 { 195 StringToDataMap::const_iterator it = m_pStringToDataMap->find( rKey ); 196 if( it != m_pStringToDataMap->end() ) 197 { 198 const rtl::OString& rValueStr = it->second; 199 int nValueLen = rValueStr.getLength(); 200 const char* pData = rValueStr.getStr(); 201 rValue.copyToBuffer( pData, nValueLen ); 202 bSuccess = true; 203 } 204 } 205 206 } 207 catch( Exception & ) 208 { 209 bSuccess = false; 210 } 211 212 return bSuccess; 213 } 214 215 bool Hdf::startIteration( void ) 216 { 217 bool bSuccess = false; 218 219 sal_Int32 nSize = m_xSFA->getSize( m_aFileURL ); 220 221 Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL ); 222 if( xIn.is() ) 223 { 224 m_nItRead = xIn->readBytes( m_aItData, nSize ); 225 if( m_nItRead == nSize ) 226 { 227 bSuccess = true; 228 m_pItData = (const char*)m_aItData.getConstArray(); 229 m_iItPos = 0; 230 } 231 else 232 { 233 stopIteration(); 234 } 235 } 236 237 return bSuccess; 238 } 239 240 bool Hdf::getNextKeyAndValue( HDFData& rKey, HDFData& rValue ) 241 { 242 bool bSuccess = false; 243 244 if( m_iItPos < m_nItRead ) 245 { 246 if( implReadLenAndData( m_pItData, m_iItPos, rKey ) ) 247 { 248 if( implReadLenAndData( m_pItData, m_iItPos, rValue ) ) 249 bSuccess = true; 250 } 251 } 252 253 return bSuccess; 254 } 255 256 void Hdf::stopIteration( void ) 257 { 258 m_aItData = Sequence<sal_Int8>(); 259 m_pItData = NULL; 260 m_nItRead = -1; 261 m_iItPos = -1; 262 } 263 } // end of namespace helpdatafileproxy 264