Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
sqstdstream.cpp
00001 /* see copyright notice in squirrel.h */ 00002 #include <new> 00003 #include <stdio.h> 00004 #include <stdlib.h> 00005 #include <string.h> 00006 #include <squirrel.h> 00007 #include <sqstdio.h> 00008 #include <sqstdblob.h> 00009 #include "sqstdstream.h" 00010 #include "sqstdblobimpl.h" 00011 00012 #define SETUP_STREAM(v) \ 00013 SQStream *self = NULL; \ 00014 if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \ 00015 return sq_throwerror(v,_SC("invalid type tag")); \ 00016 if(!self || !self->IsValid()) \ 00017 return sq_throwerror(v,_SC("the stream is invalid")); 00018 00019 SQInteger _stream_readblob(HSQUIRRELVM v) 00020 { 00021 SETUP_STREAM(v); 00022 SQUserPointer data,blobp; 00023 SQInteger size,res; 00024 sq_getinteger(v,2,&size); 00025 if(size > self->Len()) { 00026 size = self->Len(); 00027 } 00028 data = sq_getscratchpad(v,size); 00029 res = self->Read(data,size); 00030 if(res <= 0) 00031 return sq_throwerror(v,_SC("no data left to read")); 00032 blobp = sqstd_createblob(v,res); 00033 memcpy(blobp,data,res); 00034 return 1; 00035 } 00036 00037 #define SAFE_READN(ptr,len) { \ 00038 if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \ 00039 } 00040 SQInteger _stream_readn(HSQUIRRELVM v) 00041 { 00042 SETUP_STREAM(v); 00043 SQInteger format; 00044 sq_getinteger(v, 2, &format); 00045 switch(format) { 00046 case 'l': { 00047 SQInteger i; 00048 SAFE_READN(&i, sizeof(i)); 00049 sq_pushinteger(v, i); 00050 } 00051 break; 00052 case 'i': { 00053 SQInt32 i; 00054 SAFE_READN(&i, sizeof(i)); 00055 sq_pushinteger(v, i); 00056 } 00057 break; 00058 case 's': { 00059 short s; 00060 SAFE_READN(&s, sizeof(short)); 00061 sq_pushinteger(v, s); 00062 } 00063 break; 00064 case 'w': { 00065 unsigned short w; 00066 SAFE_READN(&w, sizeof(unsigned short)); 00067 sq_pushinteger(v, w); 00068 } 00069 break; 00070 case 'c': { 00071 char c; 00072 SAFE_READN(&c, sizeof(char)); 00073 sq_pushinteger(v, c); 00074 } 00075 break; 00076 case 'b': { 00077 unsigned char c; 00078 SAFE_READN(&c, sizeof(unsigned char)); 00079 sq_pushinteger(v, c); 00080 } 00081 break; 00082 case 'f': { 00083 float f; 00084 SAFE_READN(&f, sizeof(float)); 00085 sq_pushfloat(v, f); 00086 } 00087 break; 00088 case 'd': { 00089 double d; 00090 SAFE_READN(&d, sizeof(double)); 00091 sq_pushfloat(v, (SQFloat)d); 00092 } 00093 break; 00094 default: 00095 return sq_throwerror(v, _SC("invalid format")); 00096 } 00097 return 1; 00098 } 00099 00100 SQInteger _stream_writeblob(HSQUIRRELVM v) 00101 { 00102 SQUserPointer data; 00103 SQInteger size; 00104 SETUP_STREAM(v); 00105 if(SQ_FAILED(sqstd_getblob(v,2,&data))) 00106 return sq_throwerror(v,_SC("invalid parameter")); 00107 size = sqstd_getblobsize(v,2); 00108 if(self->Write(data,size) != size) 00109 return sq_throwerror(v,_SC("io error")); 00110 sq_pushinteger(v,size); 00111 return 1; 00112 } 00113 00114 SQInteger _stream_writen(HSQUIRRELVM v) 00115 { 00116 SETUP_STREAM(v); 00117 SQInteger format, ti; 00118 SQFloat tf; 00119 sq_getinteger(v, 3, &format); 00120 switch(format) { 00121 case 'l': { 00122 SQInteger i; 00123 sq_getinteger(v, 2, &ti); 00124 i = ti; 00125 self->Write(&i, sizeof(SQInteger)); 00126 } 00127 break; 00128 case 'i': { 00129 SQInt32 i; 00130 sq_getinteger(v, 2, &ti); 00131 i = (SQInt32)ti; 00132 self->Write(&i, sizeof(SQInt32)); 00133 } 00134 break; 00135 case 's': { 00136 short s; 00137 sq_getinteger(v, 2, &ti); 00138 s = (short)ti; 00139 self->Write(&s, sizeof(short)); 00140 } 00141 break; 00142 case 'w': { 00143 unsigned short w; 00144 sq_getinteger(v, 2, &ti); 00145 w = (unsigned short)ti; 00146 self->Write(&w, sizeof(unsigned short)); 00147 } 00148 break; 00149 case 'c': { 00150 char c; 00151 sq_getinteger(v, 2, &ti); 00152 c = (char)ti; 00153 self->Write(&c, sizeof(char)); 00154 } 00155 break; 00156 case 'b': { 00157 unsigned char b; 00158 sq_getinteger(v, 2, &ti); 00159 b = (unsigned char)ti; 00160 self->Write(&b, sizeof(unsigned char)); 00161 } 00162 break; 00163 case 'f': { 00164 float f; 00165 sq_getfloat(v, 2, &tf); 00166 f = (float)tf; 00167 self->Write(&f, sizeof(float)); 00168 } 00169 break; 00170 case 'd': { 00171 double d; 00172 sq_getfloat(v, 2, &tf); 00173 d = tf; 00174 self->Write(&d, sizeof(double)); 00175 } 00176 break; 00177 default: 00178 return sq_throwerror(v, _SC("invalid format")); 00179 } 00180 return 0; 00181 } 00182 00183 SQInteger _stream_seek(HSQUIRRELVM v) 00184 { 00185 SETUP_STREAM(v); 00186 SQInteger offset, origin = SQ_SEEK_SET; 00187 sq_getinteger(v, 2, &offset); 00188 if(sq_gettop(v) > 2) { 00189 SQInteger t; 00190 sq_getinteger(v, 3, &t); 00191 switch(t) { 00192 case 'b': origin = SQ_SEEK_SET; break; 00193 case 'c': origin = SQ_SEEK_CUR; break; 00194 case 'e': origin = SQ_SEEK_END; break; 00195 default: return sq_throwerror(v,_SC("invalid origin")); 00196 } 00197 } 00198 sq_pushinteger(v, self->Seek(offset, origin)); 00199 return 1; 00200 } 00201 00202 SQInteger _stream_tell(HSQUIRRELVM v) 00203 { 00204 SETUP_STREAM(v); 00205 sq_pushinteger(v, self->Tell()); 00206 return 1; 00207 } 00208 00209 SQInteger _stream_len(HSQUIRRELVM v) 00210 { 00211 SETUP_STREAM(v); 00212 sq_pushinteger(v, self->Len()); 00213 return 1; 00214 } 00215 00216 SQInteger _stream_flush(HSQUIRRELVM v) 00217 { 00218 SETUP_STREAM(v); 00219 if(!self->Flush()) 00220 sq_pushinteger(v, 1); 00221 else 00222 sq_pushnull(v); 00223 return 1; 00224 } 00225 00226 SQInteger _stream_eos(HSQUIRRELVM v) 00227 { 00228 SETUP_STREAM(v); 00229 if(self->EOS()) 00230 sq_pushinteger(v, 1); 00231 else 00232 sq_pushnull(v); 00233 return 1; 00234 } 00235 00236 SQInteger _stream__cloned(HSQUIRRELVM v) 00237 { 00238 return sq_throwerror(v,_SC("this object cannot be cloned")); 00239 } 00240 00241 static SQRegFunction _stream_methods[] = { 00242 _DECL_STREAM_FUNC(readblob,2,_SC("xn")), 00243 _DECL_STREAM_FUNC(readn,2,_SC("xn")), 00244 _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")), 00245 _DECL_STREAM_FUNC(writen,3,_SC("xnn")), 00246 _DECL_STREAM_FUNC(seek,-2,_SC("xnn")), 00247 _DECL_STREAM_FUNC(tell,1,_SC("x")), 00248 _DECL_STREAM_FUNC(len,1,_SC("x")), 00249 _DECL_STREAM_FUNC(eos,1,_SC("x")), 00250 _DECL_STREAM_FUNC(flush,1,_SC("x")), 00251 _DECL_STREAM_FUNC(_cloned,0,NULL), 00252 {0,0} 00253 }; 00254 00255 void init_streamclass(HSQUIRRELVM v) 00256 { 00257 sq_pushregistrytable(v); 00258 sq_pushstring(v,_SC("std_stream"),-1); 00259 if(SQ_FAILED(sq_get(v,-2))) { 00260 sq_pushstring(v,_SC("std_stream"),-1); 00261 sq_newclass(v,SQFalse); 00262 sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG); 00263 SQInteger i = 0; 00264 while(_stream_methods[i].name != 0) { 00265 SQRegFunction &f = _stream_methods[i]; 00266 sq_pushstring(v,f.name,-1); 00267 sq_newclosure(v,f.f,0); 00268 sq_setparamscheck(v,f.nparamscheck,f.typemask); 00269 sq_newslot(v,-3,SQFalse); 00270 i++; 00271 } 00272 sq_newslot(v,-3,SQFalse); 00273 sq_pushroottable(v); 00274 sq_pushstring(v,_SC("stream"),-1); 00275 sq_pushstring(v,_SC("std_stream"),-1); 00276 sq_get(v,-4); 00277 sq_newslot(v,-3,SQFalse); 00278 sq_pop(v,1); 00279 } 00280 else { 00281 sq_pop(v,1); //result 00282 } 00283 sq_pop(v,1); 00284 } 00285 00286 SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals) 00287 { 00288 if(sq_gettype(v,-1) != OT_TABLE) 00289 return sq_throwerror(v,_SC("table expected")); 00290 SQInteger top = sq_gettop(v); 00291 //create delegate 00292 init_streamclass(v); 00293 sq_pushregistrytable(v); 00294 sq_pushstring(v,reg_name,-1); 00295 sq_pushstring(v,_SC("std_stream"),-1); 00296 if(SQ_SUCCEEDED(sq_get(v,-3))) { 00297 sq_newclass(v,SQTrue); 00298 sq_settypetag(v,-1,typetag); 00299 SQInteger i = 0; 00300 while(methods[i].name != 0) { 00301 SQRegFunction &f = methods[i]; 00302 sq_pushstring(v,f.name,-1); 00303 sq_newclosure(v,f.f,0); 00304 sq_setparamscheck(v,f.nparamscheck,f.typemask); 00305 sq_setnativeclosurename(v,-1,f.name); 00306 sq_newslot(v,-3,SQFalse); 00307 i++; 00308 } 00309 sq_newslot(v,-3,SQFalse); 00310 sq_pop(v,1); 00311 00312 i = 0; 00313 while(globals[i].name!=0) 00314 { 00315 SQRegFunction &f = globals[i]; 00316 sq_pushstring(v,f.name,-1); 00317 sq_newclosure(v,f.f,0); 00318 sq_setparamscheck(v,f.nparamscheck,f.typemask); 00319 sq_setnativeclosurename(v,-1,f.name); 00320 sq_newslot(v,-3,SQFalse); 00321 i++; 00322 } 00323 //register the class in the target table 00324 sq_pushstring(v,name,-1); 00325 sq_pushregistrytable(v); 00326 sq_pushstring(v,reg_name,-1); 00327 sq_get(v,-2); 00328 sq_remove(v,-2); 00329 sq_newslot(v,-3,SQFalse); 00330 00331 sq_settop(v,top); 00332 return SQ_OK; 00333 } 00334 sq_settop(v,top); 00335 return SQ_ERROR; 00336 }
Generated on Tue Jul 12 2022 21:35:49 by
