1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <osl/thread.h>
23 #include <osl/file.hxx>
24 #include <cppuhelper/weak.hxx>
25 #include <cppuhelper/queryinterface.hxx>
26 #include <comphelper/processfactory.hxx>
27 #include <rtl/uri.hxx>
28 #include <rtl/ref.hxx>
29 #include <rtl/character.hxx>
30 #include <o3tl/string_view.hxx>
31 #include <libxslt/transform.h>
32 #include <libxslt/xsltutils.h>
33 #include <libxslt/security.h>
35 #include <com/sun/star/io/XActiveDataSink.hpp>
36 #include <com/sun/star/io/XInputStream.hpp>
37 #include <com/sun/star/io/XSeekable.hpp>
38 #include <com/sun/star/lang/IllegalArgumentException.hpp>
39 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
40 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
42 #include "urlparameter.hxx"
43 #include "databases.hxx"
50 using namespace com::sun::star::io
;
51 using namespace com::sun::star::uno
;
52 using namespace com::sun::star::lang
;
53 using namespace com::sun::star::ucb
;
54 using namespace com::sun::star::beans
;
55 using namespace com::sun::star::container
;
56 using namespace chelp
;
59 URLParameter::URLParameter( const OUString
& aURL
,
60 Databases
* pDatabases
)
61 : m_pDatabases( pDatabases
),
69 bool URLParameter::isErrorDocument()
71 bool bErrorDoc
= false;
75 Reference
< XHierarchicalNameAccess
> xNA
=
76 m_pDatabases
->findJarFileForPath( get_jar(), get_language(), get_path() );
77 bErrorDoc
= !xNA
.is();
84 OString
URLParameter::getByName( const char* par
)
88 if( strcmp( par
,"Program" ) == 0 )
90 else if( strcmp( par
,"Database" ) == 0 )
92 else if( strcmp( par
,"DatabasePar" ) == 0 )
94 else if( strcmp( par
,"Id" ) == 0 )
96 else if( strcmp( par
,"Path" ) == 0 )
98 else if( strcmp( par
,"Language" ) == 0 )
100 else if( strcmp( par
,"System" ) == 0 )
102 else if( strcmp( par
,"HelpPrefix" ) == 0 )
105 return OUStringToOString( val
, RTL_TEXTENCODING_UTF8
);
109 OUString
const & URLParameter::get_id()
111 if( m_aId
== "start" )
113 StaticModuleInformation
* inf
=
114 m_pDatabases
->getStaticInformationForModule( get_module(),
117 m_aId
= inf
->get_id();
123 const OUString
& URLParameter::get_tag()
126 return get_the_tag();
132 const OUString
& URLParameter::get_title()
135 return get_the_title();
136 else if( !m_aModule
.isEmpty() )
138 StaticModuleInformation
* inf
=
139 m_pDatabases
->getStaticInformationForModule( get_module(),
142 m_aTitle
= inf
->get_title();
144 else // This must be the root
151 OUString
const & URLParameter::get_language() const
157 OUString
const & URLParameter::get_program()
159 if( m_aProgram
.isEmpty() )
161 StaticModuleInformation
* inf
=
162 m_pDatabases
->getStaticInformationForModule( get_module(),
165 m_aProgram
= inf
->get_program();
171 void URLParameter::init()
173 m_bHelpDataFileRead
= false;
175 m_nHitCount
= 100; // The default maximum hitcount
179 const OUString
& URLParameter::get_the_tag()
182 if( ! m_bHelpDataFileRead
)
185 m_bHelpDataFileRead
= true;
190 return EMPTY_OUSTRING
;
194 OUString
const & URLParameter::get_path()
197 if( ! m_bHelpDataFileRead
)
199 m_bHelpDataFileRead
= true;
208 const OUString
& URLParameter::get_the_title()
211 if( ! m_bHelpDataFileRead
)
213 m_bHelpDataFileRead
= true;
218 return EMPTY_OUSTRING
;
222 OUString
URLParameter::get_jar()
225 if( ! m_bHelpDataFileRead
)
227 m_bHelpDataFileRead
= true;
232 return get_module() + ".jar";
236 void URLParameter::readHelpDataFile()
238 if( get_id().isEmpty() )
241 OUString aModule
= get_module();
242 OUString aLanguage
= get_language();
244 DataBaseIterator
aDbIt( *m_pDatabases
, aModule
, aLanguage
, false );
245 bool bSuccess
= false;
247 const char* pData
= nullptr;
249 helpdatafileproxy::HDFData aHDFData
;
250 OUString aExtensionPath
;
251 OUString aExtensionRegistryPath
;
254 helpdatafileproxy::Hdf
* pHdf
= aDbIt
.nextHdf( &aExtensionPath
, &aExtensionRegistryPath
);
258 OString keyStr
= OUStringToOString( m_aId
,RTL_TEXTENCODING_UTF8
);
259 bSuccess
= pHdf
->getValueForKey( keyStr
, aHDFData
);
262 pData
= aHDFData
.getData();
270 DbtToStringConverter
converter( pData
);
271 m_aTitle
= converter
.getTitle();
272 m_pDatabases
->replaceName( m_aTitle
);
273 m_aPath
= converter
.getFile();
274 m_aJar
= converter
.getDatabase();
275 if( !aExtensionPath
.isEmpty() )
277 m_aJar
= "?" + aExtensionPath
+ "?" + m_aJar
;
278 m_aExtensionRegistryPath
= aExtensionRegistryPath
;
280 m_aTag
= converter
.getHash();
284 // Class encapsulating the transformation of the XInputStream to XHTML
288 class InputStreamTransformer
289 : public OWeakObject
,
295 InputStreamTransformer( URLParameter
* urlParam
,
296 Databases
* pDatatabases
,
299 virtual Any SAL_CALL
queryInterface( const Type
& rType
) override
;
300 virtual void SAL_CALL
acquire() noexcept override
;
301 virtual void SAL_CALL
release() noexcept override
;
303 virtual sal_Int32 SAL_CALL
readBytes( Sequence
< sal_Int8
>& aData
,sal_Int32 nBytesToRead
) override
;
305 virtual sal_Int32 SAL_CALL
readSomeBytes( Sequence
< sal_Int8
>& aData
,sal_Int32 nMaxBytesToRead
) override
;
307 virtual void SAL_CALL
skipBytes( sal_Int32 nBytesToSkip
) override
;
309 virtual sal_Int32 SAL_CALL
available() override
;
311 virtual void SAL_CALL
closeInput() override
;
313 virtual void SAL_CALL
seek( sal_Int64 location
) override
;
315 virtual sal_Int64 SAL_CALL
getPosition() override
;
317 virtual sal_Int64 SAL_CALL
getLength() override
;
319 void addToBuffer( const char* buffer
,int len
);
321 OStringBuffer
const & getData() const { return buffer
; }
328 OStringBuffer buffer
;
333 void URLParameter::open( const Reference
< XOutputStream
>& xDataSink
)
335 if( ! xDataSink
.is() )
338 // a standard document or else an active help text, plug in the new input stream
339 rtl::Reference
<InputStreamTransformer
> p(new InputStreamTransformer( this,m_pDatabases
,isRoot() ));
342 xDataSink
->writeBytes( Sequence
< sal_Int8
>( reinterpret_cast<const sal_Int8
*>(p
->getData().getStr()), p
->getData().getLength() ) );
344 catch( const Exception
& )
348 xDataSink
->closeOutput();
352 void URLParameter::open( const Reference
< XActiveDataSink
>& xDataSink
)
354 // a standard document or else an active help text, plug in the new input stream
355 xDataSink
->setInputStream( new InputStreamTransformer( this,m_pDatabases
,isRoot() ) );
359 void URLParameter::parse()
363 sal_Int32 lstIdx
= m_aExpr
.lastIndexOf( '#' );
365 m_aExpr
= m_aExpr
.copy( 0,lstIdx
);
368 ! name( module() ) ||
370 m_aLanguage
.isEmpty() ||
371 m_aSystem
.isEmpty() )
372 throw css::ucb::IllegalIdentifierException();
376 bool URLParameter::scheme()
378 // Correct extension help links as sometimes the
379 // module is missing resulting in a malformed URL
380 if( m_aExpr
.startsWith("vnd.sun.star.help:///") )
382 sal_Int32 nLen
= m_aExpr
.getLength();
383 std::u16string_view aLastStr
=
384 m_aExpr
.subView(sal::static_int_cast
<sal_uInt32
>(nLen
) - 6);
385 if( aLastStr
== u
"DbPAR=" )
387 m_aExpr
= OUString::Concat(m_aExpr
.subView( 0, 20 )) +
389 m_aExpr
.subView( 20 ) +
394 for( sal_Int32 nPrefixLen
= 20 ; nPrefixLen
>= 18 ; --nPrefixLen
)
396 if( m_aExpr
.matchAsciiL( "vnd.sun.star.help://", nPrefixLen
) )
398 m_aExpr
= m_aExpr
.copy( nPrefixLen
);
406 bool URLParameter::module()
408 sal_Int32 idx
= 0,length
= m_aExpr
.getLength();
410 while( idx
< length
&& rtl::isAsciiAlphanumeric( m_aExpr
[idx
] ) )
415 m_aModule
= m_aExpr
.copy( 0,idx
);
416 m_aExpr
= m_aExpr
.copy( idx
);
424 bool URLParameter::name( bool modulePresent
)
426 // if modulepresent, a name may be present, but must not
428 sal_Int32 length
= m_aExpr
.getLength();
430 if( length
!= 0 && m_aExpr
[0] == '/' )
433 while( idx
< length
&& m_aExpr
[idx
] != '?' )
436 if( idx
!= 1 && ! modulePresent
)
440 m_aId
= m_aExpr
.copy( 1,idx
-1 );
441 m_aExpr
= m_aExpr
.copy( idx
);
449 bool URLParameter::query()
453 if( m_aExpr
.isEmpty() )
455 else if( m_aExpr
[0] == '?' )
456 query_
= o3tl::trim(m_aExpr
.subView( 1 ));
462 sal_Int32 delimIdx
,equalIdx
;
463 OUString parameter
,value
;
465 while( !query_
.isEmpty() )
467 delimIdx
= query_
.indexOf( '&' );
468 equalIdx
= query_
.indexOf( '=' );
469 parameter
= o3tl::trim(query_
.subView( 0,equalIdx
));
472 value
= o3tl::trim(query_
.subView( equalIdx
+ 1 ));
477 value
= o3tl::trim(query_
.subView( equalIdx
+1,delimIdx
- equalIdx
- 1 ));
478 query_
= o3tl::trim(query_
.subView( delimIdx
+1 ));
481 if( parameter
== "Language" )
483 else if( parameter
== "Device" )
485 else if( parameter
== "Program" )
487 else if( parameter
== "Eid" )
489 else if( parameter
== "UseDB" )
490 m_bUseDB
= value
!= "no";
491 else if( parameter
== "DbPAR" )
493 else if( parameter
== "Query" )
495 if( m_aQuery
.isEmpty() )
498 m_aQuery
+= " " + value
;
500 else if( parameter
== "Scope" )
502 else if( parameter
== "System" )
504 else if( parameter
== "HelpPrefix" )
505 m_aPrefix
= rtl::Uri::decode(
507 rtl_UriDecodeWithCharset
,
508 RTL_TEXTENCODING_UTF8
);
509 else if( parameter
== "HitCount" )
510 m_nHitCount
= value
.toInt32();
511 else if( parameter
== "Active" )
513 else if( parameter
== "Version" )
514 ; // ignored (but accepted) in the built-in help, useful only for the online help
526 UserData( URLParameter
* pInitial
,
527 Databases
* pDatabases
)
528 : m_pDatabases( pDatabases
),
529 m_pInitial( pInitial
)
533 Databases
* m_pDatabases
;
534 URLParameter
* m_pInitial
;
539 static UserData
*ugblData
= nullptr;
544 fileMatch(const char * URI
) {
545 if ((URI
!= nullptr) && !strncmp(URI
, "file:/", 6))
551 zipMatch(const char * URI
) {
552 if ((URI
!= nullptr) && !strncmp(URI
, "vnd.sun.star.zip:/", 18))
558 helpMatch(const char * URI
) {
559 if ((URI
!= nullptr) && !strncmp(URI
, "vnd.sun.star.help:/", 19))
565 fileOpen(const char *URI
) {
566 osl::File
*pRet
= new osl::File(OUString(URI
, strlen(URI
), RTL_TEXTENCODING_UTF8
));
567 (void)pRet
->open(osl_File_OpenFlag_Read
);
572 zipOpen(SAL_UNUSED_PARAMETER
const char *) {
573 OUString language
,jar
,path
;
575 if( !ugblData
->m_pInitial
->get_eid().isEmpty() )
576 return new Reference
<XHierarchicalNameAccess
>;
579 jar
= ugblData
->m_pInitial
->get_jar();
580 language
= ugblData
->m_pInitial
->get_language();
581 path
= ugblData
->m_pInitial
->get_path();
584 Reference
< XHierarchicalNameAccess
> xNA
=
585 ugblData
->m_pDatabases
->findJarFileForPath( jar
, language
, path
);
587 Reference
< XInputStream
> xInputStream
;
593 Any aEntry
= xNA
->getByHierarchicalName( path
);
594 Reference
< XActiveDataSink
> xSink
;
595 if( ( aEntry
>>= xSink
) && xSink
.is() )
596 xInputStream
= xSink
->getInputStream();
598 catch ( NoSuchElementException
& )
603 if( xInputStream
.is() )
605 return new Reference
<XInputStream
>(xInputStream
);
611 helpOpen(const char * URI
) {
612 OUString language
,jar
,path
;
614 URLParameter
urlpar( OUString::createFromAscii( URI
),
615 ugblData
->m_pDatabases
);
617 jar
= urlpar
.get_jar();
618 language
= urlpar
.get_language();
619 path
= urlpar
.get_path();
621 Reference
< XHierarchicalNameAccess
> xNA
=
622 ugblData
->m_pDatabases
->findJarFileForPath( jar
, language
, path
);
624 Reference
< XInputStream
> xInputStream
;
630 Any aEntry
= xNA
->getByHierarchicalName( path
);
631 Reference
< XActiveDataSink
> xSink
;
632 if( ( aEntry
>>= xSink
) && xSink
.is() )
633 xInputStream
= xSink
->getInputStream();
635 catch ( NoSuchElementException
& )
640 if( xInputStream
.is() )
641 return new Reference
<XInputStream
>(xInputStream
);
646 helpRead(void * context
, char * buffer
, int len
) {
647 Reference
< XInputStream
> *pRef
= static_cast<Reference
< XInputStream
>*>(context
);
649 Sequence
< sal_Int8
> aSeq
;
650 len
= (*pRef
)->readBytes( aSeq
,len
);
651 memcpy(buffer
, aSeq
.getConstArray(), len
);
657 zipRead(void * context
, char * buffer
, int len
) {
658 return helpRead(context
, buffer
, len
);
662 fileRead(void * context
, char * buffer
, int len
) {
664 osl::File
*pFile
= static_cast<osl::File
*>(context
);
667 sal_uInt64 uRead
= 0;
668 if (osl::FileBase::E_None
== pFile
->read(buffer
, len
, uRead
))
669 nRead
= static_cast<int>(uRead
);
675 uriClose(void * context
) {
676 Reference
< XInputStream
> *pRef
= static_cast<Reference
< XInputStream
>*>(context
);
682 fileClose(void * context
) {
683 osl::File
*pFile
= static_cast<osl::File
*>(context
);
694 InputStreamTransformer::InputStreamTransformer( URLParameter
* urlParam
,
695 Databases
* pDatabases
,
702 pDatabases
->cascadingStylesheet( urlParam
->get_language(),
705 else if( urlParam
->isActive() )
708 pDatabases
->setActiveText( urlParam
->get_module(),
709 urlParam
->get_language(),
715 UserData
userData( urlParam
,pDatabases
);
717 // Uses the implementation detail, that OString::getStr returns a zero terminated character-array
719 const char* parameter
[47];
720 OString parString
[46];
723 parString
[last
++] = "Program"_ostr
;
724 OString
aPureProgramm( urlParam
->getByName( "Program" ) );
725 parString
[last
++] = "'" + aPureProgramm
+ "'";
726 parString
[last
++] = "Database"_ostr
;
727 parString
[last
++] = "'" + urlParam
->getByName( "DatabasePar" ) + "'";
728 parString
[last
++] = "Id"_ostr
;
729 parString
[last
++] = "'" + urlParam
->getByName( "Id" ) + "'";
730 parString
[last
++] = "Path"_ostr
;
731 OString
aPath( urlParam
->getByName( "Path" ) );
732 parString
[last
++] = "'" + aPath
+ "'";
734 OString aPureLanguage
= urlParam
->getByName( "Language" );
735 parString
[last
++] = "Language"_ostr
;
736 parString
[last
++] = "'" + aPureLanguage
+ "'";
737 parString
[last
++] = "System"_ostr
;
738 parString
[last
++] = "'" + urlParam
->getByName( "System" ) + "'";
739 parString
[last
++] = "productname"_ostr
;
740 parString
[last
++] = "'" + OUStringToOString(
741 pDatabases
->getProductName(),
742 RTL_TEXTENCODING_UTF8
) + "'";
743 parString
[last
++] = "productversion"_ostr
;
744 parString
[last
++] = "'" +
745 OUStringToOString( pDatabases
->getProductVersion(),
746 RTL_TEXTENCODING_UTF8
) + "'";
748 parString
[last
++] = "imgtheme"_ostr
;
749 parString
[last
++] = "'" + chelp::Databases::getImageTheme() + "'";
750 parString
[last
++] = "hp"_ostr
;
751 parString
[last
++] = "'" + urlParam
->getByName( "HelpPrefix" ) + "'";
753 if( !parString
[last
-1].isEmpty() )
755 parString
[last
++] = "sm"_ostr
;
756 parString
[last
++] = "'vnd.sun.star.help%3A%2F%2F'"_ostr
;
757 parString
[last
++] = "qm"_ostr
;
758 parString
[last
++] = "'%3F'"_ostr
;
759 parString
[last
++] = "es"_ostr
;
760 parString
[last
++] = "'%3D'"_ostr
;
761 parString
[last
++] = "am"_ostr
;
762 parString
[last
++] = "'%26'"_ostr
;
763 parString
[last
++] = "cl"_ostr
;
764 parString
[last
++] = "'%3A'"_ostr
;
765 parString
[last
++] = "sl"_ostr
;
766 parString
[last
++] = "'%2F'"_ostr
;
767 parString
[last
++] = "hm"_ostr
;
768 parString
[last
++] = "'%23'"_ostr
;
769 parString
[last
++] = "cs"_ostr
;
770 parString
[last
++] = "'css'"_ostr
;
772 parString
[last
++] = "vendorname"_ostr
;
773 parString
[last
++] = "''"_ostr
;
774 parString
[last
++] = "vendorversion"_ostr
;
775 parString
[last
++] = "''"_ostr
;
776 parString
[last
++] = "vendorshort"_ostr
;
777 parString
[last
++] = "''"_ostr
;
780 // Do we need to add extension path?
781 OUString aExtensionPath
;
782 OUString aJar
= urlParam
->get_jar();
784 bool bAddExtensionPath
= false;
785 OUString aExtensionRegistryPath
;
786 sal_Int32 nQuestionMark1
= aJar
.indexOf( '?' );
787 sal_Int32 nQuestionMark2
= aJar
.lastIndexOf( '?' );
788 if( nQuestionMark1
!= -1 && nQuestionMark2
!= -1 && nQuestionMark1
!= nQuestionMark2
)
790 aExtensionPath
= aJar
.copy( nQuestionMark1
+ 1, nQuestionMark2
- nQuestionMark1
- 1 );
791 aExtensionRegistryPath
= urlParam
->get_ExtensionRegistryPath();
792 bAddExtensionPath
= true;
796 // Path not yet specified, search directly
797 Reference
< XHierarchicalNameAccess
> xNA
= pDatabases
->findJarFileForPath
798 ( aJar
, urlParam
->get_language(), urlParam
->get_path(), &aExtensionPath
, &aExtensionRegistryPath
);
799 if( xNA
.is() && !aExtensionPath
.isEmpty() )
800 bAddExtensionPath
= true;
803 if( bAddExtensionPath
)
805 const Reference
< XComponentContext
>& xContext(
806 comphelper::getProcessComponentContext() );
808 OUString aOUExpandedExtensionPath
= Databases::expandURL( aExtensionRegistryPath
, xContext
);
809 OString aExpandedExtensionPath
= OUStringToOString( aOUExpandedExtensionPath
, osl_getThreadTextEncoding() );
811 parString
[last
++] = "ExtensionPath"_ostr
;
812 parString
[last
++] = "'" + aExpandedExtensionPath
+ "'";
815 OString aPureExtensionId
;
816 sal_Int32 iSlash
= aPath
.indexOf( '/' );
818 aPureExtensionId
= aPath
.copy( 0, iSlash
);
820 parString
[last
++] = "ExtensionId"_ostr
;
821 parString
[last
++] = "'" + aPureExtensionId
+ "'";
824 for( int i
= 0; i
< last
; ++i
)
825 parameter
[i
] = parString
[i
].getStr();
826 parameter
[last
] = nullptr;
828 OUString xslURL
= pDatabases
->getInstallPathAsURL();
830 OString xslURLascii
= OUStringToOString(
832 RTL_TEXTENCODING_UTF8
) +
833 "main_transform.xsl";
835 ugblData
= &userData
;
838 xmlRegisterInputCallbacks(zipMatch
, zipOpen
, zipRead
, uriClose
);
839 xmlRegisterInputCallbacks(helpMatch
, helpOpen
, helpRead
, uriClose
);
840 xmlRegisterInputCallbacks(fileMatch
, fileOpen
, fileRead
, fileClose
);
842 xsltStylesheetPtr cur
=
843 xsltParseStylesheetFile(reinterpret_cast<const xmlChar
*>(xslURLascii
.getStr()));
845 xmlDocPtr doc
= xmlParseFile("vnd.sun.star.zip:/");
847 xmlDocPtr res
= nullptr;
848 xsltTransformContextPtr transformContext
= xsltNewTransformContext(cur
, doc
);
849 if (transformContext
)
851 xsltSecurityPrefsPtr securityPrefs
= xsltNewSecurityPrefs();
854 xsltSetSecurityPrefs(securityPrefs
, XSLT_SECPREF_READ_FILE
, xsltSecurityAllow
);
855 if (xsltSetCtxtSecurityPrefs(securityPrefs
, transformContext
) == 0)
857 res
= xsltApplyStylesheetUser(cur
, doc
, parameter
, nullptr, nullptr, transformContext
);
860 xmlChar
*doc_txt_ptr
=nullptr;
862 xsltSaveResultToString(&doc_txt_ptr
, &doc_txt_len
, res
, cur
);
863 addToBuffer(reinterpret_cast<char*>(doc_txt_ptr
), doc_txt_len
);
864 xmlFree(doc_txt_ptr
);
867 xsltFreeSecurityPrefs(securityPrefs
);
869 xsltFreeTransformContext(transformContext
);
871 xmlPopInputCallbacks(); //filePatch
872 xmlPopInputCallbacks(); //helpPatch
873 xmlPopInputCallbacks(); //zipMatch
876 xsltFreeStylesheet(cur
);
881 Any SAL_CALL
InputStreamTransformer::queryInterface( const Type
& rType
)
883 Any aRet
= ::cppu::queryInterface( rType
,
884 static_cast< XInputStream
* >(this),
885 static_cast< XSeekable
* >(this) );
887 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
891 void SAL_CALL
InputStreamTransformer::acquire() noexcept
893 OWeakObject::acquire();
897 void SAL_CALL
InputStreamTransformer::release() noexcept
899 OWeakObject::release();
903 sal_Int32 SAL_CALL
InputStreamTransformer::readBytes( Sequence
< sal_Int8
>& aData
,sal_Int32 nBytesToRead
)
905 std::scoped_lock
aGuard( m_aMutex
);
907 int curr
,available_
= buffer
.getLength() - pos
;
908 if( nBytesToRead
<= available_
)
913 if( 0 <= curr
&& aData
.getLength() < curr
)
914 aData
.realloc( curr
);
916 std::copy_n(buffer
.getStr() + pos
, curr
, aData
.getArray());
919 return std::max(curr
, 0);
923 sal_Int32 SAL_CALL
InputStreamTransformer::readSomeBytes( Sequence
< sal_Int8
>& aData
,sal_Int32 nMaxBytesToRead
)
925 return readBytes( aData
,nMaxBytesToRead
);
929 void SAL_CALL
InputStreamTransformer::skipBytes( sal_Int32 nBytesToSkip
)
931 std::scoped_lock
aGuard( m_aMutex
);
932 while( nBytesToSkip
-- ) ++pos
;
936 sal_Int32 SAL_CALL
InputStreamTransformer::available()
938 std::scoped_lock
aGuard( m_aMutex
);
939 return std::min
<sal_Int64
>(SAL_MAX_INT32
, buffer
.getLength() - pos
);
943 void SAL_CALL
InputStreamTransformer::closeInput()
948 void SAL_CALL
InputStreamTransformer::seek( sal_Int64 location
)
950 std::scoped_lock
aGuard( m_aMutex
);
952 throw IllegalArgumentException();
954 pos
= sal::static_int_cast
<sal_Int32
>( location
);
956 if( pos
> buffer
.getLength() )
957 pos
= buffer
.getLength();
961 sal_Int64 SAL_CALL
InputStreamTransformer::getPosition()
963 std::scoped_lock
aGuard( m_aMutex
);
964 return sal_Int64( pos
);
968 sal_Int64 SAL_CALL
InputStreamTransformer::getLength()
970 std::scoped_lock
aGuard( m_aMutex
);
972 return buffer
.getLength();
976 void InputStreamTransformer::addToBuffer( const char* buffer_
,int len_
)
978 std::scoped_lock
aGuard( m_aMutex
);
980 buffer
.append( buffer_
, len_
);
983 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */