commit fa5251f31ad01329ef6106c4799841a2ec76981c
parent 7f39818f348f1fb9ab4ce0a20e690c42bf0b1422
Author: Christian Grothoff <christian@grothoff.org>
Date: Sat, 17 Sep 2005 22:23:13 +0000
sync with Huggel
Diffstat:
2 files changed, 48 insertions(+), 76 deletions(-)
diff --git a/src/plugins/exiv2/basicio.cpp b/src/plugins/exiv2/basicio.cpp
@@ -336,29 +336,19 @@ namespace Exiv2 {
}
MemIo::MemIo(const byte* data, long size)
- {
- // If copying data is too slow it might be worth
- // creating a readonly MemIo variant
- idx_ = 0;
- data_ = (byte *) malloc(size);
- if (data_)
- {
- memcpy(data_, data, size);
- size_ = size;
- isMalloced = true;
- }
- else
- {
- size = 0;
- isMalloced = false;
- }
- }
+ : data_(const_cast<byte*>(data)),
+ idx_(0),
+ size_(size),
+ sizeAlloced_(0),
+ isMalloced_(false)
+ {
+ }
void MemIo::wrap(const byte *data, long size)
{
data_ = (byte *) data;
size_ = size;
- isMalloced = false;
+ isMalloced_ = false;
}
BasicIo::AutoPtr MemIo::temporary() const
@@ -368,21 +358,30 @@ namespace Exiv2 {
void MemIo::checkSize(long wcount)
{
- ByteVector::size_type need = wcount + idx_;
+ long need = wcount + idx_;
if (need > size_) {
- if (size_ > 0)
- data_ = (byte *) realloc(data_, need);
- else
- data_ = (byte *) malloc(need);
- }
- }
-
- long MemIo::write(const byte* data, long wcount)
- {
- checkSize(wcount);
- memcpy(&data_[idx_], data, wcount);
- idx_ += wcount;
- return wcount;
+ if (need > sizeAlloced_) {
+ // Allocate in blocks of 32kB
+ long want = 32768 * (1 + need / 32768);
+ if (size_ > 0) {
+ if (!isMalloced_) {
+ // "copy-on-expand"
+ byte* data = (byte*)malloc(want);
+ memcpy(data, data_, size_);
+ data_ = data;
+ }
+ else {
+ data_ = (byte*)realloc(data_, want);
+ }
+ }
+ else {
+ data_ = (byte*)malloc(want);
+ }
+ sizeAlloced_ = want;
+ isMalloced_ = true;
+ }
+ size_ = need;
+ }
}
void MemIo::transfer(BasicIo& src)
@@ -390,13 +389,13 @@ namespace Exiv2 {
MemIo *memIo = dynamic_cast<MemIo*>(&src);
if (memIo) {
// Optimization if this is another instance of MemIo
- if (memIo->isMalloced)
+ if (memIo->isMalloced_)
{
- isMalloced = true;
- memIo->isMalloced = false;
+ isMalloced_ = true;
+ memIo->isMalloced_ = false;
}
else
- isMalloced = false;
+ isMalloced_ = false;
data_ = memIo->data_;
idx_ = 0;
@@ -414,32 +413,9 @@ namespace Exiv2 {
if (error() || src.error()) throw Error(19, strError());
}
- long MemIo::write(BasicIo& src)
- {
- if (static_cast<BasicIo*>(this)==&src) return 0;
- if (!src.isopen()) return 0;
-
- byte buf[4096];
- long readCount = 0;
- long writeTotal = 0;
- while ((readCount = src.read(buf, sizeof(buf)))) {
- write(buf, readCount);
- writeTotal += readCount;
- }
-
- return writeTotal;
- }
-
- int MemIo::putb(byte data)
- {
- checkSize(1);
- data_[idx_++] = data;
- return data;
- }
-
int MemIo::seek(long offset, Position pos)
{
- ByteVector::size_type newIdx;
+ long newIdx;
if (pos == BasicIo::cur ) {
newIdx = idx_ + offset;
@@ -459,12 +435,12 @@ namespace Exiv2 {
long MemIo::tell() const
{
- return (long)idx_;
+ return idx_;
}
long MemIo::size() const
{
- return (long) size_;
+ return size_;
}
int MemIo::open()
@@ -493,7 +469,7 @@ namespace Exiv2 {
long MemIo::read(byte* buf, long rcount)
{
- long avail = (long)(size_ - idx_);
+ long avail = size_ - idx_;
long allow = std::min(rcount, avail);
memcpy(buf, &data_[idx_], allow);
diff --git a/src/plugins/exiv2/basicio.hpp b/src/plugins/exiv2/basicio.hpp
@@ -476,7 +476,7 @@ namespace Exiv2 {
//! @name Creators
//@{
//! Default constructor that results in an empty object
- MemIo() { idx_ = 0; isMalloced = false; data_ = NULL;}
+ MemIo() : data_(0), idx_(0), size_(0), sizeAlloced_(0), isMalloced_(false) {}
/*!
@brief Constructor that accepts a block of memory to be copied.
IO operations are performed on the copied memory.
@@ -486,7 +486,7 @@ namespace Exiv2 {
*/
MemIo(const byte* data, long size);
//! Destructor. Releases all managed memory
- ~MemIo() {if (isMalloced) free(data_);}
+ ~MemIo() {if (isMalloced_) free(data_);}
void MemIo::wrap(const byte *data, long size);
@@ -516,7 +516,7 @@ namespace Exiv2 {
@return Number of bytes written to the memory block successfully;<BR>
0 if failure;
*/
- virtual long write(const byte* data, long wcount);
+ virtual long write(const byte* data, long wcount) { return 0; }
/*!
@brief Write data that is read from another BasicIo instance to
the memory block. If needed, the size of the internal memory
@@ -527,7 +527,7 @@ namespace Exiv2 {
@return Number of bytes written to the memory block successfully;<BR>
0 if failure;
*/
- virtual long write(BasicIo& src);
+ virtual long write(BasicIo& src) { return 0; }
/*!
@brief Write one byte to the memory block. The IO position is
advanced by one byte.
@@ -535,7 +535,7 @@ namespace Exiv2 {
@return The value of the byte written if successful;<BR>
EOF if failure;
*/
- virtual int putb(byte data);
+ virtual int putb(byte data) { return EOF; }
/*!
@brief Read data from the memory block. Reading starts at the current
IO position and the position is advanced by the number of
@@ -630,16 +630,12 @@ namespace Exiv2 {
//! Assignment operator
MemIo& operator=(const MemIo& rhs);
- // Typedefs
- typedef std::vector<byte> ByteVector;
-
- // DATA
byte *data_;
- ByteVector::size_type idx_, size_;
+ long idx_;
+ long size_;
+ long sizeAlloced_; //!< Size of the allocated buffer
+ bool isMalloced_; //!< Was the buffer allocated?
- // Was the buffer allocated?
- bool isMalloced;
-
// METHODS
void checkSize(long wcount);
}; // class MemIo