fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / xmlhelp / source / cxxhelp / provider / urlparameter.cxx
blob254be3166ff3da80d6c9e8d1e7efa52679efe684
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
21 #include "bufferedinputstream.hxx"
23 #include <string.h>
24 #include <osl/diagnose.hxx>
25 #include <osl/thread.h>
26 #include <osl/file.hxx>
27 #include <cppuhelper/weak.hxx>
28 #include <cppuhelper/queryinterface.hxx>
29 #include <comphelper/processfactory.hxx>
30 #include <rtl/uri.hxx>
31 #include <rtl/ustrbuf.hxx>
32 #include <libxslt/xslt.h>
33 #include <libxslt/transform.h>
34 #include <libxslt/xsltutils.h>
35 #include "db.hxx"
36 #include <com/sun/star/io/XActiveDataSink.hpp>
37 #include <com/sun/star/io/XInputStream.hpp>
38 #include <com/sun/star/io/XSeekable.hpp>
39 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
40 #include <com/sun/star/ucb/OpenMode.hpp>
41 #include <com/sun/star/ucb/XCommandProcessor.hpp>
42 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
43 #include <com/sun/star/ucb/XContentIdentifier.hpp>
44 #include <com/sun/star/ucb/XContentProvider.hpp>
45 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
46 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
48 #include "urlparameter.hxx"
49 #include "databases.hxx"
51 namespace chelp {
53 inline bool ascii_isDigit( sal_Unicode ch )
55 return ((ch >= 0x0030) && (ch <= 0x0039));
58 inline bool ascii_isLetter( sal_Unicode ch )
60 return ( ( (ch >= 0x0041) && (ch <= 0x005A) ) ||
61 ( (ch >= 0x0061) && (ch <= 0x007A) ) );
64 inline bool isLetterOrDigit( sal_Unicode ch )
66 return ascii_isLetter( ch ) || ascii_isDigit( ch );
71 using namespace cppu;
72 using namespace com::sun::star::io;
73 using namespace com::sun::star::uno;
74 using namespace com::sun::star::lang;
75 using namespace com::sun::star::ucb;
76 using namespace com::sun::star::beans;
77 using namespace com::sun::star::container;
78 using namespace chelp;
81 URLParameter::URLParameter( const OUString& aURL,
82 Databases* pDatabases )
83 throw( com::sun::star::ucb::IllegalIdentifierException )
84 : m_pDatabases( pDatabases ),
85 m_aURL( aURL )
87 init( false );
88 parse();
92 bool URLParameter::isErrorDocument()
94 bool bErrorDoc = false;
96 if( isFile() )
98 Reference< XHierarchicalNameAccess > xNA =
99 m_pDatabases->findJarFileForPath( get_jar(), get_language(), get_path() );
100 bErrorDoc = !xNA.is();
103 return bErrorDoc;
107 OString URLParameter::getByName( const char* par )
109 OUString val;
111 if( strcmp( par,"Program" ) == 0 )
112 val = get_program();
113 else if( strcmp( par,"Database" ) == 0 )
114 val = get_module();
115 else if( strcmp( par,"DatabasePar" ) == 0 )
116 val = get_dbpar();
117 else if( strcmp( par,"Id" ) == 0 )
118 val = get_id();
119 else if( strcmp( par,"Path" ) == 0 )
120 val = get_path();
121 else if( strcmp( par,"Language" ) == 0 )
122 val = get_language();
123 else if( strcmp( par,"System" ) == 0 )
124 val = get_system();
125 else if( strcmp( par,"HelpPrefix" ) == 0 )
126 val = get_prefix();
128 return OString( val.getStr(),val.getLength(),RTL_TEXTENCODING_UTF8 );
132 OUString URLParameter::get_id()
134 if( m_aId.compareToAscii("start") == 0 )
135 { // module is set
136 StaticModuleInformation* inf =
137 m_pDatabases->getStaticInformationForModule( get_module(),
138 get_language() );
139 if( inf )
140 m_aId = inf->get_id();
142 m_bStart = true;
145 return m_aId;
148 OUString URLParameter::get_tag()
150 if( isFile() )
151 return get_the_tag();
152 else
153 return m_aTag;
157 OUString URLParameter::get_title()
159 if( isFile() )
160 return get_the_title();
161 else if( m_aModule.compareToAscii("") != 0 )
163 StaticModuleInformation* inf =
164 m_pDatabases->getStaticInformationForModule( get_module(),
165 get_language() );
166 if( inf )
167 m_aTitle = inf->get_title();
169 else // This must be the root
170 m_aTitle = OUString("root");
172 return m_aTitle;
176 OUString URLParameter::get_language()
178 if( m_aLanguage.isEmpty() )
179 return m_aDefaultLanguage;
181 return m_aLanguage;
185 OUString URLParameter::get_program()
187 if( m_aProgram.isEmpty() )
189 StaticModuleInformation* inf =
190 m_pDatabases->getStaticInformationForModule( get_module(),
191 get_language() );
192 if( inf )
193 m_aProgram = inf->get_program();
195 return m_aProgram;
199 void URLParameter::init( bool bDefaultLanguageIsInitialized )
201 (void)bDefaultLanguageIsInitialized;
203 m_bHelpDataFileRead = false;
204 m_bStart = false;
205 m_bUseDB = true;
206 m_nHitCount = 100; // The default maximum hitcount
210 OUString URLParameter::get_the_tag()
212 if(m_bUseDB) {
213 if( ! m_bHelpDataFileRead )
214 readHelpDataFile();
216 m_bHelpDataFileRead = true;
218 return m_aTag;
220 else
221 return OUString();
226 OUString URLParameter::get_the_path()
228 if(m_bUseDB) {
229 if( ! m_bHelpDataFileRead )
230 readHelpDataFile();
231 m_bHelpDataFileRead = true;
233 return m_aPath;
235 else
236 return get_id();
241 OUString URLParameter::get_the_title()
243 if(m_bUseDB) {
244 if( ! m_bHelpDataFileRead )
245 readHelpDataFile();
246 m_bHelpDataFileRead = true;
248 return m_aTitle;
250 else
251 return OUString();
255 OUString URLParameter::get_the_jar()
257 if(m_bUseDB) {
258 if( ! m_bHelpDataFileRead )
259 readHelpDataFile();
260 m_bHelpDataFileRead = true;
262 return m_aJar;
264 else
265 return get_module() + OUString(".jar");
269 void URLParameter::readHelpDataFile()
271 if( get_id().compareToAscii("") == 0 )
272 return;
274 OUString aModule = get_module();
275 OUString aLanguage = get_language();
277 DataBaseIterator aDbIt( *m_pDatabases, aModule, aLanguage, false );
278 bool bSuccess = false;
280 const sal_Char* pData = NULL;
282 helpdatafileproxy::HDFData aHDFData;
283 OUString aExtensionPath;
284 OUString aExtensionRegistryPath;
285 while( true )
287 helpdatafileproxy::Hdf* pHdf = aDbIt.nextHdf( &aExtensionPath, &aExtensionRegistryPath );
288 if( !pHdf )
289 break;
291 OString keyStr( m_aId.getStr(),m_aId.getLength(),RTL_TEXTENCODING_UTF8 );
292 bSuccess = pHdf->getValueForKey( keyStr, aHDFData );
293 if( bSuccess )
295 pData = aHDFData.getData();
296 break;
300 if( bSuccess )
302 DbtToStringConverter converter( pData );
303 m_aTitle = converter.getTitle();
304 m_pDatabases->replaceName( m_aTitle );
305 m_aPath = converter.getFile();
306 m_aJar = converter.getDatabase();
307 if( !aExtensionPath.isEmpty() )
309 OUStringBuffer aExtendedJarStrBuf;
310 aExtendedJarStrBuf.append( '?' );
311 aExtendedJarStrBuf.append( aExtensionPath );
312 aExtendedJarStrBuf.append( '?' );
313 aExtendedJarStrBuf.append( m_aJar );
314 m_aJar = aExtendedJarStrBuf.makeStringAndClear();
315 m_aExtensionRegistryPath = aExtensionRegistryPath;
317 m_aTag = converter.getHash();
323 // Class encapsulating the transformation of the XInputStream to XHTML
326 class InputStreamTransformer
327 : public OWeakObject,
328 public XInputStream,
329 public XSeekable
331 public:
333 InputStreamTransformer( URLParameter* urlParam,
334 Databases* pDatatabases,
335 bool isRoot = false );
337 ~InputStreamTransformer();
339 virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException );
340 virtual void SAL_CALL acquire( void ) throw();
341 virtual void SAL_CALL release( void ) throw();
343 virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead )
344 throw( NotConnectedException,
345 BufferSizeExceededException,
346 IOException,
347 RuntimeException);
349 virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead )
350 throw( NotConnectedException,
351 BufferSizeExceededException,
352 IOException,
353 RuntimeException);
355 virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) throw( NotConnectedException,
356 BufferSizeExceededException,
357 IOException,
358 RuntimeException );
360 virtual sal_Int32 SAL_CALL available( void ) throw( NotConnectedException,
361 IOException,
362 RuntimeException );
364 virtual void SAL_CALL closeInput( void ) throw( NotConnectedException,
365 IOException,
366 RuntimeException );
368 virtual void SAL_CALL seek( sal_Int64 location ) throw( IllegalArgumentException,
369 IOException,
370 RuntimeException );
372 virtual sal_Int64 SAL_CALL getPosition( void ) throw( IOException,RuntimeException );
374 virtual sal_Int64 SAL_CALL getLength( void ) throw( IOException,RuntimeException );
376 void addToBuffer( const char* buffer,int len );
378 sal_Int8* getData() const { return (sal_Int8*) buffer; }
380 sal_Int32 getLen() const { return sal_Int32( len ); }
382 private:
384 osl::Mutex m_aMutex;
386 int len,pos;
387 char *buffer;
392 void URLParameter::open( const Command& aCommand,
393 sal_Int32 CommandId,
394 const Reference< XCommandEnvironment >& Environment,
395 const Reference< XOutputStream >& xDataSink )
397 (void)aCommand;
398 (void)CommandId;
399 (void)Environment;
401 if( ! xDataSink.is() )
402 return;
404 if( isPicture() )
406 Reference< XInputStream > xStream;
407 Reference< XHierarchicalNameAccess > xNA =
408 m_pDatabases->jarFile( OUString( "picture.jar" ),
409 get_language() );
411 OUString path = get_path();
412 if( xNA.is() )
416 Any aEntry = xNA->getByHierarchicalName( path );
417 Reference< XActiveDataSink > xSink;
418 if( ( aEntry >>= xSink ) && xSink.is() )
419 xStream = xSink->getInputStream();
421 catch ( NoSuchElementException & )
425 if( xStream.is() )
427 sal_Int32 ret;
428 Sequence< sal_Int8 > aSeq( 4096 );
429 while( true )
433 ret = xStream->readBytes( aSeq,4096 );
434 xDataSink->writeBytes( aSeq );
435 if( ret < 4096 )
436 break;
438 catch( const Exception& )
440 break;
445 else
447 // a standard document or else an active help text, plug in the new input stream
448 InputStreamTransformer* p = new InputStreamTransformer( this,m_pDatabases,isRoot() );
451 xDataSink->writeBytes( Sequence< sal_Int8 >( p->getData(),p->getLen() ) );
453 catch( const Exception& )
456 delete p;
458 xDataSink->closeOutput();
463 void URLParameter::open( const Command& aCommand,
464 sal_Int32 CommandId,
465 const Reference< XCommandEnvironment >& Environment,
466 const Reference< XActiveDataSink >& xDataSink )
468 (void)aCommand;
469 (void)CommandId;
470 (void)Environment;
472 if( isPicture() )
474 Reference< XInputStream > xStream;
475 Reference< XHierarchicalNameAccess > xNA =
476 m_pDatabases->jarFile( OUString( "picture.jar" ),
477 get_language() );
479 OUString path = get_path();
480 if( xNA.is() )
484 Any aEntry = xNA->getByHierarchicalName( path );
485 Reference< XActiveDataSink > xSink;
486 if( ( aEntry >>= xSink ) && xSink.is() )
487 xStream = xSink->getInputStream();
489 catch ( NoSuchElementException & )
493 xDataSink->setInputStream( turnToSeekable(xStream) );
495 else
496 // a standard document or else an active help text, plug in the new input stream
497 xDataSink->setInputStream( new InputStreamTransformer( this,m_pDatabases,isRoot() ) );
501 void URLParameter::parse() throw( com::sun::star::ucb::IllegalIdentifierException )
503 m_aExpr = m_aURL;
505 sal_Int32 lstIdx = m_aExpr.lastIndexOf( sal_Unicode( '#' ) );
506 if( lstIdx != -1 )
507 m_aExpr = m_aExpr.copy( 0,lstIdx );
509 if( ! scheme() ||
510 ! name( module() ) ||
511 ! query() ||
512 m_aLanguage.isEmpty() ||
513 m_aSystem.isEmpty() )
514 throw com::sun::star::ucb::IllegalIdentifierException();
518 bool URLParameter::scheme()
520 // Correct extension help links as sometimes the
521 // module is missing resulting in a misformed URL
522 if( m_aExpr.startsWith("vnd.sun.star.help:///") )
524 sal_Int32 nLen = m_aExpr.getLength();
525 OUString aLastStr =
526 m_aExpr.copy(sal::static_int_cast<sal_uInt32>(nLen) - 6);
527 if( aLastStr.compareToAscii( "DbPAR=" ) == 0 )
529 OUString aNewExpr = m_aExpr.copy( 0, 20 );
530 OUString aSharedStr("shared");
531 aNewExpr += aSharedStr;
532 aNewExpr += m_aExpr.copy( 20 );
533 aNewExpr += aSharedStr;
534 m_aExpr = aNewExpr;
538 for( sal_Int32 nPrefixLen = 20 ; nPrefixLen >= 18 ; --nPrefixLen )
540 if( m_aExpr.matchAsciiL( "vnd.sun.star.help://", nPrefixLen ) )
542 m_aExpr = m_aExpr.copy( nPrefixLen );
543 return true;
546 return false;
550 bool URLParameter::module()
552 sal_Int32 idx = 0,length = m_aExpr.getLength();
554 while( idx < length && isLetterOrDigit( (m_aExpr.getStr())[idx] ) )
555 ++idx;
557 if( idx != 0 )
559 m_aModule = m_aExpr.copy( 0,idx );
560 m_aExpr = m_aExpr.copy( idx );
561 return true;
563 else
564 return false;
569 bool URLParameter::name( bool modulePresent )
571 // if modulepresent, a name may be present, but must not
573 sal_Int32 length = m_aExpr.getLength();
575 if( length != 0 && (m_aExpr.getStr())[0] == sal_Unicode( '/' ) )
577 sal_Int32 idx = 1;
578 while( idx < length && (m_aExpr.getStr())[idx] != '?' )
579 ++idx;
581 if( idx != 1 && ! modulePresent )
582 return false;
583 else
585 m_aId = m_aExpr.copy( 1,idx-1 );
586 m_aExpr = m_aExpr.copy( idx );
590 return true;
594 bool URLParameter::query()
596 OUString query_;
598 if( m_aExpr.isEmpty() )
599 return true;
600 else if( (m_aExpr.getStr())[0] == sal_Unicode( '?' ) )
601 query_ = m_aExpr.copy( 1 ).trim();
602 else
603 return false;
606 bool ret = true;
607 sal_Int32 delimIdx,equalIdx;
608 OUString parameter,value;
610 while( !query_.isEmpty() )
612 delimIdx = query_.indexOf( sal_Unicode( '&' ) );
613 equalIdx = query_.indexOf( sal_Unicode( '=' ) );
614 parameter = query_.copy( 0,equalIdx ).trim();
615 if( delimIdx == -1 )
617 value = query_.copy( equalIdx + 1 ).trim();
618 query_ = OUString();
620 else
622 value = query_.copy( equalIdx+1,delimIdx - equalIdx - 1 ).trim();
623 query_ = query_.copy( delimIdx+1 ).trim();
626 if( parameter.compareToAscii( "Language" ) == 0 )
627 m_aLanguage = value;
628 else if( parameter.compareToAscii( "Device" ) == 0 )
629 m_aDevice = value;
630 else if( parameter.compareToAscii( "Program" ) == 0 )
631 m_aProgram = value;
632 else if( parameter.compareToAscii( "Eid" ) == 0 )
633 m_aEid = value;
634 else if( parameter.compareToAscii( "UseDB" ) == 0 )
635 m_bUseDB = ! ( value.compareToAscii("no") == 0 );
636 else if( parameter.compareToAscii( "DbPAR" ) == 0 )
637 m_aDbPar = value;
638 else if( parameter.compareToAscii( "Query" ) == 0 )
640 if( m_aQuery.isEmpty() )
641 m_aQuery = value;
642 else
643 m_aQuery += ( OUString( " " ) + value );
645 else if( parameter.compareToAscii( "Scope" ) == 0 )
646 m_aScope = value;
647 else if( parameter.compareToAscii( "System" ) == 0 )
648 m_aSystem = value;
649 else if( parameter.compareToAscii( "HelpPrefix" ) == 0 )
650 m_aPrefix = rtl::Uri::decode(
651 value,
652 rtl_UriDecodeWithCharset,
653 RTL_TEXTENCODING_UTF8 );
654 else if( parameter.compareToAscii( "HitCount" ) == 0 )
655 m_nHitCount = value.toInt32();
656 else if( parameter.compareToAscii( "Active" ) == 0 )
657 m_aActive = value;
658 else if( parameter.compareToAscii( "Version" ) == 0 )
659 ; // ignored (but accepted) in the build-in help, useful only for the online help
660 else
661 ret = false;
664 return ret;
667 struct UserData {
669 UserData( InputStreamTransformer* pTransformer,
670 URLParameter* pInitial,
671 Databases* pDatabases )
672 : m_pTransformer( pTransformer ),
673 m_pDatabases( pDatabases ),
674 m_pInitial( pInitial )
678 InputStreamTransformer* m_pTransformer;
679 Databases* m_pDatabases;
680 URLParameter* m_pInitial;
683 UserData *ugblData = 0;
685 extern "C" {
687 static int
688 fileMatch(const char * URI) {
689 if ((URI != NULL) && !strncmp(URI, "file:/", 6))
690 return 1;
691 return 0;
694 static int
695 zipMatch(const char * URI) {
696 if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.zip:/", 18))
697 return 1;
698 return 0;
701 static int
702 helpMatch(const char * URI) {
703 if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.help:/", 19))
704 return 1;
705 return 0;
708 static void *
709 fileOpen(const char *URI) {
710 osl::File *pRet = new osl::File(OUString(URI, strlen(URI), RTL_TEXTENCODING_UTF8));
711 pRet->open(osl_File_OpenFlag_Read);
712 return pRet;
715 static void *
716 zipOpen(SAL_UNUSED_PARAMETER const char *) {
717 OUString language,jar,path;
719 if( !ugblData->m_pInitial->get_eid().isEmpty() )
720 return (void*)(new Reference< XHierarchicalNameAccess >);
721 else
723 jar = ugblData->m_pInitial->get_jar();
724 language = ugblData->m_pInitial->get_language();
725 path = ugblData->m_pInitial->get_path();
728 Reference< XHierarchicalNameAccess > xNA =
729 ugblData->m_pDatabases->findJarFileForPath( jar, language, path );
731 Reference< XInputStream > xInputStream;
733 if( xNA.is() )
737 Any aEntry = xNA->getByHierarchicalName( path );
738 Reference< XActiveDataSink > xSink;
739 if( ( aEntry >>= xSink ) && xSink.is() )
740 xInputStream = xSink->getInputStream();
742 catch ( NoSuchElementException & )
747 if( xInputStream.is() )
749 return new Reference<XInputStream>(xInputStream);
751 return 0;
754 static void *
755 helpOpen(const char * URI) {
756 OUString language,jar,path;
758 URLParameter urlpar( OUString::createFromAscii( URI ),
759 ugblData->m_pDatabases );
761 jar = urlpar.get_jar();
762 language = urlpar.get_language();
763 path = urlpar.get_path();
765 Reference< XHierarchicalNameAccess > xNA =
766 ugblData->m_pDatabases->findJarFileForPath( jar, language, path );
768 Reference< XInputStream > xInputStream;
770 if( xNA.is() )
774 Any aEntry = xNA->getByHierarchicalName( path );
775 Reference< XActiveDataSink > xSink;
776 if( ( aEntry >>= xSink ) && xSink.is() )
777 xInputStream = xSink->getInputStream();
779 catch ( NoSuchElementException & )
784 if( xInputStream.is() )
785 return new Reference<XInputStream>(xInputStream);
786 return 0;
789 static int
790 helpRead(void * context, char * buffer, int len) {
791 Reference< XInputStream > *pRef = (Reference< XInputStream >*)context;
793 Sequence< sal_Int8 > aSeq;
794 len = (*pRef)->readBytes( aSeq,len);
795 memcpy(buffer, aSeq.getConstArray(), len);
797 return len;
800 static int
801 zipRead(void * context, char * buffer, int len) {
802 if( !ugblData->m_pInitial->get_eid().isEmpty() )
804 ugblData->m_pDatabases->popupDocument( ugblData->m_pInitial,&buffer,&len);
805 return len;
807 else
808 return helpRead(context, buffer, len);
811 static int
812 fileRead(void * context, char * buffer, int len) {
813 int nRead = 0;
814 osl::File *pFile = (osl::File*)context;
815 if (pFile)
817 sal_uInt64 uRead = 0;
818 if (osl::FileBase::E_None == pFile->read(buffer, len, uRead))
819 nRead = static_cast<int>(uRead);
821 return nRead;
824 static int
825 uriClose(void * context) {
826 Reference< XInputStream > *pRef = (Reference< XInputStream >*)context;
827 delete pRef;
828 return 0;
831 static int
832 fileClose(void * context) {
833 osl::File *pFile = (osl::File*)context;
834 if (pFile)
836 pFile->close();
837 delete pFile;
839 return 0;
842 } // extern "C"
844 InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam,
845 Databases* pDatabases,
846 bool isRoot )
847 : len( 0 ),
848 pos( 0 ),
849 buffer( new char[1] ) // Initializing with one element to avoid gcc compiler warning
851 if( isRoot )
853 delete[] buffer;
854 pDatabases->cascadingStylesheet( urlParam->get_language(),
855 &buffer,
856 &len );
858 else if( urlParam->isActive() )
860 delete[] buffer;
861 pDatabases->setActiveText( urlParam->get_module(),
862 urlParam->get_language(),
863 urlParam->get_id(),
864 &buffer,
865 &len );
867 else
869 UserData userData( this,urlParam,pDatabases );
871 // Uses the implementation detail, that OString::getStr returns a zero terminated character-array
873 const char* parameter[47];
874 OString parString[46];
875 int last = 0;
877 parString[last++] = "Program";
878 OString aPureProgramm( urlParam->getByName( "Program" ) );
879 parString[last++] = OString('\'') + aPureProgramm + OString('\'');
880 parString[last++] = "Database";
881 parString[last++] = OString('\'') + urlParam->getByName( "DatabasePar" ) + OString('\'');
882 parString[last++] = "Id";
883 parString[last++] = OString('\'') + urlParam->getByName( "Id" ) + OString('\'');
884 parString[last++] = "Path";
885 OString aPath( urlParam->getByName( "Path" ) );
886 parString[last++] = OString('\'') + aPath + OString('\'');
888 OString aPureLanguage = urlParam->getByName( "Language" );
889 parString[last++] = "Language";
890 parString[last++] = OString('\'') + aPureLanguage + OString('\'');
891 parString[last++] = "System";
892 parString[last++] = OString('\'') + urlParam->getByName( "System" ) + OString('\'');
893 parString[last++] = "productname";
894 parString[last++] = OString('\'') + OString(
895 pDatabases->getProductName().getStr(),
896 pDatabases->getProductName().getLength(),
897 RTL_TEXTENCODING_UTF8 ) + OString('\'');
898 parString[last++] = "productversion";
899 parString[last++] = OString('\'') +
900 OString( pDatabases->getProductVersion().getStr(),
901 pDatabases->getProductVersion().getLength(),
902 RTL_TEXTENCODING_UTF8 ) + OString('\'');
904 parString[last++] = "imgrepos";
905 parString[last++] = OString('\'') + pDatabases->getImagesZipFileURL() + OString('\'');
906 parString[last++] = "hp";
907 parString[last++] = OString('\'') + urlParam->getByName( "HelpPrefix" ) + OString('\'');
909 if( !parString[last-1].isEmpty() )
911 parString[last++] = "sm";
912 parString[last++] = "'vnd.sun.star.help%3A%2F%2F'";
913 parString[last++] = "qm";
914 parString[last++] = "'%3F'";
915 parString[last++] = "es";
916 parString[last++] = "'%3D'";
917 parString[last++] = "am";
918 parString[last++] = "'%26'";
919 parString[last++] = "cl";
920 parString[last++] = "'%3A'";
921 parString[last++] = "sl";
922 parString[last++] = "'%2F'";
923 parString[last++] = "hm";
924 parString[last++] = "'%23'";
925 parString[last++] = "cs";
926 parString[last++] = "'css'";
928 parString[last++] = "vendorname";
929 parString[last++] = OString("''");
930 parString[last++] = "vendorversion";
931 parString[last++] = OString("''");
932 parString[last++] = "vendorshort";
933 parString[last++] = OString("''");
936 // Do we need to add extension path?
937 OUString aExtensionPath;
938 OUString aJar = urlParam->get_jar();
940 bool bAddExtensionPath = false;
941 OUString aExtensionRegistryPath;
942 sal_Int32 nQuestionMark1 = aJar.indexOf( sal_Unicode('?') );
943 sal_Int32 nQuestionMark2 = aJar.lastIndexOf( sal_Unicode('?') );
944 if( nQuestionMark1 != -1 && nQuestionMark2 != -1 && nQuestionMark1 != nQuestionMark2 )
946 aExtensionPath = aJar.copy( nQuestionMark1 + 1, nQuestionMark2 - nQuestionMark1 - 1 );
947 aExtensionRegistryPath = urlParam->get_ExtensionRegistryPath();
948 bAddExtensionPath = true;
950 else
952 // Path not yet specified, search directly
953 Reference< XHierarchicalNameAccess > xNA = pDatabases->findJarFileForPath
954 ( aJar, urlParam->get_language(), urlParam->get_path(), &aExtensionPath, &aExtensionRegistryPath );
955 if( xNA.is() && !aExtensionPath.isEmpty() )
956 bAddExtensionPath = true;
959 if( bAddExtensionPath )
961 Reference< XComponentContext > xContext(
962 comphelper::getProcessComponentContext() );
964 OUString aOUExpandedExtensionPath = Databases::expandURL( aExtensionRegistryPath, xContext );
965 OString aExpandedExtensionPath = OUStringToOString( aOUExpandedExtensionPath, osl_getThreadTextEncoding() );
967 parString[last++] = "ExtensionPath";
968 parString[last++] = OString('\'') + aExpandedExtensionPath + OString('\'');
970 // ExtensionId
971 OString aPureExtensionId;
972 sal_Int32 iSlash = aPath.indexOf( '/' );
973 if( iSlash != -1 )
974 aPureExtensionId = aPath.copy( 0, iSlash );
976 parString[last++] = "ExtensionId";
977 parString[last++] = OString('\'') + aPureExtensionId + OString('\'');
980 for( int i = 0; i < last; ++i )
981 parameter[i] = parString[i].getStr();
982 parameter[last] = 0;
984 OUString xslURL = pDatabases->getInstallPathAsURL();
986 OString xslURLascii(
987 xslURL.getStr(),
988 xslURL.getLength(),
989 RTL_TEXTENCODING_UTF8);
990 xslURLascii += "main_transform.xsl";
992 ugblData = &userData;
994 xmlInitParser();
995 xmlRegisterInputCallbacks(zipMatch, zipOpen, zipRead, uriClose);
996 xmlRegisterInputCallbacks(helpMatch, helpOpen, helpRead, uriClose);
997 xmlRegisterInputCallbacks(fileMatch, fileOpen, fileRead, fileClose);
999 xsltStylesheetPtr cur =
1000 xsltParseStylesheetFile((const xmlChar *)xslURLascii.getStr());
1002 xmlDocPtr doc = xmlParseFile("vnd.sun.star.zip:/");
1004 xmlDocPtr res = xsltApplyStylesheet(cur, doc, parameter);
1005 if (res)
1007 xmlChar *doc_txt_ptr=0;
1008 int doc_txt_len;
1009 xsltSaveResultToString(&doc_txt_ptr, &doc_txt_len, res, cur);
1010 addToBuffer((const char*)doc_txt_ptr, doc_txt_len);
1011 xmlFree(doc_txt_ptr);
1013 xmlPopInputCallbacks(); //filePatch
1014 xmlPopInputCallbacks(); //helpPatch
1015 xmlPopInputCallbacks(); //zipMatch
1016 xmlFreeDoc(res);
1017 xmlFreeDoc(doc);
1018 xsltFreeStylesheet(cur);
1023 InputStreamTransformer::~InputStreamTransformer()
1025 delete[] buffer;
1029 Any SAL_CALL InputStreamTransformer::queryInterface( const Type& rType ) throw( RuntimeException )
1031 Any aRet = ::cppu::queryInterface( rType,
1032 (static_cast< XInputStream* >(this)),
1033 (static_cast< XSeekable* >(this)) );
1035 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
1040 void SAL_CALL InputStreamTransformer::acquire( void ) throw()
1042 OWeakObject::acquire();
1047 void SAL_CALL InputStreamTransformer::release( void ) throw()
1049 OWeakObject::release();
1054 sal_Int32 SAL_CALL InputStreamTransformer::readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead )
1055 throw( NotConnectedException,
1056 BufferSizeExceededException,
1057 IOException,
1058 RuntimeException)
1060 osl::MutexGuard aGuard( m_aMutex );
1062 int curr,available_ = len-pos;
1063 if( nBytesToRead <= available_ )
1064 curr = nBytesToRead;
1065 else
1066 curr = available_;
1068 if( 0 <= curr && aData.getLength() < curr )
1069 aData.realloc( curr );
1071 for( int k = 0; k < curr; ++k )
1072 aData[k] = buffer[pos++];
1074 return curr > 0 ? curr : 0;
1078 sal_Int32 SAL_CALL InputStreamTransformer::readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead )
1079 throw( NotConnectedException,
1080 BufferSizeExceededException,
1081 IOException,
1082 RuntimeException)
1084 return readBytes( aData,nMaxBytesToRead );
1089 void SAL_CALL InputStreamTransformer::skipBytes( sal_Int32 nBytesToSkip ) throw( NotConnectedException,
1090 BufferSizeExceededException,
1091 IOException,
1092 RuntimeException )
1094 osl::MutexGuard aGuard( m_aMutex );
1095 while( nBytesToSkip-- ) ++pos;
1100 sal_Int32 SAL_CALL InputStreamTransformer::available( void ) throw( NotConnectedException,
1101 IOException,
1102 RuntimeException )
1104 osl::MutexGuard aGuard( m_aMutex );
1105 return len-pos > 0 ? len - pos : 0 ;
1110 void SAL_CALL InputStreamTransformer::closeInput( void ) throw( NotConnectedException,
1111 IOException,
1112 RuntimeException )
1118 void SAL_CALL InputStreamTransformer::seek( sal_Int64 location ) throw( IllegalArgumentException,
1119 IOException,
1120 RuntimeException )
1122 osl::MutexGuard aGuard( m_aMutex );
1123 if( location < 0 )
1124 throw IllegalArgumentException();
1125 else
1126 pos = sal::static_int_cast<sal_Int32>( location );
1128 if( pos > len )
1129 pos = len;
1134 sal_Int64 SAL_CALL InputStreamTransformer::getPosition( void ) throw( IOException,
1135 RuntimeException )
1137 osl::MutexGuard aGuard( m_aMutex );
1138 return sal_Int64( pos );
1143 sal_Int64 SAL_CALL InputStreamTransformer::getLength( void ) throw( IOException,RuntimeException )
1145 osl::MutexGuard aGuard( m_aMutex );
1147 return len;
1151 void InputStreamTransformer::addToBuffer( const char* buffer_,int len_ )
1153 osl::MutexGuard aGuard( m_aMutex );
1155 char* tmp = buffer;
1156 buffer = new char[ len+len_ ];
1157 memcpy( (void*)(buffer),(void*)(tmp),sal_uInt32( len ) );
1158 memcpy( (void*)(buffer+len),(void*)(buffer_),sal_uInt32( len_ ) );
1159 delete[] tmp;
1160 len += len_;
1163 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */