|
|
@@ -1,25 +1,25 @@
|
|
|
-/* 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"
|
|
|
+/* 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"
|
|
|
|
|
|
-static const SQChar SQSTD_STREAM_TYPE_TAG[] = _SC("std_stream");
|
|
|
-
|
|
|
-#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 || !self->IsValid()) \
|
|
|
- return sq_throwerror(v,_SC("the stream is invalid"));
|
|
|
+static const SQChar SQSTD_STREAM_TYPE_TAG[] = _SC("std_stream");
|
|
|
+
|
|
|
+#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 || !self->IsValid()) \
|
|
|
+ return sq_throwerror(v,_SC("the stream is invalid"));
|
|
|
|
|
|
SQInteger _stream_read_line(HSQUIRRELVM v) {
|
|
|
- SETUP_STREAM(v);
|
|
|
+ SETUP_STREAM(v);
|
|
|
const SQChar nl = _SC('\n');
|
|
|
const SQChar rc = _SC('\r');
|
|
|
SQInteger size, read_size;
|
|
|
@@ -64,424 +64,428 @@ SQInteger _stream_read_line(HSQUIRRELVM v) {
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-SQInteger _stream_read(HSQUIRRELVM v)
|
|
|
-{
|
|
|
- SETUP_STREAM(v);
|
|
|
- SQChar *data;
|
|
|
- SQInteger size,res;
|
|
|
+SQInteger _stream_read(HSQUIRRELVM v)
|
|
|
+{
|
|
|
+ SETUP_STREAM(v);
|
|
|
+ SQChar *data;
|
|
|
+ SQInteger size,res;
|
|
|
sq_getinteger(v,2,&size);
|
|
|
- /* DAD come back here
|
|
|
- if(self->GetHandle() != stdin && size > self->Len()) {
|
|
|
- size = self->Len();
|
|
|
+ /* DAD come back here
|
|
|
+ if(self->GetHandle() != stdin && 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"));
|
|
|
- sq_pushstring(v,data,res);
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-SQInteger _stream_gets(HSQUIRRELVM v)
|
|
|
-{
|
|
|
- SETUP_STREAM(v);
|
|
|
- SQChar *data;
|
|
|
+ */
|
|
|
+ data = sq_getscratchpad(v,size);
|
|
|
+ res = self->Read(data,size);
|
|
|
+ if(res <= 0)
|
|
|
+ return sq_throwerror(v,_SC("no data left to read"));
|
|
|
+ sq_pushstring(v,data,res);
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+SQInteger _stream_gets(HSQUIRRELVM v)
|
|
|
+{
|
|
|
+ SETUP_STREAM(v);
|
|
|
+ SQChar *data;
|
|
|
SQInteger size, read_size;
|
|
|
sq_getinteger(v,2,&size);
|
|
|
- /* DAD come back here
|
|
|
- if(self->GetHandle() != stdin && size > self->Len()) {
|
|
|
- size = self->Len();
|
|
|
- }
|
|
|
- */
|
|
|
- data = sq_getscratchpad(v,size);
|
|
|
- read_size = self->Gets(data,size);
|
|
|
- if(!read_size)
|
|
|
- return sq_throwerror(v,_SC("no data left to read"));
|
|
|
- sq_pushstring(v,data,read_size);
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-SQInteger _stream_readblob(HSQUIRRELVM v)
|
|
|
-{
|
|
|
- SETUP_STREAM(v);
|
|
|
- SQUserPointer blobp;
|
|
|
- SQInteger size,res;
|
|
|
- sq_getinteger(v,2,&size);
|
|
|
- if(size > self->Len()) {
|
|
|
- size = self->Len();
|
|
|
- }
|
|
|
- blobp = sqstd_createblob(v,size);
|
|
|
- res = self->Read(blobp,size);
|
|
|
- if(res <= 0)
|
|
|
- return sq_throwerror(v,_SC("no data left to read"));
|
|
|
- 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"));
|
|
|
+ /* DAD come back here
|
|
|
+ if(self->GetHandle() != stdin && size > self->Len()) {
|
|
|
+ size = self->Len();
|
|
|
}
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-SQInteger _stream_write_str(HSQUIRRELVM v)
|
|
|
+ */
|
|
|
+ data = sq_getscratchpad(v,size);
|
|
|
+ read_size = self->Gets(data,size);
|
|
|
+ if(!read_size)
|
|
|
+ return sq_throwerror(v,_SC("no data left to read"));
|
|
|
+ sq_pushstring(v,data,read_size);
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+SQInteger _stream_readblob(HSQUIRRELVM v)
|
|
|
+{
|
|
|
+ SETUP_STREAM(v);
|
|
|
+ SQUserPointer blobp;
|
|
|
+ SQInteger size,res;
|
|
|
+ sq_getinteger(v,2,&size);
|
|
|
+ if(size > self->Len()) {
|
|
|
+ size = self->Len();
|
|
|
+ }
|
|
|
+ blobp = sqstd_createblob(v,size);
|
|
|
+ res = self->Read(blobp,size);
|
|
|
+ if(res <= 0)
|
|
|
+ return sq_throwerror(v,_SC("no data left to read"));
|
|
|
+ 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_write_str(HSQUIRRELVM v)
|
|
|
{
|
|
|
- SQ_FUNC_VARS(v);
|
|
|
+ SQ_FUNC_VARS(v);
|
|
|
SETUP_STREAM(v);
|
|
|
SQ_GET_STRING(v, 2, str);
|
|
|
SQ_OPT_INTEGER(v, 3, start, 0);
|
|
|
- if(start < 0 || start > str_size) return sq_throwerror(v, _SC("start position out of range (%d)"), start);
|
|
|
+ if(start < 0 || start > str_size) return sq_throwerror(v, _SC("start position out of range (%d)"), start);
|
|
|
SQ_OPT_INTEGER(v, 4, len, str_size - start);
|
|
|
- if(len < 0 || len > (str_size-start)) return sq_throwerror(v, _SC("len value out of range (%d)"), len);
|
|
|
+ if(len < 0 || len > (str_size-start)) return sq_throwerror(v, _SC("len value out of range (%d)"), len);
|
|
|
+
|
|
|
+ if(self->Write(((SQChar*)str)+start, len) != len)
|
|
|
+ return sq_throwerror(v,_SC("io error"));
|
|
|
+ sq_pushinteger(v,len);
|
|
|
+ return 1;
|
|
|
+}
|
|
|
|
|
|
- if(self->Write(((SQChar*)str)+start, len) != len)
|
|
|
- return sq_throwerror(v,_SC("io error"));
|
|
|
- sq_pushinteger(v,len);
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-SQInteger _stream_write(HSQUIRRELVM v)
|
|
|
-{
|
|
|
- const SQChar *str;
|
|
|
- SQInteger total_size, size;
|
|
|
+SQInteger _stream_write(HSQUIRRELVM v)
|
|
|
+{
|
|
|
+ const SQChar *str;
|
|
|
+ SQInteger total_size, size;
|
|
|
SETUP_STREAM(v);
|
|
|
- total_size = 0;
|
|
|
+ total_size = 0;
|
|
|
for(SQInteger i=2, len=sq_gettop(v); i <= len; ++i){
|
|
|
- if(SQ_FAILED(sq_tostring(v,i)))
|
|
|
- return sq_throwerror(v,_SC("invalid parameter"));
|
|
|
- sq_getstring(v,-1,&str);
|
|
|
- size = sq_getsize(v,-1);
|
|
|
- if(self->Write((SQChar*)str,size) != size)
|
|
|
- return sq_throwerror(v,_SC("io error"));
|
|
|
+ if(SQ_FAILED(sq_tostring(v,i)))
|
|
|
+ return sq_throwerror(v,_SC("invalid parameter"));
|
|
|
+ sq_getstring(v,-1,&str);
|
|
|
+ size = sq_getsize(v,-1);
|
|
|
+ if(self->Write((SQChar*)str,size) != size)
|
|
|
+ return sq_throwerror(v,_SC("io error"));
|
|
|
sq_poptop(v); //remove converted string
|
|
|
total_size += size;
|
|
|
- }
|
|
|
- sq_pushinteger(v,total_size);
|
|
|
- return 1;
|
|
|
-}
|
|
|
+ }
|
|
|
+ sq_pushinteger(v,total_size);
|
|
|
+ return 1;
|
|
|
+}
|
|
|
|
|
|
-SQInteger _stream_write_non_null(HSQUIRRELVM v)
|
|
|
+SQInteger _stream_write_non_null(HSQUIRRELVM v)
|
|
|
{
|
|
|
if(sq_gettype(v, 2) != OT_NULL)
|
|
|
{
|
|
|
return _stream_write(v);
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-SQInteger _stream_write_fmt(HSQUIRRELVM v)
|
|
|
-{
|
|
|
- const SQChar *str;
|
|
|
- SQInteger size;
|
|
|
- SETUP_STREAM(v);
|
|
|
- if(SQ_FAILED(sq_tostring(v,2)))
|
|
|
- return sq_throwerror(v,_SC("invalid parameter"));
|
|
|
- sq_getstring(v,-1,&str);
|
|
|
- size = sq_getsize(v,-1);
|
|
|
- if(self->Write((SQChar*)str,size) != size)
|
|
|
- return sq_throwerror(v,_SC("io error"));
|
|
|
- sq_poptop(v); //remove converted string
|
|
|
- sq_pushinteger(v,size);
|
|
|
- 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 = (float)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;
|
|
|
-}
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
-SQInteger _stream_flush(HSQUIRRELVM v)
|
|
|
-{
|
|
|
- SETUP_STREAM(v);
|
|
|
- if(!self->Flush())
|
|
|
- sq_pushinteger(v, 1);
|
|
|
- else
|
|
|
- sq_pushnull(v);
|
|
|
- return 1;
|
|
|
-}
|
|
|
+SQInteger _stream_write_fmt(HSQUIRRELVM v)
|
|
|
+{
|
|
|
+ const SQChar *str;
|
|
|
+ SQInteger size;
|
|
|
+ SETUP_STREAM(v);
|
|
|
+ if(SQ_FAILED(sq_tostring(v,2)))
|
|
|
+ return sq_throwerror(v,_SC("invalid parameter"));
|
|
|
+ sq_getstring(v,-1,&str);
|
|
|
+ size = sq_getsize(v,-1);
|
|
|
+ if(self->Write((SQChar*)str,size) != size)
|
|
|
+ return sq_throwerror(v,_SC("io error"));
|
|
|
+ sq_poptop(v); //remove converted string
|
|
|
+ sq_pushinteger(v,size);
|
|
|
+ return 1;
|
|
|
+}
|
|
|
|
|
|
-SQInteger _stream_eos(HSQUIRRELVM v)
|
|
|
-{
|
|
|
- SETUP_STREAM(v);
|
|
|
- if(self->EOS())
|
|
|
- sq_pushinteger(v, 1);
|
|
|
- else
|
|
|
- sq_pushnull(v);
|
|
|
- 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 = (float)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;
|
|
|
+}
|
|
|
+
|
|
|
+ SQInteger _stream__cloned(HSQUIRRELVM v)
|
|
|
+ {
|
|
|
+ return sq_throwerror(v,_SC("this object cannot be cloned"));
|
|
|
+ }
|
|
|
|
|
|
- SQInteger _stream__cloned(HSQUIRRELVM v)
|
|
|
- {
|
|
|
- return sq_throwerror(v,_SC("this object cannot be cloned"));
|
|
|
- }
|
|
|
-
|
|
|
-static SQRegFunction _stream_methods[] = {
|
|
|
- _DECL_STREAM_FUNC(read_line,-1,_SC("xi")),
|
|
|
- _DECL_STREAM_FUNC(read,2,_SC("xn")),
|
|
|
- _DECL_STREAM_FUNC(gets,2,_SC("xn")),
|
|
|
- _DECL_STREAM_FUNC(readblob,2,_SC("xn")),
|
|
|
- _DECL_STREAM_FUNC(readn,2,_SC("xn")),
|
|
|
- _DECL_STREAM_FUNC(write_str,-2,_SC("xsii")),
|
|
|
- _DECL_STREAM_FUNC(write,-2,_SC("x.")),
|
|
|
- _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
|
|
|
- _DECL_STREAM_FUNC(writen,3,_SC("xnn")),
|
|
|
- _DECL_STREAM_FUNC(write_non_null,2,_SC("x.")),
|
|
|
- _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")),
|
|
|
- _DECL_STREAM_FUNC(_cloned,0,NULL),
|
|
|
- {NULL,(SQFUNCTION)0,0,NULL}
|
|
|
+#define _DECL_STREAM_FUNC2(name,name2, nparams,typecheck) {_SC(#name2),_stream_##name,nparams,typecheck}
|
|
|
+
|
|
|
+static SQRegFunction _stream_methods[] = {
|
|
|
+ _DECL_STREAM_FUNC(read_line,-1,_SC("xi")),
|
|
|
+ _DECL_STREAM_FUNC(read,2,_SC("xn")),
|
|
|
+ _DECL_STREAM_FUNC(gets,2,_SC("xn")),
|
|
|
+ _DECL_STREAM_FUNC(readblob,2,_SC("xn")),
|
|
|
+ _DECL_STREAM_FUNC(readn,2,_SC("xn")),
|
|
|
+ _DECL_STREAM_FUNC(write_str,-2,_SC("xsii")),
|
|
|
+ _DECL_STREAM_FUNC(write,-2,_SC("x.")),
|
|
|
+ _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
|
|
|
+ _DECL_STREAM_FUNC(writen,3,_SC("xnn")),
|
|
|
+ _DECL_STREAM_FUNC(write_non_null,2,_SC("x.")),
|
|
|
+ _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
|
|
|
+ _DECL_STREAM_FUNC(tell,1,_SC("x")),
|
|
|
+ _DECL_STREAM_FUNC(len,1,_SC("x")),
|
|
|
+ _DECL_STREAM_FUNC2(len,size,1,_SC("x")),
|
|
|
+ _DECL_STREAM_FUNC2(len,length,1,_SC("x")),
|
|
|
+ _DECL_STREAM_FUNC(eos,1,_SC("x")),
|
|
|
+ _DECL_STREAM_FUNC(flush,1,_SC("x")),
|
|
|
+ _DECL_STREAM_FUNC(_cloned,0,NULL),
|
|
|
+ {NULL,(SQFUNCTION)0,0,NULL}
|
|
|
};
|
|
|
|
|
|
-void init_streamclass(HSQUIRRELVM v)
|
|
|
-{
|
|
|
- sq_pushregistrytable(v);
|
|
|
- sq_pushstring(v,SQSTD_STREAM_TYPE_TAG,-1);
|
|
|
- if(SQ_FAILED(sq_get(v,-2))) {
|
|
|
- sq_pushstring(v,SQSTD_STREAM_TYPE_TAG,-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_newslot(v,-3,SQFalse);
|
|
|
- i++;
|
|
|
- }
|
|
|
- sq_newslot(v,-3,SQFalse);
|
|
|
- sq_pushroottable(v);
|
|
|
- sq_pushstring(v,_SC("stream"),-1);
|
|
|
- sq_pushstring(v,_SC("std_stream"),-1);
|
|
|
- sq_get(v,-4);
|
|
|
- sq_newslot(v,-3,SQFalse);
|
|
|
- sq_pop(v,1);
|
|
|
- }
|
|
|
- else {
|
|
|
- sq_pop(v,1); //result
|
|
|
- }
|
|
|
- sq_pop(v,1);
|
|
|
-}
|
|
|
-
|
|
|
-SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,const SQRegFunction *methods,const 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) {
|
|
|
- const 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_newslot(v,-3,SQFalse);
|
|
|
- i++;
|
|
|
- }
|
|
|
- sq_newslot(v,-3,SQFalse);
|
|
|
- sq_pop(v,1);
|
|
|
-
|
|
|
- i = 0;
|
|
|
- while(globals[i].name!=0)
|
|
|
- {
|
|
|
- const 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_newslot(v,-3,SQFalse);
|
|
|
- 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_newslot(v,-3,SQFalse);
|
|
|
-
|
|
|
- sq_settop(v,top);
|
|
|
- return SQ_OK;
|
|
|
- }
|
|
|
- sq_settop(v,top);
|
|
|
- return SQ_ERROR;
|
|
|
-}
|
|
|
+void init_streamclass(HSQUIRRELVM v)
|
|
|
+{
|
|
|
+ sq_pushregistrytable(v);
|
|
|
+ sq_pushstring(v,SQSTD_STREAM_TYPE_TAG,-1);
|
|
|
+ if(SQ_FAILED(sq_get(v,-2))) {
|
|
|
+ sq_pushstring(v,SQSTD_STREAM_TYPE_TAG,-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_newslot(v,-3,SQFalse);
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ sq_newslot(v,-3,SQFalse);
|
|
|
+ sq_pushroottable(v);
|
|
|
+ sq_pushstring(v,_SC("stream"),-1);
|
|
|
+ sq_pushstring(v,_SC("std_stream"),-1);
|
|
|
+ sq_get(v,-4);
|
|
|
+ sq_newslot(v,-3,SQFalse);
|
|
|
+ sq_pop(v,1);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ sq_pop(v,1); //result
|
|
|
+ }
|
|
|
+ sq_pop(v,1);
|
|
|
+}
|
|
|
+
|
|
|
+SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,const SQRegFunction *methods,const 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) {
|
|
|
+ const 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_newslot(v,-3,SQFalse);
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ sq_newslot(v,-3,SQFalse);
|
|
|
+ sq_pop(v,1);
|
|
|
+
|
|
|
+ i = 0;
|
|
|
+ while(globals[i].name!=0)
|
|
|
+ {
|
|
|
+ const 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_newslot(v,-3,SQFalse);
|
|
|
+ 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_newslot(v,-3,SQFalse);
|
|
|
+
|
|
|
+ sq_settop(v,top);
|
|
|
+ return SQ_OK;
|
|
|
+ }
|
|
|
+ sq_settop(v,top);
|
|
|
+ return SQ_ERROR;
|
|
|
+}
|