Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

333 lines
7.0 KiB

  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. #if defined(VSCRIPT_DLL_EXPORT) || defined(VSQUIRREL_TEST)
  12. #include "memdbgon.h"
  13. #endif
  14. #define SETUP_STREAM(v) \
  15. SQStream *self = NULL; \
  16. if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \
  17. return sq_throwerror(v,_SC("invalid type tag")); \
  18. if(!self->IsValid()) \
  19. return sq_throwerror(v,_SC("the stream is invalid"));
  20. SQInteger _stream_readblob(HSQUIRRELVM v)
  21. {
  22. SETUP_STREAM(v);
  23. SQUserPointer data,blobp;
  24. SQInteger size,res;
  25. sq_getinteger(v,2,&size);
  26. if(size > self->Len()) {
  27. size = self->Len();
  28. }
  29. data = sq_getscratchpad(v,size);
  30. res = self->Read(data,size);
  31. if(res <= 0)
  32. return sq_throwerror(v,_SC("no data left to read"));
  33. blobp = sqstd_createblob(v,res);
  34. memcpy(blobp,data,res);
  35. return 1;
  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. SQInteger _stream_writeblob(HSQUIRRELVM v)
  100. {
  101. SQUserPointer data;
  102. SQInteger size;
  103. SETUP_STREAM(v);
  104. if(SQ_FAILED(sqstd_getblob(v,2,&data)))
  105. return sq_throwerror(v,_SC("invalid parameter"));
  106. size = sqstd_getblobsize(v,2);
  107. if(self->Write(data,size) != size)
  108. return sq_throwerror(v,_SC("io error"));
  109. sq_pushinteger(v,size);
  110. return 1;
  111. }
  112. SQInteger _stream_writen(HSQUIRRELVM v)
  113. {
  114. SETUP_STREAM(v);
  115. SQInteger format, ti;
  116. SQFloat tf;
  117. sq_getinteger(v, 3, &format);
  118. switch(format) {
  119. case 'l': {
  120. SQInteger i;
  121. sq_getinteger(v, 2, &ti);
  122. i = ti;
  123. self->Write(&i, sizeof(SQInteger));
  124. }
  125. break;
  126. case 'i': {
  127. SQInt32 i;
  128. sq_getinteger(v, 2, &ti);
  129. i = (SQInt32)ti;
  130. self->Write(&i, sizeof(SQInt32));
  131. }
  132. break;
  133. case 's': {
  134. short s;
  135. sq_getinteger(v, 2, &ti);
  136. s = (short)ti;
  137. self->Write(&s, sizeof(short));
  138. }
  139. break;
  140. case 'w': {
  141. unsigned short w;
  142. sq_getinteger(v, 2, &ti);
  143. w = (unsigned short)ti;
  144. self->Write(&w, sizeof(unsigned short));
  145. }
  146. break;
  147. case 'c': {
  148. char c;
  149. sq_getinteger(v, 2, &ti);
  150. c = (char)ti;
  151. self->Write(&c, sizeof(char));
  152. }
  153. break;
  154. case 'b': {
  155. unsigned char b;
  156. sq_getinteger(v, 2, &ti);
  157. b = (unsigned char)ti;
  158. self->Write(&b, sizeof(unsigned char));
  159. }
  160. break;
  161. case 'f': {
  162. float f;
  163. sq_getfloat(v, 2, &tf);
  164. f = (float)tf;
  165. self->Write(&f, sizeof(float));
  166. }
  167. break;
  168. case 'd': {
  169. double d;
  170. sq_getfloat(v, 2, &tf);
  171. d = tf;
  172. self->Write(&d, sizeof(double));
  173. }
  174. break;
  175. default:
  176. return sq_throwerror(v, _SC("invalid format"));
  177. }
  178. return 0;
  179. }
  180. SQInteger _stream_seek(HSQUIRRELVM v)
  181. {
  182. SETUP_STREAM(v);
  183. SQInteger offset, origin = SQ_SEEK_SET;
  184. sq_getinteger(v, 2, &offset);
  185. if(sq_gettop(v) > 2) {
  186. SQInteger t;
  187. sq_getinteger(v, 3, &t);
  188. switch(t) {
  189. case 'b': origin = SQ_SEEK_SET; break;
  190. case 'c': origin = SQ_SEEK_CUR; break;
  191. case 'e': origin = SQ_SEEK_END; break;
  192. default: return sq_throwerror(v,_SC("invalid origin"));
  193. }
  194. }
  195. sq_pushinteger(v, self->Seek(offset, origin));
  196. return 1;
  197. }
  198. SQInteger _stream_tell(HSQUIRRELVM v)
  199. {
  200. SETUP_STREAM(v);
  201. sq_pushinteger(v, self->Tell());
  202. return 1;
  203. }
  204. SQInteger _stream_len(HSQUIRRELVM v)
  205. {
  206. SETUP_STREAM(v);
  207. sq_pushinteger(v, self->Len());
  208. return 1;
  209. }
  210. SQInteger _stream_flush(HSQUIRRELVM v)
  211. {
  212. SETUP_STREAM(v);
  213. if(!self->Flush())
  214. sq_pushinteger(v, 1);
  215. else
  216. sq_pushnull(v);
  217. return 1;
  218. }
  219. SQInteger _stream_eos(HSQUIRRELVM v)
  220. {
  221. SETUP_STREAM(v);
  222. if(self->EOS())
  223. sq_pushinteger(v, 1);
  224. else
  225. sq_pushnull(v);
  226. return 1;
  227. }
  228. static SQRegFunction _stream_methods[] = {
  229. _DECL_STREAM_FUNC(readblob,2,_SC("xn")),
  230. _DECL_STREAM_FUNC(readn,2,_SC("xn")),
  231. _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
  232. _DECL_STREAM_FUNC(writen,3,_SC("xnn")),
  233. _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
  234. _DECL_STREAM_FUNC(tell,1,_SC("x")),
  235. _DECL_STREAM_FUNC(len,1,_SC("x")),
  236. _DECL_STREAM_FUNC(eos,1,_SC("x")),
  237. _DECL_STREAM_FUNC(flush,1,_SC("x")),
  238. {0,0}
  239. };
  240. void init_streamclass(HSQUIRRELVM v)
  241. {
  242. sq_pushregistrytable(v);
  243. sq_pushstring(v,_SC("std_stream"),-1);
  244. if(SQ_FAILED(sq_get(v,-2))) {
  245. sq_pushstring(v,_SC("std_stream"),-1);
  246. sq_newclass(v,SQFalse);
  247. sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);
  248. SQInteger i = 0;
  249. while(_stream_methods[i].name != 0) {
  250. SQRegFunction &f = _stream_methods[i];
  251. sq_pushstring(v,f.name,-1);
  252. sq_newclosure(v,f.f,0);
  253. sq_setparamscheck(v,f.nparamscheck,f.typemask);
  254. sq_createslot(v,-3);
  255. i++;
  256. }
  257. sq_createslot(v,-3);
  258. sq_pushroottable(v);
  259. sq_pushstring(v,_SC("stream"),-1);
  260. sq_pushstring(v,_SC("std_stream"),-1);
  261. sq_get(v,-4);
  262. sq_createslot(v,-3);
  263. sq_pop(v,1);
  264. }
  265. else {
  266. sq_pop(v,1); //result
  267. }
  268. sq_pop(v,1);
  269. }
  270. SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
  271. {
  272. if(sq_gettype(v,-1) != OT_TABLE)
  273. return sq_throwerror(v,_SC("table expected"));
  274. SQInteger top = sq_gettop(v);
  275. //create delegate
  276. init_streamclass(v);
  277. sq_pushregistrytable(v);
  278. sq_pushstring(v,reg_name,-1);
  279. sq_pushstring(v,_SC("std_stream"),-1);
  280. if(SQ_SUCCEEDED(sq_get(v,-3))) {
  281. sq_newclass(v,SQTrue);
  282. sq_settypetag(v,-1,typetag);
  283. SQInteger i = 0;
  284. while(methods[i].name != 0) {
  285. SQRegFunction &f = methods[i];
  286. sq_pushstring(v,f.name,-1);
  287. sq_newclosure(v,f.f,0);
  288. sq_setparamscheck(v,f.nparamscheck,f.typemask);
  289. sq_setnativeclosurename(v,-1,f.name);
  290. sq_createslot(v,-3);
  291. i++;
  292. }
  293. sq_createslot(v,-3);
  294. sq_pop(v,1);
  295. i = 0;
  296. while(globals[i].name!=0)
  297. {
  298. SQRegFunction &f = globals[i];
  299. sq_pushstring(v,f.name,-1);
  300. sq_newclosure(v,f.f,0);
  301. sq_setparamscheck(v,f.nparamscheck,f.typemask);
  302. sq_setnativeclosurename(v,-1,f.name);
  303. sq_createslot(v,-3);
  304. i++;
  305. }
  306. //register the class in the target table
  307. sq_pushstring(v,name,-1);
  308. sq_pushregistrytable(v);
  309. sq_pushstring(v,reg_name,-1);
  310. sq_get(v,-2);
  311. sq_remove(v,-2);
  312. sq_createslot(v,-3);
  313. sq_settop(v,top);
  314. return SQ_OK;
  315. }
  316. sq_settop(v,top);
  317. return SQ_ERROR;
  318. }