New grow and skid sounds from remaxim
[supertux.git] / src / squirrel / sqstdlib / sqstdblobimpl.h
1 /*      see copyright notice in squirrel.h */
2 #ifndef _SQSTD_BLOBIMPL_H_
3 #define _SQSTD_BLOBIMPL_H_
4
5 struct 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 _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; }
100 private:
101         SQInteger _size;
102         SQInteger _allocated;
103         SQInteger _ptr;
104         unsigned char *_buf;
105         bool _owns;
106 };
107
108 #endif //_SQSTD_BLOBIMPL_H_