Code::Blocks  SVN r11506
sqstdstream.cpp
Go to the documentation of this file.
1 /* see copyright notice in squirrel.h */
2 #include <new>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <squirrel.h>
7 #include <sqstdio.h>
8 #include <sqstdblob.h>
9 #include "sqstdstream.h"
10 #include "sqstdblobimpl.h"
11 
12 #define SETUP_STREAM(v) \
13  SQStream *self = NULL; \
14  if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \
15  return sq_throwerror(v,_SC("invalid type tag")); \
16  if(!self->IsValid()) \
17  return sq_throwerror(v,_SC("the stream is invalid"));
18 
19 SQInteger _stream_readblob(HSQUIRRELVM v)
20 {
21  SETUP_STREAM(v);
22  SQUserPointer data,blobp;
23  SQInteger size,res;
24  sq_getinteger(v,2,&size);
25  if(size > self->Len()) {
26  size = self->Len();
27  }
28  data = sq_getscratchpad(v,size);
29  res = self->Read(data,size);
30  if(res <= 0)
31  return sq_throwerror(v,_SC("no data left to read"));
32  blobp = sqstd_createblob(v,res);
33  memcpy(blobp,data,res);
34  return 1;
35 }
36 
37 #define SAFE_READN(ptr,len) { \
38  if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
39  }
40 SQInteger _stream_readn(HSQUIRRELVM v)
41 {
42  SETUP_STREAM(v);
43  SQInteger format;
44  sq_getinteger(v, 2, &format);
45  switch(format) {
46  case 'l': {
47  SQInteger i;
48  SAFE_READN(&i, sizeof(i));
49  sq_pushinteger(v, i);
50  }
51  break;
52  case 'i': {
53  SQInt32 i;
54  SAFE_READN(&i, sizeof(i));
55  sq_pushinteger(v, i);
56  }
57  break;
58  case 's': {
59  short s;
60  SAFE_READN(&s, sizeof(short));
61  sq_pushinteger(v, s);
62  }
63  break;
64  case 'w': {
65  unsigned short w;
66  SAFE_READN(&w, sizeof(unsigned short));
67  sq_pushinteger(v, w);
68  }
69  break;
70  case 'c': {
71  char c;
72  SAFE_READN(&c, sizeof(char));
73  sq_pushinteger(v, c);
74  }
75  break;
76  case 'b': {
77  unsigned char c;
78  SAFE_READN(&c, sizeof(unsigned char));
79  sq_pushinteger(v, c);
80  }
81  break;
82  case 'f': {
83  float f;
84  SAFE_READN(&f, sizeof(float));
85  sq_pushfloat(v, f);
86  }
87  break;
88  case 'd': {
89  double d;
90  SAFE_READN(&d, sizeof(double));
91  sq_pushfloat(v, (SQFloat)d);
92  }
93  break;
94  default:
95  return sq_throwerror(v, _SC("invalid format"));
96  }
97  return 1;
98 }
99 
100 SQInteger _stream_writeblob(HSQUIRRELVM v)
101 {
102  SQUserPointer data;
103  SQInteger size;
104  SETUP_STREAM(v);
105  if(SQ_FAILED(sqstd_getblob(v,2,&data)))
106  return sq_throwerror(v,_SC("invalid parameter"));
107  size = sqstd_getblobsize(v,2);
108  if(self->Write(data,size) != size)
109  return sq_throwerror(v,_SC("io error"));
110  sq_pushinteger(v,size);
111  return 1;
112 }
113 
114 SQInteger _stream_writen(HSQUIRRELVM v)
115 {
116  SETUP_STREAM(v);
117  SQInteger format, ti;
118  SQFloat tf;
119  sq_getinteger(v, 3, &format);
120  switch(format) {
121  case 'l': {
122  SQInteger i;
123  sq_getinteger(v, 2, &ti);
124  i = ti;
125  self->Write(&i, sizeof(SQInteger));
126  }
127  break;
128  case 'i': {
129  SQInt32 i;
130  sq_getinteger(v, 2, &ti);
131  i = (SQInt32)ti;
132  self->Write(&i, sizeof(SQInt32));
133  }
134  break;
135  case 's': {
136  short s;
137  sq_getinteger(v, 2, &ti);
138  s = (short)ti;
139  self->Write(&s, sizeof(short));
140  }
141  break;
142  case 'w': {
143  unsigned short w;
144  sq_getinteger(v, 2, &ti);
145  w = (unsigned short)ti;
146  self->Write(&w, sizeof(unsigned short));
147  }
148  break;
149  case 'c': {
150  char c;
151  sq_getinteger(v, 2, &ti);
152  c = (char)ti;
153  self->Write(&c, sizeof(char));
154  }
155  break;
156  case 'b': {
157  unsigned char b;
158  sq_getinteger(v, 2, &ti);
159  b = (unsigned char)ti;
160  self->Write(&b, sizeof(unsigned char));
161  }
162  break;
163  case 'f': {
164  float f;
165  sq_getfloat(v, 2, &tf);
166  f = (float)tf;
167  self->Write(&f, sizeof(float));
168  }
169  break;
170  case 'd': {
171  double d;
172  sq_getfloat(v, 2, &tf);
173  d = tf;
174  self->Write(&d, sizeof(double));
175  }
176  break;
177  default:
178  return sq_throwerror(v, _SC("invalid format"));
179  }
180  return 0;
181 }
182 
183 SQInteger _stream_seek(HSQUIRRELVM v)
184 {
185  SETUP_STREAM(v);
186  SQInteger offset, origin = SQ_SEEK_SET;
187  sq_getinteger(v, 2, &offset);
188  if(sq_gettop(v) > 2) {
189  SQInteger t;
190  sq_getinteger(v, 3, &t);
191  switch(t) {
192  case 'b': origin = SQ_SEEK_SET; break;
193  case 'c': origin = SQ_SEEK_CUR; break;
194  case 'e': origin = SQ_SEEK_END; break;
195  default: return sq_throwerror(v,_SC("invalid origin"));
196  }
197  }
198  sq_pushinteger(v, self->Seek(offset, origin));
199  return 1;
200 }
201 
202 SQInteger _stream_tell(HSQUIRRELVM v)
203 {
204  SETUP_STREAM(v);
205  sq_pushinteger(v, self->Tell());
206  return 1;
207 }
208 
209 SQInteger _stream_len(HSQUIRRELVM v)
210 {
211  SETUP_STREAM(v);
212  sq_pushinteger(v, self->Len());
213  return 1;
214 }
215 
216 SQInteger _stream_flush(HSQUIRRELVM v)
217 {
218  SETUP_STREAM(v);
219  if(!self->Flush())
220  sq_pushinteger(v, 1);
221  else
222  sq_pushnull(v);
223  return 1;
224 }
225 
226 SQInteger _stream_eos(HSQUIRRELVM v)
227 {
228  SETUP_STREAM(v);
229  if(self->EOS())
230  sq_pushinteger(v, 1);
231  else
232  sq_pushnull(v);
233  return 1;
234 }
235 
236 static SQRegFunction _stream_methods[] = {
237  _DECL_STREAM_FUNC(readblob,2,_SC("xn")),
238  _DECL_STREAM_FUNC(readn,2,_SC("xn")),
239  _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
240  _DECL_STREAM_FUNC(writen,3,_SC("xnn")),
241  _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
242  _DECL_STREAM_FUNC(tell,1,_SC("x")),
243  _DECL_STREAM_FUNC(len,1,_SC("x")),
244  _DECL_STREAM_FUNC(eos,1,_SC("x")),
245  _DECL_STREAM_FUNC(flush,1,_SC("x")),
246  {0,0}
247 };
248 
249 void init_streamclass(HSQUIRRELVM v)
250 {
252  sq_pushstring(v,_SC("std_stream"),-1);
253  if(SQ_FAILED(sq_get(v,-2))) {
254  sq_pushstring(v,_SC("std_stream"),-1);
255  sq_newclass(v,SQFalse);
256  sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);
257  SQInteger i = 0;
258  while(_stream_methods[i].name != 0) {
259  SQRegFunction &f = _stream_methods[i];
260  sq_pushstring(v,f.name,-1);
261  sq_newclosure(v,f.f,0);
262  sq_setparamscheck(v,f.nparamscheck,f.typemask);
263  sq_createslot(v,-3);
264  i++;
265  }
266  sq_createslot(v,-3);
267  sq_pushroottable(v);
268  sq_pushstring(v,_SC("stream"),-1);
269  sq_pushstring(v,_SC("std_stream"),-1);
270  sq_get(v,-4);
271  sq_createslot(v,-3);
272  sq_pop(v,1);
273  }
274  else {
275  sq_pop(v,1); //result
276  }
277  sq_pop(v,1);
278 }
279 
280 SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
281 {
282  if(sq_gettype(v,-1) != OT_TABLE)
283  return sq_throwerror(v,_SC("table expected"));
284  SQInteger top = sq_gettop(v);
285  //create delegate
286  init_streamclass(v);
288  sq_pushstring(v,reg_name,-1);
289  sq_pushstring(v,_SC("std_stream"),-1);
290  if(SQ_SUCCEEDED(sq_get(v,-3))) {
291  sq_newclass(v,SQTrue);
292  sq_settypetag(v,-1,typetag);
293  SQInteger i = 0;
294  while(methods[i].name != 0) {
295  SQRegFunction &f = methods[i];
296  sq_pushstring(v,f.name,-1);
297  sq_newclosure(v,f.f,0);
298  sq_setparamscheck(v,f.nparamscheck,f.typemask);
299  sq_setnativeclosurename(v,-1,f.name);
300  sq_createslot(v,-3);
301  i++;
302  }
303  sq_createslot(v,-3);
304  sq_pop(v,1);
305 
306  i = 0;
307  while(globals[i].name!=0)
308  {
309  SQRegFunction &f = globals[i];
310  sq_pushstring(v,f.name,-1);
311  sq_newclosure(v,f.f,0);
312  sq_setparamscheck(v,f.nparamscheck,f.typemask);
313  sq_setnativeclosurename(v,-1,f.name);
314  sq_createslot(v,-3);
315  i++;
316  }
317  //register the class in the target table
318  sq_pushstring(v,name,-1);
320  sq_pushstring(v,reg_name,-1);
321  sq_get(v,-2);
322  sq_remove(v,-2);
323  sq_createslot(v,-3);
324 
325  sq_settop(v,top);
326  return SQ_OK;
327  }
328  sq_settop(v,top);
329  return SQ_ERROR;
330 }
SQRESULT sq_get(HSQUIRRELVM v, SQInteger idx)
Definition: sqapi.cpp:840
#define SETUP_STREAM(v)
Definition: sqstdstream.cpp:12
SQRESULT sq_newclass(HSQUIRRELVM v, SQBool hasbase)
Definition: sqapi.cpp:239
void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop)
Definition: sqapi.cpp:678
SQInteger _stream_len(HSQUIRRELVM v)
#define SAFE_READN(ptr, len)
Definition: sqstdstream.cpp:37
SQRESULT sq_throwerror(HSQUIRRELVM v, const SQChar *err)
Definition: sqapi.cpp:918
SQInteger _stream_writen(HSQUIRRELVM v)
SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size)
Definition: sqstdblob.cpp:228
void sq_pushnull(HSQUIRRELVM v)
Definition: sqapi.cpp:190
void sq_pushroottable(HSQUIRRELVM v)
Definition: sqapi.cpp:437
void sq_pushregistrytable(HSQUIRRELVM v)
Definition: sqapi.cpp:442
void sq_pushfloat(HSQUIRRELVM v, SQFloat n)
Definition: sqapi.cpp:212
SQRESULT sq_getinteger(HSQUIRRELVM v, SQInteger idx, SQInteger *i)
Definition: sqapi.cpp:509
void init_streamclass(HSQUIRRELVM v)
SQInteger sq_gettop(HSQUIRRELVM v)
Definition: sqapi.cpp:664
void sq_pushinteger(HSQUIRRELVM v, SQInteger n)
Definition: sqapi.cpp:202
void sq_newclosure(HSQUIRRELVM v, SQFUNCTION func, SQUnsignedInteger nfreevars)
Definition: sqapi.cpp:338
SQRESULT sq_setnativeclosurename(HSQUIRRELVM v, SQInteger idx, const SQChar *name)
Definition: sqapi.cpp:362
void sq_settop(HSQUIRRELVM v, SQInteger newtop)
Definition: sqapi.cpp:669
SQRESULT sq_getfloat(HSQUIRRELVM v, SQInteger idx, SQFloat *f)
Definition: sqapi.cpp:519
SQInteger _stream_flush(HSQUIRRELVM v)
void sq_remove(HSQUIRRELVM v, SQInteger idx)
Definition: sqapi.cpp:691
SQInteger _stream_writeblob(HSQUIRRELVM v)
SQRESULT sq_setparamscheck(HSQUIRRELVM v, SQInteger nparamscheck, const SQChar *typemask)
Definition: sqapi.cpp:373
SQInteger sqstd_getblobsize(HSQUIRRELVM v, SQInteger idx)
Definition: sqstdblob.cpp:220
void sq_pushstring(HSQUIRRELVM v, const SQChar *s, SQInteger len)
Definition: sqapi.cpp:195
SQObjectType sq_gettype(HSQUIRRELVM v, SQInteger idx)
Definition: sqapi.cpp:489
SQRESULT sqstd_getblob(HSQUIRRELVM v, SQInteger idx, SQUserPointer *ptr)
Definition: sqstdblob.cpp:211
SQRESULT declare_stream(HSQUIRRELVM v, const SQChar *name, SQUserPointer typetag, const SQChar *reg_name, SQRegFunction *methods, SQRegFunction *globals)
char SQChar
SQInteger _stream_tell(HSQUIRRELVM v)
SQRESULT sq_settypetag(HSQUIRRELVM v, SQInteger idx, SQUserPointer typetag)
Definition: sqapi.cpp:591
SQChar * sq_getscratchpad(HSQUIRRELVM v, SQInteger minsize)
Definition: sqapi.cpp:1044
SQInteger _stream_seek(HSQUIRRELVM v)
static SQRegFunction _stream_methods[]
SQInteger _stream_readblob(HSQUIRRELVM v)
Definition: sqstdstream.cpp:19
SQInteger _stream_eos(HSQUIRRELVM v)
SQInteger _stream_readn(HSQUIRRELVM v)
Definition: sqstdstream.cpp:40