summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2013-11-15 12:09:10 +0000
committerMichael Meeks <michael.meeks@collabora.com>2013-11-15 13:45:58 +0000
commit9013a3a76dd773cf3f292267c9aac8046f19f0aa (patch)
tree501cc50731df78ddb44353dc466f1af9a8bbd831 /desktop
parent96e23cb9305da8b00db2587104932ee9d5d3122c (diff)
liblibo: expose a C API for ABI reasons, and wrap with C++.
Change-Id: I7b3bcead05788e663d94724522bfa3f227b15499
Diffstat (limited to 'desktop')
-rw-r--r--desktop/Library_libreoffice.mk2
-rw-r--r--desktop/inc/liblibreoffice.h46
-rw-r--r--desktop/inc/liblibreoffice.hxx46
-rw-r--r--desktop/source/lib/init.cxx106
-rw-r--r--desktop/source/lib/shim.c (renamed from desktop/source/lib/shim.cxx)24
5 files changed, 169 insertions, 55 deletions
diff --git a/desktop/Library_libreoffice.mk b/desktop/Library_libreoffice.mk
index b35c75da0284..dbdf6acc3e7e 100644
--- a/desktop/Library_libreoffice.mk
+++ b/desktop/Library_libreoffice.mk
@@ -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 \
))
diff --git a/desktop/inc/liblibreoffice.h b/desktop/inc/liblibreoffice.h
new file mode 100644
index 000000000000..db3b8358a9af
--- /dev/null
+++ b/desktop/inc/liblibreoffice.h
@@ -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: */
diff --git a/desktop/inc/liblibreoffice.hxx b/desktop/inc/liblibreoffice.hxx
index 28c23476c899..81207ac4eedc 100644
--- a/desktop/inc/liblibreoffice.hxx
+++ b/desktop/inc/liblibreoffice.hxx
@@ -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: */
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index d26d5b8752a0..817d84673e0b 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -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" {
+
+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;
-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: */
diff --git a/desktop/source/lib/shim.cxx b/desktop/source/lib/shim.c
index 8c47dc42ad1e..c821d2dd9e23 100644
--- a/desktop/source/lib/shim.cxx
+++ b/desktop/source/lib/shim.c
@@ -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: */