Return-Path: X-Original-To: apmail-incubator-ooo-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-ooo-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 0AE647FEC for ; Sun, 27 Nov 2011 22:37:36 +0000 (UTC) Received: (qmail 57427 invoked by uid 500); 27 Nov 2011 22:37:35 -0000 Delivered-To: apmail-incubator-ooo-commits-archive@incubator.apache.org Received: (qmail 57383 invoked by uid 500); 27 Nov 2011 22:37:35 -0000 Mailing-List: contact ooo-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ooo-dev@incubator.apache.org Delivered-To: mailing list ooo-commits@incubator.apache.org Received: (qmail 57275 invoked by uid 99); 27 Nov 2011 22:37:35 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 27 Nov 2011 22:37:35 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 27 Nov 2011 22:37:23 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 4D483238897F; Sun, 27 Nov 2011 22:37:01 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: svn commit: r1206884 [1/4] - in /incubator/ooo/ooo-site/trunk/content/ucb/docs: ./ ucp-ref/ Date: Sun, 27 Nov 2011 22:36:59 -0000 To: ooo-commits@incubator.apache.org From: kschenk@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20111127223701.4D483238897F@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: kschenk Date: Sun Nov 27 22:36:56 2011 New Revision: 1206884 URL: http://svn.apache.org/viewvc?rev=1206884&view=rev Log: kls -- added ucb/docs Added: incubator/ooo/ooo-site/trunk/content/ucb/docs/ incubator/ooo/ooo-site/trunk/content/ucb/docs/cachemap.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/errorhandling.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/fileurl.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucb-api-usage.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucb-configuration.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucb-overview.odp (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/ incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/file-ucp.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/ftp-contents.gif (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/ftp-ucp.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/help-ucp.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/hierarchy-contents.gif (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/hierarchy-ucp.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/odma-ucp.gif (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/odma-ucp.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/package-contents.gif (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/package-ucp.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/tdoc-contents.gif (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/tdoc-ucp.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/webdav-contents.gif (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/webdav-ucp.html (with props) incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/wfs.gif (with props) Added: incubator/ooo/ooo-site/trunk/content/ucb/docs/cachemap.html URL: http://svn.apache.org/viewvc/incubator/ooo/ooo-site/trunk/content/ucb/docs/cachemap.html?rev=1206884&view=auto ============================================================================== --- incubator/ooo/ooo-site/trunk/content/ucb/docs/cachemap.html (added) +++ incubator/ooo/ooo-site/trunk/content/ucb/docs/cachemap.html Sun Nov 27 22:36:56 2011 @@ -0,0 +1,1017 @@ + + + + + Cachemaps + + + + + + + + +
+

OpenOffice.orgCachemaps

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Contents

+
+

Abstract
+ Solution 1 (Single Mutex)
+ Solution 2 (Weak References)
+ Solution 3 (Best of Both Worlds)
+ Performance Measurements

+


+
+

+ Abstract

+
+

I quite often have the need for a construct I will call a + cachemap. A cachemap is like an ordinary map (or hashmap), in + that it maps from keys (normally strings) to objects, but it also + controls the lifetime of the mapped objects. If a client requests an + object that is not yet instantiated, a (refcounted) instance is + created, inserted into the cachemap, and returned to the client. If + the client no longer needs the object (the refcount of the object + drops to zero), it is automatically removed from the cachemap. And if + a client requests an object that is already present in the cachemap + (because it was requested by a client before, and its refcount is + still positive), the present instance is returned. Skeleton C++ class + definitions for the cachemap and the objects it manages could look + like the following:

+
+
+
+
class ObjectContainer // the cachemap
+{
+public:
+    rtl::Reference< Object > get(rtl::OUString const & rKey);
+};
+
+class Object // the objects managed by the cachemap
+{
+public:
+    void acquire() SAL_THROW(());
+
+    void release() SAL_THROW(());
+};
+
+
+
+

The problems in implementing this are that (1) the cachemap must not + acquire() + the objects it currently has in its map (otherwise, the refcounts of + those objects could never drop to zero, and they would never be + removed from the map), and (2) in a multi-threaded environment there + is a problem when one thread does a final release() + of an object (refcount drops to zero and object is removed from the + map) and at the same time another thread happens to call get() + to request that very object.

+

Below, I describe three different implementations that solve these + problems. The first solution was my initial idea, but it tends to be + slow. The second is based on weak references, but it turned out to be + slow, too. The third combines ideas from the other two + solutions---and it turned out to be fast. So, if you are interested + in boiler plate code for a fast implementation of the cachemap + pattern, turn to the third solution + directly.

+

The three solutions all follow the same conventions. They + implement an ObjectContainerN + (the cachemap, mapping from strings to objects) and a corresponding + ObjectN + (the refcounted objects managed by the cachemap). The source code + presented here is also available within the ucb project + (ucb/workben/cachemap), + and it is presented here without the (somewhat longish) copyright + headers.

+


+
+

+ Solution 1 (Single Mutex)

+
+

The + combined header file for both ObjectContainer1 + and Object1 is + cachemapobject1.hxx:

+
+
+
+
#ifndef INCLUDED_UCB_CACHEMAPOBJECT1_HXX
+#define INCLUDED_UCB_CACHEMAPOBJECT1_HXX
+
+#ifndef _OSL_INTERLOCK_H_
+#include "osl/interlck.h"
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include "osl/mutex.hxx"
+#endif
+#ifndef _RTL_REF_HXX_
+#include "rtl/ref.hxx"
+#endif
+#ifndef _SAL_TYPES_H_
+#include "sal/types.h"
+#endif
+#ifndef _SALHELPER_SIMPLEREFERENCEOBJECT_HXX_
+#include "salhelper/simplereferenceobject.hxx"
+#endif
+
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace rtl { class OUString; }
+namespace ucb { namespace cachemap { class Object1; } }
+
+namespace ucb { namespace cachemap {
+
+class ObjectContainer1: public salhelper::SimpleReferenceObject
+{
+public:
+    ObjectContainer1();
+
+    virtual ~ObjectContainer1() SAL_THROW(());
+
+    rtl::Reference< Object1 > get(rtl::OUString const & rKey);
+
+private:
+    typedef std::map< rtl::OUString, Object1 * > Map;
+
+    Map m_aMap;
+    osl::Mutex m_aMutex;
+
+    void releaseElement(Object1 * pElement) SAL_THROW(());
+
+    friend class Object1; // to access Map, releaseElement()
+};
+
+class Object1
+{
+public:
+    inline void acquire() SAL_THROW(())
+    { osl_incrementInterlockedCount(&m_nRefCount); }
+
+    inline void release() SAL_THROW(())
+    { m_xContainer->releaseElement(this); }
+
+private:
+    rtl::Reference< ObjectContainer1 > m_xContainer;
+    ObjectContainer1::Map::iterator m_aContainerIt;
+    oslInterlockedCount m_nRefCount;
+
+    inline Object1(rtl::Reference< ObjectContainer1 > const & rContainer);
+
+    inline ~Object1() SAL_THROW(());
+
+    Object1(Object1 &); // not implemented
+    void operator =(Object1); // not implemented
+
+    friend class ObjectContainer1;
+        // to access m_aContainerIt, m_nRefCount, Object1(), ~Object1()
+#if defined WNT
+    friend struct std::auto_ptr< Object1 > // to access ~Object
+        // work around compiler bug...
+#else // WNT
+    friend class std::auto_ptr< Object1 >; // to access ~Object1()
+#endif // WNT
+};
+
+} }
+
+#endif // INCLUDED_UCB_CACHEMAPOBJECT1_HXX
+
+
+
+

A few notes:

+
    +
  • It is a good idea to use valid + C++ identifiers as include guards for header files. That is, do not + use identifiers that start with an underline followed by an upper + case letter (e.g., _UCB_CACHEMAPOBJECT1_HXX_) + or that contain two underlines in a row, because those identifiers + are reserved for internal use by the compiler and standard library + implementation. (Lakos, + section 2.4, suggestes the INCLUDED_XXX + style.)

    +
  • Use the convention of (redundant but + compilation time reducing) external include guards for standard + header files, too. For this to work, it is necessary that everybody + use the same identifiers for the various standard header files, of + course. (See Lakos, + section 2.5.)

    +
  • ObjectContainer1 + turns out to be a refcounted object. This was not required in the + introduction of the cachemap pattern, but it is rather a consequence + of the chosen implementation (and it should not hurt any client, + either).

    +
  • In ObjectContainer1, + a std::map + is used instead of a (de facto standard?) std::hash_map + that might be a bit faster. The implementation of ObjectContainer1 + relies on the fact that iterators into a std::map + are not invalidated when calling insert() + or erase(). + There seems to be no corresponding guarantee for std::hash_map.

    +
  • ObjectContainer1 + and Object1 + need to be mutual friends. If one entity is a friend of another, + these entities are strongly coupled, and it seems always best to + keep them together in a single header file (thereby breaking the + rule to have a seperate header file for each class).

    +
  • Logically, only ObjectContainer1 + is allowed to create and destroy instances of Object1, + hence the design decision to make the constructor and destructor of + Object1 + private and make ObjectContainer1 + a friend of Object1. + But a std::auto_ptr< + Object1 > is needed at one place in the + implementation, and that std::auto_ptr + also needs access to the destructor of Object1. + It seemed best to simply make std::auto_ptr< + Object1 > a friend of Object1, + too, in this situation (though too many friends can be an indication + of bad design.) Alas, the Microsoft compiler used on the Windows x86 platform + (WNT define) + needs to see struct (or nothing) in this friend declaration, + instead of the correct class, so some + platform-dependent code is needed here (and in retrospect it might seem better to make the destructor of + Object1 public and get rid of all this).

    +
+

The corresponding implementation file is + cachemapobject1.cxx:

+
+
+
+
#ifndef INCLUDED_UCB_CACHEMAPOBJECT1_HXX
+#include "cachemapobject1.hxx"
+#endif
+
+#ifndef _OSL_DIAGNOSE_H_
+#include "osl/diagnose.h"
+#endif
+#ifndef _OSL_INTERLOCK_H_
+#include "osl/interlck.h"
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include "osl/mutex.hxx"
+#endif
+#ifndef _RTL_REF_HXX_
+#include "rtl/ref.hxx"
+#endif
+#ifndef _RTL_USTRING_HXX_
+#include "rtl/ustring.hxx"
+#endif
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+using ucb::cachemap::Object1;
+using ucb::cachemap::ObjectContainer1;
+
+inline
+Object1::Object1(rtl::Reference< ObjectContainer1 > const & rContainer):
+    m_xContainer(rContainer),
+    m_nRefCount(0)
+{
+    OSL_ASSERT(m_xContainer.is());
+}
+
+inline Object1::~Object1() SAL_THROW(())
+{}
+
+void ObjectContainer1::releaseElement(Object1 * pElement) SAL_THROW(())
+{
+    OSL_ASSERT(pElement);
+    bool bDelete = false;
+    {
+        osl::MutexGuard aGuard(m_aMutex);
+        if (osl_decrementInterlockedCount(&pElement->m_nRefCount) == 0)
+        {
+            m_aMap.erase(pElement->m_aContainerIt);
+            bDelete = true;
+        }
+    }
+    if (bDelete)
+        delete pElement;
+}
+
+ObjectContainer1::ObjectContainer1()
+{}
+
+ObjectContainer1::~ObjectContainer1() SAL_THROW(())
+{}
+
+rtl::Reference< Object1 > ObjectContainer1::get(rtl::OUString const & rKey)
+{
+    osl::MutexGuard aGuard(m_aMutex);
+    Map::iterator aIt(m_aMap.find(rKey));
+    if (aIt == m_aMap.end())
+    {
+        std::auto_ptr< Object1 > xElement(new Object1(this));
+        aIt = m_aMap.insert(Map::value_type(rKey, xElement.get())).first;
+        aIt->second->m_aContainerIt = aIt;
+        xElement.release();
+    }
+    return aIt->second;
+}
+
+
+
+
    +
  • It is always a good idea to + include the header file that belongs to an implementation file first + in that file. That way, there is an automatic check that each header + file is self-contained (for almost every header, there is a + corresponding implementation file, and compilation of that file + fails if the header is not self-contained). (See Lakos, + section 3.2.)

    +
  • Note how releaseElement() + deletes the element only after the mutex has been released. It is + good practice to do as little as absolutely necessary during the + time a mutex is locked.

    +
  • Note how a std::auto_ptr< + Object1 > is used to ensure the newly created + Object1 + is properly deleted in case the insert() + happens to throw an exception.

    +
+

The way the problems mentionend in the introduction are solved + here is that ObjectContainer1 + only holds pointers to instances of Object1, + not refcounting references, and that Object1::release() + is simply forwarded to ObjectContainer1::releaseElement(). + The releaseElement() + method checks whether the refcount of the object drops to zero and + removes it from the map, if appropriate. The methods + ObjectContainer1::releaseElement() + and ObjectContainer1::get() + share a mutex, so that there can never be the situation that one + thread tries to get an object another thread is about to delete. The + disadvantage of this solution is that every call to + Object1::release() + needs to acquire a mutex, which is quite expensive on typical + platforms.

+


+
+

+ Solution 2 (Weak References)

+
+

The UNO concept of weak references offers itself as another + solution to the problem: ObjectContainer2 + holds weak references to instances of Object2, + and the mechanism used in the ObjectContainer2::get() + method to translate a weak reference to an Object2 + into a hard reference (that may then turn out to be null) solves all + the problems for us.

+

With this solution, only ObjectContainer2 + needs to know Object2, + and not also the other way around (as it was in the first solution + due to the mutual friend-ness of the two classes). Therefore, there + are individual header files for Object2 + and ObjectContainer2.

+

The header file + cachemapobject2.hxx + is nothing more than a skeleton (Object2 + is so bare-bones it does not even need an implementation file):

+
+
+
+
#ifndef INCLUDED_UCB_CACHEMAPOBJECT2_HXX
+#define INCLUDED_UCB_CACHEMAPOBJECT2_HXX
+
+#ifndef _CPPUHELPER_WEAK_HXX_
+#include "cppuhelper/weak.hxx"
+#endif
+
+namespace ucb { namespace cachemap {
+
+class Object2: public cppu::OWeakObject
+{};
+
+} }
+
+#endif // INCLUDED_UCB_CACHEMAPOBJECT2_HXX
+
+
+
+

The header file + cachemapobjectcontainer2.hxx + is hardly more interesting:

+
+
+
+
#ifndef INCLUDED_UCB_CACHEMAPOBJECTCONTAINER2_HXX
+#define INCLUDED_UCB_CACHEMAPOBJECTCONTAINER2_HXX
+
+#ifndef _CPPUHELPER_WEAKREF_HXX_
+#include "cppuhelper/weakref.hxx"
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include "osl/mutex.hxx"
+#endif
+#ifndef _RTL_REF_HXX_
+#include "rtl/ref.hxx"
+#endif
+#ifndef _SAL_TYPES_H_
+#include "sal/types.h"
+#endif
+
+#ifndef INCLUDED_HASH_MAP
+#include <hash_map>
+#define INCLUDED_HASH_MAP
+#endif
+
+namespace rtl {
+    class OUString;
+    struct OUStringHash;
+}
+namespace ucb { namespace cachemap { class Object2; } }
+
+namespace ucb { namespace cachemap {
+
+class ObjectContainer2
+{
+public:
+    ObjectContainer2();
+
+    ~ObjectContainer2() SAL_THROW(());
+
+    rtl::Reference< Object2 > get(rtl::OUString const & rKey);
+
+private:
+    typedef std::hash_map< rtl::OUString,
+                           com::sun::star::uno::WeakReference< Object2 >,
+                           rtl::OUStringHash >
+    Map;
+
+    ObjectContainer2(ObjectContainer2 &); // not implemented
+    void operator =(ObjectContainer2); // not implemented
+
+    Map m_aMap;
+    osl::Mutex m_aMutex;
+};
+
+} }
+
+#endif // INCLUDED_UCB_CACHEMAPOBJECTCONTAINER2_HXX
+
+
+
+
    +
  • Here, a (de facto standard?) + std::hash_map + is used instead of a std::map + as used for ObjectContainer1: + We do not need any guarantees about iterators, so there is no reason + not to use the (potentially faster) std::hash_map.

    +
+

The solution to the implementation problems is hidden in the + implementation of cppu::OWeakObject + and com::sun::star::uno::WeakReference, + so the implementation file + cachemapobjectcontainer2.cxx + is quite simple, too:

+
+
+
+
#ifndef INCLUDED_UCB_CACHEMAPOBJECTCONTAINER2_HXX
+#include "cachemapobjectcontainer2.hxx"
+#endif
+
+#ifndef INCLUDED_UCB_CACHEMAPOBJECT2_HXX
+#include "cachemapobject2.hxx"
+#endif
+
+#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
+#include "com/sun/star/uno/Reference.hxx"
+#endif
+#ifndef _COM_SUN_STAR_UNO_XWEAK_HPP_
+#include "com/sun/star/uno/XWeak.hpp"
+#endif
+#ifndef _CPPUHELPER_WEAKREF_HXX_
+#include "cppuhelper/weakref.hxx"
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include "osl/mutex.hxx"
+#endif
+#ifndef _RTL_REF_HXX_
+#include "rtl/ref.hxx"
+#endif
+#ifndef _RTL_USTRING_HXX_
+#include "rtl/ustring.hxx"
+#endif
+
+using namespace com::sun;
+using ucb::cachemap::Object2;
+using ucb::cachemap::ObjectContainer2;
+
+ObjectContainer2::ObjectContainer2()
+{}
+
+ObjectContainer2::~ObjectContainer2() SAL_THROW(())
+{}
+
+rtl::Reference< Object2 > ObjectContainer2::get(rtl::OUString const & rKey)
+{
+    rtl::Reference< Object2 > xElement;
+    {
+        osl::MutexGuard aGuard(m_aMutex);
+        Map::iterator aIt(m_aMap.find(rKey));
+        if (aIt != m_aMap.end())
+            xElement = static_cast< Object2 * >(
+                           star::uno::Reference< star::uno::XWeak >(
+                                   aIt->second.get(), star::uno::UNO_QUERY).
+                               get());
+        if (!xElement.is())
+        {
+            xElement = new Object2;
+            m_aMap[rKey]
+                = star::uno::WeakReference< Object2 >(xElement.get());
+        }
+    }
+    return xElement;
+}
+
+
+
+

The main trick (hack?) here is to translate from a + com::sun::star::uno::WeakReference< + Object2 > via a com::sun::star::uno::Reference< + com::sun::star::uno::XWeak > to an rtl::Reference< + Object2 > (in general, you must go from a + com::sun::star::uno::WeakReference< + T > to a com::sun::star::uno::Reference< + T >, but it is not possible to have a + com::sun::star::uno::Reference< + Object2 >, so we must go via the base class XWeak + here).

+

The drawback of this solution is that it is not faster than the + initial one (even slower on some platforms). The overhead of using + the (generic) mechanism of weak references when requesting objects + outweights the benefits of the faster refcounting.

+

Another point that can well be a drawback of this solution is that + a weak reference to a destroyed object is not removed from the map; + it is replaced with a weak references to a living object the next + time ObjectContainer2::get() + requests that object, but it is never erased from the map. Therefore, + the map itself keeps growing over the lifetime of the + ObjectContainer2 + instance.

+


+
+

+ Solution 3 (Best of Both Worlds)

+
+

If exploiting the generic facilities in the second solution did + not give any performance advantage, let us try to become faster with + a hand-crafted version (i.e, combining the hand-crafted framework of + the first solution with the implementation details of the second + one).

+

The header file + cachemapobject3.hxx + is almost identical to the header file from the first solution + (differences are in green):

+
+
+
+
#ifndef INCLUDED_UCB_CACHEMAPOBJECT3_HXX
+#define INCLUDED_UCB_CACHEMAPOBJECT3_HXX
+
+#ifndef _OSL_INTERLOCK_H_
+#include "osl/interlck.h"
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include "osl/mutex.hxx"
+#endif
+#ifndef _RTL_REF_HXX_
+#include "rtl/ref.hxx"
+#endif
+#ifndef _SAL_TYPES_H_
+#include "sal/types.h"
+#endif
+#ifndef _SALHELPER_SIMPLEREFERENCEOBJECT_HXX_
+#include "salhelper/simplereferenceobject.hxx"
+#endif
+
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace rtl { class OUString; }
+namespace ucb { namespace cachemap { class Object3; } }
+
+namespace ucb { namespace cachemap {
+
+class ObjectContainer3: public salhelper::SimpleReferenceObject
+{
+public:
+    ObjectContainer3();
+
+    virtual ~ObjectContainer3() SAL_THROW(());
+
+    rtl::Reference< Object3 > get(rtl::OUString const & rKey);
+
+private:
+    typedef std::map< rtl::OUString, Object3 * > Map;
+
+    Map m_aMap;
+    osl::Mutex m_aMutex;
+
+    void releaseElement(Object3 * pElement) SAL_THROW(());
+
+    friend class Object3; // to access Map, releaseElement()
+};
+
+class Object3
+{
+public:
+    inline void acquire() SAL_THROW(())
+    { osl_incrementInterlockedCount(&m_nRefCount); }
+
+    void release() SAL_THROW(());
+
+private:
+    rtl::Reference< ObjectContainer3 > m_xContainer;
+    ObjectContainer3::Map::iterator m_aContainerIt;
+    oslInterlockedCount m_nRefCount;
+
+    inline Object3(rtl::Reference< ObjectContainer3 > const & rContainer);
+
+    inline ~Object3() SAL_THROW(());
+
+    Object3(Object3 &); // not implemented
+    void operator =(Object3); // not implemented
+
+    friend class ObjectContainer3;
+        // to access m_aContainerIt, m_nRefCount, Object3(), ~Object3()
+#if defined WNT
+    friend struct std::auto_ptr< Object3 >; // to access ~Object3()
+#else // WNT
+    friend class std::auto_ptr< Object3 >; // to access ~Object3()
+#endif // WNT
+};
+
+} }
+
+#endif // INCLUDED_UCB_CACHEMAPOBJECT3_HXX
+
+
+
+

Also, the implementation file + cachemapobject3.cxx + has a strong resemblence to the implementation file from the first + solution (again, differences in green):

+
+
+
+
#ifndef INCLUDED_UCB_CACHEMAPOBJECT3_HXX
+#include "cachemapobject3.hxx"
+#endif
+
+#ifndef _OSL_DIAGNOSE_H_
+#include "osl/diagnose.h"
+#endif
+#ifndef _OSL_INTERLOCK_H_
+#include "osl/interlck.h"
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include "osl/mutex.hxx"
+#endif
+#ifndef _RTL_REF_HXX_
+#include "rtl/ref.hxx"
+#endif
+#ifndef _RTL_USTRING_HXX_
+#include "rtl/ustring.hxx"
+#endif
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+using ucb::cachemap::Object3;
+using ucb::cachemap::ObjectContainer3;
+
+inline
+Object3::Object3(rtl::Reference< ObjectContainer3 > const & rContainer):
+    m_xContainer(rContainer),
+    m_nRefCount(0)
+{
+    OSL_ASSERT(m_xContainer.is());
+}
+
+inline Object3::~Object3() SAL_THROW(())
+{}
+
+void Object3::release() SAL_THROW(())
+{
+    if (osl_decrementInterlockedCount(&m_nRefCount) == 0)
+    {
+        m_xContainer->releaseElement(this);
+        delete this;
+    }
+}
+
+void ObjectContainer3::releaseElement(Object3 * pElement) SAL_THROW(())
+{
+    OSL_ASSERT(pElement);
+    osl::MutexGuard aGuard(m_aMutex);
+    if (pElement->m_aContainerIt != m_aMap.end())
+        m_aMap.erase(pElement->m_aContainerIt);
+}
+
+ObjectContainer3::ObjectContainer3()
+{}
+
+ObjectContainer3::~ObjectContainer3() SAL_THROW(())
+{}
+
+rtl::Reference< Object3 > ObjectContainer3::get(rtl::OUString const & rKey)
+{
+    osl::MutexGuard aGuard(m_aMutex);
+    Map::iterator aIt(m_aMap.find(rKey));
+    if (aIt == m_aMap.end())
+    {
+        std::auto_ptr< Object3 > xElement(new Object3(this));
+        aIt = m_aMap.insert(Map::value_type(rKey, xElement.get())).first;
+        aIt->second->m_aContainerIt = aIt;
+        xElement.release();
+        return aIt->second;
+    }
+    else if (osl_incrementInterlockedCount(&aIt->second->m_nRefCount) > 1)
+    {
+        rtl::Reference< Object3 > xElement(aIt->second);
+        osl_decrementInterlockedCount(&aIt->second->m_nRefCount);
+        return xElement;
+    }
+    else
+    {
+        osl_decrementInterlockedCount(&aIt->second->m_nRefCount);
+        aIt->second->m_aContainerIt = m_aMap.end();
+        aIt->second = new Object3(this);
+        aIt->second->m_aContainerIt = aIt;
+        return aIt->second;
+    }
+}
+
+
+
+

This implementation does not need to lock a mutex in every call to + Object3::release(). + Only if the refcount drops to zero is the mutex of the + ObjectContainer3 + locked and the object removed from the map. It is possible that an + ObjectContainer3::get() + gets in the way between dropping the refcount to zero and locking the + mutex. But the get() + method notices that (it goes through a cycle of incrementing and + decrementing the refcount itself, and if the refcount is not larger + than 1, the object is about to be deleted) and leaves alone the + to-be-deleted object and inserts into the map a fresh instance + instead.

+

Note that this implementation also does not have the drawback of + an ever-growing map, because each object is removed from the map as + soon as its refcount drops to zero.

+


+
+

+ Performance Measurements

+
+

A simple test file + (cachemaptest.cxx) + makes 200000 get() + requests, half of which find objects already present in the map. The + refcount of each requested object is incremented and decremented 50 + times in a row. Only 100 different identifiers are used for the + objects, so that the second solution does not suffer from the problem + of an ever-growing map. The measurements for two of our production + platforms (Solaris Sparc with Forte compiler and Windows x86 with + Microsoft compiler) are as follows (all times in miliseconds; because + of different machines used, only comparisions within each column are + meaningful):

+ + + + + + + + + + + + + + + + + + + + + + + + +
+


+

+
+

unxsols3.pro

+
+

wntmsci7.pro

+
+

Solution 1

+
+

9137

+
+

3846

+
+

Solution 2

+
+

8634

+
+

5598

+
+

Solution 3

+
+

3166

+
+

2704

+
+


+
+
+
+

Author: Stephan + Bergmann ($Date: 2001/06/14 14:49:37 $)
Copyright 2001 + OpenOffice.org Foundation. All Rights Reserved.
+

+
+
+
+
+ + Propchange: incubator/ooo/ooo-site/trunk/content/ucb/docs/cachemap.html ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/ooo/ooo-site/trunk/content/ucb/docs/errorhandling.html URL: http://svn.apache.org/viewvc/incubator/ooo/ooo-site/trunk/content/ucb/docs/errorhandling.html?rev=1206884&view=auto ============================================================================== --- incubator/ooo/ooo-site/trunk/content/ucb/docs/errorhandling.html (added) +++ incubator/ooo/ooo-site/trunk/content/ucb/docs/errorhandling.html Sun Nov 27 22:36:56 2011 @@ -0,0 +1,516 @@ + + + + + + + + + + + + +  + + + + +
+
+

+OpenOffice.org +UCB Commands - Error Handling Concept & Specification

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+General Error Handling Concept

+
Every UCB Content supports a set of commands. A UCB client +calls +css::ucb::XCommandProcessor::execute(...) if it wants the +content to execute a command. Errors occurring while executing a command +are managed using exceptions. +

Any exceptions can be used by a UCP implementation to interact with +a UCB client. For example, if a file should be written to disk (using UCB's +insert +command) and another file with the same name already exists, an exception +could be used to query the user whether he wants to overwrite the existing +file. If the user confirms, the file will be overwritten, if he rejects, +the insert command will be aborted. +

Exceptions generally should be handed over to an +css::task::XInteractionHandler +implementation, which generally was obtained from a command's environment +(css::ucb::XCommandEnvironment. If no Interaction handler is available +or if the Interaction Handler did not handle the request, the exception +must be thrown directly. This will always aborts the command. Using an +Interaction Handler has the advantage, that additional data can be supplied +to the command implementation without the need to abort and to retry the +command (after supplying the missing data). The data supplied to the requesting +code either may lead in continuing or aborting the command. +

A css::task::XInteractionHandler handles css::task::XInteractionRequests. +An Interaction Request contains an exception (the request) and a number +of css::task::XInteractionContinuations, which define the responses +that can be used to "answer" the request. There are some standard continuations +defined, which are namely +css::task::XInteractionAbort, css::task::XInteractionRetry, +css::task::XInteractionApprove +and +css::task::XInteractionDisapprove. For example, for a GUI Interaction +Handler these continuations could be assigned to buttons in a message box +(Approve equals "Yes" button, Disapprove equals "No" button, ...). The +Interaction Handler code does some work dependent on the kind of request +and the possible continuations (like displaying a login dialog and supplying +the data entered to the authentication request), +selects one of +the continuations provided and returns. The code that called the Interaction +Handler now can act according to the kind of continuation that was previously +selected. Not every Interaction Handler implementation must be able to +handle all requests. If an Interaction Handler cannot handle a request, +no continuation will be selected after the call to XInteractionHandler::handle( +... ). In this case the code that called the Interaction Handler must act +as if no handler were available and throw the exception that was previously +passed to the Interaction Handler. +

For exceptions located in the module com::sun::star::ucb, the +member Context (which is introduced by the base class of all UNO +exceptions – css::uno::Exception) should be filled with the command processor +(css::ucb::XCommandProcessor implementation) that executes the command. +

The following pseudo code illustrates how to proceed with an error: +
  + + + + +
+
// Create the exception to propagate...
+xxxxException aEx( ... );
+
+xxxxContinuation aCont;
+ +
// Obtain Interaction Handler
+uno::Reference< task::XInteractionHandler > xIH = ...
+
+bool bSelection = false;
+if ( xIH.is() )
+{
+    // IH available. Create Interaction Request.
+    xxxxRequest aReq = ...( aEx, ... );
+
+    // Pass over the request to the IH.
+    xIH.handle( aReq );
+
+    // Get selected continuation
+    aCont = aReq.getSelection();
+
+    // Was IH able to handle the request?
+    if ( aCont.is() )
+        bSelection = true;
+}
+
+// Act according to bSelection and aCont
+bool bSuccess = ...;
+
+if ( !bSuccess )
+{
+    if ( !bSelection )
+    {
+        // No IH or IH did not handle exception.
+        throw aEx;
+    }
+ +
    // IH handled the selection.
+    throw ucb::CommandFailedException( aEx );
+}
+
+// Continue...
+
+

+

+Exception Specifications for the Well-Known +UCB Commands

+
There is a number of predefined exceptions for the well-known +UCB Commands. Every new command introduced by a UCB Content implementation +can also introduce new exceptions. If these exceptions are interactive, +there is the problem, that any existing Interaction Handlers most possibly +won't be able to handle them. Thus reusing existing interactive exceptions +should be the way of choice whenever possible. +

The implementation of a command should use the predefined exception +for the appropriate error condition whenever possible. But It can use any +other exceptions, for example, if there is no matching predefined exception +for a concrete error condition. +
  +

+All commands

+The following exceptions can be thrown by all UCB Commands: +
  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExceptionDescription
css::ucb::UnsupportedCommandExceptionThrown if the requested command is not supported by a content.
css::lang::IllegalArgumentExceptionThrown if the data type of the given command's argument does not match +the command's definition.
css::ucb::InteractiveAugmentedIOExceptionUsed to indicate IO errors (exception contains an css::ucb::IOErrorCode)
css::ucb:InteractiveNetworkResolveNameException
css::ucb:InteractiveNetworkConnectException
css::ucb:InteractiveNetworkReadException
css::ucb:InteractiveNetworkWriteException
css::ucb:InteractiveNetworkGeneralException
css::ucb:InteractiveNetworkOffLineException
css::ucb::AuthenticationRequestUsed to collect missing authentication information. An implementation +of css::ucb::XInteractionSupplyAuthentication (that will be filled by the +Interaction Handler with the missing data) should be supplied with the +continuations.
+ +

Exceptions, that are never passed to an Interaction Handler: +
  + + + + + + + + + + + + + + + + + + + + + + + + +
ExceptionDescription
css::ucb::CommandFailedExceptionThrown if the execution of the command failed (but only after communication +with an Interaction Handler). This exception contains the "original" exception +that was passed to the Interaction Handler.
css::ucb::CommandAbortedExceptionThrown if the execution of the command was ended by calling css::ucb::XCommandProcessor::abort().
css::ucb::DuplicateCommandIdentifierExceptionThrown if two threads passed the same (non-zero) command identifier +to css::ucb::XCommandProcessor::execute().
+ +

+getCommandInfo

+No special exceptions defined. +

+getPropertySetInfo

+No special exceptions defined. +

+getPropertyValues

+No special exceptions defined. Note that most error handling (except command +name and parameter checking ) is done using the css::sdbc::XRow implementation +returned by this command. +

+setPropertyValues

+Note that setPropertyValues does not throw an exception in the case +that one or more of the requested property values cannot be set! The +implementation should set as much property values as possible. This command +returns a sequence< any > which has exactly the same number of +elements like the number of properties to set. Every sequence element contains +the status for a property. The first sequence elements corresponds to the +first element in the sequence of +css::beans::PropertyValues passed +as command argument and so on. The exceptions will never be passed to an +Interaction Handler by the implementation of the setPropertyValues command. +

An any containing: +

    +
  • +No value indicates, that the property value was set successfully.
  • + +
  • +css::beans::UnknownPropertyException indicates, that the property +is not known to the content implementation.
  • + +
  • +css::beans::IllegalTypeException indicates, that the data type of +the property value is not acceptable.
  • + +
  • +css::lang::IllegalAccessException indicates, that the property is +constant (css::beans::PropertyAttribute::READONLY is set).
  • + +
  • +css::lang::IllegalArgumentException indicates, that the property +value is not acceptable. For instance, setting an empty title may be illegal.
  • + +
  • +Any other execption derived from css::uno::Exception indicates, +that the value was not set successfully. For example, this can be a css::ucb::InteractiveAugmentedIOException +transporting the error code css::ucb::IOErrorCode::ACCESS_DENIED.
  • +
+If the value to set is equal to the current value, no exception must be +added to the returned sequence +

+open

+ + + + + + + + + + + + + + + + + + + +
ExceptionDescription
css::ucb::UnsupportedOpenModeExceptionUsed to indicate that the requested css::ucb::OpenMode is not supported.
css::ucb::UnsupportedDataSinkExceptionUsed to indicate that the type of data sink supplied is not supported.
+ +

+delete

+No special exceptions defined. +

+insert

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExceptionDescription
css::ucb::MissingPropertiesExceptionUsed if one or more properties were not set that are needed to make +the content persistent (like the name for a newly created file). The exception +transports a list of property names.
css::ucb::MissingInputStreamExceptionUsed if no css::io::XInputStream was given with the command argument, +but is required.
css::ucb::UnsupportedNameClashExceptionUsed if the parameter ReplaceExisting of the command's argument +was set to false and the implementation is unable to determine whether +there are existing data. The member NameClash of the exception must +be set to NameClash::ERROR. +
Must also be thrown in case the requested nameclash is just not yet +implemented (a missing feature, so to speak).
css::ucb::NameClashExceptionUsed if the parameter ReplaceExisting of the command's argument +was set to false and there exists a resource with a clashing name +in the target folder of the operation.
+ +

+transfer

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExceptionDescription
css::ucb::InteractiveBadTransferURLExceptionUsed if the Source URL given with the command's argument is not supported +by the command's implementation. For example, an FTP-UCP needs not be able +to handle other URLs then FTP-URLs.
css::ucb::UnsupportedNameClashExceptionUsed if the nameclash directive specified in parameter NameClash +of command's argument is not supported. For example, if the NameClash +was set to NameClash::ERROR, to NameClash::RENAME or to NameClash::ASK, +the implementation must be able determine whether there are existing data.  +
This exception must also used if NameClash::RENAME was specified +and the implementation is unable to create a valid new name after a suitable +number of tries. +
It must also be thrown in case the requested nameclash is just not yet +implemented (a missing feature, so to speak).
css::ucb::NameClashExceptionUsed if the parameter NameClash of the command's argument was +set to NameClash::ERROR and there exists a resource with a clashing +name in the target folder of the operation.
css::ucb::NameClashResolveRequestIf the parameter NameClash of the command's argument was set +to NameClashh::ASK this interaction request can be used to obtain +a new name. Implementations of css::ucb::XInteractionSupplyName and css::ucb::XInteractionReplaceExistingData +(that will be filled by the Interaction Handler with the missing data) +should be supplied with the continuations.
+ +

+globalTransfer

+ + + + + + + + + + + + + + + + + + + + + + + + +
ExceptionDescription
css::ucb::UnsupportedNameClashExceptionUsed if the nameclash directive specified in parameter NameClash +of command's argument is not supported. For example, if the NameClash +was set to NameClash::ERROR, to NameClash::RENAME or to NameClash::ASK, +the implementation must be able determine whether there are existing data.  +
This exception must also used if NameClash::RENAME was specified +and the implementation is unable to create a valid new name after a suitable +number of tries.
css::ucb::NameClashExceptionUsed if the parameter NameClash of the command's argument was +set to NameClash::ERROR and there exists a resource with a clashing +name in the target folder of the operation.
css::ucb::NameClashResolveRequestIf the parameter NameClash of the command's argument was set +to NameClashh::ASK this interaction request can be used to obtain +a new name. Implementations of css::ucb::XInteractionSupplyName and css::ucb::XInteractionReplaceExistingData +(that will be filled by the Interaction Handler with the missing data) +should be supplied with the continuations.
+ +

+search

+Not yet specified. Will be done later. (No implementations yet.) +

+update

+Not yet specified. Will be done later. (No implementations yet.) +

+synchronize

+Not yet specified. Will be done later. (No implementations yet.) +

+close

+Not yet specified. Will be done later. (No implementations yet.) +

+undelete

+Not yet specified. Will be done later. (No implementations yet.)
+
+
Author: Kai +Sommerfeld ($Date: 2007/05/26 10:33:56 $) +
Copyright 2001 OpenOffice.org Foundation. +All Rights Reserved.
+
+ +
+ + Propchange: incubator/ooo/ooo-site/trunk/content/ucb/docs/errorhandling.html ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/ooo/ooo-site/trunk/content/ucb/docs/fileurl.html URL: http://svn.apache.org/viewvc/incubator/ooo/ooo-site/trunk/content/ucb/docs/fileurl.html?rev=1206884&view=auto ============================================================================== --- incubator/ooo/ooo-site/trunk/content/ucb/docs/fileurl.html (added) +++ incubator/ooo/ooo-site/trunk/content/ucb/docs/fileurl.html Sun Nov 27 22:36:56 2011 @@ -0,0 +1,192 @@ + + + + Be Careful with file URLs + + + + + + + + +
+

OpenOffice.orgBe Careful with file URLs

+
+
+ +

Different Ways to Name Files

+ +

There are (at least) five ways to name files:

+
    +
  1. +

    The platform-specific notation, called pathnames here + (e.g., /abc/def/ghi.txt on Unix, + a:\bcd\efg\hij.txt on DOS and Windows, and + abc:def:ghi.txt on Macintosh).

    +
  2. +
  3. +

    A UNC-like notation, called UNC names here (e.g., + //./abc/def/ghi.txt or + //./a:/bcd/efg/hij.txt). The osl layer used to make + heavy use of these as a platform-independent notation, but since osl + has shifted to file URLs as the platform-independent notation (see + below), UNC names have been deprecated and became pretty much useless + (and are only mentioned here for completeness).

    +
  4. +
  5. +

    The file URLs used by the osl layer as a platform-independent + notation, called osl URLs here (e.g., + file:///abc/def/ghi.txt or + file:///a:/bcd/efg/hij.txt). Read on to learn why it is + important to explicitly label these file URLs as osl + URLs.

    +
  6. +
  7. +

    The file URLs used by the File Content Provider (FCP) within the + Universal Content Broker (UCB), called FCP URLs (e.g., + file:///home/usr123/work/abc.txt or + file:///user/work/abc.txt). Normally, osl URLs and FCP + URLs are the same (after all, the FCP uses osl to access the files). + But the FCP has a feature called mount points that allows it + to restrict access to only certain files (those that lie below a given + set of mount points in the file system hierarchy), and to give names + to these files that hide their real locations.

    + +

    For example, if you have a mount point named user at + the osl URL file:///home/usr123, the osl URL + file:///home/usr123/work/abc.txt corresponds to the FCP + URL file:///user/work/abc.txt. If you only have that + single mount point, the osl URL + file:///home/usr567/work/def.txt has no corresponding FCP + URL (and cannot be accessed via the FCP).

    +
  8. +
  9. +

    The URLs used by the UCB, called UCB URLs (e.g., + file:///a:/bcd/efg/hij.txt or + vnd.sun.star.wfs:///user/work/abc.txt). Normally, FCP + URLs and UCB URLs are the same, because the UCB hands file URLs + directly to the FCP. But there is a special content provider, the + Remote Access Content Provider (RAP), that allows to rewrite URLs + before passing them on to other content providers. This is used, for + example, in the Sun ONE Webtop (S1W), where there are typically two + file systems: a client file system accessed via normal (FCP) file URLs + (i.e., there is no rewriting RAP between the UCB and the client FCP), + and a server file system accessed via (FCP) URLs where the + file scheme has been replaced with + vnd.sun.star.wfs (i.e., there is a rewriting RAP between + the UCB and the server FCP).

    +
  10. +
+ +

The last two notations (FCP URLs and UCB URLs) are relatively unknown, +because in a plain OpenOffice installation neither mount points nor the RAP +are used, so that osl URLs, FCP URLs and UCB URLs are all identical. But when +you want to write correct code that also works in unusal deployments (or in +the S1W, which should be regarded not too unusal), you have to be well aware +of these different notations all labeled as "URLs."

+ +

Where Different Notations are Used

+ +

As mentioned before, use of UNC names is deprecated. Also, since most code +accesses the FCP not directly, but via the UCB, FCP URLs are only of interest +to hard core UCB users (who should know what they are doing, anyway). So, in +the following we can concentrate on three different notations: pathnames, osl +URLs, and UCB URLs.

+ +

Where Pathnames are Used

+ +

Pathnames are used in only a few places, because the default notation used +by osl (the lowest level of concern to us) already are osl URLs (which are a +level above pathnames). It can be argued that interfaces that use pathnames +should use osl URLs instead, and that pathnames are only of interest when +communicating with the external world (other processes, or the human +user).

+ +

One place where pathnames are used is class utl::TempFile.

+ +

Where osl URLs are Used

+ +

The osl file system functions (in osl/file.h and +osl/file.hxx) now generally use osl URLs in their interfaces.

+ +

There should be few places above osl where osl URLs instead of UCB URLs are +used (because generally all file access should be done through the UCB, and +not directly via osl). One notable exception is the handling of temporary +files (see above).

+ +

Where UCB URLs are Used

+ +

Generally, all interfaces that are designed to communicate resource names +within the OpenOffice framework should use UCB URLs, and all implemenations +that access resources by these names should do so via the UCB. Another +advantage of this is that without any extra effort not only file resources can +be accessed, but also other resources like HTTP and FTP (by using appropriate +URLs, but these URLs can be opaque to the code, only interpreted by the +UCB).

+ +

Converting between Different Notations

+ +

Sometimes it may be necessary to convert between different notations, and +the routines to do so are well available:

+
    +
  • +

    The methods osl::FileBase::getFileURLFromSystemPath() + and osl::FileBase::getSystemPathFromFileURL() (and their + plain C counterparts in osl/file.h) convert between + pathnames (called "system paths" here) and osl URLs.

    +
  • +
  • +

    The methods + utl::LocalFileHelper::ConvertSystemPathToURL() and + utl::LocalFileHelper::ConvertURLToSystemPath() convert + between pathnames (again called "system paths" here) and UCB URLs.

    + +

    Because there can be scenarios where you have multiple FCPs on + different file systems, it can be ambigious how to convert from a + pathname (that does not contain any information identifying a specific + file system) to a UCB URL. Therefore, + ConvertSystemPathToURL() requires an additional parameter + BaseURL that identifies the FCP to be used.

    +
  • +
  • +

    There are convenience methods + utl::LocalFileHelper::ConvertPhysicalNameToURL() and + utl::LocalFileHelper::ConvertURLToPhysicalName() that + choose the local FCP as BaseURL and then forward + to the above LocalFileHelper methods.

    + +

    For this to work, the UCB maintains a notion of locality + of content providers. This is an heuristic algorithm based on how the + UCB accesses individual content providers (within the same process, + via a pipe on the same machine, via a socket over a network). The net + effect is that the UCB should always choose as most local the FCP + running on the same machine as the UCB, and using these + LocalFileHelper methods will then always convert between + UCB URLs and pathnames that are valid on this machine.

    + +

    ConvertURLToPhysicalName() also makes sure to do the + conversion only if the given UCB URL corresponds to a local pathname + (and not to a pathname on a non-local file system).

    +
  • +
+ +

There is no direct way to convert between osl URLs and UCB URLs. To +convert from an osl URL to a UCB URL, use +osl::FileBase::getSystemPathFromFileURL() followed by +utl::LocalFileHelper::ConvertPhysicalNameToURL(). To convert +from a UCB URL to an osl URL, use +utl::LocalFileHelper::ConvertURLToPhysicalName() followed by +osl::FileBase::getFileURLFromSystemPath. But be aware that this +only works if the osl URL and the UCB URL shall denote files within the same +file system.

+ + + + + +
+

Author: Stephan Bergmann (Last modification $Date: 2003/12/06 22:37:31 $). Copyright 2001 OpenOffice.org Foundation. All Rights Reserved.

+
+ + Propchange: incubator/ooo/ooo-site/trunk/content/ucb/docs/fileurl.html ------------------------------------------------------------------------------ svn:eol-style = native