#ifndef UNX #define UNX #endif #ifndef GCC #define GCC #endif #ifndef LINUX #define LINUX #endif #ifndef CPPU_ENV #define CPPU_ENV gcc4 #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace com::sun::star::uno; using namespace com::sun::star::lang; using namespace com::sun::star::bridge; using namespace com::sun::star::util; using namespace rtl; using namespace cppu; class InStream : public cppu::OWeakObject, public com::sun::star::io::XInputStream, public com::sun::star::io::XSeekable { const std::string &m_string; ::sal_Int32 m_counter; public: InStream(const std::string &str) : m_string(str), m_counter(0) { } virtual ~InStream() { } ::sal_Int32 available() throw (com::sun::star::io::NotConnectedException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException); void skipBytes(::sal_Int32 skip) throw (com::sun::star::io::NotConnectedException, com::sun::star::io::BufferSizeExceededException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException); ::sal_Int32 readBytes(::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 num) throw (com::sun::star::io::NotConnectedException, com::sun::star::io::BufferSizeExceededException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException); ::sal_Int32 readSomeBytes(::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 num) throw (com::sun::star::io::NotConnectedException, com::sun::star::io::BufferSizeExceededException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException); void seek(::sal_Int64 location) throw (com::sun::star::lang::IllegalArgumentException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException); ::sal_Int64 getPosition() throw (com::sun::star::io::IOException, com::sun::star::uno::RuntimeException); ::sal_Int64 getLength() throw (com::sun::star::io::IOException, com::sun::star::uno::RuntimeException); void closeInput() throw (com::sun::star::io::NotConnectedException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException); virtual com::sun::star::uno::Any SAL_CALL queryInterface(const com::sun::star::uno::Type& rType ) throw( com::sun::star::uno::RuntimeException); virtual void SAL_CALL acquire() throw(); virtual void SAL_CALL release() throw(); }; int main() { rtl::Bootstrap::set(OUString::createFromAscii("URE_MORE_TYPES"),OUString::createFromAscii("file:///usr/lib/libreoffice/program/types/offapi.rdb")); rtl::Bootstrap::set(OUString::createFromAscii("URE_MORE_SERVICES"),OUString::createFromAscii("file:///usr/lib/libreoffice/program/services/services.rdb")); auto rComponentContext = ::cppu::defaultBootstrap_InitialComponentContext(OUString::createFromAscii("file:///usr/lib/ure/lib/unorc")); Reference< XMultiServiceFactory > rOfficeServiceManager; std::string name = "test_pipe"; try { using namespace com::sun::star::connection; // retrieve the servicemanager from the context Reference< XMultiComponentFactory > rServiceManager = rComponentContext->getServiceManager(); Reference xConnector(rServiceManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.connection.Connector"), rComponentContext), UNO_QUERY); Reference xConnection = xConnector->connect(OUString::createFromAscii((std::string("pipe,name=" + name)).c_str())); if(!xConnection.is()) { std::cerr << "LibreOffice error: Can't connect to " << name << std::endl; return 1; } // instantiate a sample service with the servicemanager. Reference< XBridgeFactory > xBridgeFactory(rServiceManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.bridge.BridgeFactory" ),rComponentContext), UNO_QUERY); if(!xBridgeFactory.is()) { std::cerr << "LibreOffice error: Can't create bridge-factory" << std::endl; return 1; } Reference< XInterface > bridge_int = xBridgeFactory->createBridge(OUString::createFromAscii(""), OUString::createFromAscii("urp"), xConnection, 0); if(!bridge_int.is()) { std::cerr << "LibreOffice error: Can't create bridge" << std::endl; return 1; } Reference< XBridge > bridge(bridge_int, UNO_QUERY); Reference< XComponent > bridge_comp(bridge_int, UNO_QUERY); Reference< XMultiServiceFactory > OfficeServiceManager(bridge->getInstance(OUString::createFromAscii("StarOffice.ServiceManager")), UNO_QUERY); rOfficeServiceManager = OfficeServiceManager; if(!rOfficeServiceManager.is()) { std::cerr << "LibreOffice error: XMultiServiceFactory interface is not exported for StarOffice.ServiceManager" << std::endl; return 1; } std::cerr << "Successfully connected to LibreOffice" << std::endl; //now setting performance options Reference< XInterface > rConfProvider(rOfficeServiceManager->createInstance( OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider" ))); Reference ConfFactory(rConfProvider, UNO_QUERY); { Sequence < ::com::sun::star::uno::Any > node_path(1); ::com::sun::star::beans::PropertyValue pvalue; pvalue.Name = OUString::createFromAscii("nodePath"); pvalue.Value <<= OUString::createFromAscii("org.openoffice.Office.Common/Internal"); node_path[0] <<= pvalue; Reference< XInterface > rConfUpdater = ConfFactory->createInstanceWithArguments( OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess"), node_path ); Reference< ::com::sun::star::beans::XPropertySet > property(rConfUpdater, UNO_QUERY); com::sun::star::uno::Any val; val <<= OUString::createFromAscii(("file:///tmp/sv" + name +".tmp").c_str()); property->setPropertyValue(OUString::createFromAscii("CurrentTempURL"), val); Reference< ::com::sun::star::util::XChangesBatch > batch(rConfUpdater, UNO_QUERY); batch->commitChanges(); } } catch(const Exception &e ) { OString o; if(e.Message.convertToString(&o, RTL_TEXTENCODING_ASCII_US, RTL_UNICODETOTEXT_FLAGS_UNDEFINED_UNDERLINE | RTL_UNICODETOTEXT_FLAGS_INVALID_UNDERLINE)) { std::cerr << o.pData->buffer << std::endl; } else { std::cerr << "LibreOffice connect error. Can't produce good error message because of encoding" << std::endl; } return 1; } Reference< ::com::sun::star::document::XTypeDetection > xdetector(rOfficeServiceManager->createInstance( OUString::createFromAscii("com.sun.star.document.TypeDetection")), UNO_QUERY); std::string content(500000, 'a'); //XXX: more than 5 minutes //std::string content(50000, 'a'); //XXX: very slow //std::string content(50, 'a'); //XXX: not so bad InStream* in_s = new InStream(content); Reference< com::sun::star::io::XInputStream > xinputstream(in_s); Sequence < ::com::sun::star::beans::PropertyValue > detect_seq(2); detect_seq[0].Name = OUString::createFromAscii("InputStream"); detect_seq[0].Value <<= xinputstream; detect_seq[1].Name = OUString::createFromAscii("Hidden"); detect_seq[1].Value <<= true; OUString internal_str = xdetector->queryTypeByDescriptor(detect_seq, true); OString o; internal_str.convertToString(&o, RTL_TEXTENCODING_ASCII_US, RTL_UNICODETOTEXT_FLAGS_UNDEFINED_UNDERLINE | RTL_UNICODETOTEXT_FLAGS_INVALID_UNDERLINE); std::cerr << "LibreOffice: filetype " << o.pData->buffer << std::endl; return 0; } ::sal_Int32 InStream::available() throw (com::sun::star::io::NotConnectedException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException) { return static_cast< ::sal_Int32 >(m_string.size()) - m_counter; } void InStream::skipBytes(::sal_Int32 skip) throw (com::sun::star::io::NotConnectedException, com::sun::star::io::BufferSizeExceededException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException) { m_counter += skip; } ::sal_Int32 InStream::readBytes(::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 num) throw (com::sun::star::io::NotConnectedException, com::sun::star::io::BufferSizeExceededException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException) { ::sal_Int32 real_copy = std::max(0, std::min(num, static_cast< ::sal_Int32>(m_string.size()) - m_counter)); if(real_copy == 0) return 0; aData.realloc(real_copy); std::memcpy(aData.getArray(), m_string.data() + m_counter, real_copy); m_counter += real_copy; return real_copy; } ::sal_Int32 InStream::readSomeBytes(::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 num) throw (com::sun::star::io::NotConnectedException, com::sun::star::io::BufferSizeExceededException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException) { return readBytes(aData, num); } void InStream::seek(::sal_Int64 location) throw (com::sun::star::lang::IllegalArgumentException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException) { m_counter = location; } ::sal_Int64 InStream::getPosition() throw (com::sun::star::io::IOException, com::sun::star::uno::RuntimeException) { return m_counter; } ::sal_Int64 InStream::getLength() throw (com::sun::star::io::IOException, com::sun::star::uno::RuntimeException) { return m_string.size(); } void InStream::closeInput() throw (com::sun::star::io::NotConnectedException, com::sun::star::io::IOException, com::sun::star::uno::RuntimeException) { } com::sun::star::uno::Any SAL_CALL InStream::queryInterface( const com::sun::star::uno::Type& rType ) throw( com::sun::star::uno::RuntimeException) { com::sun::star::uno::Any aRet = cppu::queryInterface( rType, static_cast(this) , static_cast(this) ); return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); } void SAL_CALL InStream::acquire() throw() { OWeakObject::acquire(); } void SAL_CALL InStream::release() throw() { OWeakObject::release(); }