sqstdblobimpl.h
00001
00002 #ifndef _SQSTD_BLOBIMPL_H_
00003 #define _SQSTD_BLOBIMPL_H_
00004
00005 struct SQBlob : public SQStream
00006 {
00007 SQBlob(SQInteger size) {
00008 _size = size;
00009 _allocated = size;
00010 _buf = (unsigned char *)sq_malloc(size);
00011 memset(_buf, 0, _size);
00012 _ptr = 0;
00013 _owns = true;
00014 }
00015 virtual ~SQBlob() {
00016 sq_free(_buf, _allocated);
00017 }
00018 SQInteger Write(void *buffer, SQInteger size) {
00019 if(!CanAdvance(size)) {
00020 GrowBufOf(_ptr + size - _size);
00021 }
00022 memcpy(&_buf[_ptr], buffer, size);
00023 _ptr += size;
00024 return size;
00025 }
00026 SQInteger Read(void *buffer,SQInteger size) {
00027 SQInteger n = size;
00028 if(!CanAdvance(size)) {
00029 if((_size - _ptr) > 0)
00030 n = _size - _ptr;
00031 else return 0;
00032 }
00033 memcpy(buffer, &_buf[_ptr], n);
00034 _ptr += n;
00035 return n;
00036 }
00037 bool Resize(SQInteger n) {
00038 if(!_owns) return false;
00039 if(n != _allocated) {
00040 unsigned char *newbuf = (unsigned char *)sq_malloc(n);
00041 memset(newbuf,0,n);
00042 if(_size > n)
00043 memcpy(newbuf,_buf,n);
00044 else
00045 memcpy(newbuf,_buf,_size);
00046 sq_free(_buf,_allocated);
00047 _buf=newbuf;
00048 _allocated = n;
00049 if(_size > _allocated)
00050 _size = _allocated;
00051 if(_ptr > _allocated)
00052 _ptr = _allocated;
00053 }
00054 return true;
00055 }
00056 bool GrowBufOf(SQInteger n)
00057 {
00058 bool ret = true;
00059 if(_size + n > _allocated) {
00060 if(_size + n > _size * 2)
00061 ret = Resize(_size + n);
00062 else
00063 ret = Resize(_size * 2);
00064 }
00065 _size = _size + n;
00066 return ret;
00067 }
00068 bool CanAdvance(SQInteger n) {
00069 if(_ptr+n>_size)return false;
00070 return true;
00071 }
00072 SQInteger Seek(SQInteger offset, SQInteger origin) {
00073 switch(origin) {
00074 case SQ_SEEK_SET:
00075 if(offset > _size || offset < 0) return -1;
00076 _ptr = offset;
00077 break;
00078 case SQ_SEEK_CUR:
00079 if(_ptr + offset > _size || _ptr + offset < 0) return -1;
00080 _ptr += offset;
00081 break;
00082 case SQ_SEEK_END:
00083 if(_size + offset > _size || _size + offset < 0) return -1;
00084 _ptr = _size + offset;
00085 break;
00086 default: return -1;
00087 }
00088 return 0;
00089 }
00090 bool IsValid() {
00091 return _buf?true:false;
00092 }
00093 bool EOS() {
00094 return _ptr == _size;
00095 }
00096 SQInteger Flush() { return 0; }
00097 SQInteger Tell() { return _ptr; }
00098 SQInteger Len() { return _size; }
00099 SQUserPointer GetBuf(){ return _buf; }
00100 private:
00101 SQInteger _size;
00102 SQInteger _allocated;
00103 SQInteger _ptr;
00104 unsigned char *_buf;
00105 bool _owns;
00106 };
00107
00108 #endif //_SQSTD_BLOBIMPL_H_