1/* see copyright notice in squirrel.h */
2#ifndef _SQSTD_BLOBIMPL_H_
3#define _SQSTD_BLOBIMPL_H_
4
5struct SQBlob : public SQStream
6{
7 SQBlob(SQInteger size) {
8 _size = size;
9 _allocated = size;
10 _buf = (unsigned char *)sq_malloc(size);
11 memset(_buf, 0, _size);
12 _ptr = 0;
13 _owns = true;
14 }
15 virtual ~SQBlob() {
16 sq_free(_buf, _allocated);
17 }
18 SQInteger Write(void *buffer, SQInteger size) {
19 if(!CanAdvance(size)) {
20 GrowBufOf(_ptr + size - _size);
21 }
22 memcpy(&_buf[_ptr], buffer, size);
23 _ptr += size;
24 return size;
25 }
26 SQInteger Read(void *buffer,SQInteger size) {
27 SQInteger n = size;
28 if(!CanAdvance(size)) {
29 if((_size - _ptr) > 0)
30 n = _size - _ptr;
31 else return 0;
32 }
33 memcpy(buffer, &_buf[_ptr], n);
34 _ptr += n;
35 return n;
36 }
37 bool Resize(SQInteger n) {
38 if(!_owns) return false;
39 if(n != _allocated) {
40 unsigned char *newbuf = (unsigned char *)sq_malloc(n);
41 memset(newbuf,0,n);
42 if(_size > n)
43 memcpy(newbuf,_buf,n);
44 else
45 memcpy(newbuf,_buf,_size);
46 sq_free(_buf,_allocated);
47 _buf=newbuf;
48 _allocated = n;
49 if(_size > _allocated)
50 _size = _allocated;
51 if(_ptr > _allocated)
52 _ptr = _allocated;
53 }
54 return true;
55 }
56 bool GrowBufOf(SQInteger n)
57 {
58 bool ret = true;
59 if(_size + n > _allocated) {
60 if(_size + n > _size * 2)
61 ret = Resize(_size + n);
62 else
63 ret = Resize(_size * 2);
64 }
65 _size = _size + n;
66 return ret;
67 }
68 bool CanAdvance(SQInteger n) {
69 if(_ptr+n>_size)return false;
70 return true;
71 }
72 SQInteger Seek(SQInteger offset, SQInteger origin) {
73 switch(origin) {
74 case SQ_SEEK_SET:
75 if(offset > _size || offset < 0) return -1;
76 _ptr = offset;
77 break;
78 case SQ_SEEK_CUR:
79 if(_ptr + offset > _size || _ptr + offset < 0) return -1;
80 _ptr += offset;
81 break;
82 case SQ_SEEK_END:
83 if(_size + offset > _size || _size + offset < 0) return -1;
84 _ptr = _size + offset;
85 break;
86 default: return -1;
87 }
88 return 0;
89 }
90 bool IsValid() {
91 return _size == 0 || _buf?true:false;
92 }
93 bool EOS() {
94 return _ptr == _size;
95 }
96 SQInteger Flush() { return 0; }
97 SQInteger Tell() { return _ptr; }
98 SQInteger Len() { return _size; }
99 SQUserPointer GetBuf(){ return _buf; }
100private:
101 SQInteger _size;
102 SQInteger _allocated;
103 SQInteger _ptr;
104 unsigned char *_buf;
105 bool _owns;
106};
107
108#endif //_SQSTD_BLOBIMPL_H_
109