Kaydet (Commit) 9013a3a7 authored tarafından Michael Meeks's avatar Michael Meeks

liblibo: expose a C API for ABI reasons, and wrap with C++.

Change-Id: I7b3bcead05788e663d94724522bfa3f227b15499
üst 96e23cb9
...@@ -25,7 +25,7 @@ $(eval $(call gb_StaticLibrary_use_libraries,libreoffice,\ ...@@ -25,7 +25,7 @@ $(eval $(call gb_StaticLibrary_use_libraries,libreoffice,\
$(gb_UWINAPI) \ $(gb_UWINAPI) \
)) ))
$(eval $(call gb_StaticLibrary_add_exception_objects,libreoffice,\ $(eval $(call gb_StaticLibrary_add_cobjects,libreoffice,\
desktop/source/lib/shim \ desktop/source/lib/shim \
)) ))
......
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_DESKTOP_INC_LIBLIBREOFFICE_H
#define INCLUDED_DESKTOP_INC_LIBLIBREOFFICE_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _LibreOffice LibreOffice;
typedef struct _LibreOfficeDocument LibreOfficeDocument;
struct _LibreOffice {
int nSize;
void (*destroy) (LibreOffice *pThis);
int (*initialize) (LibreOffice *pThis,
const char *pInstallPath);
LibreOfficeDocument *(*documentLoad) (LibreOffice *pThis,
const char *pURL);
char * (*getError) (LibreOffice *pThis);
};
struct _LibreOfficeDocument {
int nSize;
void (*destroy) (LibreOfficeDocument *pThis);
int (*saveAs) (LibreOfficeDocument *pThis,
const char *pUrl, const char *pFormat);
};
LibreOffice *lo_init (const char *install_path);
#ifdef __cplusplus
}
#endif
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -10,30 +10,60 @@ ...@@ -10,30 +10,60 @@
#ifndef INCLUDED_DESKTOP_INC_LIBLIBREOFFICE_HXX #ifndef INCLUDED_DESKTOP_INC_LIBLIBREOFFICE_HXX
#define INCLUDED_DESKTOP_INC_LIBLIBREOFFICE_HXX #define INCLUDED_DESKTOP_INC_LIBLIBREOFFICE_HXX
#include <liblibreoffice.h>
/*
* The reasons this C++ code is not as pretty as it could be are:
* a) provide a pure C API - that's useful for some people
* b) allow ABI stability - C++ vtables are not good for that.
* c) avoid C++ types as part of the API.
*/
class LODocument class LODocument
{ {
LibreOfficeDocument *mpDoc;
public: public:
virtual ~LODocument() {} inline LODocument( LibreOfficeDocument *pDoc ) : mpDoc( pDoc ) {}
inline ~LODocument() { mpDoc->destroy( mpDoc ); }
// Save as the given format, if format is NULL sniff from ext'n // Save as the given format, if format is NULL sniff from ext'n
virtual bool saveAs (const char *url, const char *format = NULL) = 0; inline bool saveAs( const char *url, const char *format = NULL )
{
return mpDoc->saveAs( mpDoc, url, format );
}
}; };
class LibLibreOffice class LibLibreOffice
{ {
LibreOffice *mpThis;
public: public:
virtual ~LibLibreOffice () {}; inline LibLibreOffice( LibreOffice *pThis ) : mpThis( pThis ) {}
inline ~LibLibreOffice() { mpThis->destroy( mpThis ); };
virtual bool initialize (const char *installPath) = 0; inline bool initialize( const char *installPath )
{
return mpThis->initialize( mpThis, installPath );
}
virtual LODocument *documentLoad (const char *url) = 0; inline LODocument *documentLoad( const char *url )
{
LibreOfficeDocument *pDoc = mpThis->documentLoad( mpThis, url );
if( !pDoc )
return NULL;
return new LODocument( pDoc );
}
// return the last error as a string, free me. // return the last error as a string, free me.
virtual char *getError() = 0; inline char *getError() { return mpThis->getError( mpThis ); }
}; };
LibLibreOffice *lo_init (const char *install_path); inline LibLibreOffice *lo_cpp_init( const char *install_path )
{
LibreOffice *pThis = lo_init( install_path );
if( !pThis || !pThis->nSize > 0 )
return NULL;
return new LibLibreOffice( pThis );
}
#endif #endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "liblibreoffice.hxx" #include "liblibreoffice.h"
#include <tools/errinf.hxx> #include <tools/errinf.hxx>
#include <osl/file.hxx> #include <osl/file.hxx>
...@@ -97,29 +97,53 @@ aImpressExtensionMap[] = { ...@@ -97,29 +97,53 @@ aImpressExtensionMap[] = {
{ NULL, NULL } { NULL, NULL }
}; };
extern "C" {
SAL_DLLPUBLIC_EXPORT LibreOffice *liblibreoffice_hook(void);
static void doc_destroy( LibreOfficeDocument *pThis );
static int doc_saveAs( LibreOfficeDocument *pThis, const char *pUrl, const char *pFormat );
class LibLODocument_Impl : public LODocument struct LibLODocument_Impl : public _LibreOfficeDocument
{ {
uno::Reference < css::lang::XComponent > mxComponent; uno::Reference < css::lang::XComponent > mxComponent;
public:
LibLODocument_Impl( const uno::Reference < css::lang::XComponent > &xComponent ) LibLODocument_Impl( const uno::Reference < css::lang::XComponent > &xComponent )
: mxComponent( xComponent ) : mxComponent( xComponent )
{ } {
virtual bool saveAs (const char *url, const char *format); nSize = sizeof( LibreOffice );
destroy = doc_destroy;
saveAs = doc_saveAs;
}
}; };
class LibLibreOffice_Impl : public LibLibreOffice static void doc_destroy( LibreOfficeDocument *pThis )
{ {
public: LibLODocument_Impl *pDocument = static_cast< LibLODocument_Impl *>( pThis );
rtl::OUString maLastExceptionMsg; delete pDocument;
}
virtual bool initialize (const char *installPath); static void lo_destroy (LibreOffice *pThis);
static int lo_initialize (LibreOffice *pThis,
const char *pInstallPath);
static LibreOfficeDocument *lo_documentLoad (LibreOffice *pThis,
const char *pURL);
static char * lo_getError (LibreOffice *pThis);
virtual LODocument *documentLoad (const char *url); struct LibLibreOffice_Impl : public _LibreOffice
{
rtl::OUString maLastExceptionMsg;
virtual char *getError(); LibLibreOffice_Impl()
{
nSize = sizeof( LibreOfficeDocument );
virtual ~LibLibreOffice_Impl (); destroy = lo_destroy;
initialize = lo_initialize;
documentLoad = lo_documentLoad;
getError = lo_getError;
}
}; };
// Wonder global state ... // Wonder global state ...
...@@ -149,15 +173,17 @@ static OUString getAbsoluteURL( const char *pURL ) ...@@ -149,15 +173,17 @@ static OUString getAbsoluteURL( const char *pURL )
return sAbsoluteDocUrl; return sAbsoluteDocUrl;
} }
LODocument * static LibreOfficeDocument *
LibLibreOffice_Impl::documentLoad( const char *docUrl ) lo_documentLoad( LibreOffice *pThis, const char *pURL )
{ {
OUString aURL = getAbsoluteURL( docUrl ); LibLibreOffice_Impl *pLib = static_cast< LibLibreOffice_Impl *>( pThis );
OUString aURL = getAbsoluteURL( pURL );
uno::Reference < css::frame::XDesktop2 > xComponentLoader = uno::Reference < css::frame::XDesktop2 > xComponentLoader =
css::frame::Desktop::create(xContext); css::frame::Desktop::create(xContext);
maLastExceptionMsg = ""; pLib->maLastExceptionMsg = "";
try { try {
uno::Reference < css::lang::XComponent > xComponent = uno::Reference < css::lang::XComponent > xComponent =
xComponentLoader->loadComponentFromURL( xComponentLoader->loadComponentFromURL(
...@@ -166,21 +192,26 @@ LibLibreOffice_Impl::documentLoad( const char *docUrl ) ...@@ -166,21 +192,26 @@ LibLibreOffice_Impl::documentLoad( const char *docUrl )
if( xComponentLoader.is() ) if( xComponentLoader.is() )
return new LibLODocument_Impl( xComponent ); return new LibLODocument_Impl( xComponent );
else else
maLastExceptionMsg = "unknown load failure"; pLib->maLastExceptionMsg = "unknown load failure";
} catch (const uno::Exception &ex) { } catch (const uno::Exception &ex) {
maLastExceptionMsg = ex.Message; pLib->maLastExceptionMsg = ex.Message;
} }
return NULL; return NULL;
} }
bool LibLODocument_Impl::saveAs (const char *url, const char *format) static int
doc_saveAs( LibreOfficeDocument *pThis,
const char *url, const char *format )
{ {
LibLODocument_Impl *pDocument = static_cast< LibLODocument_Impl *>( pThis );
OUString sFormat = getUString( format ); OUString sFormat = getUString( format );
OUString aURL = getAbsoluteURL( url ); OUString aURL = getAbsoluteURL( url );
try { try {
uno::Reference< frame::XModel > xDocument( mxComponent, uno::UNO_QUERY_THROW ); uno::Reference< frame::XModel > xDocument( pDocument->mxComponent,
uno::UNO_QUERY_THROW );
uno::Sequence< beans::PropertyValue > aSeq = xDocument->getArgs(); uno::Sequence< beans::PropertyValue > aSeq = xDocument->getArgs();
OUString aDocumentService; OUString aDocumentService;
...@@ -242,7 +273,8 @@ bool LibLODocument_Impl::saveAs (const char *url, const char *format) ...@@ -242,7 +273,8 @@ bool LibLODocument_Impl::saveAs (const char *url, const char *format)
aSeq[1].Name = "FilterName"; aSeq[1].Name = "FilterName";
aSeq[1].Value <<= aFilterName; aSeq[1].Value <<= aFilterName;
uno::Reference< frame::XStorable > xStorable( mxComponent, uno::UNO_QUERY_THROW ); uno::Reference< frame::XStorable > xStorable( pDocument->mxComponent,
uno::UNO_QUERY_THROW );
xStorable->storeToURL( aURL, aSeq ); xStorable->storeToURL( aURL, aSeq );
return true; return true;
...@@ -252,9 +284,11 @@ bool LibLODocument_Impl::saveAs (const char *url, const char *format) ...@@ -252,9 +284,11 @@ bool LibLODocument_Impl::saveAs (const char *url, const char *format)
} }
} }
char *LibLibreOffice_Impl::getError() static char *
lo_getError (LibreOffice *pThis)
{ {
OString aStr = rtl::OUStringToOString( maLastExceptionMsg, RTL_TEXTENCODING_UTF8 ); LibLibreOffice_Impl *pLib = static_cast< LibLibreOffice_Impl *>( pThis );
OString aStr = rtl::OUStringToOString( pLib->maLastExceptionMsg, RTL_TEXTENCODING_UTF8 );
char *pMem = (char *) malloc (aStr.getLength() + 1); char *pMem = (char *) malloc (aStr.getLength() + 1);
strcpy( pMem, aStr.getStr() ); strcpy( pMem, aStr.getStr() );
return pMem; return pMem;
...@@ -308,21 +342,23 @@ initialize_uno( const OUString &aAppURL ) ...@@ -308,21 +342,23 @@ initialize_uno( const OUString &aAppURL )
// configmgr setup ? // configmgr setup ?
} }
bool static int
LibLibreOffice_Impl::initialize( const char *app_path ) lo_initialize( LibreOffice *pThis, const char *app_path )
{ {
(void) pThis;
static bool bInitialized = false; static bool bInitialized = false;
if( bInitialized ) if( bInitialized )
return true; return 1;
if( !app_path ) if( !app_path )
return false; return 0;
OUString aAppPath( app_path, strlen( app_path ), RTL_TEXTENCODING_UTF8 ); OUString aAppPath( app_path, strlen( app_path ), RTL_TEXTENCODING_UTF8 );
OUString aAppURL; OUString aAppURL;
if( osl::FileBase::getFileURLFromSystemPath( aAppPath, aAppURL ) != if( osl::FileBase::getFileURLFromSystemPath( aAppPath, aAppURL ) !=
osl::FileBase::E_None ) osl::FileBase::E_None )
return false; return 0;
try { try {
initialize_uno( aAppURL ); initialize_uno( aAppURL );
...@@ -344,23 +380,23 @@ LibLibreOffice_Impl::initialize( const char *app_path ) ...@@ -344,23 +380,23 @@ LibLibreOffice_Impl::initialize( const char *app_path )
return bInitialized; return bInitialized;
} }
extern "C" { LibreOffice *liblibreoffice_hook(void)
SAL_DLLPUBLIC_EXPORT LibLibreOffice *liblibreoffice_hook(void);
}
LibLibreOffice *liblibreoffice_hook(void)
{ {
if( !gImpl ) if( !gImpl )
{ {
fprintf( stderr, "create libreoffice object\n" ); fprintf( stderr, "create libreoffice object\n" );
gImpl = new LibLibreOffice_Impl(); gImpl = new LibLibreOffice_Impl();
} }
return gImpl; return static_cast< LibreOffice *>( gImpl );
} }
LibLibreOffice_Impl::~LibLibreOffice_Impl () static void lo_destroy (LibreOffice *pThis)
{ {
LibLibreOffice_Impl *pLib = static_cast< LibLibreOffice_Impl *>( pThis );
delete pLib;
gImpl = NULL; gImpl = NULL;
} }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <osl/module.h> #include <osl/module.h>
#include <sal/types.h> #include <sal/types.h>
#include <liblibreoffice.hxx> #include <liblibreoffice.h>
#include <dlfcn.h> #include <dlfcn.h>
#ifdef AIX #ifdef AIX
...@@ -23,32 +23,34 @@ ...@@ -23,32 +23,34 @@
#define TARGET_LIB SAL_MODULENAME( "sofficeapp" ) #define TARGET_LIB SAL_MODULENAME( "sofficeapp" )
extern "C" { typedef LibreOffice *(HookFunction)(void);
typedef LibLibreOffice *(HookFunction)(void);
};
SAL_DLLPUBLIC_EXPORT LibLibreOffice *lo_init( const char *install_path ) SAL_DLLPUBLIC_EXPORT LibreOffice *lo_init( const char *install_path )
{ {
char *imp_lib;
void *dlhandle;
HookFunction *pSym;
if( !install_path ) if( !install_path )
return NULL; return NULL;
char* imp_lib = (char *) malloc( strlen (install_path) + sizeof( TARGET_LIB ) + 2 ); if( !( imp_lib = (char *) malloc( strlen (install_path) + sizeof( TARGET_LIB ) + 2 ) ) )
if(!imp_lib)
{ {
fprintf( stderr, "failed to open library : not enough memory\n"); fprintf( stderr, "failed to open library : not enough memory\n");
return NULL; return NULL;
} }
strcpy( imp_lib, install_path ); strcpy( imp_lib, install_path );
strcat( imp_lib, "/" ); strcat( imp_lib, "/" );
strcat( imp_lib, TARGET_LIB ); strcat( imp_lib, TARGET_LIB );
void *dlhandle = dlopen( imp_lib, RTLD_LAZY );
if( !dlhandle ) if( !( dlhandle = dlopen( imp_lib, RTLD_LAZY ) ) )
{ {
fprintf( stderr, "failed to open library '%s'\n", imp_lib ); fprintf( stderr, "failed to open library '%s'\n", imp_lib );
free( imp_lib ); free( imp_lib );
return NULL; return NULL;
} }
HookFunction *pSym = (HookFunction *) dlsym( dlhandle, "liblibreoffice_hook" ); pSym = (HookFunction *) dlsym( dlhandle, "liblibreoffice_hook" );
if( !pSym ) { if( !pSym ) {
fprintf( stderr, "failed to find hook in library '%s'\n", imp_lib ); fprintf( stderr, "failed to find hook in library '%s'\n", imp_lib );
free( imp_lib ); free( imp_lib );
...@@ -59,6 +61,6 @@ SAL_DLLPUBLIC_EXPORT LibLibreOffice *lo_init( const char *install_path ) ...@@ -59,6 +61,6 @@ SAL_DLLPUBLIC_EXPORT LibLibreOffice *lo_init( const char *install_path )
return pSym(); return pSym();
} }
#endif // LINUX - port me ! #endif // not LINUX => port me !
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -44,7 +44,7 @@ int main (int argc, char **argv) ...@@ -44,7 +44,7 @@ int main (int argc, char **argv)
return 1; return 1;
} }
LibLibreOffice *pOffice = lo_init( argv[1] ); LibLibreOffice *pOffice = lo_cpp_init( argv[1] );
if( !pOffice ) if( !pOffice )
{ {
fprintf( stderr, "Failed to initialize\n" ); fprintf( stderr, "Failed to initialize\n" );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment