-/* see copyright notice in squirrel.h */\r
-#include <new>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <squirrel.h>\r
-#include <sqstdio.h>\r
-#include <sqstdblob.h>\r
-#include "sqstdstream.h"\r
-#include "sqstdblobimpl.h"\r
-\r
-#define SETUP_STREAM(v) \\r
- SQStream *self = NULL; \\r
- if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \\r
- return sq_throwerror(v,_SC("invalid type tag")); \\r
- if(!self->IsValid()) \\r
- return sq_throwerror(v,_SC("the stream is invalid"));\r
-\r
-SQInteger _stream_readblob(HSQUIRRELVM v)\r
-{\r
- SETUP_STREAM(v);\r
- SQUserPointer data,blobp;\r
- SQInteger size,res;\r
- sq_getinteger(v,2,&size);\r
- if(size > self->Len()) {\r
- size = self->Len();\r
- }\r
- data = sq_getscratchpad(v,size);\r
- res = self->Read(data,size);\r
- if(res <= 0)\r
- return sq_throwerror(v,_SC("no data left to read"));\r
- blobp = sqstd_createblob(v,res);\r
- memcpy(blobp,data,res);\r
- return 1;\r
-}\r
-\r
-#define SAFE_READN(ptr,len) { \\r
- if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \\r
- }\r
-SQInteger _stream_readn(HSQUIRRELVM v)\r
-{\r
- SETUP_STREAM(v);\r
- SQInteger format;\r
- sq_getinteger(v, 2, &format);\r
- switch(format) {\r
- case 'l': {\r
- SQInteger i;\r
- SAFE_READN(&i, sizeof(i));\r
- sq_pushinteger(v, i);\r
- }\r
- break;\r
- case 'i': {\r
- SQInt32 i;\r
- SAFE_READN(&i, sizeof(i));\r
- sq_pushinteger(v, i);\r
- }\r
- break;\r
- case 's': {\r
- short s;\r
- SAFE_READN(&s, sizeof(short));\r
- sq_pushinteger(v, s);\r
- }\r
- break;\r
- case 'w': {\r
- unsigned short w;\r
- SAFE_READN(&w, sizeof(unsigned short));\r
- sq_pushinteger(v, w);\r
- }\r
- break;\r
- case 'c': {\r
- char c;\r
- SAFE_READN(&c, sizeof(char));\r
- sq_pushinteger(v, c);\r
- }\r
- break;\r
- case 'b': {\r
- unsigned char c;\r
- SAFE_READN(&c, sizeof(unsigned char));\r
- sq_pushinteger(v, c);\r
- }\r
- break;\r
- case 'f': {\r
- float f;\r
- SAFE_READN(&f, sizeof(float));\r
- sq_pushfloat(v, f);\r
- }\r
- break;\r
- case 'd': {\r
- double d;\r
- SAFE_READN(&d, sizeof(double));\r
- sq_pushfloat(v, (SQFloat)d);\r
- }\r
- break;\r
- default:\r
- return sq_throwerror(v, _SC("invalid format"));\r
- }\r
- return 1;\r
-}\r
-\r
-SQInteger _stream_writeblob(HSQUIRRELVM v)\r
-{\r
- SQUserPointer data;\r
- SQInteger size;\r
- SETUP_STREAM(v);\r
- if(SQ_FAILED(sqstd_getblob(v,2,&data)))\r
- return sq_throwerror(v,_SC("invalid parameter"));\r
- size = sqstd_getblobsize(v,2);\r
- if(self->Write(data,size) != size)\r
- return sq_throwerror(v,_SC("io error"));\r
- sq_pushinteger(v,size);\r
- return 1;\r
-}\r
-\r
-SQInteger _stream_writen(HSQUIRRELVM v)\r
-{\r
- SETUP_STREAM(v);\r
- SQInteger format, ti;\r
- SQFloat tf;\r
- sq_getinteger(v, 3, &format);\r
- switch(format) {\r
- case 'l': {\r
- SQInteger i;\r
- sq_getinteger(v, 2, &ti);\r
- i = ti;\r
- self->Write(&i, sizeof(SQInteger));\r
- }\r
- break;\r
- case 'i': {\r
- SQInt32 i;\r
- sq_getinteger(v, 2, &ti);\r
- i = (SQInt32)ti;\r
- self->Write(&i, sizeof(SQInt32));\r
- }\r
- break;\r
- case 's': {\r
- short s;\r
- sq_getinteger(v, 2, &ti);\r
- s = (short)ti;\r
- self->Write(&s, sizeof(short));\r
- }\r
- break;\r
- case 'w': {\r
- unsigned short w;\r
- sq_getinteger(v, 2, &ti);\r
- w = (unsigned short)ti;\r
- self->Write(&w, sizeof(unsigned short));\r
- }\r
- break;\r
- case 'c': {\r
- char c;\r
- sq_getinteger(v, 2, &ti);\r
- c = (char)ti;\r
- self->Write(&c, sizeof(char));\r
- }\r
- break;\r
- case 'b': {\r
- unsigned char b;\r
- sq_getinteger(v, 2, &ti);\r
- b = (unsigned char)ti;\r
- self->Write(&b, sizeof(unsigned char));\r
- }\r
- break;\r
- case 'f': {\r
- float f;\r
- sq_getfloat(v, 2, &tf);\r
- f = tf;\r
- self->Write(&f, sizeof(float));\r
- }\r
- break;\r
- case 'd': {\r
- double d;\r
- sq_getfloat(v, 2, &tf);\r
- d = tf;\r
- self->Write(&d, sizeof(double));\r
- }\r
- break;\r
- default:\r
- return sq_throwerror(v, _SC("invalid format"));\r
- }\r
- return 0;\r
-}\r
-\r
-SQInteger _stream_seek(HSQUIRRELVM v)\r
-{\r
- SETUP_STREAM(v);\r
- SQInteger offset, origin = SQ_SEEK_SET;\r
- sq_getinteger(v, 2, &offset);\r
- if(sq_gettop(v) > 2) {\r
- SQInteger t;\r
- sq_getinteger(v, 3, &t);\r
- switch(t) {\r
- case 'b': origin = SQ_SEEK_SET; break;\r
- case 'c': origin = SQ_SEEK_CUR; break;\r
- case 'e': origin = SQ_SEEK_END; break;\r
- default: return sq_throwerror(v,_SC("invalid origin"));\r
- }\r
- }\r
- sq_pushinteger(v, self->Seek(offset, origin));\r
- return 1;\r
-}\r
-\r
-SQInteger _stream_tell(HSQUIRRELVM v)\r
-{\r
- SETUP_STREAM(v);\r
- sq_pushinteger(v, self->Tell());\r
- return 1;\r
-}\r
-\r
-SQInteger _stream_len(HSQUIRRELVM v)\r
-{\r
- SETUP_STREAM(v);\r
- sq_pushinteger(v, self->Len());\r
- return 1;\r
-}\r
-\r
-SQInteger _stream_flush(HSQUIRRELVM v)\r
-{\r
- SETUP_STREAM(v);\r
- if(!self->Flush())\r
- sq_pushinteger(v, 1);\r
- else\r
- sq_pushnull(v);\r
- return 1;\r
-}\r
-\r
-SQInteger _stream_eos(HSQUIRRELVM v)\r
-{\r
- SETUP_STREAM(v);\r
- if(self->EOS())\r
- sq_pushinteger(v, 1);\r
- else\r
- sq_pushnull(v);\r
- return 1;\r
-}\r
-\r
-static SQRegFunction _stream_methods[] = {\r
- _DECL_STREAM_FUNC(readblob,2,_SC("xn")),\r
- _DECL_STREAM_FUNC(readn,2,_SC("xn")),\r
- _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),\r
- _DECL_STREAM_FUNC(writen,3,_SC("xnn")),\r
- _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),\r
- _DECL_STREAM_FUNC(tell,1,_SC("x")),\r
- _DECL_STREAM_FUNC(len,1,_SC("x")),\r
- _DECL_STREAM_FUNC(eos,1,_SC("x")),\r
- _DECL_STREAM_FUNC(flush,1,_SC("x")),\r
- {0,0}\r
-};\r
-\r
-void init_streamclass(HSQUIRRELVM v)\r
-{\r
- sq_pushregistrytable(v);\r
- sq_pushstring(v,_SC("std_stream"),-1);\r
- if(SQ_FAILED(sq_get(v,-2))) {\r
- sq_pushstring(v,_SC("std_stream"),-1);\r
- sq_newclass(v,SQFalse);\r
- sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);\r
- SQInteger i = 0;\r
- while(_stream_methods[i].name != 0) {\r
- SQRegFunction &f = _stream_methods[i];\r
- sq_pushstring(v,f.name,-1);\r
- sq_newclosure(v,f.f,0);\r
- sq_setparamscheck(v,f.nparamscheck,f.typemask);\r
- sq_createslot(v,-3);\r
- i++;\r
- }\r
- sq_createslot(v,-3);\r
- sq_pushroottable(v);\r
- sq_pushstring(v,_SC("stream"),-1);\r
- sq_pushstring(v,_SC("std_stream"),-1);\r
- sq_get(v,-4);\r
- sq_createslot(v,-3);\r
- sq_pop(v,1);\r
- }\r
- else {\r
- sq_pop(v,1); //result\r
- }\r
- sq_pop(v,1);\r
-}\r
-\r
-SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)\r
-{\r
- if(sq_gettype(v,-1) != OT_TABLE)\r
- return sq_throwerror(v,_SC("table expected"));\r
- SQInteger top = sq_gettop(v);\r
- //create delegate\r
- init_streamclass(v);\r
- sq_pushregistrytable(v);\r
- sq_pushstring(v,reg_name,-1);\r
- sq_pushstring(v,_SC("std_stream"),-1);\r
- if(SQ_SUCCEEDED(sq_get(v,-3))) {\r
- sq_newclass(v,SQTrue);\r
- sq_settypetag(v,-1,typetag);\r
- SQInteger i = 0;\r
- while(methods[i].name != 0) {\r
- SQRegFunction &f = methods[i];\r
- sq_pushstring(v,f.name,-1);\r
- sq_newclosure(v,f.f,0);\r
- sq_setparamscheck(v,f.nparamscheck,f.typemask);\r
- sq_setnativeclosurename(v,-1,f.name);\r
- sq_createslot(v,-3);\r
- i++;\r
- }\r
- sq_createslot(v,-3);\r
- sq_pop(v,1);\r
- \r
- i = 0;\r
- while(globals[i].name!=0)\r
- {\r
- SQRegFunction &f = globals[i];\r
- sq_pushstring(v,f.name,-1);\r
- sq_newclosure(v,f.f,0);\r
- sq_setparamscheck(v,f.nparamscheck,f.typemask);\r
- sq_setnativeclosurename(v,-1,f.name);\r
- sq_createslot(v,-3);\r
- i++;\r
- }\r
- //register the class in the target table\r
- sq_pushstring(v,name,-1);\r
- sq_pushregistrytable(v);\r
- sq_pushstring(v,reg_name,-1);\r
- sq_get(v,-2);\r
- sq_remove(v,-2);\r
- sq_createslot(v,-3);\r
-\r
- sq_settop(v,top);\r
- return SQ_OK;\r
- }\r
- sq_settop(v,top);\r
- return SQ_ERROR;\r
-}\r
+/* see copyright notice in squirrel.h */
+#include <new>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <squirrel.h>
+#include <sqstdio.h>
+#include <sqstdblob.h>
+#include "sqstdstream.h"
+#include "sqstdblobimpl.h"
+
+#define SETUP_STREAM(v) \
+ SQStream *self = NULL; \
+ if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \
+ return sq_throwerror(v,_SC("invalid type tag")); \
+ if(!self->IsValid()) \
+ return sq_throwerror(v,_SC("the stream is invalid"));
+
+SQInteger _stream_readblob(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ SQUserPointer data,blobp;
+ SQInteger size,res;
+ sq_getinteger(v,2,&size);
+ if(size > self->Len()) {
+ size = self->Len();
+ }
+ data = sq_getscratchpad(v,size);
+ res = self->Read(data,size);
+ if(res <= 0)
+ return sq_throwerror(v,_SC("no data left to read"));
+ blobp = sqstd_createblob(v,res);
+ memcpy(blobp,data,res);
+ return 1;
+}
+
+#define SAFE_READN(ptr,len) { \
+ if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
+ }
+SQInteger _stream_readn(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ SQInteger format;
+ sq_getinteger(v, 2, &format);
+ switch(format) {
+ case 'l': {
+ SQInteger i;
+ SAFE_READN(&i, sizeof(i));
+ sq_pushinteger(v, i);
+ }
+ break;
+ case 'i': {
+ SQInt32 i;
+ SAFE_READN(&i, sizeof(i));
+ sq_pushinteger(v, i);
+ }
+ break;
+ case 's': {
+ short s;
+ SAFE_READN(&s, sizeof(short));
+ sq_pushinteger(v, s);
+ }
+ break;
+ case 'w': {
+ unsigned short w;
+ SAFE_READN(&w, sizeof(unsigned short));
+ sq_pushinteger(v, w);
+ }
+ break;
+ case 'c': {
+ char c;
+ SAFE_READN(&c, sizeof(char));
+ sq_pushinteger(v, c);
+ }
+ break;
+ case 'b': {
+ unsigned char c;
+ SAFE_READN(&c, sizeof(unsigned char));
+ sq_pushinteger(v, c);
+ }
+ break;
+ case 'f': {
+ float f;
+ SAFE_READN(&f, sizeof(float));
+ sq_pushfloat(v, f);
+ }
+ break;
+ case 'd': {
+ double d;
+ SAFE_READN(&d, sizeof(double));
+ sq_pushfloat(v, (SQFloat)d);
+ }
+ break;
+ default:
+ return sq_throwerror(v, _SC("invalid format"));
+ }
+ return 1;
+}
+
+SQInteger _stream_writeblob(HSQUIRRELVM v)
+{
+ SQUserPointer data;
+ SQInteger size;
+ SETUP_STREAM(v);
+ if(SQ_FAILED(sqstd_getblob(v,2,&data)))
+ return sq_throwerror(v,_SC("invalid parameter"));
+ size = sqstd_getblobsize(v,2);
+ if(self->Write(data,size) != size)
+ return sq_throwerror(v,_SC("io error"));
+ sq_pushinteger(v,size);
+ return 1;
+}
+
+SQInteger _stream_writen(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ SQInteger format, ti;
+ SQFloat tf;
+ sq_getinteger(v, 3, &format);
+ switch(format) {
+ case 'l': {
+ SQInteger i;
+ sq_getinteger(v, 2, &ti);
+ i = ti;
+ self->Write(&i, sizeof(SQInteger));
+ }
+ break;
+ case 'i': {
+ SQInt32 i;
+ sq_getinteger(v, 2, &ti);
+ i = (SQInt32)ti;
+ self->Write(&i, sizeof(SQInt32));
+ }
+ break;
+ case 's': {
+ short s;
+ sq_getinteger(v, 2, &ti);
+ s = (short)ti;
+ self->Write(&s, sizeof(short));
+ }
+ break;
+ case 'w': {
+ unsigned short w;
+ sq_getinteger(v, 2, &ti);
+ w = (unsigned short)ti;
+ self->Write(&w, sizeof(unsigned short));
+ }
+ break;
+ case 'c': {
+ char c;
+ sq_getinteger(v, 2, &ti);
+ c = (char)ti;
+ self->Write(&c, sizeof(char));
+ }
+ break;
+ case 'b': {
+ unsigned char b;
+ sq_getinteger(v, 2, &ti);
+ b = (unsigned char)ti;
+ self->Write(&b, sizeof(unsigned char));
+ }
+ break;
+ case 'f': {
+ float f;
+ sq_getfloat(v, 2, &tf);
+ f = tf;
+ self->Write(&f, sizeof(float));
+ }
+ break;
+ case 'd': {
+ double d;
+ sq_getfloat(v, 2, &tf);
+ d = tf;
+ self->Write(&d, sizeof(double));
+ }
+ break;
+ default:
+ return sq_throwerror(v, _SC("invalid format"));
+ }
+ return 0;
+}
+
+SQInteger _stream_seek(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ SQInteger offset, origin = SQ_SEEK_SET;
+ sq_getinteger(v, 2, &offset);
+ if(sq_gettop(v) > 2) {
+ SQInteger t;
+ sq_getinteger(v, 3, &t);
+ switch(t) {
+ case 'b': origin = SQ_SEEK_SET; break;
+ case 'c': origin = SQ_SEEK_CUR; break;
+ case 'e': origin = SQ_SEEK_END; break;
+ default: return sq_throwerror(v,_SC("invalid origin"));
+ }
+ }
+ sq_pushinteger(v, self->Seek(offset, origin));
+ return 1;
+}
+
+SQInteger _stream_tell(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ sq_pushinteger(v, self->Tell());
+ return 1;
+}
+
+SQInteger _stream_len(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ sq_pushinteger(v, self->Len());
+ return 1;
+}
+
+SQInteger _stream_flush(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ if(!self->Flush())
+ sq_pushinteger(v, 1);
+ else
+ sq_pushnull(v);
+ return 1;
+}
+
+SQInteger _stream_eos(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ if(self->EOS())
+ sq_pushinteger(v, 1);
+ else
+ sq_pushnull(v);
+ return 1;
+}
+
+static SQRegFunction _stream_methods[] = {
+ _DECL_STREAM_FUNC(readblob,2,_SC("xn")),
+ _DECL_STREAM_FUNC(readn,2,_SC("xn")),
+ _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
+ _DECL_STREAM_FUNC(writen,3,_SC("xnn")),
+ _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
+ _DECL_STREAM_FUNC(tell,1,_SC("x")),
+ _DECL_STREAM_FUNC(len,1,_SC("x")),
+ _DECL_STREAM_FUNC(eos,1,_SC("x")),
+ _DECL_STREAM_FUNC(flush,1,_SC("x")),
+ {0,0}
+};
+
+void init_streamclass(HSQUIRRELVM v)
+{
+ sq_pushregistrytable(v);
+ sq_pushstring(v,_SC("std_stream"),-1);
+ if(SQ_FAILED(sq_get(v,-2))) {
+ sq_pushstring(v,_SC("std_stream"),-1);
+ sq_newclass(v,SQFalse);
+ sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);
+ SQInteger i = 0;
+ while(_stream_methods[i].name != 0) {
+ SQRegFunction &f = _stream_methods[i];
+ sq_pushstring(v,f.name,-1);
+ sq_newclosure(v,f.f,0);
+ sq_setparamscheck(v,f.nparamscheck,f.typemask);
+ sq_createslot(v,-3);
+ i++;
+ }
+ sq_createslot(v,-3);
+ sq_pushroottable(v);
+ sq_pushstring(v,_SC("stream"),-1);
+ sq_pushstring(v,_SC("std_stream"),-1);
+ sq_get(v,-4);
+ sq_createslot(v,-3);
+ sq_pop(v,1);
+ }
+ else {
+ sq_pop(v,1); //result
+ }
+ sq_pop(v,1);
+}
+
+SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
+{
+ if(sq_gettype(v,-1) != OT_TABLE)
+ return sq_throwerror(v,_SC("table expected"));
+ SQInteger top = sq_gettop(v);
+ //create delegate
+ init_streamclass(v);
+ sq_pushregistrytable(v);
+ sq_pushstring(v,reg_name,-1);
+ sq_pushstring(v,_SC("std_stream"),-1);
+ if(SQ_SUCCEEDED(sq_get(v,-3))) {
+ sq_newclass(v,SQTrue);
+ sq_settypetag(v,-1,typetag);
+ SQInteger i = 0;
+ while(methods[i].name != 0) {
+ SQRegFunction &f = methods[i];
+ sq_pushstring(v,f.name,-1);
+ sq_newclosure(v,f.f,0);
+ sq_setparamscheck(v,f.nparamscheck,f.typemask);
+ sq_setnativeclosurename(v,-1,f.name);
+ sq_createslot(v,-3);
+ i++;
+ }
+ sq_createslot(v,-3);
+ sq_pop(v,1);
+
+ i = 0;
+ while(globals[i].name!=0)
+ {
+ SQRegFunction &f = globals[i];
+ sq_pushstring(v,f.name,-1);
+ sq_newclosure(v,f.f,0);
+ sq_setparamscheck(v,f.nparamscheck,f.typemask);
+ sq_setnativeclosurename(v,-1,f.name);
+ sq_createslot(v,-3);
+ i++;
+ }
+ //register the class in the target table
+ sq_pushstring(v,name,-1);
+ sq_pushregistrytable(v);
+ sq_pushstring(v,reg_name,-1);
+ sq_get(v,-2);
+ sq_remove(v,-2);
+ sq_createslot(v,-3);
+
+ sq_settop(v,top);
+ return SQ_OK;
+ }
+ sq_settop(v,top);
+ return SQ_ERROR;
+}