diff options
author | Noel Grandin <noel@peralex.com> | 2015-06-17 14:24:53 +0200 |
---|---|---|
committer | Noel Grandin <noel@peralex.com> | 2015-06-19 10:56:11 +0200 |
commit | 4f1587965e85e09796c2074d90e9067337f2b710 (patch) | |
tree | 965e0f8ae9fb35255c022fc2a300f6b5ebada50f /sdext | |
parent | 031a347668e56c1b38c0539d30e9a1cbb808ca02 (diff) |
tdf#42374 - read PDF in larger chunks
Optimise the reading of the imported PDF file by reading in larger chunks.
Eliminates roughly 10% of the time on my box
Change-Id: I48fff325076850a4ccd32ad85a3092621a923034
Diffstat (limited to 'sdext')
-rw-r--r-- | sdext/source/pdfimport/wrapper/wrapper.cxx | 94 |
1 files changed, 67 insertions, 27 deletions
diff --git a/sdext/source/pdfimport/wrapper/wrapper.cxx b/sdext/source/pdfimport/wrapper/wrapper.cxx index 4215163697e8..197b39f2ac26 100644 --- a/sdext/source/pdfimport/wrapper/wrapper.cxx +++ b/sdext/source/pdfimport/wrapper/wrapper.cxx @@ -905,32 +905,6 @@ void Parser::parseLine( const OString& rLine ) SAL_WARN_IF(m_nCharIndex!=-1, "sdext.pdfimport", "leftover scanner input"); } -oslFileError readLine( oslFileHandle pFile, OStringBuffer& line ) -{ - OSL_PRECOND( line.isEmpty(), "line buf not empty" ); - - // TODO(P3): read larger chunks - sal_Char aChar('\n'); - sal_uInt64 nBytesRead; - oslFileError nRes; - - // skip garbage \r \n at start of line - while( osl_File_E_None == (nRes=osl_readFile(pFile, &aChar, 1, &nBytesRead)) && - nBytesRead == 1 && - (aChar == '\n' || aChar == '\r') ) ; - - if( aChar != '\n' && aChar != '\r' ) - line.append( aChar ); - - while( osl_File_E_None == (nRes=osl_readFile(pFile, &aChar, 1, &nBytesRead)) && - nBytesRead == 1 && aChar != '\n' && aChar != '\r' ) - { - line.append( aChar ); - } - - return nRes; -} - } // namespace static bool checkEncryption( const OUString& i_rPath, @@ -1007,6 +981,45 @@ static bool checkEncryption( const OUString& i_rPa return bSuccess; } +class Buffering +{ + static const int SIZE = 64*1024; + std::unique_ptr<char[]> aBuffer; + oslFileHandle& pOut; + size_t pos; + sal_uInt64 left; + +public: + Buffering(oslFileHandle& out) : aBuffer(new char[SIZE]), pOut(out), pos(0), left(0) {} + + oslFileError read(char *pChar, short count, sal_uInt64* pBytesRead) + { + oslFileError nRes = osl_File_E_None; + sal_uInt64 nBytesRead = 0; + while (count > 0) + { + if (left == 0) + { + nRes = osl_readFile(pOut, aBuffer.get(), SIZE, &left); + if (nRes != osl_File_E_None || left == 0) + { + *pBytesRead = nBytesRead; + return nRes; + } + pos = 0; + } + *pChar = aBuffer.get()[pos]; + --count; + ++pos; + --left; + ++pChar; + ++nBytesRead; + } + *pBytesRead = nBytesRead; + return osl_File_E_None; + } +}; + bool xpdf_ImportFromFile( const OUString& rURL, const ContentSinkSharedPtr& rSink, const uno::Reference< task::XInteractionHandler >& xIHdl, @@ -1104,9 +1117,36 @@ bool xpdf_ImportFromFile( const OUString& rURL, // OutputDev. stderr is used for alternate streams, like // embedded fonts and bitmaps Parser aParser(rSink,pErr,xContext); + Buffering aBuffering(pOut); OStringBuffer line; - while( osl_File_E_None == readLine(pOut, line) && !line.isEmpty() ) + for( ;; ) + { + char aChar('\n'); + sal_uInt64 nBytesRead; + oslFileError nRes; + + // skip garbage \r \n at start of line + while( osl_File_E_None == (nRes = aBuffering.read(&aChar, 1, &nBytesRead)) && + nBytesRead == 1 && + (aChar == '\n' || aChar == '\r') ) ; + if ( osl_File_E_None != nRes ) + break; + + if( aChar != '\n' && aChar != '\r' ) + line.append( aChar ); + + while( osl_File_E_None == (nRes = aBuffering.read(&aChar, 1, &nBytesRead)) && + nBytesRead == 1 && aChar != '\n' && aChar != '\r' ) + { + line.append( aChar ); + } + if ( osl_File_E_None != nRes ) + break; + if ( line.isEmpty() ) + break; + aParser.parseLine(line.makeStringAndClear()); + } } } catch( uno::Exception& ) |