The Squirrel interpreter. See http://www.squirrel-lang.org/
sqstdlib/sqstdio.cpp@3:7268a3ceaffc, 2014-12-16 (annotated)
- Committer:
- jhnwkmn
- Date:
- Tue Dec 16 11:39:42 2014 +0000
- Revision:
- 3:7268a3ceaffc
- Parent:
- 0:97a4f8cc534c
Accepts \r as line terminator as well.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jhnwkmn | 0:97a4f8cc534c | 1 | /* see copyright notice in squirrel.h */ |
jhnwkmn | 0:97a4f8cc534c | 2 | #include <new> |
jhnwkmn | 0:97a4f8cc534c | 3 | #include <stdio.h> |
jhnwkmn | 0:97a4f8cc534c | 4 | #include <squirrel.h> |
jhnwkmn | 0:97a4f8cc534c | 5 | #include <sqstdio.h> |
jhnwkmn | 0:97a4f8cc534c | 6 | #include "sqstdstream.h" |
jhnwkmn | 0:97a4f8cc534c | 7 | |
jhnwkmn | 0:97a4f8cc534c | 8 | #define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001) |
jhnwkmn | 0:97a4f8cc534c | 9 | //basic API |
jhnwkmn | 0:97a4f8cc534c | 10 | SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode) |
jhnwkmn | 0:97a4f8cc534c | 11 | { |
jhnwkmn | 0:97a4f8cc534c | 12 | #ifndef SQUNICODE |
jhnwkmn | 0:97a4f8cc534c | 13 | return (SQFILE)fopen(filename,mode); |
jhnwkmn | 0:97a4f8cc534c | 14 | #else |
jhnwkmn | 0:97a4f8cc534c | 15 | return (SQFILE)_wfopen(filename,mode); |
jhnwkmn | 0:97a4f8cc534c | 16 | #endif |
jhnwkmn | 0:97a4f8cc534c | 17 | } |
jhnwkmn | 0:97a4f8cc534c | 18 | |
jhnwkmn | 0:97a4f8cc534c | 19 | SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file) |
jhnwkmn | 0:97a4f8cc534c | 20 | { |
jhnwkmn | 0:97a4f8cc534c | 21 | return (SQInteger)fread(buffer,size,count,(FILE *)file); |
jhnwkmn | 0:97a4f8cc534c | 22 | } |
jhnwkmn | 0:97a4f8cc534c | 23 | |
jhnwkmn | 0:97a4f8cc534c | 24 | SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file) |
jhnwkmn | 0:97a4f8cc534c | 25 | { |
jhnwkmn | 0:97a4f8cc534c | 26 | return (SQInteger)fwrite(buffer,size,count,(FILE *)file); |
jhnwkmn | 0:97a4f8cc534c | 27 | } |
jhnwkmn | 0:97a4f8cc534c | 28 | |
jhnwkmn | 0:97a4f8cc534c | 29 | SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin) |
jhnwkmn | 0:97a4f8cc534c | 30 | { |
jhnwkmn | 0:97a4f8cc534c | 31 | SQInteger realorigin; |
jhnwkmn | 0:97a4f8cc534c | 32 | switch(origin) { |
jhnwkmn | 0:97a4f8cc534c | 33 | case SQ_SEEK_CUR: realorigin = SEEK_CUR; break; |
jhnwkmn | 0:97a4f8cc534c | 34 | case SQ_SEEK_END: realorigin = SEEK_END; break; |
jhnwkmn | 0:97a4f8cc534c | 35 | case SQ_SEEK_SET: realorigin = SEEK_SET; break; |
jhnwkmn | 0:97a4f8cc534c | 36 | default: return -1; //failed |
jhnwkmn | 0:97a4f8cc534c | 37 | } |
jhnwkmn | 0:97a4f8cc534c | 38 | return fseek((FILE *)file,(long)offset,(int)realorigin); |
jhnwkmn | 0:97a4f8cc534c | 39 | } |
jhnwkmn | 0:97a4f8cc534c | 40 | |
jhnwkmn | 0:97a4f8cc534c | 41 | SQInteger sqstd_ftell(SQFILE file) |
jhnwkmn | 0:97a4f8cc534c | 42 | { |
jhnwkmn | 0:97a4f8cc534c | 43 | return ftell((FILE *)file); |
jhnwkmn | 0:97a4f8cc534c | 44 | } |
jhnwkmn | 0:97a4f8cc534c | 45 | |
jhnwkmn | 0:97a4f8cc534c | 46 | SQInteger sqstd_fflush(SQFILE file) |
jhnwkmn | 0:97a4f8cc534c | 47 | { |
jhnwkmn | 0:97a4f8cc534c | 48 | return fflush((FILE *)file); |
jhnwkmn | 0:97a4f8cc534c | 49 | } |
jhnwkmn | 0:97a4f8cc534c | 50 | |
jhnwkmn | 0:97a4f8cc534c | 51 | SQInteger sqstd_fclose(SQFILE file) |
jhnwkmn | 0:97a4f8cc534c | 52 | { |
jhnwkmn | 0:97a4f8cc534c | 53 | return fclose((FILE *)file); |
jhnwkmn | 0:97a4f8cc534c | 54 | } |
jhnwkmn | 0:97a4f8cc534c | 55 | |
jhnwkmn | 0:97a4f8cc534c | 56 | SQInteger sqstd_feof(SQFILE file) |
jhnwkmn | 0:97a4f8cc534c | 57 | { |
jhnwkmn | 0:97a4f8cc534c | 58 | return feof((FILE *)file); |
jhnwkmn | 0:97a4f8cc534c | 59 | } |
jhnwkmn | 0:97a4f8cc534c | 60 | |
jhnwkmn | 0:97a4f8cc534c | 61 | //File |
jhnwkmn | 0:97a4f8cc534c | 62 | struct SQFile : public SQStream { |
jhnwkmn | 0:97a4f8cc534c | 63 | SQFile() { _handle = NULL; _owns = false;} |
jhnwkmn | 0:97a4f8cc534c | 64 | SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;} |
jhnwkmn | 0:97a4f8cc534c | 65 | virtual ~SQFile() { Close(); } |
jhnwkmn | 0:97a4f8cc534c | 66 | bool Open(const SQChar *filename ,const SQChar *mode) { |
jhnwkmn | 0:97a4f8cc534c | 67 | Close(); |
jhnwkmn | 0:97a4f8cc534c | 68 | if( (_handle = sqstd_fopen(filename,mode)) ) { |
jhnwkmn | 0:97a4f8cc534c | 69 | _owns = true; |
jhnwkmn | 0:97a4f8cc534c | 70 | return true; |
jhnwkmn | 0:97a4f8cc534c | 71 | } |
jhnwkmn | 0:97a4f8cc534c | 72 | return false; |
jhnwkmn | 0:97a4f8cc534c | 73 | } |
jhnwkmn | 0:97a4f8cc534c | 74 | void Close() { |
jhnwkmn | 0:97a4f8cc534c | 75 | if(_handle && _owns) { |
jhnwkmn | 0:97a4f8cc534c | 76 | sqstd_fclose(_handle); |
jhnwkmn | 0:97a4f8cc534c | 77 | _handle = NULL; |
jhnwkmn | 0:97a4f8cc534c | 78 | _owns = false; |
jhnwkmn | 0:97a4f8cc534c | 79 | } |
jhnwkmn | 0:97a4f8cc534c | 80 | } |
jhnwkmn | 0:97a4f8cc534c | 81 | SQInteger Read(void *buffer,SQInteger size) { |
jhnwkmn | 0:97a4f8cc534c | 82 | return sqstd_fread(buffer,1,size,_handle); |
jhnwkmn | 0:97a4f8cc534c | 83 | } |
jhnwkmn | 0:97a4f8cc534c | 84 | SQInteger Write(void *buffer,SQInteger size) { |
jhnwkmn | 0:97a4f8cc534c | 85 | return sqstd_fwrite(buffer,1,size,_handle); |
jhnwkmn | 0:97a4f8cc534c | 86 | } |
jhnwkmn | 0:97a4f8cc534c | 87 | SQInteger Flush() { |
jhnwkmn | 0:97a4f8cc534c | 88 | return sqstd_fflush(_handle); |
jhnwkmn | 0:97a4f8cc534c | 89 | } |
jhnwkmn | 0:97a4f8cc534c | 90 | SQInteger Tell() { |
jhnwkmn | 0:97a4f8cc534c | 91 | return sqstd_ftell(_handle); |
jhnwkmn | 0:97a4f8cc534c | 92 | } |
jhnwkmn | 0:97a4f8cc534c | 93 | SQInteger Len() { |
jhnwkmn | 0:97a4f8cc534c | 94 | SQInteger prevpos=Tell(); |
jhnwkmn | 0:97a4f8cc534c | 95 | Seek(0,SQ_SEEK_END); |
jhnwkmn | 0:97a4f8cc534c | 96 | SQInteger size=Tell(); |
jhnwkmn | 0:97a4f8cc534c | 97 | Seek(prevpos,SQ_SEEK_SET); |
jhnwkmn | 0:97a4f8cc534c | 98 | return size; |
jhnwkmn | 0:97a4f8cc534c | 99 | } |
jhnwkmn | 0:97a4f8cc534c | 100 | SQInteger Seek(SQInteger offset, SQInteger origin) { |
jhnwkmn | 0:97a4f8cc534c | 101 | return sqstd_fseek(_handle,offset,origin); |
jhnwkmn | 0:97a4f8cc534c | 102 | } |
jhnwkmn | 0:97a4f8cc534c | 103 | bool IsValid() { return _handle?true:false; } |
jhnwkmn | 0:97a4f8cc534c | 104 | bool EOS() { return Tell()==Len()?true:false;} |
jhnwkmn | 0:97a4f8cc534c | 105 | SQFILE GetHandle() {return _handle;} |
jhnwkmn | 0:97a4f8cc534c | 106 | private: |
jhnwkmn | 0:97a4f8cc534c | 107 | SQFILE _handle; |
jhnwkmn | 0:97a4f8cc534c | 108 | bool _owns; |
jhnwkmn | 0:97a4f8cc534c | 109 | }; |
jhnwkmn | 0:97a4f8cc534c | 110 | |
jhnwkmn | 0:97a4f8cc534c | 111 | static SQInteger _file__typeof(HSQUIRRELVM v) |
jhnwkmn | 0:97a4f8cc534c | 112 | { |
jhnwkmn | 0:97a4f8cc534c | 113 | sq_pushstring(v,_SC("file"),-1); |
jhnwkmn | 0:97a4f8cc534c | 114 | return 1; |
jhnwkmn | 0:97a4f8cc534c | 115 | } |
jhnwkmn | 0:97a4f8cc534c | 116 | |
jhnwkmn | 0:97a4f8cc534c | 117 | static SQInteger _file_releasehook(SQUserPointer p, SQInteger size) |
jhnwkmn | 0:97a4f8cc534c | 118 | { |
jhnwkmn | 0:97a4f8cc534c | 119 | SQFile *self = (SQFile*)p; |
jhnwkmn | 0:97a4f8cc534c | 120 | self->~SQFile(); |
jhnwkmn | 0:97a4f8cc534c | 121 | sq_free(self,sizeof(SQFile)); |
jhnwkmn | 0:97a4f8cc534c | 122 | return 1; |
jhnwkmn | 0:97a4f8cc534c | 123 | } |
jhnwkmn | 0:97a4f8cc534c | 124 | |
jhnwkmn | 0:97a4f8cc534c | 125 | static SQInteger _file_constructor(HSQUIRRELVM v) |
jhnwkmn | 0:97a4f8cc534c | 126 | { |
jhnwkmn | 0:97a4f8cc534c | 127 | const SQChar *filename,*mode; |
jhnwkmn | 0:97a4f8cc534c | 128 | bool owns = true; |
jhnwkmn | 0:97a4f8cc534c | 129 | SQFile *f; |
jhnwkmn | 0:97a4f8cc534c | 130 | SQFILE newf; |
jhnwkmn | 0:97a4f8cc534c | 131 | if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) { |
jhnwkmn | 0:97a4f8cc534c | 132 | sq_getstring(v, 2, &filename); |
jhnwkmn | 0:97a4f8cc534c | 133 | sq_getstring(v, 3, &mode); |
jhnwkmn | 0:97a4f8cc534c | 134 | newf = sqstd_fopen(filename, mode); |
jhnwkmn | 0:97a4f8cc534c | 135 | if(!newf) return sq_throwerror(v, _SC("cannot open file")); |
jhnwkmn | 0:97a4f8cc534c | 136 | } else if(sq_gettype(v,2) == OT_USERPOINTER) { |
jhnwkmn | 0:97a4f8cc534c | 137 | owns = !(sq_gettype(v,3) == OT_NULL); |
jhnwkmn | 0:97a4f8cc534c | 138 | sq_getuserpointer(v,2,&newf); |
jhnwkmn | 0:97a4f8cc534c | 139 | } else { |
jhnwkmn | 0:97a4f8cc534c | 140 | return sq_throwerror(v,_SC("wrong parameter")); |
jhnwkmn | 0:97a4f8cc534c | 141 | } |
jhnwkmn | 0:97a4f8cc534c | 142 | |
jhnwkmn | 0:97a4f8cc534c | 143 | f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns); |
jhnwkmn | 0:97a4f8cc534c | 144 | if(SQ_FAILED(sq_setinstanceup(v,1,f))) { |
jhnwkmn | 0:97a4f8cc534c | 145 | f->~SQFile(); |
jhnwkmn | 0:97a4f8cc534c | 146 | sq_free(f,sizeof(SQFile)); |
jhnwkmn | 0:97a4f8cc534c | 147 | return sq_throwerror(v, _SC("cannot create blob with negative size")); |
jhnwkmn | 0:97a4f8cc534c | 148 | } |
jhnwkmn | 0:97a4f8cc534c | 149 | sq_setreleasehook(v,1,_file_releasehook); |
jhnwkmn | 0:97a4f8cc534c | 150 | return 0; |
jhnwkmn | 0:97a4f8cc534c | 151 | } |
jhnwkmn | 0:97a4f8cc534c | 152 | |
jhnwkmn | 0:97a4f8cc534c | 153 | static SQInteger _file_close(HSQUIRRELVM v) |
jhnwkmn | 0:97a4f8cc534c | 154 | { |
jhnwkmn | 0:97a4f8cc534c | 155 | SQFile *self = NULL; |
jhnwkmn | 0:97a4f8cc534c | 156 | if(SQ_SUCCEEDED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_FILE_TYPE_TAG)) |
jhnwkmn | 0:97a4f8cc534c | 157 | && self != NULL) |
jhnwkmn | 0:97a4f8cc534c | 158 | { |
jhnwkmn | 0:97a4f8cc534c | 159 | self->Close(); |
jhnwkmn | 0:97a4f8cc534c | 160 | } |
jhnwkmn | 0:97a4f8cc534c | 161 | return 0; |
jhnwkmn | 0:97a4f8cc534c | 162 | } |
jhnwkmn | 0:97a4f8cc534c | 163 | |
jhnwkmn | 0:97a4f8cc534c | 164 | //bindings |
jhnwkmn | 0:97a4f8cc534c | 165 | #define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck} |
jhnwkmn | 0:97a4f8cc534c | 166 | static SQRegFunction _file_methods[] = { |
jhnwkmn | 0:97a4f8cc534c | 167 | _DECL_FILE_FUNC(constructor,3,_SC("x")), |
jhnwkmn | 0:97a4f8cc534c | 168 | _DECL_FILE_FUNC(_typeof,1,_SC("x")), |
jhnwkmn | 0:97a4f8cc534c | 169 | _DECL_FILE_FUNC(close,1,_SC("x")), |
jhnwkmn | 0:97a4f8cc534c | 170 | {0,0,0,0}, |
jhnwkmn | 0:97a4f8cc534c | 171 | }; |
jhnwkmn | 0:97a4f8cc534c | 172 | |
jhnwkmn | 0:97a4f8cc534c | 173 | |
jhnwkmn | 0:97a4f8cc534c | 174 | |
jhnwkmn | 0:97a4f8cc534c | 175 | SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own) |
jhnwkmn | 0:97a4f8cc534c | 176 | { |
jhnwkmn | 0:97a4f8cc534c | 177 | SQInteger top = sq_gettop(v); |
jhnwkmn | 0:97a4f8cc534c | 178 | sq_pushregistrytable(v); |
jhnwkmn | 0:97a4f8cc534c | 179 | sq_pushstring(v,_SC("std_file"),-1); |
jhnwkmn | 0:97a4f8cc534c | 180 | if(SQ_SUCCEEDED(sq_get(v,-2))) { |
jhnwkmn | 0:97a4f8cc534c | 181 | sq_remove(v,-2); //removes the registry |
jhnwkmn | 0:97a4f8cc534c | 182 | sq_pushroottable(v); // push the this |
jhnwkmn | 0:97a4f8cc534c | 183 | sq_pushuserpointer(v,file); //file |
jhnwkmn | 0:97a4f8cc534c | 184 | if(own){ |
jhnwkmn | 0:97a4f8cc534c | 185 | sq_pushinteger(v,1); //true |
jhnwkmn | 0:97a4f8cc534c | 186 | } |
jhnwkmn | 0:97a4f8cc534c | 187 | else{ |
jhnwkmn | 0:97a4f8cc534c | 188 | sq_pushnull(v); //false |
jhnwkmn | 0:97a4f8cc534c | 189 | } |
jhnwkmn | 0:97a4f8cc534c | 190 | if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) { |
jhnwkmn | 0:97a4f8cc534c | 191 | sq_remove(v,-2); |
jhnwkmn | 0:97a4f8cc534c | 192 | return SQ_OK; |
jhnwkmn | 0:97a4f8cc534c | 193 | } |
jhnwkmn | 0:97a4f8cc534c | 194 | } |
jhnwkmn | 0:97a4f8cc534c | 195 | sq_settop(v,top); |
jhnwkmn | 0:97a4f8cc534c | 196 | return SQ_OK; |
jhnwkmn | 0:97a4f8cc534c | 197 | } |
jhnwkmn | 0:97a4f8cc534c | 198 | |
jhnwkmn | 0:97a4f8cc534c | 199 | SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file) |
jhnwkmn | 0:97a4f8cc534c | 200 | { |
jhnwkmn | 0:97a4f8cc534c | 201 | SQFile *fileobj = NULL; |
jhnwkmn | 0:97a4f8cc534c | 202 | if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) { |
jhnwkmn | 0:97a4f8cc534c | 203 | *file = fileobj->GetHandle(); |
jhnwkmn | 0:97a4f8cc534c | 204 | return SQ_OK; |
jhnwkmn | 0:97a4f8cc534c | 205 | } |
jhnwkmn | 0:97a4f8cc534c | 206 | return sq_throwerror(v,_SC("not a file")); |
jhnwkmn | 0:97a4f8cc534c | 207 | } |
jhnwkmn | 0:97a4f8cc534c | 208 | |
jhnwkmn | 0:97a4f8cc534c | 209 | |
jhnwkmn | 0:97a4f8cc534c | 210 | |
jhnwkmn | 0:97a4f8cc534c | 211 | static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer file) |
jhnwkmn | 0:97a4f8cc534c | 212 | { |
jhnwkmn | 0:97a4f8cc534c | 213 | SQInteger ret; |
jhnwkmn | 0:97a4f8cc534c | 214 | char c; |
jhnwkmn | 0:97a4f8cc534c | 215 | if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) |
jhnwkmn | 0:97a4f8cc534c | 216 | return c; |
jhnwkmn | 0:97a4f8cc534c | 217 | return 0; |
jhnwkmn | 0:97a4f8cc534c | 218 | } |
jhnwkmn | 0:97a4f8cc534c | 219 | |
jhnwkmn | 0:97a4f8cc534c | 220 | #ifdef SQUNICODE |
jhnwkmn | 0:97a4f8cc534c | 221 | static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file) |
jhnwkmn | 0:97a4f8cc534c | 222 | { |
jhnwkmn | 0:97a4f8cc534c | 223 | #define READ() \ |
jhnwkmn | 0:97a4f8cc534c | 224 | if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \ |
jhnwkmn | 0:97a4f8cc534c | 225 | return 0; |
jhnwkmn | 0:97a4f8cc534c | 226 | |
jhnwkmn | 0:97a4f8cc534c | 227 | static const SQInteger utf8_lengths[16] = |
jhnwkmn | 0:97a4f8cc534c | 228 | { |
jhnwkmn | 0:97a4f8cc534c | 229 | 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */ |
jhnwkmn | 0:97a4f8cc534c | 230 | 0,0,0,0, /* 1000 to 1011 : not valid */ |
jhnwkmn | 0:97a4f8cc534c | 231 | 2,2, /* 1100, 1101 : 2 bytes */ |
jhnwkmn | 0:97a4f8cc534c | 232 | 3, /* 1110 : 3 bytes */ |
jhnwkmn | 0:97a4f8cc534c | 233 | 4 /* 1111 :4 bytes */ |
jhnwkmn | 0:97a4f8cc534c | 234 | }; |
jhnwkmn | 0:97a4f8cc534c | 235 | static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07}; |
jhnwkmn | 0:97a4f8cc534c | 236 | unsigned char inchar; |
jhnwkmn | 0:97a4f8cc534c | 237 | SQInteger c = 0; |
jhnwkmn | 0:97a4f8cc534c | 238 | READ(); |
jhnwkmn | 0:97a4f8cc534c | 239 | c = inchar; |
jhnwkmn | 0:97a4f8cc534c | 240 | // |
jhnwkmn | 0:97a4f8cc534c | 241 | if(c >= 0x80) { |
jhnwkmn | 0:97a4f8cc534c | 242 | SQInteger tmp; |
jhnwkmn | 0:97a4f8cc534c | 243 | SQInteger codelen = utf8_lengths[c>>4]; |
jhnwkmn | 0:97a4f8cc534c | 244 | if(codelen == 0) |
jhnwkmn | 0:97a4f8cc534c | 245 | return 0; |
jhnwkmn | 0:97a4f8cc534c | 246 | //"invalid UTF-8 stream"; |
jhnwkmn | 0:97a4f8cc534c | 247 | tmp = c&byte_masks[codelen]; |
jhnwkmn | 0:97a4f8cc534c | 248 | for(SQInteger n = 0; n < codelen-1; n++) { |
jhnwkmn | 0:97a4f8cc534c | 249 | tmp<<=6; |
jhnwkmn | 0:97a4f8cc534c | 250 | READ(); |
jhnwkmn | 0:97a4f8cc534c | 251 | tmp |= inchar & 0x3F; |
jhnwkmn | 0:97a4f8cc534c | 252 | } |
jhnwkmn | 0:97a4f8cc534c | 253 | c = tmp; |
jhnwkmn | 0:97a4f8cc534c | 254 | } |
jhnwkmn | 0:97a4f8cc534c | 255 | return c; |
jhnwkmn | 0:97a4f8cc534c | 256 | } |
jhnwkmn | 0:97a4f8cc534c | 257 | #endif |
jhnwkmn | 0:97a4f8cc534c | 258 | |
jhnwkmn | 0:97a4f8cc534c | 259 | static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file) |
jhnwkmn | 0:97a4f8cc534c | 260 | { |
jhnwkmn | 0:97a4f8cc534c | 261 | SQInteger ret; |
jhnwkmn | 0:97a4f8cc534c | 262 | wchar_t c; |
jhnwkmn | 0:97a4f8cc534c | 263 | if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) |
jhnwkmn | 0:97a4f8cc534c | 264 | return (SQChar)c; |
jhnwkmn | 0:97a4f8cc534c | 265 | return 0; |
jhnwkmn | 0:97a4f8cc534c | 266 | } |
jhnwkmn | 0:97a4f8cc534c | 267 | |
jhnwkmn | 0:97a4f8cc534c | 268 | static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file) |
jhnwkmn | 0:97a4f8cc534c | 269 | { |
jhnwkmn | 0:97a4f8cc534c | 270 | SQInteger ret; |
jhnwkmn | 0:97a4f8cc534c | 271 | unsigned short c; |
jhnwkmn | 0:97a4f8cc534c | 272 | if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) { |
jhnwkmn | 0:97a4f8cc534c | 273 | c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00); |
jhnwkmn | 0:97a4f8cc534c | 274 | return (SQChar)c; |
jhnwkmn | 0:97a4f8cc534c | 275 | } |
jhnwkmn | 0:97a4f8cc534c | 276 | return 0; |
jhnwkmn | 0:97a4f8cc534c | 277 | } |
jhnwkmn | 0:97a4f8cc534c | 278 | |
jhnwkmn | 0:97a4f8cc534c | 279 | SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size) |
jhnwkmn | 0:97a4f8cc534c | 280 | { |
jhnwkmn | 0:97a4f8cc534c | 281 | SQInteger ret; |
jhnwkmn | 0:97a4f8cc534c | 282 | if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret; |
jhnwkmn | 0:97a4f8cc534c | 283 | return -1; |
jhnwkmn | 0:97a4f8cc534c | 284 | } |
jhnwkmn | 0:97a4f8cc534c | 285 | |
jhnwkmn | 0:97a4f8cc534c | 286 | SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size) |
jhnwkmn | 0:97a4f8cc534c | 287 | { |
jhnwkmn | 0:97a4f8cc534c | 288 | return sqstd_fwrite(p,1,size,(SQFILE)file); |
jhnwkmn | 0:97a4f8cc534c | 289 | } |
jhnwkmn | 0:97a4f8cc534c | 290 | |
jhnwkmn | 0:97a4f8cc534c | 291 | SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror) |
jhnwkmn | 0:97a4f8cc534c | 292 | { |
jhnwkmn | 0:97a4f8cc534c | 293 | SQFILE file = sqstd_fopen(filename,_SC("rb")); |
jhnwkmn | 0:97a4f8cc534c | 294 | SQInteger ret; |
jhnwkmn | 0:97a4f8cc534c | 295 | unsigned short us; |
jhnwkmn | 0:97a4f8cc534c | 296 | unsigned char uc; |
jhnwkmn | 0:97a4f8cc534c | 297 | SQLEXREADFUNC func = _io_file_lexfeed_PLAIN; |
jhnwkmn | 0:97a4f8cc534c | 298 | if(file){ |
jhnwkmn | 0:97a4f8cc534c | 299 | ret = sqstd_fread(&us,1,2,file); |
jhnwkmn | 0:97a4f8cc534c | 300 | if(ret != 2) { |
jhnwkmn | 0:97a4f8cc534c | 301 | //probably an empty file |
jhnwkmn | 0:97a4f8cc534c | 302 | us = 0; |
jhnwkmn | 0:97a4f8cc534c | 303 | } |
jhnwkmn | 0:97a4f8cc534c | 304 | if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE |
jhnwkmn | 0:97a4f8cc534c | 305 | sqstd_fseek(file,0,SQ_SEEK_SET); |
jhnwkmn | 0:97a4f8cc534c | 306 | if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) { |
jhnwkmn | 0:97a4f8cc534c | 307 | sqstd_fclose(file); |
jhnwkmn | 0:97a4f8cc534c | 308 | return SQ_OK; |
jhnwkmn | 0:97a4f8cc534c | 309 | } |
jhnwkmn | 0:97a4f8cc534c | 310 | } |
jhnwkmn | 0:97a4f8cc534c | 311 | else { //SCRIPT |
jhnwkmn | 0:97a4f8cc534c | 312 | switch(us) |
jhnwkmn | 0:97a4f8cc534c | 313 | { |
jhnwkmn | 0:97a4f8cc534c | 314 | //gotta swap the next 2 lines on BIG endian machines |
jhnwkmn | 0:97a4f8cc534c | 315 | case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian; |
jhnwkmn | 0:97a4f8cc534c | 316 | case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian; |
jhnwkmn | 0:97a4f8cc534c | 317 | case 0xBBEF: |
jhnwkmn | 0:97a4f8cc534c | 318 | if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { |
jhnwkmn | 0:97a4f8cc534c | 319 | sqstd_fclose(file); |
jhnwkmn | 0:97a4f8cc534c | 320 | return sq_throwerror(v,_SC("io error")); |
jhnwkmn | 0:97a4f8cc534c | 321 | } |
jhnwkmn | 0:97a4f8cc534c | 322 | if(uc != 0xBF) { |
jhnwkmn | 0:97a4f8cc534c | 323 | sqstd_fclose(file); |
jhnwkmn | 0:97a4f8cc534c | 324 | return sq_throwerror(v,_SC("Unrecognozed ecoding")); |
jhnwkmn | 0:97a4f8cc534c | 325 | } |
jhnwkmn | 0:97a4f8cc534c | 326 | #ifdef SQUNICODE |
jhnwkmn | 0:97a4f8cc534c | 327 | func = _io_file_lexfeed_UTF8; |
jhnwkmn | 0:97a4f8cc534c | 328 | #else |
jhnwkmn | 0:97a4f8cc534c | 329 | func = _io_file_lexfeed_PLAIN; |
jhnwkmn | 0:97a4f8cc534c | 330 | #endif |
jhnwkmn | 0:97a4f8cc534c | 331 | break;//UTF-8 ; |
jhnwkmn | 0:97a4f8cc534c | 332 | default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii |
jhnwkmn | 0:97a4f8cc534c | 333 | } |
jhnwkmn | 0:97a4f8cc534c | 334 | |
jhnwkmn | 0:97a4f8cc534c | 335 | if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){ |
jhnwkmn | 0:97a4f8cc534c | 336 | sqstd_fclose(file); |
jhnwkmn | 0:97a4f8cc534c | 337 | return SQ_OK; |
jhnwkmn | 0:97a4f8cc534c | 338 | } |
jhnwkmn | 0:97a4f8cc534c | 339 | } |
jhnwkmn | 0:97a4f8cc534c | 340 | sqstd_fclose(file); |
jhnwkmn | 0:97a4f8cc534c | 341 | return SQ_ERROR; |
jhnwkmn | 0:97a4f8cc534c | 342 | } |
jhnwkmn | 0:97a4f8cc534c | 343 | return sq_throwerror(v,_SC("cannot open the file")); |
jhnwkmn | 0:97a4f8cc534c | 344 | } |
jhnwkmn | 0:97a4f8cc534c | 345 | |
jhnwkmn | 0:97a4f8cc534c | 346 | SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror) |
jhnwkmn | 0:97a4f8cc534c | 347 | { |
jhnwkmn | 0:97a4f8cc534c | 348 | if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) { |
jhnwkmn | 0:97a4f8cc534c | 349 | sq_push(v,-2); |
jhnwkmn | 0:97a4f8cc534c | 350 | if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) { |
jhnwkmn | 0:97a4f8cc534c | 351 | sq_remove(v,retval?-2:-1); //removes the closure |
jhnwkmn | 0:97a4f8cc534c | 352 | return 1; |
jhnwkmn | 0:97a4f8cc534c | 353 | } |
jhnwkmn | 0:97a4f8cc534c | 354 | sq_pop(v,1); //removes the closure |
jhnwkmn | 0:97a4f8cc534c | 355 | } |
jhnwkmn | 0:97a4f8cc534c | 356 | return SQ_ERROR; |
jhnwkmn | 0:97a4f8cc534c | 357 | } |
jhnwkmn | 0:97a4f8cc534c | 358 | |
jhnwkmn | 0:97a4f8cc534c | 359 | SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename) |
jhnwkmn | 0:97a4f8cc534c | 360 | { |
jhnwkmn | 0:97a4f8cc534c | 361 | SQFILE file = sqstd_fopen(filename,_SC("wb+")); |
jhnwkmn | 0:97a4f8cc534c | 362 | if(!file) return sq_throwerror(v,_SC("cannot open the file")); |
jhnwkmn | 0:97a4f8cc534c | 363 | if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) { |
jhnwkmn | 0:97a4f8cc534c | 364 | sqstd_fclose(file); |
jhnwkmn | 0:97a4f8cc534c | 365 | return SQ_OK; |
jhnwkmn | 0:97a4f8cc534c | 366 | } |
jhnwkmn | 0:97a4f8cc534c | 367 | sqstd_fclose(file); |
jhnwkmn | 0:97a4f8cc534c | 368 | return SQ_ERROR; //forward the error |
jhnwkmn | 0:97a4f8cc534c | 369 | } |
jhnwkmn | 0:97a4f8cc534c | 370 | |
jhnwkmn | 0:97a4f8cc534c | 371 | SQInteger _g_io_loadfile(HSQUIRRELVM v) |
jhnwkmn | 0:97a4f8cc534c | 372 | { |
jhnwkmn | 0:97a4f8cc534c | 373 | const SQChar *filename; |
jhnwkmn | 0:97a4f8cc534c | 374 | SQBool printerror = SQFalse; |
jhnwkmn | 0:97a4f8cc534c | 375 | sq_getstring(v,2,&filename); |
jhnwkmn | 0:97a4f8cc534c | 376 | if(sq_gettop(v) >= 3) { |
jhnwkmn | 0:97a4f8cc534c | 377 | sq_getbool(v,3,&printerror); |
jhnwkmn | 0:97a4f8cc534c | 378 | } |
jhnwkmn | 0:97a4f8cc534c | 379 | if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) |
jhnwkmn | 0:97a4f8cc534c | 380 | return 1; |
jhnwkmn | 0:97a4f8cc534c | 381 | return SQ_ERROR; //propagates the error |
jhnwkmn | 0:97a4f8cc534c | 382 | } |
jhnwkmn | 0:97a4f8cc534c | 383 | |
jhnwkmn | 0:97a4f8cc534c | 384 | SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v) |
jhnwkmn | 0:97a4f8cc534c | 385 | { |
jhnwkmn | 0:97a4f8cc534c | 386 | const SQChar *filename; |
jhnwkmn | 0:97a4f8cc534c | 387 | sq_getstring(v,2,&filename); |
jhnwkmn | 0:97a4f8cc534c | 388 | if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename))) |
jhnwkmn | 0:97a4f8cc534c | 389 | return 1; |
jhnwkmn | 0:97a4f8cc534c | 390 | return SQ_ERROR; //propagates the error |
jhnwkmn | 0:97a4f8cc534c | 391 | } |
jhnwkmn | 0:97a4f8cc534c | 392 | |
jhnwkmn | 0:97a4f8cc534c | 393 | SQInteger _g_io_dofile(HSQUIRRELVM v) |
jhnwkmn | 0:97a4f8cc534c | 394 | { |
jhnwkmn | 0:97a4f8cc534c | 395 | const SQChar *filename; |
jhnwkmn | 0:97a4f8cc534c | 396 | SQBool printerror = SQFalse; |
jhnwkmn | 0:97a4f8cc534c | 397 | sq_getstring(v,2,&filename); |
jhnwkmn | 0:97a4f8cc534c | 398 | if(sq_gettop(v) >= 3) { |
jhnwkmn | 0:97a4f8cc534c | 399 | sq_getbool(v,3,&printerror); |
jhnwkmn | 0:97a4f8cc534c | 400 | } |
jhnwkmn | 0:97a4f8cc534c | 401 | sq_push(v,1); //repush the this |
jhnwkmn | 0:97a4f8cc534c | 402 | if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror))) |
jhnwkmn | 0:97a4f8cc534c | 403 | return 1; |
jhnwkmn | 0:97a4f8cc534c | 404 | return SQ_ERROR; //propagates the error |
jhnwkmn | 0:97a4f8cc534c | 405 | } |
jhnwkmn | 0:97a4f8cc534c | 406 | |
jhnwkmn | 0:97a4f8cc534c | 407 | #define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck} |
jhnwkmn | 0:97a4f8cc534c | 408 | static SQRegFunction iolib_funcs[]={ |
jhnwkmn | 0:97a4f8cc534c | 409 | _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")), |
jhnwkmn | 0:97a4f8cc534c | 410 | _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")), |
jhnwkmn | 0:97a4f8cc534c | 411 | _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")), |
jhnwkmn | 0:97a4f8cc534c | 412 | {0,0} |
jhnwkmn | 0:97a4f8cc534c | 413 | }; |
jhnwkmn | 0:97a4f8cc534c | 414 | |
jhnwkmn | 0:97a4f8cc534c | 415 | SQRESULT sqstd_register_iolib(HSQUIRRELVM v) |
jhnwkmn | 0:97a4f8cc534c | 416 | { |
jhnwkmn | 0:97a4f8cc534c | 417 | SQInteger top = sq_gettop(v); |
jhnwkmn | 0:97a4f8cc534c | 418 | //create delegate |
jhnwkmn | 0:97a4f8cc534c | 419 | declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs); |
jhnwkmn | 0:97a4f8cc534c | 420 | sq_pushstring(v,_SC("stdout"),-1); |
jhnwkmn | 0:97a4f8cc534c | 421 | sqstd_createfile(v,stdout,SQFalse); |
jhnwkmn | 0:97a4f8cc534c | 422 | sq_newslot(v,-3,SQFalse); |
jhnwkmn | 0:97a4f8cc534c | 423 | sq_pushstring(v,_SC("stdin"),-1); |
jhnwkmn | 0:97a4f8cc534c | 424 | sqstd_createfile(v,stdin,SQFalse); |
jhnwkmn | 0:97a4f8cc534c | 425 | sq_newslot(v,-3,SQFalse); |
jhnwkmn | 0:97a4f8cc534c | 426 | sq_pushstring(v,_SC("stderr"),-1); |
jhnwkmn | 0:97a4f8cc534c | 427 | sqstd_createfile(v,stderr,SQFalse); |
jhnwkmn | 0:97a4f8cc534c | 428 | sq_newslot(v,-3,SQFalse); |
jhnwkmn | 0:97a4f8cc534c | 429 | sq_settop(v,top); |
jhnwkmn | 0:97a4f8cc534c | 430 | return SQ_OK; |
jhnwkmn | 0:97a4f8cc534c | 431 | } |