fixed warnings in squirrel
[supertux.git] / src / squirrel / sqstdlib / sqstdblob.cpp
1 /* see copyright notice in squirrel.h */
2 #include <new>
3 #include <squirrel.h>
4 #include <sqstdio.h>
5 #include <string.h>
6 #include <sqstdblob.h>
7 #include "sqstdstream.h"
8 #include "sqstdblobimpl.h"
9
10 #define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002)
11
12 //Blob
13
14
15 #define SETUP_BLOB(v) \
16         SQBlob *self = NULL; \
17         { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,SQSTD_BLOB_TYPE_TAG))) \
18                 return SQ_ERROR; }
19
20
21 static int _blob_resize(HSQUIRRELVM v)
22 {
23         SETUP_BLOB(v);
24         SQInteger size;
25         sq_getinteger(v,2,&size);
26         if(!self->Resize(size))
27                 return sq_throwerror(v,_SC("resize failed"));
28         return 0;
29 }
30
31 static void __swap_dword(unsigned int *n)
32 {
33         *n=(unsigned int)(((*n&0xFF000000)>>24)  |
34                         ((*n&0x00FF0000)>>8)  |
35                         ((*n&0x0000FF00)<<8)  |
36                         ((*n&0x000000FF)<<24));
37 }
38
39 static void __swap_word(unsigned short *n)
40 {
41         *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
42 }
43
44 static int _blob_swap4(HSQUIRRELVM v)
45 {
46         SETUP_BLOB(v);
47         int num=(self->Len()-(self->Len()%4))>>2;
48         unsigned int *t=(unsigned int *)self->GetBuf();
49         for(int i = 0; i < num; i++) {
50                 __swap_dword(&t[i]);
51         }
52         return 0;
53 }
54
55 static int _blob_swap2(HSQUIRRELVM v)
56 {
57         SETUP_BLOB(v);
58         int num=(self->Len()-(self->Len()%2))>>1;
59         unsigned short *t = (unsigned short *)self->GetBuf();
60         for(int i = 0; i < num; i++) {
61                 __swap_word(&t[i]);
62         }
63         return 0;
64 }
65
66 static int _blob__set(HSQUIRRELVM v)
67 {
68         SETUP_BLOB(v);
69         SQInteger idx,val;
70         sq_getinteger(v,2,&idx);
71         sq_getinteger(v,3,&val);
72         if(idx < 0 || idx >= self->Len())
73                 return sq_throwerror(v,_SC("index out of range"));
74         ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;
75         sq_push(v,3);
76         return 1;
77 }
78
79 static int _blob__get(HSQUIRRELVM v)
80 {
81         SETUP_BLOB(v);
82         SQInteger idx;
83         sq_getinteger(v,2,&idx);
84         if(idx < 0 || idx >= self->Len())
85                 return sq_throwerror(v,_SC("index out of range"));
86         sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);
87         return 1;
88 }
89
90 static int _blob__nexti(HSQUIRRELVM v)
91 {
92         SETUP_BLOB(v);
93         if(sq_gettype(v,2) == OT_NULL) {
94                 sq_pushinteger(v, 0);
95                 return 1;
96         }
97         SQInteger idx;
98         if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
99                 if(idx+1 < self->Len()) {
100                         sq_pushinteger(v, idx+1);
101                         return 1;
102                 }
103                 sq_pushnull(v);
104                 return 1;
105         }
106         return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
107 }
108
109 static int _blob__typeof(HSQUIRRELVM v)
110 {
111         sq_pushstring(v,_SC("blob"),-1);
112         return 1;
113 }
114
115 static int _blob_releasehook(SQUserPointer p, int )
116 {
117         SQBlob *self = (SQBlob*)p;
118         delete self;
119         return 1;
120 }
121
122 static int _blob_constructor(HSQUIRRELVM v)
123 {
124         SQInteger nparam = sq_gettop(v);
125         SQInteger size = 0;
126         if(nparam == 2) {
127                 sq_getinteger(v, 2, &size);
128         }
129         if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));
130         SQBlob *b = new SQBlob(size);
131         if(SQ_FAILED(sq_setinstanceup(v,1,b))) {
132                 delete b;
133                 return sq_throwerror(v, _SC("cannot create blob with negative size"));
134         }
135         sq_setreleasehook(v,1,_blob_releasehook);
136         return 0;
137 }
138
139 #define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}
140 static SQRegFunction _blob_methods[] = {
141         _DECL_BLOB_FUNC(constructor,-1,_SC("xn")),
142         _DECL_BLOB_FUNC(resize,2,_SC("xn")),
143         _DECL_BLOB_FUNC(swap2,1,_SC("x")),
144         _DECL_BLOB_FUNC(swap4,1,_SC("x")),
145         _DECL_BLOB_FUNC(_set,3,_SC("xnn")),
146         _DECL_BLOB_FUNC(_get,2,_SC("xn")),
147         _DECL_BLOB_FUNC(_typeof,1,_SC("x")),
148         _DECL_BLOB_FUNC(_nexti,2,_SC("x")),
149         {0,0,0,0}
150 };
151
152
153
154 //GLOBAL FUNCTIONS
155
156 static int _g_blob_casti2f(HSQUIRRELVM v)
157 {
158         SQInteger i;
159         sq_getinteger(v,2,&i);
160         sq_pushfloat(v,*((SQFloat *)&i));
161         return 1;
162 }
163
164 static int _g_blob_castf2i(HSQUIRRELVM v)
165 {
166         SQFloat f;
167         sq_getfloat(v,2,&f);
168         sq_pushinteger(v,*((SQInteger *)&f));
169         return 1;
170 }
171
172 static int _g_blob_swap2(HSQUIRRELVM v)
173 {
174         SQInteger i;
175         sq_getinteger(v,2,&i);
176         short s=(short)i;
177         sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
178         return 1;
179 }
180
181 static int _g_blob_swap4(HSQUIRRELVM v)
182 {
183         SQInteger i;
184         sq_getinteger(v,2,&i);
185         __swap_dword((unsigned int *)&i);
186         sq_pushinteger(v,i);
187         return 1;
188 }
189
190 static int _g_blob_swapfloat(HSQUIRRELVM v)
191 {
192         SQFloat f;
193         sq_getfloat(v,2,&f);
194         __swap_dword((unsigned int *)&f);
195         sq_pushfloat(v,f);
196         return 1;
197 }
198
199 #define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}
200 static SQRegFunction bloblib_funcs[]={
201         _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),
202         _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),
203         _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
204         _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
205         _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
206         {0,0,0,0}
207 };
208
209 SQRESULT sqstd_getblob(HSQUIRRELVM v,int idx,SQUserPointer *ptr)
210 {
211         SQBlob *blob;
212         if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,SQSTD_BLOB_TYPE_TAG)))
213                 return -1;
214         *ptr = blob->GetBuf();
215         return SQ_OK;
216 }
217
218 int sqstd_getblobsize(HSQUIRRELVM v,int idx)
219 {
220         SQBlob *blob;
221         if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,SQSTD_BLOB_TYPE_TAG)))
222                 return -1;
223         return blob->Len();
224 }
225
226 SQUserPointer sqstd_createblob(HSQUIRRELVM v, int size)
227 {
228         int top = sq_gettop(v);
229 //      SQUserPointer p = sq_newuserdata(v, sizeof(SQBlob));
230 //      sq_setreleasehook(v,-1,_blob_releasehook);
231 //      sq_settypetag(v,-1,SQSTD_BLOB_TYPE_TAG);
232 //      new (p) SQBlob(size);
233         sq_pushregistrytable(v);
234         sq_pushstring(v,_SC("std_blob"),-1);
235         if(SQ_SUCCEEDED(sq_get(v,-2))) {
236                 sq_remove(v,-2); //removes the registry
237                 sq_push(v,1); // push the this
238                 sq_pushinteger(v,size); //size
239                 SQBlob *blob = NULL;
240                 if(SQ_SUCCEEDED(sq_call(v,2,SQTrue))
241                         && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,SQSTD_BLOB_TYPE_TAG))) {
242                         sq_remove(v,-2);
243                         sq_remove(v,-2);
244                         return blob->GetBuf();
245                 }
246         }
247         sq_settop(v,top);
248         return NULL;
249 }
250
251 SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)
252 {
253         return declare_stream(v,_SC("blob"),SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
254 }
255