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

Change-Id: I7b3bcead05788e663d94724522bfa3f227b15499
This commit is contained in:
Michael Meeks 2013-11-15 12:09:10 +00:00
parent 96e23cb930
commit 9013a3a76d
6 changed files with 170 additions and 56 deletions

View file

@ -25,7 +25,7 @@ $(eval $(call gb_StaticLibrary_use_libraries,libreoffice,\
$(gb_UWINAPI) \
))
$(eval $(call gb_StaticLibrary_add_exception_objects,libreoffice,\
$(eval $(call gb_StaticLibrary_add_cobjects,libreoffice,\
desktop/source/lib/shim \
))

View file

@ -0,0 +1,46 @@
/* -*- 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: */

View file

@ -10,30 +10,60 @@
#ifndef 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
{
LibreOfficeDocument *mpDoc;
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
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
{
LibreOffice *mpThis;
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.
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
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -13,7 +13,7 @@
#include <string.h>
#include <stdlib.h>
#include "liblibreoffice.hxx"
#include "liblibreoffice.h"
#include <tools/errinf.hxx>
#include <osl/file.hxx>
@ -97,29 +97,53 @@ aImpressExtensionMap[] = {
{ NULL, NULL }
};
extern "C" {
class LibLODocument_Impl : public LODocument
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 );
struct LibLODocument_Impl : public _LibreOfficeDocument
{
uno::Reference < css::lang::XComponent > mxComponent;
public:
LibLODocument_Impl( const uno::Reference < css::lang::XComponent > &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:
rtl::OUString maLastExceptionMsg;
LibLODocument_Impl *pDocument = static_cast< LibLODocument_Impl *>( pThis );
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 ...
@ -149,15 +173,17 @@ static OUString getAbsoluteURL( const char *pURL )
return sAbsoluteDocUrl;
}
LODocument *
LibLibreOffice_Impl::documentLoad( const char *docUrl )
static LibreOfficeDocument *
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 =
css::frame::Desktop::create(xContext);
maLastExceptionMsg = "";
pLib->maLastExceptionMsg = "";
try {
uno::Reference < css::lang::XComponent > xComponent =
xComponentLoader->loadComponentFromURL(
@ -166,21 +192,26 @@ LibLibreOffice_Impl::documentLoad( const char *docUrl )
if( xComponentLoader.is() )
return new LibLODocument_Impl( xComponent );
else
maLastExceptionMsg = "unknown load failure";
pLib->maLastExceptionMsg = "unknown load failure";
} catch (const uno::Exception &ex) {
maLastExceptionMsg = ex.Message;
pLib->maLastExceptionMsg = ex.Message;
}
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 aURL = getAbsoluteURL( url );
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();
OUString aDocumentService;
@ -242,7 +273,8 @@ bool LibLODocument_Impl::saveAs (const char *url, const char *format)
aSeq[1].Name = "FilterName";
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 );
return true;
@ -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);
strcpy( pMem, aStr.getStr() );
return pMem;
@ -308,21 +342,23 @@ initialize_uno( const OUString &aAppURL )
// configmgr setup ?
}
bool
LibLibreOffice_Impl::initialize( const char *app_path )
static int
lo_initialize( LibreOffice *pThis, const char *app_path )
{
(void) pThis;
static bool bInitialized = false;
if( bInitialized )
return true;
return 1;
if( !app_path )
return false;
return 0;
OUString aAppPath( app_path, strlen( app_path ), RTL_TEXTENCODING_UTF8 );
OUString aAppURL;
if( osl::FileBase::getFileURLFromSystemPath( aAppPath, aAppURL ) !=
osl::FileBase::E_None )
return false;
return 0;
try {
initialize_uno( aAppURL );
@ -344,23 +380,23 @@ LibLibreOffice_Impl::initialize( const char *app_path )
return bInitialized;
}
extern "C" {
SAL_DLLPUBLIC_EXPORT LibLibreOffice *liblibreoffice_hook(void);
}
LibLibreOffice *liblibreoffice_hook(void)
LibreOffice *liblibreoffice_hook(void)
{
if( !gImpl )
{
fprintf( stderr, "create libreoffice object\n" );
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;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -14,7 +14,7 @@
#include <osl/module.h>
#include <sal/types.h>
#include <liblibreoffice.hxx>
#include <liblibreoffice.h>
#include <dlfcn.h>
#ifdef AIX
@ -23,32 +23,34 @@
#define TARGET_LIB SAL_MODULENAME( "sofficeapp" )
extern "C" {
typedef LibLibreOffice *(HookFunction)(void);
};
typedef LibreOffice *(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 )
return NULL;
char* imp_lib = (char *) malloc( strlen (install_path) + sizeof( TARGET_LIB ) + 2 );
if(!imp_lib)
if( !( imp_lib = (char *) malloc( strlen (install_path) + sizeof( TARGET_LIB ) + 2 ) ) )
{
fprintf( stderr, "failed to open library : not enough memory\n");
return NULL;
}
strcpy( imp_lib, install_path );
strcat( imp_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 );
free( imp_lib );
return NULL;
}
HookFunction *pSym = (HookFunction *) dlsym( dlhandle, "liblibreoffice_hook" );
pSym = (HookFunction *) dlsym( dlhandle, "liblibreoffice_hook" );
if( !pSym ) {
fprintf( stderr, "failed to find hook in library '%s'\n", imp_lib );
free( imp_lib );
@ -59,6 +61,6 @@ SAL_DLLPUBLIC_EXPORT LibLibreOffice *lo_init( const char *install_path )
return pSym();
}
#endif // LINUX - port me !
#endif // not LINUX => port me !
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -44,7 +44,7 @@ int main (int argc, char **argv)
return 1;
}
LibLibreOffice *pOffice = lo_init( argv[1] );
LibLibreOffice *pOffice = lo_cpp_init( argv[1] );
if( !pOffice )
{
fprintf( stderr, "Failed to initialize\n" );