/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: urlparameter.cxx,v $ * * $Revision: 1.38 $ * * last change: $Author: hr $ $Date: 2006-06-20 00:40:34 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. * * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2005 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * ************************************************************************/ #define WORKAROUND_98119 #ifdef WORKAROUND_98119 #include #endif #include #ifndef _VOS_DIAGNOSE_HXX_ #include #endif #ifndef _OSL_THREAD_H_ #include #endif #ifndef _RTL_MEMORY_H_ #include #endif #ifndef _OSL_FILE_HXX_ #include #endif #ifndef _CPPUHELPER_WEAK_HXX_ #include #endif #ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ #include #endif #ifndef _RTL_URI_HXX_ #include #endif #ifdef SYSTEM_SABLOT #include #include #else #ifndef SablotHIncl #include #endif #ifndef ShandlerHIncl #include #endif #endif #ifndef BERKELEYDBPROXY_DB_HXX_ #include "db.hxx" #endif #ifndef _URLPARAMETER_HXX_ #include #endif #ifndef _DATABASES_HXX_ #include #endif #ifndef _RTL_URI_HXX_ #include #endif #ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HPP_ #include #endif #ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_ #include #endif #ifndef _COM_SUN_STAR_IO_XSEEKABLE_HPP_ #include #endif #ifndef _COM_SUN_STAR_UCB_OPENCOMMANDARGUMENT2_HPP_ #include #endif #ifndef _COM_SUN_STAR_UCB_OPENMODE_HPP_ #include #endif #ifndef _COM_SUN_STAR_UCB_XCOMMANDPROCESSOR_HPP_ #include #endif #ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_HPP_ #include #endif #ifndef _COM_SUN_STAR_UCB_XCONTENTIDENTIFIER_HPP_ #include #endif #ifndef _COM_SUN_STAR_UCB_XCONTENTPROVIDER_HPP_ #include #endif #ifndef _COM_SUN_STAR_UCB_XCONTENTIDENTIFIERFACTORY_HPP_ #include #endif #ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMEACCESS_HPP_ #include #endif namespace chelp { inline bool ascii_isDigit( sal_Unicode ch ) { return ((ch >= 0x0030) && (ch <= 0x0039)); } inline bool ascii_isLetter( sal_Unicode ch ) { return ( ( (ch >= 0x0041) && (ch <= 0x005A) ) || ( (ch >= 0x0061) && (ch <= 0x007A) ) ); } inline bool isLetterOrDigit( sal_Unicode ch ) { return ascii_isLetter( ch ) || ascii_isDigit( ch ); } } using namespace cppu; using namespace com::sun::star::io; using namespace com::sun::star::uno; using namespace com::sun::star::lang; using namespace com::sun::star::ucb; using namespace com::sun::star::container; using namespace berkeleydbproxy; using namespace chelp; URLParameter::URLParameter( const rtl::OUString& aURL, Databases* pDatabases ) throw( com::sun::star::ucb::IllegalIdentifierException ) : m_pDatabases( pDatabases ), m_aURL( aURL ) { init( false ); parse(); } URLParameter::URLParameter( const rtl::OUString& aURL, const rtl::OUString& aDefaultLanguage, Databases* pDatabases ) throw( com::sun::star::ucb::IllegalIdentifierException ) : m_pDatabases( pDatabases ), m_aURL( aURL ), m_aDefaultLanguage( aDefaultLanguage ) { init( true ); parse(); } bool URLParameter::isErrorDocument() { if( isFile() ) { Reference< XHierarchicalNameAccess > xNA = m_pDatabases->jarFile( get_jar(), get_language() ); return ! ( xNA.is() && xNA->hasByHierarchicalName( get_path() ) ); } return false; } rtl::OString URLParameter::getByName( const char* par ) { rtl::OUString val; if( strcmp( par,"Program" ) == 0 ) val = get_program(); else if( strcmp( par,"Database" ) == 0 ) val = get_module(); else if( strcmp( par,"DatabasePar" ) == 0 ) val = get_dbpar(); else if( strcmp( par,"Id" ) == 0 ) val = get_id(); else if( strcmp( par,"Path" ) == 0 ) val = get_path(); else if( strcmp( par,"Language" ) == 0 ) val = get_language(); else if( strcmp( par,"System" ) == 0 ) val = get_system(); else if( strcmp( par,"HelpPrefix" ) == 0 ) val = get_prefix(); return rtl::OString( val.getStr(),val.getLength(),RTL_TEXTENCODING_UTF8 ); } rtl::OUString URLParameter::get_id() { if( m_aId.compareToAscii("start") == 0 ) { // module is set StaticModuleInformation* inf = m_pDatabases->getStaticInformationForModule( get_module(), get_language() ); if( inf ) m_aId = inf->get_id(); m_bStart = true; } return m_aId; } rtl::OUString URLParameter::get_tag() { if( isFile() ) return get_the_tag(); else return m_aTag; } rtl::OUString URLParameter::get_title() { if( isFile() ) return get_the_title(); else if( m_aModule.compareToAscii("") != 0 ) { StaticModuleInformation* inf = m_pDatabases->getStaticInformationForModule( get_module(), get_language() ); if( inf ) m_aTitle = inf->get_title(); } else // This must be the root m_aTitle = rtl::OUString::createFromAscii("root"); return m_aTitle; } rtl::OUString URLParameter::get_language() { if( m_aLanguage.getLength() == 0 ) return m_aDefaultLanguage; return m_aLanguage; } rtl::OUString URLParameter::get_program() { if( ! m_aProgram.getLength() ) { StaticModuleInformation* inf = m_pDatabases->getStaticInformationForModule( get_module(), get_language() ); if( inf ) m_aProgram = inf->get_program(); } return m_aProgram; } void URLParameter::init( bool bDefaultLanguageIsInitialized ) { (void)bDefaultLanguageIsInitialized; m_bBerkeleyRead = false; m_bStart = false; m_bUseDB = true; m_nHitCount = 100; // The default maximum hitcount } rtl::OUString URLParameter::get_the_tag() { if(m_bUseDB) { if( ! m_bBerkeleyRead ) readBerkeley(); m_bBerkeleyRead = true; return m_aTag; } else return rtl::OUString(); } rtl::OUString URLParameter::get_the_path() { if(m_bUseDB) { if( ! m_bBerkeleyRead ) readBerkeley(); m_bBerkeleyRead = true; return m_aPath; } else return get_id(); } rtl::OUString URLParameter::get_the_title() { if(m_bUseDB) { if( ! m_bBerkeleyRead ) readBerkeley(); m_bBerkeleyRead = true; return m_aTitle; } else return rtl::OUString(); } rtl::OUString URLParameter::get_the_jar() { if(m_bUseDB) { if( ! m_bBerkeleyRead ) readBerkeley(); m_bBerkeleyRead = true; return m_aJar; } else return get_module() + rtl::OUString::createFromAscii(".jar"); } void URLParameter::readBerkeley() { if( get_id().compareToAscii("") == 0 ) return; Db* db = m_pDatabases->getBerkeley( get_module(), get_language() ); if( ! db ) return; rtl::OString keyStr( m_aId.getStr(),m_aId.getLength(),RTL_TEXTENCODING_UTF8 ); Dbt key( static_cast< void* >( const_cast< sal_Char* >( keyStr.getStr() ) ), keyStr.getLength() ); Dbt data; int err = db->get( 0,&key,&data,0 ); (void)err; DbtToStringConverter converter( static_cast< sal_Char* >( data.get_data() ), data.get_size() ); m_aTitle = converter.getTitle(); m_pDatabases->replaceName( m_aTitle ); m_aPath = converter.getFile(); m_aJar = converter.getDatabase(); m_aTag = converter.getHash(); } // Class encapsulating the transformation of the XInputStream to XHTML class InputStreamTransformer : public OWeakObject, public XInputStream, public XSeekable { public: InputStreamTransformer( URLParameter* urlParam, Databases* pDatatabases, bool isRoot = false ); ~InputStreamTransformer(); virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException ); virtual void SAL_CALL acquire( void ) throw(); virtual void SAL_CALL release( void ) throw(); virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead ) throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead ) throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException ); virtual sal_Int32 SAL_CALL available( void ) throw( NotConnectedException, IOException, RuntimeException ); virtual void SAL_CALL closeInput( void ) throw( NotConnectedException, IOException, RuntimeException ); virtual void SAL_CALL seek( sal_Int64 location ) throw( IllegalArgumentException, IOException, RuntimeException ); virtual sal_Int64 SAL_CALL getPosition( void ) throw( IOException,RuntimeException ); virtual sal_Int64 SAL_CALL getLength( void ) throw( IOException,RuntimeException ); void addToBuffer( const char* buffer,int len ); sal_Int8* getData() const { return (sal_Int8*) buffer; } sal_Int32 getLen() const { return sal_Int32( len ); } private: osl::Mutex m_aMutex; int len,pos; char *buffer; }; void URLParameter::open( const Reference< XMultiServiceFactory >& rxSMgr, const Command& aCommand, sal_Int32 CommandId, const Reference< XCommandEnvironment >& Environment, const Reference< XOutputStream >& xDataSink ) { (void)rxSMgr; (void)aCommand; (void)CommandId; (void)Environment; if( ! xDataSink.is() ) return; if( isPicture() ) { Reference< XInputStream > xStream; Reference< XHierarchicalNameAccess > xNA = m_pDatabases->jarFile( rtl::OUString::createFromAscii( "picture.jar" ), get_language() ); rtl::OUString path = get_path(); if( xNA.is() ) { try { Any aEntry = xNA->getByHierarchicalName( path ); Reference< XActiveDataSink > xSink; if( ( aEntry >>= xSink ) && xSink.is() ) xStream = xSink->getInputStream(); } catch ( NoSuchElementException & ) { } } if( xStream.is() ) { sal_Int32 ret; Sequence< sal_Int8 > aSeq( 4096 ); while( true ) { try { ret = xStream->readBytes( aSeq,4096 ); xDataSink->writeBytes( aSeq ); if( ret < 4096 ) break; } catch( const Exception& ) { break; } } } } else { // a standard document or else an active help text, plug in the new input stream InputStreamTransformer* p = new InputStreamTransformer( this,m_pDatabases,isRoot() ); try { xDataSink->writeBytes( Sequence< sal_Int8 >( p->getData(),p->getLen() ) ); } catch( const Exception& ) { } delete p; } xDataSink->closeOutput(); } void URLParameter::open( const Reference< XMultiServiceFactory >& rxSMgr, const Command& aCommand, sal_Int32 CommandId, const Reference< XCommandEnvironment >& Environment, const Reference< XActiveDataSink >& xDataSink ) { (void)rxSMgr; (void)aCommand; (void)CommandId; (void)Environment; if( isPicture() ) { Reference< XInputStream > xStream; Reference< XHierarchicalNameAccess > xNA = m_pDatabases->jarFile( rtl::OUString::createFromAscii( "picture.jar" ), get_language() ); rtl::OUString path = get_path(); if( xNA.is() ) { try { Any aEntry = xNA->getByHierarchicalName( path ); Reference< XActiveDataSink > xSink; if( ( aEntry >>= xSink ) && xSink.is() ) xStream = xSink->getInputStream(); } catch ( NoSuchElementException & ) { } } #ifdef WORKAROUND_98119 xDataSink->setInputStream( turnToSeekable(xStream) ); #else xDataSink->setInputStream( xStream ); #endif } else // a standard document or else an active help text, plug in the new input stream xDataSink->setInputStream( new InputStreamTransformer( this,m_pDatabases,isRoot() ) ); } // #include void URLParameter::parse() throw( com::sun::star::ucb::IllegalIdentifierException ) { // fprintf(stdout,"url send to xmlhelp: %s\n",(rtl::OUStringToOString(m_aURL,RTL_TEXTENCODING_UTF8).getStr())); m_aExpr = m_aURL; sal_Int32 lstIdx = m_aExpr.lastIndexOf( sal_Unicode( '#' ) ); if( lstIdx != -1 ) m_aExpr = m_aExpr.copy( 0,lstIdx ); if( ! scheme() || ! name( module() ) || ! query() || ! m_aLanguage.getLength() || ! m_aSystem.getLength() ) throw com::sun::star::ucb::IllegalIdentifierException(); } bool URLParameter::scheme() { #define PREFIX_LENGTH 20 if( m_aExpr.compareToAscii( "vnd.sun.star.help://",PREFIX_LENGTH ) == 0 ) { m_aExpr = m_aExpr.copy( PREFIX_LENGTH ); #undef PREFIX_LENGTH return true; } #define PREFIX_LENGTH 19 else if( m_aExpr.compareToAscii( "vnd.sun.star.help:/",PREFIX_LENGTH ) == 0 ) { m_aExpr = m_aExpr.copy( PREFIX_LENGTH ); #undef PREFIX_LENGTH return true; } #define PREFIX_LENGTH 18 else if( m_aExpr.compareToAscii( "vnd.sun.star.help:",PREFIX_LENGTH ) == 0 ) { m_aExpr = m_aExpr.copy( PREFIX_LENGTH ); #undef PREFIX_LENGTH return true; } else return false; } bool URLParameter::module() { sal_Int32 idx = 0,length = m_aExpr.getLength(); while( idx < length && isLetterOrDigit( (m_aExpr.getStr())[idx] ) ) ++idx; if( idx != 0 ) { m_aModule = m_aExpr.copy( 0,idx ); m_aExpr = m_aExpr.copy( idx ); return true; } else return false; } bool URLParameter::name( bool modulePresent ) { // if modulepresent, a name may be present, but must not sal_Int32 length = m_aExpr.getLength(); if( length != 0 && (m_aExpr.getStr())[0] == sal_Unicode( '/' ) ) { sal_Int32 idx = 1; while( idx < length && (m_aExpr.getStr())[idx] != '?' ) // ( isLetterOrDigit( (m_aExpr.getStr())[idx] ) // || (m_aExpr.getStr())[idx] == '/' // || (m_aExpr.getStr())[idx] == '.' )) ++idx; if( idx != 1 && ! modulePresent ) return false; else { m_aId = m_aExpr.copy( 1,idx-1 ); m_aExpr = m_aExpr.copy( idx ); } } // fprintf(stdout,"id %s\n",(rtl::OUStringToOString(m_aId,RTL_TEXTENCODING_UTF8).getStr())); return true; } bool URLParameter::query() { rtl::OUString query_; if( ! m_aExpr.getLength() ) return true; else if( (m_aExpr.getStr())[0] == sal_Unicode( '?' ) ) query_ = m_aExpr.copy( 1 ).trim(); else return false; bool ret = true; sal_Int32 delimIdx,equalIdx; rtl::OUString parameter,value; while( query_.getLength() != 0 ) { delimIdx = query_.indexOf( sal_Unicode( '&' ) ); equalIdx = query_.indexOf( sal_Unicode( '=' ) ); parameter = query_.copy( 0,equalIdx ).trim(); if( delimIdx == -1 ) { value = query_.copy( equalIdx + 1 ).trim(); query_ = rtl::OUString(); } else { value = query_.copy( equalIdx+1,delimIdx - equalIdx - 1 ).trim(); query_ = query_.copy( delimIdx+1 ).trim(); } if( parameter.compareToAscii( "Language" ) == 0 ) m_aLanguage = value; else if( parameter.compareToAscii( "Device" ) == 0 ) m_aDevice = value; else if( parameter.compareToAscii( "Program" ) == 0 ) m_aProgram = value; else if( parameter.compareToAscii( "Eid" ) == 0 ) m_aEid = value; else if( parameter.compareToAscii( "UseDB" ) == 0 ) m_bUseDB = ! ( value.compareToAscii("no") == 0 ); else if( parameter.compareToAscii( "DbPAR" ) == 0 ) m_aDbPar = value; else if( parameter.compareToAscii( "Query" ) == 0 ) { if( ! m_aQuery.getLength() ) m_aQuery = value; else m_aQuery += ( rtl::OUString::createFromAscii( " " ) + value ); } else if( parameter.compareToAscii( "Scope" ) == 0 ) m_aScope = value; else if( parameter.compareToAscii( "System" ) == 0 ) m_aSystem = value; else if( parameter.compareToAscii( "HelpPrefix" ) == 0 ) m_aPrefix = rtl::Uri::decode( value, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); else if( parameter.compareToAscii( "HitCount" ) == 0 ) m_nHitCount = value.toInt32(); else if( parameter.compareToAscii( "Active" ) == 0 ) m_aActive = value; else ret = false; } return ret; } //////////////////////////////////////////////////////////////////////////////// // InutStreamTransformerImpl // //////////////////////////////////////////////////////////////////////////////// int schemehandlergetall( void *userData, SablotHandle processor_, const char *scheme, const char *rest, char **buffer, int *byteCount); int schemehandlerfreememory( void *userData, SablotHandle processor_, char *buffer ); int schemehandleropen( void *userData, SablotHandle processor_, const char *scheme, const char *rest, int *handle ); int schemehandlerget( void *userData, SablotHandle processor_, int handle, char *buffer, int *byteCount ); int schemehandlerput( void *userData, SablotHandle processor_, int handle, const char *buffer, int *byteCount ); int schemehandlerclose( void *userData, SablotHandle processor_, int handle ); struct UserData { UserData( InputStreamTransformer* pTransformer, URLParameter* pInitial, Databases* pDatabases ) : m_pTransformer( pTransformer ), m_pDatabases( pDatabases ), m_pInitial( pInitial ) { } InputStreamTransformer* m_pTransformer; Databases* m_pDatabases; URLParameter* m_pInitial; }; InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam, Databases* pDatabases, bool isRoot ) : len( 0 ), pos( 0 ), buffer( new char[0] ) { if( isRoot ) { delete[] buffer; pDatabases->cascadingStylesheet( urlParam->get_language(), &buffer, &len ); } else if( urlParam->isActive() ) { delete[] buffer; pDatabases->setActiveText( urlParam->get_module(), urlParam->get_language(), urlParam->get_id(), &buffer, &len ); } else { SchemeHandler schemeHandler; schemeHandler.getAll = schemehandlergetall; schemeHandler.freeMemory = schemehandlerfreememory; schemeHandler.open = schemehandleropen; schemeHandler.get = schemehandlerget; schemeHandler.put = schemehandlerput; schemeHandler.close = schemehandlerclose; UserData userData( this,urlParam,pDatabases ); // Uses the implementation detail, that rtl::OString::getStr returns a zero terminated character-array const char* parameter[42]; rtl::OString parString[43]; int last = 0; parString[last++] = "Program"; parString[last++] = urlParam->getByName( "Program" ); parString[last++] = "Database"; parString[last++] = urlParam->getByName( "DatabasePar" ); parString[last++] = "Id"; parString[last++] = urlParam->getByName( "Id" ); parString[last++] = "Path"; parString[last++] = urlParam->getByName( "Path" ); parString[last++] = "Language"; parString[last++] = urlParam->getByName( "Language" ); parString[last++] = "System"; parString[last++] = urlParam->getByName( "System" ); parString[last++] = "productname"; parString[last++] = rtl::OString( pDatabases->getProductName().getStr(), pDatabases->getProductName().getLength(), RTL_TEXTENCODING_UTF8 ); parString[last++] = "productversion"; parString[last++] = rtl::OString( pDatabases->getProductVersion().getStr(), pDatabases->getProductVersion().getLength(), RTL_TEXTENCODING_UTF8 ); parString[last++] = "imgrepos"; parString[last++] = pDatabases->getImagesZipFileURL(); parString[last++] = "hp"; parString[last++] = urlParam->getByName( "HelpPrefix" ); if( parString[last-1].getLength() ) { parString[last++] = "sm"; parString[last++] = "vnd.sun.star.help%3A%2F%2F"; parString[last++] = "qm"; parString[last++] = "%3F"; parString[last++] = "es"; parString[last++] = "%3D"; parString[last++] = "am"; parString[last++] = "%26"; parString[last++] = "cl"; parString[last++] = "%3A"; parString[last++] = "sl"; parString[last++] = "%2F"; parString[last++] = "hm"; parString[last++] = "%23"; parString[last++] = "cs"; parString[last++] = "css"; parString[last++] = "vendorname"; parString[last++] = rtl::OString( pDatabases->getVendorName().getStr(), pDatabases->getVendorName().getLength(), RTL_TEXTENCODING_UTF8 ); parString[last++] = "vendorversion"; parString[last++] = rtl::OString( pDatabases->getVendorVersion().getStr(), pDatabases->getVendorVersion().getLength(), RTL_TEXTENCODING_UTF8 ); parString[last++] = "vendorshort"; parString[last++] = rtl::OString( pDatabases->getVendorShort().getStr(), pDatabases->getVendorShort().getLength(), RTL_TEXTENCODING_UTF8 ); } for( int i = 0; i < last; ++i ) parameter[i] = parString[i].getStr(); parameter[last] = 0; SablotHandle p; SablotCreateProcessor(&p); SablotRegHandler( p,HLR_SCHEME,&schemeHandler,(void*)(&userData) ); rtl::OUString xslURL = pDatabases->getInstallPathAsURL/*WithOutEncoding*/(); rtl::OString xslURLascii( xslURL.getStr(), xslURL.getLength(), RTL_TEXTENCODING_ASCII_US/*osl_getThreadTextEncoding()*/); xslURLascii += "main_transform.xsl"; const char aVndPkgConstStr[] = "vnd.sun.star.pkg:/"; const char aVndResConstStr[] = "vnd.sun.star.resultat:/"; char aVndPkgStr[ sizeof( aVndPkgConstStr ) ]; strcpy( aVndPkgStr, aVndPkgConstStr ); char aVndResStr[ sizeof( aVndResConstStr ) ]; strcpy( aVndResStr, aVndResConstStr ); #ifdef SYSTEM_SABLOT SablotRunProcessor( p, xslURLascii.getStr(), aVndPkgStr, aVndResStr, parameter, 0); #else SablotRunProcessor( p, const_cast(xslURLascii.getStr()), aVndPkgStr, aVndResStr, const_cast(parameter), 0); #endif SablotDestroyProcessor( p ); } } InputStreamTransformer::~InputStreamTransformer() { delete[] buffer; } Any SAL_CALL InputStreamTransformer::queryInterface( const Type& rType ) throw( RuntimeException ) { Any aRet = ::cppu::queryInterface( rType, SAL_STATIC_CAST( XInputStream*,this ), SAL_STATIC_CAST( XSeekable*,this ) ); return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); } void SAL_CALL InputStreamTransformer::acquire( void ) throw() { OWeakObject::acquire(); } void SAL_CALL InputStreamTransformer::release( void ) throw() { OWeakObject::release(); } sal_Int32 SAL_CALL InputStreamTransformer::readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead ) throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) { osl::MutexGuard aGuard( m_aMutex ); int curr,available_ = len-pos; if( nBytesToRead <= available_ ) curr = nBytesToRead; else curr = available_; if( 0 <= curr && aData.getLength() < curr ) aData.realloc( curr ); for( int k = 0; k < curr; ++k ) aData[k] = buffer[pos++]; return curr > 0 ? curr : 0; } sal_Int32 SAL_CALL InputStreamTransformer::readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead ) throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) { return readBytes( aData,nMaxBytesToRead ); } void SAL_CALL InputStreamTransformer::skipBytes( sal_Int32 nBytesToSkip ) throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException ) { osl::MutexGuard aGuard( m_aMutex ); while( nBytesToSkip-- ) ++pos; } sal_Int32 SAL_CALL InputStreamTransformer::available( void ) throw( NotConnectedException, IOException, RuntimeException ) { osl::MutexGuard aGuard( m_aMutex ); return len-pos > 0 ? len - pos : 0 ; } void SAL_CALL InputStreamTransformer::closeInput( void ) throw( NotConnectedException, IOException, RuntimeException ) { } void SAL_CALL InputStreamTransformer::seek( sal_Int64 location ) throw( IllegalArgumentException, IOException, RuntimeException ) { osl::MutexGuard aGuard( m_aMutex ); if( location < 0 ) throw IllegalArgumentException(); else pos = sal::static_int_cast( location ); if( pos > len ) pos = len; } sal_Int64 SAL_CALL InputStreamTransformer::getPosition( void ) throw( IOException, RuntimeException ) { osl::MutexGuard aGuard( m_aMutex ); return sal_Int64( pos ); } sal_Int64 SAL_CALL InputStreamTransformer::getLength( void ) throw( IOException,RuntimeException ) { osl::MutexGuard aGuard( m_aMutex ); return len; } void InputStreamTransformer::addToBuffer( const char* buffer_,int len_ ) { osl::MutexGuard aGuard( m_aMutex ); char* tmp = buffer; buffer = new char[ len+len_ ]; rtl_copyMemory( (void*)(buffer),(void*)(tmp),sal_uInt32( len ) ); rtl_copyMemory( (void*)(buffer+len),(void*)(buffer_),sal_uInt32( len_ ) ); delete[] tmp; len += len_; } /** * getAll: open the URI and return the whole string * scheme = URI scheme (e.g. "http") * rest = the rest of the URI (without colon) * the document is returned in a handler-allocated buffer * byteCount holds the byte count on return * return *buffer = NULL if not processed */ int schemehandlergetall( void *userData, SablotHandle processor_, const char *scheme, const char *rest, char **buffer, int *byteCount ) { (void)processor_; rtl::OUString language,jar,path; UserData *uData = reinterpret_cast< UserData* >( userData ); if( strcmp( scheme,"vnd.sun.star.help" ) == 0 ) { URLParameter urlpar( rtl::OUString::createFromAscii( scheme ) + rtl::OUString::createFromAscii( ":" ) + rtl::OUString::createFromAscii( rest ), uData->m_pDatabases ); jar = urlpar.get_jar(); language = urlpar.get_language(); path = urlpar.get_path(); } else if( strcmp( scheme,"vnd.sun.star.pkg" ) == 0 ) { if( uData->m_pInitial->get_eid().getLength() ) { uData->m_pDatabases->popupDocument( uData->m_pInitial,buffer,byteCount ); return 0; } else { jar = uData->m_pInitial->get_jar(); language = uData->m_pInitial->get_language(); path = uData->m_pInitial->get_path(); } } else { *buffer = 0; *byteCount = 0; return 0; } // fprintf(stdout,"jarFile %s\n",(rtl::OUStringToOString(jar,RTL_TEXTENCODING_UTF8).getStr())); // fprintf(stdout,"lang %s\n",(rtl::OUStringToOString(language,RTL_TEXTENCODING_UTF8).getStr())); // fprintf(stdout,"path %s\n",(rtl::OUStringToOString(path,RTL_TEXTENCODING_UTF8).getStr())); Reference< XInputStream > xInputStream; Reference< XHierarchicalNameAccess > xNA = uData->m_pDatabases->jarFile( jar,language ); if( xNA.is() ) { try { Any aEntry = xNA->getByHierarchicalName( path ); Reference< XActiveDataSink > xSink; if( ( aEntry >>= xSink ) && xSink.is() ) xInputStream = xSink->getInputStream(); } catch ( NoSuchElementException & ) { } } if( xInputStream.is() ) { sal_Int32 size = 0; Reference< XSeekable > xSeekable( xInputStream,UNO_QUERY ); if( xSeekable.is() ) size = sal_Int32( xSeekable->getLength() ); else size = sal_Int32( xInputStream->available() ); *buffer = new char[ 1+size ]; (*buffer)[ size ] = 0; Sequence< sal_Int8 > aSeq; xInputStream->readBytes( aSeq,size ); rtl_copyMemory( (void*)(*buffer),(void*)(aSeq.getConstArray()),sal_uInt32(size) ); *byteCount = size; } else uData->m_pDatabases->errorDocument( language,buffer,byteCount ); return 0; } /* freeMemory: free the buffer allocated by getAll */ int schemehandlerfreememory( void *userData, SablotHandle processor_, char *buffer ) { (void)userData; (void)processor_; delete[] buffer; return 0; } /* open: open the URI and return a handle scheme = URI scheme (e.g. "http") rest = the rest of the URI (without colon) the resulting handle is returned in '*handle' */ int schemehandleropen( void *userData, SablotHandle processor_, const char *scheme, const char *rest, int *handle ) { (void)userData; (void)processor_; (void)scheme; (void)rest; *handle = 0; return 0; } /* get: retrieve data from the URI handle = the handle assigned on open buffer = pointer to the data *byteCount = number of bytes to read (the number actually read is returned here) */ int schemehandlerget( void *userData, SablotHandle processor_, int handle, char *buffer, int *byteCount ) { (void)userData; (void)processor_; (void)handle; (void)buffer; *byteCount = 0; return 0; } /* put: save data to the URI (if possible) handle = the handle assigned on open buffer = pointer to the data *byteCount = number of bytes to write (the number actually written is returned here) */ int schemehandlerput( void *userData, SablotHandle processor_, int handle, const char *buffer, int *byteCount ) { (void)processor_; (void)handle; UserData *uData = reinterpret_cast< UserData* >( userData ); uData->m_pTransformer->addToBuffer( buffer,*byteCount ); return 0; } /* close: close the URI with the given handle handle = the handle assigned on open */ int schemehandlerclose( void *userData, SablotHandle processor_, int handle ) { (void)userData; (void)processor_; (void)handle; return 0; }