[Libreoffice-commits] core.git: desktop/inc desktop/Library_libreoffice.mk desktop/source smoketest/libtest.cxx

Michael Meeks michael.meeks at collabora.com
Fri Nov 15 04:41:34 PST 2013


 desktop/Library_libreoffice.mk |    2 
 desktop/inc/liblibreoffice.h   |   46 +++++++++++++++++
 desktop/inc/liblibreoffice.hxx |   46 ++++++++++++++---
 desktop/source/lib/init.cxx    |  106 +++++++++++++++++++++++++++--------------
 desktop/source/lib/shim.c      |   66 +++++++++++++++++++++++++
 desktop/source/lib/shim.cxx    |   64 ------------------------
 smoketest/libtest.cxx          |    2 
 7 files changed, 223 insertions(+), 109 deletions(-)

New commits:
commit 9013a3a76dd773cf3f292267c9aac8046f19f0aa
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Nov 15 12:09:10 2013 +0000

    liblibo: expose a C API for ABI reasons, and wrap with C++.
    
    Change-Id: I7b3bcead05788e663d94724522bfa3f227b15499

diff --git a/desktop/Library_libreoffice.mk b/desktop/Library_libreoffice.mk
index b35c75d..dbdf6ac 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 0000000..db3b835
--- /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 28c2347..81207ac 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 d26d5b8..817d846 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
similarity index 72%
rename from desktop/source/lib/shim.cxx
rename to desktop/source/lib/shim.c
index 8c47dc4..c821d2d 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: */
diff --git a/smoketest/libtest.cxx b/smoketest/libtest.cxx
index 2ec55cf..e1e7970 100644
--- a/smoketest/libtest.cxx
+++ b/smoketest/libtest.cxx
@@ -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" );


More information about the Libreoffice-commits mailing list