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