1 /* see copyright notice in squirrel.h */
7 #include "sqstdstream.h"
8 #include "sqstdblobimpl.h"
10 #define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002)
15 #define SETUP_BLOB(v) \
16 SQBlob *self = NULL; \
17 { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,SQSTD_BLOB_TYPE_TAG))) \
21 static int _blob_resize(HSQUIRRELVM v)
25 sq_getinteger(v,2,&size);
26 if(!self->Resize(size))
27 return sq_throwerror(v,_SC("resize failed"));
31 static void __swap_dword(unsigned int *n)
33 *n=(unsigned int)(((*n&0xFF000000)>>24) |
34 ((*n&0x00FF0000)>>8) |
35 ((*n&0x0000FF00)<<8) |
36 ((*n&0x000000FF)<<24));
39 static void __swap_word(unsigned short *n)
41 *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
44 static int _blob_swap4(HSQUIRRELVM 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++) {
55 static int _blob_swap2(HSQUIRRELVM 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++) {
66 static int _blob__set(HSQUIRRELVM v)
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;
79 static int _blob__get(HSQUIRRELVM v)
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]);
90 static int _blob__nexti(HSQUIRRELVM v)
93 if(sq_gettype(v,2) == OT_NULL) {
98 if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
99 if(idx+1 < self->Len()) {
100 sq_pushinteger(v, idx+1);
106 return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
109 static int _blob__typeof(HSQUIRRELVM v)
111 sq_pushstring(v,_SC("blob"),-1);
115 static int _blob_releasehook(SQUserPointer p, int size)
117 SQBlob *self = (SQBlob*)p;
122 static int _blob_constructor(HSQUIRRELVM v)
124 SQInteger nparam = sq_gettop(v);
127 sq_getinteger(v, 2, &size);
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))) {
133 return sq_throwerror(v, _SC("cannot create blob with negative size"));
135 sq_setreleasehook(v,1,_blob_releasehook);
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")),
156 static int _g_blob_casti2f(HSQUIRRELVM v)
159 sq_getinteger(v,2,&i);
160 sq_pushfloat(v,*((SQFloat *)&i));
164 static int _g_blob_castf2i(HSQUIRRELVM v)
168 sq_pushinteger(v,*((SQInteger *)&f));
172 static int _g_blob_swap2(HSQUIRRELVM v)
175 sq_getinteger(v,2,&i);
177 sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
181 static int _g_blob_swap4(HSQUIRRELVM v)
184 sq_getinteger(v,2,&i);
185 __swap_dword((unsigned int *)&i);
190 static int _g_blob_swapfloat(HSQUIRRELVM v)
194 __swap_dword((unsigned int *)&f);
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")),
209 SQRESULT sqstd_getblob(HSQUIRRELVM v,int idx,SQUserPointer *ptr)
212 if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,SQSTD_BLOB_TYPE_TAG)))
214 *ptr = blob->GetBuf();
218 int sqstd_getblobsize(HSQUIRRELVM v,int idx)
221 if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,SQSTD_BLOB_TYPE_TAG)))
226 SQUserPointer sqstd_createblob(HSQUIRRELVM v, int size)
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
240 if(SQ_SUCCEEDED(sq_call(v,2,SQTrue))
241 && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,SQSTD_BLOB_TYPE_TAG))) {
244 return blob->GetBuf();
251 SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)
253 return declare_stream(v,_SC("blob"),SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);