LibreOffice Module xmlhelp (master) 1
urlparameter.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
21#include <string.h>
22#include <osl/thread.h>
23#include <osl/file.hxx>
24#include <cppuhelper/weak.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>
34#include "db.hxx"
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>
41
42#include "urlparameter.hxx"
43#include "databases.hxx"
44
45#include <algorithm>
46#include <memory>
47#include <mutex>
48
49using namespace cppu;
50using namespace com::sun::star::io;
51using namespace com::sun::star::uno;
52using namespace com::sun::star::lang;
53using namespace com::sun::star::ucb;
54using namespace com::sun::star::beans;
55using namespace com::sun::star::container;
56using namespace chelp;
57
58
59URLParameter::URLParameter( const OUString& aURL,
60 Databases* pDatabases )
61 : m_pDatabases( pDatabases ),
62 m_aURL( aURL )
63{
64 init();
65 parse();
66}
67
68
70{
71 bool bErrorDoc = false;
72
73 if( isFile() )
74 {
77 bErrorDoc = !xNA.is();
78 }
79
80 return bErrorDoc;
81}
82
83
84OString URLParameter::getByName( const char* par )
85{
86 OUString val;
87
88 if( strcmp( par,"Program" ) == 0 )
89 val = get_program();
90 else if( strcmp( par,"Database" ) == 0 )
91 val = get_module();
92 else if( strcmp( par,"DatabasePar" ) == 0 )
93 val = get_dbpar();
94 else if( strcmp( par,"Id" ) == 0 )
95 val = get_id();
96 else if( strcmp( par,"Path" ) == 0 )
97 val = get_path();
98 else if( strcmp( par,"Language" ) == 0 )
99 val = get_language();
100 else if( strcmp( par,"System" ) == 0 )
101 val = get_system();
102 else if( strcmp( par,"HelpPrefix" ) == 0 )
103 val = m_aPrefix;
104
105 return OUStringToOString( val, RTL_TEXTENCODING_UTF8 );
106}
107
108
109OUString const & URLParameter::get_id()
110{
111 if( m_aId == "start" )
112 { // module is set
115 get_language() );
116 if( inf )
117 m_aId = inf->get_id();
118 }
119
120 return m_aId;
121}
122
124{
125 if( isFile() )
126 return get_the_tag();
127 else
128 return m_aTag;
129}
130
131
133{
134 if( isFile() )
135 return get_the_title();
136 else if( !m_aModule.isEmpty() )
137 {
140 get_language() );
141 if( inf )
142 m_aTitle = inf->get_title();
143 }
144 else // This must be the root
145 m_aTitle = "root";
146
147 return m_aTitle;
148}
149
150
151OUString const & URLParameter::get_language() const
152{
153 return m_aLanguage;
154}
155
156
158{
159 if( m_aProgram.isEmpty() )
160 {
163 get_language() );
164 if( inf )
165 m_aProgram = inf->get_program();
166 }
167 return m_aProgram;
168}
169
170
172{
173 m_bHelpDataFileRead = false;
174 m_bUseDB = true;
175 m_nHitCount = 100; // The default maximum hitcount
176}
177
178
180{
181 if(m_bUseDB) {
182 if( ! m_bHelpDataFileRead )
184
185 m_bHelpDataFileRead = true;
186
187 return m_aTag;
188 }
189 else
190 return OUString();
191}
192
193
194OUString const & URLParameter::get_path()
195{
196 if(m_bUseDB) {
197 if( ! m_bHelpDataFileRead )
199 m_bHelpDataFileRead = true;
200
201 return m_aPath;
202 }
203 else
204 return get_id();
205}
206
207
209{
210 if(m_bUseDB) {
211 if( ! m_bHelpDataFileRead )
213 m_bHelpDataFileRead = true;
214
215 return m_aTitle;
216 }
217 else
218 return OUString();
219}
220
221
223{
224 if(m_bUseDB) {
225 if( ! m_bHelpDataFileRead )
227 m_bHelpDataFileRead = true;
228
229 return m_aJar;
230 }
231 else
232 return get_module() + ".jar";
233}
234
235
237{
238 if( get_id().isEmpty() )
239 return;
240
241 OUString aModule = get_module();
242 OUString aLanguage = get_language();
243
244 DataBaseIterator aDbIt( *m_pDatabases, aModule, aLanguage, false );
245 bool bSuccess = false;
246
247 const char* pData = nullptr;
248
250 OUString aExtensionPath;
251 OUString aExtensionRegistryPath;
252 while( true )
253 {
254 helpdatafileproxy::Hdf* pHdf = aDbIt.nextHdf( &aExtensionPath, &aExtensionRegistryPath );
255 if( !pHdf )
256 break;
257
258 OString keyStr = OUStringToOString( m_aId,RTL_TEXTENCODING_UTF8 );
259 bSuccess = pHdf->getValueForKey( keyStr, aHDFData );
260 if( bSuccess )
261 {
262 pData = aHDFData.getData();
263 break;
264 }
265 }
266
267 if( !bSuccess )
268 return;
269
270 DbtToStringConverter converter( pData );
271 m_aTitle = converter.getTitle();
273 m_aPath = converter.getFile();
274 m_aJar = converter.getDatabase();
275 if( !aExtensionPath.isEmpty() )
276 {
277 m_aJar = "?" + aExtensionPath + "?" + m_aJar;
278 m_aExtensionRegistryPath = aExtensionRegistryPath;
279 }
280 m_aTag = converter.getHash();
281}
282
283
284// Class encapsulating the transformation of the XInputStream to XHTML
285
286namespace {
287
288class InputStreamTransformer
289 : public OWeakObject,
290 public XInputStream,
291 public XSeekable
292{
293public:
294
295 InputStreamTransformer( URLParameter* urlParam,
296 Databases* pDatatabases,
297 bool isRoot );
298
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;
302
303 virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead ) override;
304
305 virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead ) override;
306
307 virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) override;
308
309 virtual sal_Int32 SAL_CALL available() override;
310
311 virtual void SAL_CALL closeInput() override;
312
313 virtual void SAL_CALL seek( sal_Int64 location ) override;
314
315 virtual sal_Int64 SAL_CALL getPosition() override;
316
317 virtual sal_Int64 SAL_CALL getLength() override;
318
319 void addToBuffer( const char* buffer,int len );
320
321 OStringBuffer const & getData() const { return buffer; }
322
323private:
324
325 std::mutex m_aMutex;
326
327 int pos;
328 OStringBuffer buffer;
329};
330
331}
332
333void URLParameter::open( const Reference< XOutputStream >& xDataSink )
334{
335 if( ! xDataSink.is() )
336 return;
337
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() ));
340 try
341 {
342 xDataSink->writeBytes( Sequence< sal_Int8 >( reinterpret_cast<const sal_Int8*>(p->getData().getStr()), p->getData().getLength() ) );
343 }
344 catch( const Exception& )
345 {
346 }
347 p.clear();
348 xDataSink->closeOutput();
349}
350
351
353{
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() ) );
356}
357
358
360{
361 m_aExpr = m_aURL;
362
363 sal_Int32 lstIdx = m_aExpr.lastIndexOf( '#' );
364 if( lstIdx != -1 )
365 m_aExpr = m_aExpr.copy( 0,lstIdx );
366
367 if( ! scheme() ||
368 ! name( module() ) ||
369 ! query() ||
370 m_aLanguage.isEmpty() ||
371 m_aSystem.isEmpty() )
372 throw css::ucb::IllegalIdentifierException();
373}
374
375
377{
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:///") )
381 {
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=" )
386 {
387 m_aExpr = OUString::Concat(m_aExpr.subView( 0, 20 )) +
388 "shared" +
389 m_aExpr.subView( 20 ) +
390 "shared";
391 }
392 }
393
394 for( sal_Int32 nPrefixLen = 20 ; nPrefixLen >= 18 ; --nPrefixLen )
395 {
396 if( m_aExpr.matchAsciiL( "vnd.sun.star.help://", nPrefixLen ) )
397 {
398 m_aExpr = m_aExpr.copy( nPrefixLen );
399 return true;
400 }
401 }
402 return false;
403}
404
405
407{
408 sal_Int32 idx = 0,length = m_aExpr.getLength();
409
410 while( idx < length && rtl::isAsciiAlphanumeric( m_aExpr[idx] ) )
411 ++idx;
412
413 if( idx != 0 )
414 {
415 m_aModule = m_aExpr.copy( 0,idx );
416 m_aExpr = m_aExpr.copy( idx );
417 return true;
418 }
419 else
420 return false;
421}
422
423
424bool URLParameter::name( bool modulePresent )
425{
426 // if modulepresent, a name may be present, but must not
427
428 sal_Int32 length = m_aExpr.getLength();
429
430 if( length != 0 && m_aExpr[0] == '/' )
431 {
432 sal_Int32 idx = 1;
433 while( idx < length && m_aExpr[idx] != '?' )
434 ++idx;
435
436 if( idx != 1 && ! modulePresent )
437 return false;
438 else
439 {
440 m_aId = m_aExpr.copy( 1,idx-1 );
441 m_aExpr = m_aExpr.copy( idx );
442 }
443 }
444
445 return true;
446}
447
448
450{
451 OUString query_;
452
453 if( m_aExpr.isEmpty() )
454 return true;
455 else if( m_aExpr[0] == '?' )
456 query_ = o3tl::trim(m_aExpr.subView( 1 ));
457 else
458 return false;
459
460
461 bool ret = true;
462 sal_Int32 delimIdx,equalIdx;
463 OUString parameter,value;
464
465 while( !query_.isEmpty() )
466 {
467 delimIdx = query_.indexOf( '&' );
468 equalIdx = query_.indexOf( '=' );
469 parameter = o3tl::trim(query_.subView( 0,equalIdx ));
470 if( delimIdx == -1 )
471 {
472 value = o3tl::trim(query_.subView( equalIdx + 1 ));
473 query_.clear();
474 }
475 else
476 {
477 value = o3tl::trim(query_.subView( equalIdx+1,delimIdx - equalIdx - 1 ));
478 query_ = o3tl::trim(query_.subView( delimIdx+1 ));
479 }
480
481 if( parameter == "Language" )
483 else if( parameter == "Device" )
484 ;
485 else if( parameter == "Program" )
487 else if( parameter == "Eid" )
488 m_aEid = value;
489 else if( parameter == "UseDB" )
490 m_bUseDB = value != "no";
491 else if( parameter == "DbPAR" )
492 m_aDbPar = value;
493 else if( parameter == "Query" )
494 {
495 if( m_aQuery.isEmpty() )
496 m_aQuery = value;
497 else
498 m_aQuery += " " + value;
499 }
500 else if( parameter == "Scope" )
501 m_aScope = value;
502 else if( parameter == "System" )
504 else if( parameter == "HelpPrefix" )
505 m_aPrefix = rtl::Uri::decode(
506 value,
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
515 else
516 ret = false;
517 }
518
519 return ret;
520}
521
522namespace {
523
524struct UserData {
525
526 UserData( URLParameter* pInitial,
527 Databases* pDatabases )
528 : m_pDatabases( pDatabases ),
529 m_pInitial( pInitial )
530 {
531 }
532
533 Databases* m_pDatabases;
534 URLParameter* m_pInitial;
535};
536
537}
538
539static UserData *ugblData = nullptr;
540
541extern "C" {
542
543static int
544fileMatch(const char * URI) {
545 if ((URI != nullptr) && !strncmp(URI, "file:/", 6))
546 return 1;
547 return 0;
548}
549
550static int
551zipMatch(const char * URI) {
552 if ((URI != nullptr) && !strncmp(URI, "vnd.sun.star.zip:/", 18))
553 return 1;
554 return 0;
555}
556
557static int
558helpMatch(const char * URI) {
559 if ((URI != nullptr) && !strncmp(URI, "vnd.sun.star.help:/", 19))
560 return 1;
561 return 0;
562}
563
564static void *
565fileOpen(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);
568 return pRet;
569}
570
571static void *
572zipOpen(SAL_UNUSED_PARAMETER const char *) {
573 OUString language,jar,path;
574
575 if( !ugblData->m_pInitial->get_eid().isEmpty() )
577 else
578 {
579 jar = ugblData->m_pInitial->get_jar();
580 language = ugblData->m_pInitial->get_language();
581 path = ugblData->m_pInitial->get_path();
582 }
583
585 ugblData->m_pDatabases->findJarFileForPath( jar, language, path );
586
587 Reference< XInputStream > xInputStream;
588
589 if( xNA.is() )
590 {
591 try
592 {
593 Any aEntry = xNA->getByHierarchicalName( path );
595 if( ( aEntry >>= xSink ) && xSink.is() )
596 xInputStream = xSink->getInputStream();
597 }
598 catch ( NoSuchElementException & )
599 {
600 }
601 }
602
603 if( xInputStream.is() )
604 {
605 return new Reference<XInputStream>(xInputStream);
606 }
607 return nullptr;
608}
609
610static void *
611helpOpen(const char * URI) {
612 OUString language,jar,path;
613
614 URLParameter urlpar( OUString::createFromAscii( URI ),
615 ugblData->m_pDatabases );
616
617 jar = urlpar.get_jar();
618 language = urlpar.get_language();
619 path = urlpar.get_path();
620
622 ugblData->m_pDatabases->findJarFileForPath( jar, language, path );
623
624 Reference< XInputStream > xInputStream;
625
626 if( xNA.is() )
627 {
628 try
629 {
630 Any aEntry = xNA->getByHierarchicalName( path );
632 if( ( aEntry >>= xSink ) && xSink.is() )
633 xInputStream = xSink->getInputStream();
634 }
635 catch ( NoSuchElementException & )
636 {
637 }
638 }
639
640 if( xInputStream.is() )
641 return new Reference<XInputStream>(xInputStream);
642 return nullptr;
643}
644
645static int
646helpRead(void * context, char * buffer, int len) {
647 Reference< XInputStream > *pRef = static_cast<Reference< XInputStream >*>(context);
648
650 len = (*pRef)->readBytes( aSeq,len);
651 memcpy(buffer, aSeq.getConstArray(), len);
652
653 return len;
654}
655
656static int
657zipRead(void * context, char * buffer, int len) {
658 return helpRead(context, buffer, len);
659}
660
661static int
662fileRead(void * context, char * buffer, int len) {
663 int nRead = 0;
664 osl::File *pFile = static_cast<osl::File*>(context);
665 if (pFile)
666 {
667 sal_uInt64 uRead = 0;
668 if (osl::FileBase::E_None == pFile->read(buffer, len, uRead))
669 nRead = static_cast<int>(uRead);
670 }
671 return nRead;
672}
673
674static int
675uriClose(void * context) {
676 Reference< XInputStream > *pRef = static_cast<Reference< XInputStream >*>(context);
677 delete pRef;
678 return 0;
679}
680
681static int
682fileClose(void * context) {
683 osl::File *pFile = static_cast<osl::File*>(context);
684 if (pFile)
685 {
686 pFile->close();
687 delete pFile;
688 }
689 return 0;
690}
691
692} // extern "C"
693
694InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam,
695 Databases* pDatabases,
696 bool isRoot )
697 : pos( 0 )
698{
699 if( isRoot )
700 {
701 buffer.setLength(0);
702 pDatabases->cascadingStylesheet( urlParam->get_language(),
703 buffer );
704 }
705 else if( urlParam->isActive() )
706 {
707 buffer.setLength(0);
708 pDatabases->setActiveText( urlParam->get_module(),
709 urlParam->get_language(),
710 urlParam->get_id(),
711 buffer );
712 }
713 else
714 {
715 UserData userData( urlParam,pDatabases );
716
717 // Uses the implementation detail, that OString::getStr returns a zero terminated character-array
718
719 const char* parameter[47];
720 OString parString[46];
721 int last = 0;
722
723 parString[last++] = "Program";
724 OString aPureProgramm( urlParam->getByName( "Program" ) );
725 parString[last++] = "'" + aPureProgramm + "'";
726 parString[last++] = "Database";
727 parString[last++] = "'" + urlParam->getByName( "DatabasePar" ) + "'";
728 parString[last++] = "Id";
729 parString[last++] = "'" + urlParam->getByName( "Id" ) + "'";
730 parString[last++] = "Path";
731 OString aPath( urlParam->getByName( "Path" ) );
732 parString[last++] = "'" + aPath + "'";
733
734 OString aPureLanguage = urlParam->getByName( "Language" );
735 parString[last++] = "Language";
736 parString[last++] = "'" + aPureLanguage + "'";
737 parString[last++] = "System";
738 parString[last++] = "'" + urlParam->getByName( "System" ) + "'";
739 parString[last++] = "productname";
740 parString[last++] = "'" + OUStringToOString(
741 pDatabases->getProductName(),
742 RTL_TEXTENCODING_UTF8 ) + "'";
743 parString[last++] = "productversion";
744 parString[last++] = "'" +
746 RTL_TEXTENCODING_UTF8 ) + "'";
747
748 parString[last++] = "imgtheme";
749 parString[last++] = "'" + pDatabases->getImageTheme() + "'";
750 parString[last++] = "hp";
751 parString[last++] = "'" + urlParam->getByName( "HelpPrefix" ) + "'";
752
753 if( !parString[last-1].isEmpty() )
754 {
755 parString[last++] = "sm";
756 parString[last++] = "'vnd.sun.star.help%3A%2F%2F'";
757 parString[last++] = "qm";
758 parString[last++] = "'%3F'";
759 parString[last++] = "es";
760 parString[last++] = "'%3D'";
761 parString[last++] = "am";
762 parString[last++] = "'%26'";
763 parString[last++] = "cl";
764 parString[last++] = "'%3A'";
765 parString[last++] = "sl";
766 parString[last++] = "'%2F'";
767 parString[last++] = "hm";
768 parString[last++] = "'%23'";
769 parString[last++] = "cs";
770 parString[last++] = "'css'";
771
772 parString[last++] = "vendorname";
773 parString[last++] = OString("''");
774 parString[last++] = "vendorversion";
775 parString[last++] = OString("''");
776 parString[last++] = "vendorshort";
777 parString[last++] = OString("''");
778 }
779
780 // Do we need to add extension path?
781 OUString aExtensionPath;
782 OUString aJar = urlParam->get_jar();
783
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 )
789 {
790 aExtensionPath = aJar.copy( nQuestionMark1 + 1, nQuestionMark2 - nQuestionMark1 - 1 );
791 aExtensionRegistryPath = urlParam->get_ExtensionRegistryPath();
792 bAddExtensionPath = true;
793 }
794 else
795 {
796 // Path not yet specified, search directly
798 ( aJar, urlParam->get_language(), urlParam->get_path(), &aExtensionPath, &aExtensionRegistryPath );
799 if( xNA.is() && !aExtensionPath.isEmpty() )
800 bAddExtensionPath = true;
801 }
802
803 if( bAddExtensionPath )
804 {
807
808 OUString aOUExpandedExtensionPath = Databases::expandURL( aExtensionRegistryPath, xContext );
809 OString aExpandedExtensionPath = OUStringToOString( aOUExpandedExtensionPath, osl_getThreadTextEncoding() );
810
811 parString[last++] = "ExtensionPath";
812 parString[last++] = "'" + aExpandedExtensionPath + "'";
813
814 // ExtensionId
815 OString aPureExtensionId;
816 sal_Int32 iSlash = aPath.indexOf( '/' );
817 if( iSlash != -1 )
818 aPureExtensionId = aPath.copy( 0, iSlash );
819
820 parString[last++] = "ExtensionId";
821 parString[last++] = "'" + aPureExtensionId + "'";
822 }
823
824 for( int i = 0; i < last; ++i )
825 parameter[i] = parString[i].getStr();
826 parameter[last] = nullptr;
827
828 OUString xslURL = pDatabases->getInstallPathAsURL();
829
830 OString xslURLascii = OUStringToOString(
831 xslURL,
832 RTL_TEXTENCODING_UTF8) +
833 "main_transform.xsl";
834
835 ugblData = &userData;
836
837 xmlInitParser();
838 xmlRegisterInputCallbacks(zipMatch, zipOpen, zipRead, uriClose);
839 xmlRegisterInputCallbacks(helpMatch, helpOpen, helpRead, uriClose);
840 xmlRegisterInputCallbacks(fileMatch, fileOpen, fileRead, fileClose);
841
842 xsltStylesheetPtr cur =
843 xsltParseStylesheetFile(reinterpret_cast<const xmlChar *>(xslURLascii.getStr()));
844
845 xmlDocPtr doc = xmlParseFile("vnd.sun.star.zip:/");
846
847 xmlDocPtr res = nullptr;
848 xsltTransformContextPtr transformContext = xsltNewTransformContext(cur, doc);
849 if (transformContext)
850 {
851 xsltSecurityPrefsPtr securityPrefs = xsltNewSecurityPrefs();
852 if (securityPrefs)
853 {
854 xsltSetSecurityPrefs(securityPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityAllow);
855 if (xsltSetCtxtSecurityPrefs(securityPrefs, transformContext) == 0)
856 {
857 res = xsltApplyStylesheetUser(cur, doc, parameter, nullptr, nullptr, transformContext);
858 if (res)
859 {
860 xmlChar *doc_txt_ptr=nullptr;
861 int doc_txt_len;
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);
865 }
866 }
867 xsltFreeSecurityPrefs(securityPrefs);
868 }
869 xsltFreeTransformContext(transformContext);
870 }
871 xmlPopInputCallbacks(); //filePatch
872 xmlPopInputCallbacks(); //helpPatch
873 xmlPopInputCallbacks(); //zipMatch
874 xmlFreeDoc(res);
875 xmlFreeDoc(doc);
876 xsltFreeStylesheet(cur);
877 }
878}
879
880
881Any SAL_CALL InputStreamTransformer::queryInterface( const Type& rType )
882{
883 Any aRet = ::cppu::queryInterface( rType,
884 static_cast< XInputStream* >(this),
885 static_cast< XSeekable* >(this) );
886
887 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
888}
889
890
891void SAL_CALL InputStreamTransformer::acquire() noexcept
892{
893 OWeakObject::acquire();
894}
895
896
897void SAL_CALL InputStreamTransformer::release() noexcept
898{
899 OWeakObject::release();
900}
901
902
903sal_Int32 SAL_CALL InputStreamTransformer::readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead )
904{
905 std::scoped_lock aGuard( m_aMutex );
906
907 int curr,available_ = buffer.getLength() - pos;
908 if( nBytesToRead <= available_ )
909 curr = nBytesToRead;
910 else
911 curr = available_;
912
913 if( 0 <= curr && aData.getLength() < curr )
914 aData.realloc( curr );
915
916 std::copy_n(buffer.getStr() + pos, curr, aData.getArray());
917 pos += curr;
918
919 return std::max(curr, 0);
920}
921
922
923sal_Int32 SAL_CALL InputStreamTransformer::readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead )
924{
925 return readBytes( aData,nMaxBytesToRead );
926}
927
928
929void SAL_CALL InputStreamTransformer::skipBytes( sal_Int32 nBytesToSkip )
930{
931 std::scoped_lock aGuard( m_aMutex );
932 while( nBytesToSkip-- ) ++pos;
933}
934
935
936sal_Int32 SAL_CALL InputStreamTransformer::available()
937{
938 std::scoped_lock aGuard( m_aMutex );
939 return std::min<sal_Int64>(SAL_MAX_INT32, buffer.getLength() - pos);
940}
941
942
943void SAL_CALL InputStreamTransformer::closeInput()
944{
945}
946
947
948void SAL_CALL InputStreamTransformer::seek( sal_Int64 location )
949{
950 std::scoped_lock aGuard( m_aMutex );
951 if( location < 0 )
952 throw IllegalArgumentException();
953
954 pos = sal::static_int_cast<sal_Int32>( location );
955
956 if( pos > buffer.getLength() )
957 pos = buffer.getLength();
958}
959
960
961sal_Int64 SAL_CALL InputStreamTransformer::getPosition()
962{
963 std::scoped_lock aGuard( m_aMutex );
964 return sal_Int64( pos );
965}
966
967
968sal_Int64 SAL_CALL InputStreamTransformer::getLength()
969{
970 std::scoped_lock aGuard( m_aMutex );
971
972 return buffer.getLength();
973}
974
975
976void InputStreamTransformer::addToBuffer( const char* buffer_,int len_ )
977{
978 std::scoped_lock aGuard( m_aMutex );
979
980 buffer.append( buffer_, len_ );
981}
982
983/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::util::URL m_aURL
helpdatafileproxy::Hdf * nextHdf(OUString *o_pExtensionPath=nullptr, OUString *o_pExtensionRegistryPath=nullptr)
Definition: databases.cxx:1408
css::uno::Reference< css::container::XHierarchicalNameAccess > findJarFileForPath(const OUString &jar, const OUString &Language, const OUString &path, OUString *o_pExtensionPath=nullptr, OUString *o_pExtensionRegistryPath=nullptr)
Definition: databases.cxx:882
OString getImageTheme() const
Definition: databases.cxx:179
const OUString & getProductName() const
Definition: databases.hxx:219
void cascadingStylesheet(const OUString &Language, OStringBuffer &buffer)
Returns the cascading style sheet used to format the HTML-output.
Definition: databases.cxx:949
OUString getInstallPathAsURL()
Definition: databases.cxx:273
StaticModuleInformation * getStaticInformationForModule(std::u16string_view Module, const OUString &Language)
Definition: databases.cxx:323
void replaceName(OUString &oustring) const
Definition: databases.cxx:207
void setActiveText(const OUString &Module, const OUString &Language, std::u16string_view Id, OStringBuffer &buffer)
Returns the active help text for the given module, language and id.
Definition: databases.cxx:1055
const OUString & getProductVersion() const
Definition: databases.hxx:220
OUString getDatabase() const
const OUString & get_program() const
Definition: databases.hxx:79
const OUString & get_id() const
Definition: databases.hxx:78
const OUString & get_title() const
Definition: databases.hxx:77
OUString const & get_id()
bool isActive() const
OUString get_the_title()
const OUString & get_ExtensionRegistryPath() const
OString getByName(const char *par)
OUString const & get_dbpar() const
OUString m_aExtensionRegistryPath
void open(const css::uno::Reference< css::io::XActiveDataSink > &xDataSink)
const OUString & get_module() const
const OUString & get_system() const
bool name(bool modulePresent)
Databases * m_pDatabases
OUString const & get_language() const
OUString const & get_path()
OUString const & get_program()
const char * getData() const
Definition: db.hxx:44
bool getValueForKey(const OString &rKey, HDFData &rValue)
Definition: db.cxx:152
Any value
URL aURL
float u
std::mutex m_aMutex
const sal_uInt16 idx[]
void * p
tools::SvRef< SvBaseLink > xSink
Sequence< sal_Int8 > aSeq
std::unique_ptr< sal_Int32[]> pData
constexpr OUStringLiteral aData
Reference< XComponentContext > getProcessComponentContext()
Type
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
int i
constexpr OUStringLiteral last
std::basic_string_view< charT, traits > trim(std::basic_string_view< charT, traits > str)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
UserData(OUString aPropertyPath, bool isReadOnly)
signed char sal_Int8
static int helpMatch(const char *URI)
static UserData * ugblData
static int zipMatch(const char *URI)
static int uriClose(void *context)
static int fileClose(void *context)
static int zipRead(void *context, char *buffer, int len)
static int fileMatch(const char *URI)
static void * zipOpen(SAL_UNUSED_PARAMETER const char *)
static void * helpOpen(const char *URI)
static int fileRead(void *context, char *buffer, int len)
static void * fileOpen(const char *URI)
static int helpRead(void *context, char *buffer, int len)
size_t pos