[Libreoffice-commits] core.git: linguistic/source

Michael Meeks michael.meeks at suse.com
Wed Feb 20 08:22:41 PST 2013


 linguistic/source/dicimp.cxx |   74 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 59 insertions(+), 15 deletions(-)

New commits:
commit 28300209604ee1bb8e5050322b29e95a07f679d8
Author: Michael Meeks <michael.meeks at suse.com>
Date:   Wed Feb 20 16:19:30 2013 +0000

    fdo#42122 - truncate files that shrink to avoid dictionary corruption.
    
    fixes a nasty apparently introduced by 7e01bc8d28ffefd4539a5eae2587e1f7da0999e7
    
    Change-Id: I8227cb49a5dfa885d4dc38ce353a356bb5ed8a69

diff --git a/linguistic/source/dicimp.cxx b/linguistic/source/dicimp.cxx
index 2216a8c..9dc63e3 100644
--- a/linguistic/source/dicimp.cxx
+++ b/linguistic/source/dicimp.cxx
@@ -386,33 +386,75 @@ static rtl::OString formatForSave(const uno::Reference< XDictionaryEntry > &xEnt
    return aStr.makeStringAndClear();
 }
 
+struct TmpDictionary
+{
+    OUString maURL, maTmpURL;
+    uno::Reference< ucb::XSimpleFileAccess3 > mxAccess;
+
+    void cleanTmpFile()
+    {
+        try
+        {
+            mxAccess->kill(maTmpURL);
+        }
+        catch (const uno::Exception &) { }
+    }
+    TmpDictionary(const OUString &rURL)
+        : maURL( rURL )
+    {
+        maTmpURL = maURL + ".tmp";
+    }
+    ~TmpDictionary()
+    {
+        cleanTmpFile();
+    }
+
+    uno::Reference< io::XStream > openTmpFile()
+    {
+        uno::Reference< io::XStream > xStream;
+
+        try
+        {
+            mxAccess = ucb::SimpleFileAccess::create(
+                        comphelper::getProcessComponentContext());
+            xStream = mxAccess->openFileReadWrite(maTmpURL);
+        } catch (const uno::Exception &) { }
+
+        return xStream;
+    }
+
+    bool renameTmpToURL()
+    {
+        try
+        {
+            mxAccess->move(maTmpURL, maURL);
+        }
+        catch (const uno::Exception &)
+        {
+            DBG_ASSERT( 0, "failed to overwrite dict" );
+            return static_cast< sal_uLong >(-1);
+        }
+        return 0;
+    }
+};
 
 sal_uLong DictionaryNeo::saveEntries(const OUString &rURL)
 {
-    MutexGuard  aGuard( GetLinguMutex() );
+    MutexGuard aGuard( GetLinguMutex() );
 
     if (rURL.isEmpty())
         return 0;
     DBG_ASSERT(!INetURLObject( rURL ).HasError(), "lng : invalid URL");
 
-    uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
+    // lifecycle manage the .tmp file
+    TmpDictionary aTmpDictionary(rURL);
+    uno::Reference< io::XStream > xStream = aTmpDictionary.openTmpFile();
 
-    // get XOutputStream stream
-    uno::Reference< io::XStream > xStream;
-    try
-    {
-        uno::Reference< ucb::XSimpleFileAccess3 > xAccess( ucb::SimpleFileAccess::create(xContext) );
-        xStream = xAccess->openFileReadWrite( rURL );
-    }
-    catch (const uno::Exception &)
-    {
-        DBG_ASSERT( 0, "failed to get input stream" );
-    }
     if (!xStream.is())
         return static_cast< sal_uLong >(-1);
 
-    SvStreamPtr pStream = SvStreamPtr( utl::UcbStreamHelper::CreateStream( xStream ) );
     sal_uLong nErr = sal::static_int_cast< sal_uLong >(-1);
+    SvStreamPtr pStream = SvStreamPtr( utl::UcbStreamHelper::CreateStream( xStream ) );
 
     //
     // Always write as the latest version, i.e. DIC_VERSION_7
@@ -449,9 +491,11 @@ sal_uLong DictionaryNeo::saveEntries(const OUString &rURL)
         rtl::OString aOutStr = formatForSave(pEntry[i], eEnc);
         pStream->WriteLine (aOutStr);
         if (0 != (nErr = pStream->GetError()))
-            return nErr;
+            break;
     }
 
+    nErr = aTmpDictionary.renameTmpToURL();
+
     //If we are migrating from an older version, then on first successful
     //write, we're now converted to the latest version, i.e. DIC_VERSION_7
     nDicVersion = DIC_VERSION_7;


More information about the Libreoffice-commits mailing list