diff options
| -rw-r--r-- | include/Buffer.h | 12 | ||||
| -rw-r--r-- | lib/Buffer.cc | 78 | 
2 files changed, 69 insertions, 21 deletions
diff --git a/include/Buffer.h b/include/Buffer.h index 316af13..8996b2d 100644 --- a/include/Buffer.h +++ b/include/Buffer.h @@ -11,7 +11,7 @@  class Buffer : public Handle {    public: -      Buffer(); +      Buffer(bool seekable = false);        Buffer(const Buffer &);        virtual ~Buffer();      virtual ssize_t write(const void *buf, size_t count) throw(GeneralException); @@ -22,12 +22,16 @@ class Buffer : public Handle {      virtual Buffer operator=(const Buffer &);      virtual bool CanWatch() const;      virtual ssize_t GetSize() const; -    char operator[](size_t) const; -    char & operator[](size_t); +    virtual bool CanSeek() const; +    virtual off_t seek(off_t, int = SEEK_SET) throw (GeneralException); +    virtual off_t tell() const; +    Byte operator[](size_t) const; +    Byte & operator[](size_t);    private: -    char * buffer, zero; +    Byte * buffer, zero;      size_t realsiz, bufsiz, ptr; +    bool seekable;  };  #endif diff --git a/lib/Buffer.cc b/lib/Buffer.cc index db8b3ee..d0e5af2 100644 --- a/lib/Buffer.cc +++ b/lib/Buffer.cc @@ -5,14 +5,14 @@  #include "Buffer.h"  #include "generic.h" -Buffer::Buffer() : Handle(-1), buffer(0), zero(0), realsiz(0), bufsiz(0), ptr(0) { } +Buffer::Buffer(bool _seekable) : Handle(-1), buffer(0), zero(0), realsiz(0), bufsiz(0), ptr(0), seekable(_seekable) { }  Buffer::~Buffer() {      free(buffer);  } -Buffer::Buffer(const Buffer & b) : Handle(-1), buffer(0), zero(b.zero), realsiz(b.realsiz), bufsiz(b.bufsiz), ptr(b.ptr) { -    buffer = (char *) malloc(bufsiz); +Buffer::Buffer(const Buffer & b) : Handle(-1), buffer(0), zero(b.zero), realsiz(b.realsiz), bufsiz(b.bufsiz), ptr(b.ptr), seekable(b.seekable) { +    buffer = (Byte *) malloc(bufsiz);      memcpy(buffer, b.buffer, bufsiz);  } @@ -23,7 +23,7 @@ ssize_t Buffer::write(const void *buf, size_t count) throw (GeneralException) {      if (count + realsiz > bufsiz) {  	int numblocks = (count + realsiz) / realloc_threshold;  	int remains = (count + realsiz) % realloc_threshold; -	buffer = (char *) realloc(buffer, bufsiz = ((numblocks + (remains ? 1 : 0)) * realloc_threshold)); +	buffer = (Byte *) realloc(buffer, bufsiz = ((numblocks + (remains ? 1 : 0)) * realloc_threshold));      }      memcpy(buffer + realsiz, buf, count);      realsiz += count; @@ -40,13 +40,15 @@ ssize_t Buffer::read(void *buf, size_t count) throw (GeneralException) {      memcpy(buf, buffer + ptr, count);      ptr += count; -     -    if (ptr >= realloc_threshold) { -	int numblocks = (bufsiz / realloc_threshold) - (ptr / realloc_threshold); -	memmove(buffer, buffer + (bufsiz - numblocks * realloc_threshold), numblocks * realloc_threshold); -	ptr -= (bufsiz - numblocks * realloc_threshold); -	realsiz -= (bufsiz - numblocks * realloc_threshold); -	buffer = (char *) realloc(buffer, bufsiz = (numblocks * realloc_threshold)); + +    if (!seekable) { +        if (ptr >= realloc_threshold) { +	    int numblocks = (bufsiz / realloc_threshold) - (ptr / realloc_threshold); +	    memmove(buffer, buffer + (bufsiz - numblocks * realloc_threshold), numblocks * realloc_threshold); +	    ptr -= (bufsiz - numblocks * realloc_threshold); +	    realsiz -= (bufsiz - numblocks * realloc_threshold); +	    buffer = (Byte *) realloc(buffer, bufsiz = (numblocks * realloc_threshold)); +        }      }      return count; @@ -69,8 +71,9 @@ Buffer Buffer::operator=(const Buffer & b) {  	free(buffer);  	realsiz = b.realsiz;  	ptr = b.ptr; +        seekable = b.seekable;  	if ((bufsiz = b.bufsiz)) { -	    buffer = (char *) malloc(bufsiz); +	    buffer = (Byte *) malloc(bufsiz);  	    memcpy(buffer, b.buffer, realsiz);  	} else {  	    buffer = 0; @@ -87,18 +90,59 @@ ssize_t Buffer::GetSize() const {      return realsiz;  } -char Buffer::operator[](size_t p) const { +Byte Buffer::operator[](size_t p) const {      if (p >= realsiz) {  	return 0;      } else { -	return buffer[ptr + p]; +        if (seekable) { +            return buffer[p]; +        } else { +            return buffer[ptr + p]; +        }      }  } -char & Buffer::operator[](size_t p) { +Byte & Buffer::operator[](size_t p) { +    if (p > bufsiz) { +	int numblocks = p / realloc_threshold; +	int remains = p % realloc_threshold; +	buffer = (Byte *) realloc(buffer, bufsiz = ((numblocks + (remains ? 1 : 0)) * realloc_threshold)); +    }      if (p >= realsiz) { -	return zero; +        memset(buffer + realsiz, 0, p - realsiz); +        realsiz = p; +    } + +    if (seekable) { +        return buffer[p];      } else { -	return buffer[ptr + p]; +        return buffer[ptr + p];      }  } + +bool Buffer::CanSeek() const { +    return seekable; +} + +off_t Buffer::seek(off_t off, int wheel) throw (GeneralException) { +    if (!seekable) { +        throw GeneralException("This buffer is a fifo, thus is not seekable"); +    } +    switch (wheel) { +    case SEEK_SET: +        ptr = off; +        break; +    case SEEK_CUR: +        ptr += off; +        break; +    case SEEK_END: +        ptr = realsiz + off; +        break; +    } +    operator[](ptr) = operator[](ptr); +    return ptr; +} + +off_t Buffer::tell() const { +    return ptr; +}  | 
