Resolves: tdf#67555 writeFile honors ntfs symlinks as it turns out
and correctly truncates the file without replacing it by a delete + recreate. So we can drop the custom temp directory+move code of fdo#42122 - truncate files that shrink to avoid dictionary corruption This reverts commit2830020960
. and so don't need fdo#66420: fix user dictionaries on Windows This reverts commitd68de51956
. Change-Id: I7f2010f4113f78cd0667632253b56055d189cbff
This commit is contained in:
@@ -36,6 +36,7 @@
|
|||||||
#include <com/sun/star/linguistic2/DictionaryType.hpp>
|
#include <com/sun/star/linguistic2/DictionaryType.hpp>
|
||||||
#include <com/sun/star/linguistic2/DictionaryEventFlags.hpp>
|
#include <com/sun/star/linguistic2/DictionaryEventFlags.hpp>
|
||||||
#include <com/sun/star/registry/XRegistryKey.hpp>
|
#include <com/sun/star/registry/XRegistryKey.hpp>
|
||||||
|
#include <com/sun/star/io/TempFile.hpp>
|
||||||
#include <com/sun/star/io/XInputStream.hpp>
|
#include <com/sun/star/io/XInputStream.hpp>
|
||||||
#include <com/sun/star/io/XOutputStream.hpp>
|
#include <com/sun/star/io/XOutputStream.hpp>
|
||||||
|
|
||||||
@@ -368,61 +369,6 @@ static OString formatForSave(const uno::Reference< XDictionaryEntry > &xEntry,
|
|||||||
return aStr.makeStringAndClear();
|
return aStr.makeStringAndClear();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TmpDictionary
|
|
||||||
{
|
|
||||||
OUString maURL, maTmpURL;
|
|
||||||
uno::Reference< ucb::XSimpleFileAccess3 > mxAccess;
|
|
||||||
|
|
||||||
void cleanTmpFile()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (mxAccess.is())
|
|
||||||
{
|
|
||||||
mxAccess->kill(maTmpURL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (const uno::Exception &) { }
|
|
||||||
}
|
|
||||||
explicit 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
sal_uLong renameTmpToURL()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mxAccess->move(maTmpURL, maURL);
|
|
||||||
}
|
|
||||||
catch (const uno::Exception &)
|
|
||||||
{
|
|
||||||
SAL_WARN( "linguistic", "failed to overwrite dict" );
|
|
||||||
return static_cast< sal_uLong >(-1);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
sal_uLong DictionaryNeo::saveEntries(const OUString &rURL)
|
sal_uLong DictionaryNeo::saveEntries(const OUString &rURL)
|
||||||
{
|
{
|
||||||
MutexGuard aGuard( GetLinguMutex() );
|
MutexGuard aGuard( GetLinguMutex() );
|
||||||
@@ -431,16 +377,23 @@ sal_uLong DictionaryNeo::saveEntries(const OUString &rURL)
|
|||||||
return 0;
|
return 0;
|
||||||
DBG_ASSERT(!INetURLObject( rURL ).HasError(), "lng : invalid URL");
|
DBG_ASSERT(!INetURLObject( rURL ).HasError(), "lng : invalid URL");
|
||||||
|
|
||||||
// lifecycle manage the .tmp file
|
uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
|
||||||
TmpDictionary aTmpDictionary(rURL);
|
|
||||||
uno::Reference< io::XStream > xStream = aTmpDictionary.openTmpFile();
|
|
||||||
|
|
||||||
|
// get XOutputStream stream
|
||||||
|
uno::Reference<io::XStream> xStream;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
xStream = io::TempFile::create(xContext);
|
||||||
|
}
|
||||||
|
catch (const uno::Exception &)
|
||||||
|
{
|
||||||
|
DBG_ASSERT( 0, "failed to get input stream" );
|
||||||
|
}
|
||||||
if (!xStream.is())
|
if (!xStream.is())
|
||||||
return static_cast< sal_uLong >(-1);
|
return static_cast< sal_uLong >(-1);
|
||||||
|
|
||||||
SvStreamPtr pStream = SvStreamPtr( utl::UcbStreamHelper::CreateStream( xStream ) );
|
SvStreamPtr pStream = SvStreamPtr( utl::UcbStreamHelper::CreateStream( xStream ) );
|
||||||
|
|
||||||
|
|
||||||
// Always write as the latest version, i.e. DIC_VERSION_7
|
// Always write as the latest version, i.e. DIC_VERSION_7
|
||||||
|
|
||||||
rtl_TextEncoding eEnc = RTL_TEXTENCODING_UTF8;
|
rtl_TextEncoding eEnc = RTL_TEXTENCODING_UTF8;
|
||||||
@@ -475,16 +428,26 @@ sal_uLong DictionaryNeo::saveEntries(const OUString &rURL)
|
|||||||
OString aOutStr = formatForSave(aEntrie, eEnc);
|
OString aOutStr = formatForSave(aEntrie, eEnc);
|
||||||
pStream->WriteLine (aOutStr);
|
pStream->WriteLine (aOutStr);
|
||||||
if (0 != (nErr = pStream->GetError()))
|
if (0 != (nErr = pStream->GetError()))
|
||||||
break;
|
return nErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pStream.reset(); // fdo#66420 close streams so Win32 can move the file
|
try
|
||||||
xStream.clear();
|
{
|
||||||
nErr = aTmpDictionary.renameTmpToURL();
|
pStream.reset();
|
||||||
|
uno::Reference< ucb::XSimpleFileAccess3 > xAccess(ucb::SimpleFileAccess::create(xContext));
|
||||||
//If we are migrating from an older version, then on first successful
|
Reference<io::XInputStream> xInputStream(xStream, UNO_QUERY_THROW);
|
||||||
//write, we're now converted to the latest version, i.e. DIC_VERSION_7
|
uno::Reference<io::XSeekable> xSeek(xInputStream, UNO_QUERY_THROW);
|
||||||
nDicVersion = DIC_VERSION_7;
|
xSeek->seek(0);
|
||||||
|
xAccess->writeFile(rURL, xInputStream);
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
catch (const uno::Exception &)
|
||||||
|
{
|
||||||
|
DBG_ASSERT( 0, "failed to write stream" );
|
||||||
|
return static_cast< sal_uLong >(-1);
|
||||||
|
}
|
||||||
|
|
||||||
return nErr;
|
return nErr;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user