109 lines
2.2 KiB
C
109 lines
2.2 KiB
C
|
/* see copyright notice in squirrel.h */
|
||
|
#ifndef _SQSTD_BLOBIMPL_H_
|
||
|
#define _SQSTD_BLOBIMPL_H_
|
||
|
|
||
|
struct SQBlob : public SQStream
|
||
|
{
|
||
|
SQBlob(SQInteger size) {
|
||
|
_size = size;
|
||
|
_allocated = size;
|
||
|
_buf = (unsigned char *)sq_malloc(size);
|
||
|
memset(_buf, 0, _size);
|
||
|
_ptr = 0;
|
||
|
_owns = true;
|
||
|
}
|
||
|
virtual ~SQBlob() {
|
||
|
sq_free(_buf, _allocated);
|
||
|
}
|
||
|
SQInteger Write(void *buffer, SQInteger size) {
|
||
|
if(!CanAdvance(size)) {
|
||
|
GrowBufOf(_ptr + size - _size);
|
||
|
}
|
||
|
memcpy(&_buf[_ptr], buffer, size);
|
||
|
_ptr += size;
|
||
|
return size;
|
||
|
}
|
||
|
SQInteger Read(void *buffer,SQInteger size) {
|
||
|
SQInteger n = size;
|
||
|
if(!CanAdvance(size)) {
|
||
|
if((_size - _ptr) > 0)
|
||
|
n = _size - _ptr;
|
||
|
else return 0;
|
||
|
}
|
||
|
memcpy(buffer, &_buf[_ptr], n);
|
||
|
_ptr += n;
|
||
|
return n;
|
||
|
}
|
||
|
bool Resize(SQInteger n) {
|
||
|
if(!_owns) return false;
|
||
|
if(n != _allocated) {
|
||
|
unsigned char *newbuf = (unsigned char *)sq_malloc(n);
|
||
|
memset(newbuf,0,n);
|
||
|
if(_size > n)
|
||
|
memcpy(newbuf,_buf,n);
|
||
|
else
|
||
|
memcpy(newbuf,_buf,_size);
|
||
|
sq_free(_buf,_allocated);
|
||
|
_buf=newbuf;
|
||
|
_allocated = n;
|
||
|
if(_size > _allocated)
|
||
|
_size = _allocated;
|
||
|
if(_ptr > _allocated)
|
||
|
_ptr = _allocated;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
bool GrowBufOf(SQInteger n)
|
||
|
{
|
||
|
bool ret = true;
|
||
|
if(_size + n > _allocated) {
|
||
|
if(_size + n > _size * 2)
|
||
|
ret = Resize(_size + n);
|
||
|
else
|
||
|
ret = Resize(_size * 2);
|
||
|
}
|
||
|
_size = _size + n;
|
||
|
return ret;
|
||
|
}
|
||
|
bool CanAdvance(SQInteger n) {
|
||
|
if(_ptr+n>_size)return false;
|
||
|
return true;
|
||
|
}
|
||
|
SQInteger Seek(SQInteger offset, SQInteger origin) {
|
||
|
switch(origin) {
|
||
|
case SQ_SEEK_SET:
|
||
|
if(offset > _size || offset < 0) return -1;
|
||
|
_ptr = offset;
|
||
|
break;
|
||
|
case SQ_SEEK_CUR:
|
||
|
if(_ptr + offset > _size || _ptr + offset < 0) return -1;
|
||
|
_ptr += offset;
|
||
|
break;
|
||
|
case SQ_SEEK_END:
|
||
|
if(_size + offset > _size || _size + offset < 0) return -1;
|
||
|
_ptr = _size + offset;
|
||
|
break;
|
||
|
default: return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
bool IsValid() {
|
||
|
return _buf?true:false;
|
||
|
}
|
||
|
bool EOS() {
|
||
|
return _ptr == _size;
|
||
|
}
|
||
|
SQInteger Flush() { return 0; }
|
||
|
SQInteger Tell() { return _ptr; }
|
||
|
SQInteger Len() { return _size; }
|
||
|
SQUserPointer GetBuf(){ return _buf; }
|
||
|
private:
|
||
|
SQInteger _size;
|
||
|
SQInteger _allocated;
|
||
|
SQInteger _ptr;
|
||
|
unsigned char *_buf;
|
||
|
bool _owns;
|
||
|
};
|
||
|
|
||
|
#endif //_SQSTD_BLOBIMPL_H_
|