#1272 Use in-memory temporary files.
This commit is contained in:
parent
013771b4c1
commit
2ebacb6b0b
@ -365,8 +365,9 @@ case "$host_os" in
|
||||
CPPFLAGS="$CPPFLAGS" # mingw doesn't link pthreads if you specify -std !!
|
||||
;;
|
||||
*)
|
||||
if [ $GCC_VERSION -le 5 ]; then CPPFLAGS="$CPPFLAGS -std=c++98" # // most others use c++98
|
||||
else CPPFLAGS="$CPPFLAGS -std=gnu++98" # // but not GCC 6
|
||||
CPPFLAGS="$CPPFLAGS -std=c++98"
|
||||
if [[ ! -z "$GCC_VERSION" ]]; then
|
||||
if [[ "$GCC_VERSION" -ge 6 ]]; then CPPFLAGS="$CPPFLAGS -std=gnu++98" ; fi # // not GCC 6
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -242,20 +242,6 @@ namespace Exiv2 {
|
||||
*/
|
||||
virtual std::wstring wpath() const =0;
|
||||
#endif
|
||||
/*!
|
||||
@brief Returns a temporary data storage location. This is often
|
||||
needed to rewrite an IO source.
|
||||
|
||||
For example, data may be read from the original IO source, modified
|
||||
in some way, and then saved to the temporary instance. After the
|
||||
operation is complete, the BasicIo::transfer method can be used to
|
||||
replace the original IO source with the modified version. Subclasses
|
||||
are free to return any class that derives from BasicIo.
|
||||
|
||||
@return An instance of BasicIo on success
|
||||
@throw Error In case of failure
|
||||
*/
|
||||
virtual BasicIo::AutoPtr temporary() const = 0;
|
||||
|
||||
/*!
|
||||
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
|
||||
@ -527,16 +513,6 @@ namespace Exiv2 {
|
||||
*/
|
||||
virtual std::wstring wpath() const;
|
||||
#endif
|
||||
/*!
|
||||
@brief Returns a temporary data storage location. The actual type
|
||||
returned depends upon the size of the file represented a FileIo
|
||||
object. For small files, a MemIo is returned while for large files
|
||||
a FileIo is returned. Callers should not rely on this behavior,
|
||||
however, since it may change.
|
||||
@return An instance of BasicIo on success
|
||||
@throw Error If opening the temporary file fails
|
||||
*/
|
||||
virtual BasicIo::AutoPtr temporary() const;
|
||||
|
||||
/*!
|
||||
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
|
||||
@ -548,15 +524,6 @@ namespace Exiv2 {
|
||||
virtual void populateFakeData();
|
||||
//@}
|
||||
|
||||
/*!
|
||||
@brief Returns the path to a temporary data storage location.
|
||||
*/
|
||||
#ifdef EXV_UNICODE_PATH
|
||||
static std::wstring temporaryPath();
|
||||
#else
|
||||
static std::string temporaryPath();
|
||||
#endif
|
||||
|
||||
private:
|
||||
// NOT IMPLEMENTED
|
||||
//! Copy constructor
|
||||
@ -745,13 +712,6 @@ namespace Exiv2 {
|
||||
*/
|
||||
virtual std::wstring wpath() const;
|
||||
#endif
|
||||
/*!
|
||||
@brief Returns a temporary data storage location. Currently returns
|
||||
an empty MemIo object, but callers should not rely on this
|
||||
behavior since it may change.
|
||||
@return An instance of BasicIo
|
||||
*/
|
||||
virtual BasicIo::AutoPtr temporary() const;
|
||||
|
||||
/*!
|
||||
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
|
||||
@ -1090,13 +1050,6 @@ namespace Exiv2 {
|
||||
*/
|
||||
virtual std::wstring wpath() const;
|
||||
#endif
|
||||
/*!
|
||||
@brief Returns a temporary data storage location. Currently returns
|
||||
an empty MemIo object, but callers should not rely on this
|
||||
behavior since it may change.
|
||||
@return An instance of BasicIo
|
||||
*/
|
||||
virtual BasicIo::AutoPtr temporary() const;
|
||||
|
||||
/*!
|
||||
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
|
||||
|
||||
@ -2039,6 +2039,52 @@ namespace {
|
||||
return os.str();
|
||||
} // tm2Str
|
||||
|
||||
// use static CS/MUTEX to make temporaryPath() thread safe
|
||||
#if defined(_MSC_VER) || defined(__MINGW__)
|
||||
static CRITICAL_SECTION cs;
|
||||
#else
|
||||
/* Unix/Linux/Cygwin/MacOSX */
|
||||
#include <pthread.h>
|
||||
#if defined(__APPLE__)
|
||||
/* This is the critical section object (statically allocated). */
|
||||
static pthread_mutex_t cs = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
|
||||
#else
|
||||
static pthread_mutex_t cs = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static std::string temporaryPath()
|
||||
{
|
||||
static int count = 0 ;
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW__)
|
||||
EnterCriticalSection(&cs);
|
||||
char lpTempPathBuffer[MAX_PATH];
|
||||
GetTempPath(MAX_PATH,lpTempPathBuffer);
|
||||
std::string tmp(lpTempPathBuffer);
|
||||
tmp += "\\";
|
||||
HANDLE process=0;
|
||||
DWORD pid = ::GetProcessId(process);
|
||||
#else
|
||||
pid_t pid = ::getpid();
|
||||
pthread_mutex_lock( &cs );
|
||||
std::string tmp = "/tmp/";
|
||||
#endif
|
||||
char sCount[12];
|
||||
sprintf(sCount,"_%d",++count);
|
||||
|
||||
std::string result = tmp + Exiv2::toString(pid) + sCount ;
|
||||
if ( Exiv2::fileExists(result) ) std::remove(result.c_str());
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW__)
|
||||
LeaveCriticalSection(&cs);
|
||||
#else
|
||||
pthread_mutex_unlock( &cs );
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int metacopy(const std::string& source,
|
||||
const std::string& tgt,
|
||||
int targetType,
|
||||
@ -2072,9 +2118,9 @@ namespace {
|
||||
|
||||
// Open or create the target file
|
||||
#ifdef EXV_UNICODE_PATH
|
||||
std::string target = bStdout ? Exiv2::ws2s(Exiv2::FileIo::temporaryPath()) : tgt;
|
||||
std::string target = bStdout ? Exiv2::ws2s(temporaryPath()) : tgt;
|
||||
#else
|
||||
std::string target = bStdout ? Exiv2::FileIo::temporaryPath() : tgt;
|
||||
std::string target = bStdout ? temporaryPath() : tgt;
|
||||
#endif
|
||||
|
||||
Exiv2::Image::AutoPtr targetImage;
|
||||
|
||||
104
src/basicio.cpp
104
src/basicio.cpp
@ -566,100 +566,6 @@ namespace Exiv2 {
|
||||
}
|
||||
#endif
|
||||
|
||||
BasicIo::AutoPtr FileIo::temporary() const
|
||||
{
|
||||
BasicIo::AutoPtr basicIo;
|
||||
|
||||
Impl::StructStat buf;
|
||||
int ret = p_->stat(buf);
|
||||
#if defined WIN32 && !defined __CYGWIN__
|
||||
DWORD nlink = p_->winNumberOfLinks();
|
||||
#else
|
||||
nlink_t nlink = buf.st_nlink;
|
||||
#endif
|
||||
#ifdef EXV_UNICODE_PATH
|
||||
std::wstring tmpname;
|
||||
#else
|
||||
std::string tmpname;
|
||||
#endif
|
||||
// If file is > 1MB and doesn't have hard links then use a file, otherwise
|
||||
// use a memory buffer. I.e., files with hard links always use a memory
|
||||
// buffer, which is a workaround to ensure that the links don't get broken.
|
||||
if (ret != 0 || (buf.st_size > 1048576 && nlink == 1))
|
||||
{
|
||||
pid_t pid = ::getpid();
|
||||
std::auto_ptr<FileIo> fileIo;
|
||||
#ifdef EXV_UNICODE_PATH
|
||||
tmpname = temporaryPath() + s2ws(toString(pid));
|
||||
fileIo = std::auto_ptr<FileIo>(new FileIo(tmpname));
|
||||
#else
|
||||
tmpname = temporaryPath() + toString(pid);
|
||||
fileIo = std::auto_ptr<FileIo>(new FileIo(tmpname));
|
||||
#endif
|
||||
if (fileIo->open("w+b") != 0) {
|
||||
#ifdef EXV_UNICODE_PATH
|
||||
#if defined(_MSC_VER)
|
||||
if( !DeleteFileW( tmpname.c_str()) )
|
||||
{
|
||||
perror("Error deleting file");
|
||||
throw WError(10, ws2s(tmpname).c_str(), "w+b", strError().c_str());
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#if defined(_MSC_VER) || defined(__MINGW__)
|
||||
if( !DeleteFile( tmpname.c_str() ) )
|
||||
#else
|
||||
if( remove( tmpname.c_str() ) != 0 )
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
perror("Error deleting file");
|
||||
}
|
||||
throw Error(10, tmpname.c_str(), "w+b", strError());
|
||||
}
|
||||
fileIo->p_->copyXattrFrom(*this);
|
||||
basicIo = fileIo;
|
||||
} else {
|
||||
basicIo.reset(new MemIo);
|
||||
}
|
||||
|
||||
return basicIo;
|
||||
}
|
||||
|
||||
static std::string tempPath()
|
||||
{
|
||||
static int count = 0 ;
|
||||
char sCount[12];
|
||||
sprintf(sCount,"_%d",count++);
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW__)
|
||||
char lpTempPathBuffer[MAX_PATH];
|
||||
GetTempPath(MAX_PATH,lpTempPathBuffer);
|
||||
std::string tmp(lpTempPathBuffer);
|
||||
tmp += "\\";
|
||||
#else
|
||||
std::string tmp = "/tmp/";
|
||||
#endif
|
||||
|
||||
pid_t pid = ::getpid();
|
||||
std::string result = tmp + toString(pid) + sCount ;
|
||||
if ( Exiv2::fileExists(result) ) std::remove(result.c_str());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef EXV_UNICODE_PATH
|
||||
std::wstring FileIo::temporaryPath()
|
||||
{
|
||||
return s2ws(tempPath());
|
||||
}
|
||||
#else
|
||||
std::string FileIo::temporaryPath()
|
||||
{
|
||||
return tempPath();
|
||||
}
|
||||
#endif
|
||||
|
||||
long FileIo::write(const byte* data, long wcount)
|
||||
{
|
||||
assert(p_->fp_ != 0);
|
||||
@ -1218,11 +1124,6 @@ namespace Exiv2 {
|
||||
delete p_;
|
||||
}
|
||||
|
||||
BasicIo::AutoPtr MemIo::temporary() const
|
||||
{
|
||||
return BasicIo::AutoPtr(new MemIo);
|
||||
}
|
||||
|
||||
long MemIo::write(const byte* data, long wcount)
|
||||
{
|
||||
p_->reserve(wcount);
|
||||
@ -1991,11 +1892,6 @@ namespace Exiv2 {
|
||||
}
|
||||
#endif
|
||||
|
||||
BasicIo::AutoPtr RemoteIo::temporary() const
|
||||
{
|
||||
return BasicIo::AutoPtr(new MemIo);
|
||||
}
|
||||
|
||||
void RemoteIo::populateFakeData()
|
||||
{
|
||||
assert(p_->isMalloced_);
|
||||
|
||||
@ -169,7 +169,7 @@ namespace Exiv2 {
|
||||
CrwParser::encode(blob, buf.pData_, buf.size_, this);
|
||||
|
||||
// Write new buffer to file
|
||||
BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
|
||||
MemIo::AutoPtr tempIo(new MemIo);
|
||||
assert(tempIo.get() != 0);
|
||||
tempIo->write((blob.size() > 0 ? &blob[0] : 0), static_cast<long>(blob.size()));
|
||||
io_->close();
|
||||
|
||||
@ -809,7 +809,7 @@ namespace {
|
||||
}
|
||||
|
||||
// create temporary output file
|
||||
BasicIo::AutoPtr tempIo(io.temporary());
|
||||
BasicIo::AutoPtr tempIo(new MemIo);
|
||||
assert (tempIo.get() != 0);
|
||||
if (!tempIo->isopen()) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
|
||||
@ -589,7 +589,7 @@ namespace Exiv2
|
||||
throw Error(9, io_->path(), strError());
|
||||
}
|
||||
IoCloser closer(*io_);
|
||||
BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
|
||||
BasicIo::AutoPtr tempIo(new MemIo);
|
||||
assert (tempIo.get() != 0);
|
||||
|
||||
doWriteMetadata(*tempIo); // may throw
|
||||
|
||||
@ -834,7 +834,7 @@ namespace Exiv2 {
|
||||
// exiv2 -pS E.jpg
|
||||
|
||||
// binary copy io_ to a temporary file
|
||||
BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
|
||||
BasicIo::AutoPtr tempIo(new MemIo);
|
||||
|
||||
assert (tempIo.get() != 0);
|
||||
for ( uint64_t i = 0 ; i < (count/2)+1 ; i++ ) {
|
||||
@ -866,7 +866,7 @@ namespace Exiv2 {
|
||||
throw Error(9, io_->path(), strError());
|
||||
}
|
||||
IoCloser closer(*io_);
|
||||
BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
|
||||
BasicIo::AutoPtr tempIo(new MemIo);
|
||||
assert (tempIo.get() != 0);
|
||||
|
||||
doWriteMetadata(*tempIo); // may throw
|
||||
|
||||
@ -163,7 +163,7 @@ namespace Exiv2 {
|
||||
throw Error(9, io_->path(), strError());
|
||||
}
|
||||
IoCloser closer(*io_);
|
||||
BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
|
||||
BasicIo::AutoPtr tempIo(new MemIo);
|
||||
assert (tempIo.get() != 0);
|
||||
|
||||
doWriteMetadata(*tempIo); // may throw
|
||||
|
||||
@ -494,7 +494,7 @@ namespace Exiv2 {
|
||||
throw Error(9, io_->path(), strError());
|
||||
}
|
||||
IoCloser closer(*io_);
|
||||
BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
|
||||
BasicIo::AutoPtr tempIo(new MemIo);
|
||||
assert (tempIo.get() != 0);
|
||||
|
||||
doWriteMetadata(*tempIo); // may throw
|
||||
|
||||
@ -348,7 +348,7 @@ namespace Exiv2 {
|
||||
throw Error(9, io_->path(), strError());
|
||||
}
|
||||
IoCloser closer(*io_);
|
||||
BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
|
||||
BasicIo::AutoPtr tempIo(new MemIo);
|
||||
assert (tempIo.get() != 0);
|
||||
|
||||
doWriteMetadata(*tempIo); // may throw
|
||||
|
||||
@ -1968,7 +1968,7 @@ namespace Exiv2 {
|
||||
encoder.add(createdTree.get(), parsedTree.get(), root);
|
||||
// Write binary representation from the composite tree
|
||||
DataBuf header = pHeader->write();
|
||||
BasicIo::AutoPtr tempIo(io.temporary()); // may throw
|
||||
BasicIo::AutoPtr tempIo(new MemIo);
|
||||
assert(tempIo.get() != 0);
|
||||
IoWrapper ioWrapper(*tempIo, header.pData_, header.size_, pOffsetWriter);
|
||||
uint32_t imageIdx(uint32_t(-1));
|
||||
|
||||
@ -120,7 +120,7 @@ namespace Exiv2 {
|
||||
throw Error(9, io_->path(), strError());
|
||||
}
|
||||
IoCloser closer(*io_);
|
||||
BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
|
||||
BasicIo::AutoPtr tempIo(new MemIo);
|
||||
assert (tempIo.get() != 0);
|
||||
|
||||
doWriteMetadata(*tempIo); // may throw
|
||||
|
||||
@ -159,7 +159,7 @@ namespace Exiv2 {
|
||||
if (xmpPacket_.substr(0, 5) != "<?xml") {
|
||||
xmpPacket_ = xmlHeader + xmpPacket_ + xmlFooter;
|
||||
}
|
||||
BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
|
||||
BasicIo::AutoPtr tempIo(new MemIo);
|
||||
assert(tempIo.get() != 0);
|
||||
// Write XMP packet
|
||||
if ( tempIo->write(reinterpret_cast<const byte*>(xmpPacket_.data()),
|
||||
|
||||
@ -76,7 +76,6 @@ TESTS = addmoddel.sh \
|
||||
modify-test.sh \
|
||||
path-test.sh \
|
||||
preview-test.sh \
|
||||
stdin-test.sh \
|
||||
stringto-test.sh \
|
||||
tiff-test.sh \
|
||||
webp-test.sh \
|
||||
|
||||
Loading…
Reference in New Issue
Block a user