1 #include "scriptfile.h"
2 #include <new>
3 #include <assert.h>
4 #include <string>
5 #include <string.h>
6 #include <stdio.h>
7
8 #ifdef _WIN32_WCE
9 #include <windows.h> // For GetModuleFileName
10 #ifdef GetObject
11 #undef GetObject
12 #endif
13 #endif
14
15 using namespace std;
16
17 BEGIN_AS_NAMESPACE
18
ScriptFile_Factory()19 CScriptFile *ScriptFile_Factory()
20 {
21 return new CScriptFile();
22 }
23
ScriptFile_Factory_Generic(asIScriptGeneric * gen)24 void ScriptFile_Factory_Generic(asIScriptGeneric *gen)
25 {
26 *(CScriptFile**)gen->GetAddressOfReturnLocation() = ScriptFile_Factory();
27 }
28
ScriptFile_AddRef_Generic(asIScriptGeneric * gen)29 void ScriptFile_AddRef_Generic(asIScriptGeneric *gen)
30 {
31 CScriptFile *file = (CScriptFile*)gen->GetObject();
32 file->AddRef();
33 }
34
ScriptFile_Release_Generic(asIScriptGeneric * gen)35 void ScriptFile_Release_Generic(asIScriptGeneric *gen)
36 {
37 CScriptFile *file = (CScriptFile*)gen->GetObject();
38 file->Release();
39 }
40
ScriptFile_Open_Generic(asIScriptGeneric * gen)41 void ScriptFile_Open_Generic(asIScriptGeneric *gen)
42 {
43 CScriptFile *file = (CScriptFile*)gen->GetObject();
44 std::string *f = (std::string*)gen->GetArgAddress(0);
45 std::string *m = (std::string*)gen->GetArgAddress(1);
46 int r = file->Open(*f, *m);
47 gen->SetReturnDWord(r);
48 }
49
ScriptFile_Close_Generic(asIScriptGeneric * gen)50 void ScriptFile_Close_Generic(asIScriptGeneric *gen)
51 {
52 CScriptFile *file = (CScriptFile*)gen->GetObject();
53 int r = file->Close();
54 gen->SetReturnDWord(r);
55 }
56
ScriptFile_GetSize_Generic(asIScriptGeneric * gen)57 void ScriptFile_GetSize_Generic(asIScriptGeneric *gen)
58 {
59 CScriptFile *file = (CScriptFile*)gen->GetObject();
60 int r = file->GetSize();
61 gen->SetReturnDWord(r);
62 }
63
ScriptFile_ReadString_Generic(asIScriptGeneric * gen)64 void ScriptFile_ReadString_Generic(asIScriptGeneric *gen)
65 {
66 CScriptFile *file = (CScriptFile*)gen->GetObject();
67 int len = gen->GetArgDWord(0);
68 string str = file->ReadString(len);
69 gen->SetReturnObject(&str);
70 }
71
ScriptFile_ReadLine_Generic(asIScriptGeneric * gen)72 void ScriptFile_ReadLine_Generic(asIScriptGeneric *gen)
73 {
74 CScriptFile *file = (CScriptFile*)gen->GetObject();
75 std::string str = file->ReadLine();
76 gen->SetReturnObject(&str);
77 }
78
ScriptFile_ReadInt_Generic(asIScriptGeneric * gen)79 void ScriptFile_ReadInt_Generic(asIScriptGeneric *gen)
80 {
81 CScriptFile *file = (CScriptFile*)gen->GetObject();
82 asUINT bytes = *(asUINT*)gen->GetAddressOfArg(0);
83 *(asINT64*)gen->GetAddressOfReturnLocation() = file->ReadInt(bytes);
84 }
85
ScriptFile_ReadUInt_Generic(asIScriptGeneric * gen)86 void ScriptFile_ReadUInt_Generic(asIScriptGeneric *gen)
87 {
88 CScriptFile *file = (CScriptFile*)gen->GetObject();
89 asUINT bytes = *(asUINT*)gen->GetAddressOfArg(0);
90 *(asQWORD*)gen->GetAddressOfReturnLocation() = file->ReadUInt(bytes);
91 }
92
ScriptFile_ReadFloat_Generic(asIScriptGeneric * gen)93 void ScriptFile_ReadFloat_Generic(asIScriptGeneric *gen)
94 {
95 CScriptFile *file = (CScriptFile*)gen->GetObject();
96 *(float*)gen->GetAddressOfReturnLocation() = file->ReadFloat();
97 }
98
ScriptFile_ReadDouble_Generic(asIScriptGeneric * gen)99 void ScriptFile_ReadDouble_Generic(asIScriptGeneric *gen)
100 {
101 CScriptFile *file = (CScriptFile*)gen->GetObject();
102 *(double*)gen->GetAddressOfReturnLocation() = file->ReadDouble();
103 }
104
ScriptFile_WriteString_Generic(asIScriptGeneric * gen)105 void ScriptFile_WriteString_Generic(asIScriptGeneric *gen)
106 {
107 CScriptFile *file = (CScriptFile*)gen->GetObject();
108 std::string *str = (std::string*)gen->GetArgAddress(0);
109 gen->SetReturnDWord(file->WriteString(*str));
110 }
111
ScriptFile_WriteInt_Generic(asIScriptGeneric * gen)112 void ScriptFile_WriteInt_Generic(asIScriptGeneric *gen)
113 {
114 CScriptFile *file = (CScriptFile*)gen->GetObject();
115 asINT64 val = *(asINT64*)gen->GetAddressOfArg(0);
116 asUINT bytes = *(asUINT*)gen->GetAddressOfArg(1);
117 *(int*)gen->GetAddressOfReturnLocation() = file->WriteInt(val, bytes);
118 }
119
ScriptFile_WriteUInt_Generic(asIScriptGeneric * gen)120 void ScriptFile_WriteUInt_Generic(asIScriptGeneric *gen)
121 {
122 CScriptFile *file = (CScriptFile*)gen->GetObject();
123 asQWORD val = *(asQWORD*)gen->GetAddressOfArg(0);
124 asUINT bytes = *(asUINT*)gen->GetAddressOfArg(1);
125 *(int*)gen->GetAddressOfReturnLocation() = file->WriteUInt(val, bytes);
126 }
127
ScriptFile_WriteFloat_Generic(asIScriptGeneric * gen)128 void ScriptFile_WriteFloat_Generic(asIScriptGeneric *gen)
129 {
130 CScriptFile *file = (CScriptFile*)gen->GetObject();
131 float val = *(float*)gen->GetAddressOfArg(0);
132 *(int*)gen->GetAddressOfReturnLocation() = file->WriteFloat(val);
133 }
134
ScriptFile_WriteDouble_Generic(asIScriptGeneric * gen)135 void ScriptFile_WriteDouble_Generic(asIScriptGeneric *gen)
136 {
137 CScriptFile *file = (CScriptFile*)gen->GetObject();
138 double val = *(double*)gen->GetAddressOfArg(0);
139 *(int*)gen->GetAddressOfReturnLocation() = file->WriteDouble(val);
140 }
141
ScriptFile_IsEOF_Generic(asIScriptGeneric * gen)142 void ScriptFile_IsEOF_Generic(asIScriptGeneric *gen)
143 {
144 CScriptFile *file = (CScriptFile*)gen->GetObject();
145 bool r = file->IsEOF();
146 gen->SetReturnByte(r);
147 }
148
ScriptFile_GetPos_Generic(asIScriptGeneric * gen)149 void ScriptFile_GetPos_Generic(asIScriptGeneric *gen)
150 {
151 CScriptFile *file = (CScriptFile*)gen->GetObject();
152 gen->SetReturnDWord(file->GetPos());
153 }
154
ScriptFile_SetPos_Generic(asIScriptGeneric * gen)155 void ScriptFile_SetPos_Generic(asIScriptGeneric *gen)
156 {
157 CScriptFile *file = (CScriptFile*)gen->GetObject();
158 int pos = (int)gen->GetArgDWord(0);
159 gen->SetReturnDWord(file->SetPos(pos));
160 }
161
ScriptFile_MovePos_Generic(asIScriptGeneric * gen)162 void ScriptFile_MovePos_Generic(asIScriptGeneric *gen)
163 {
164 CScriptFile *file = (CScriptFile*)gen->GetObject();
165 int delta = (int)gen->GetArgDWord(0);
166 gen->SetReturnDWord(file->MovePos(delta));
167 }
168
RegisterScriptFile_Native(asIScriptEngine * engine)169 void RegisterScriptFile_Native(asIScriptEngine *engine)
170 {
171 int r;
172
173 r = engine->RegisterObjectType("file", 0, asOBJ_REF); assert( r >= 0 );
174 r = engine->RegisterObjectBehaviour("file", asBEHAVE_FACTORY, "file @f()", asFUNCTION(ScriptFile_Factory), asCALL_CDECL); assert( r >= 0 );
175 r = engine->RegisterObjectBehaviour("file", asBEHAVE_ADDREF, "void f()", asMETHOD(CScriptFile,AddRef), asCALL_THISCALL); assert( r >= 0 );
176 r = engine->RegisterObjectBehaviour("file", asBEHAVE_RELEASE, "void f()", asMETHOD(CScriptFile,Release), asCALL_THISCALL); assert( r >= 0 );
177
178 r = engine->RegisterObjectMethod("file", "int open(const string &in, const string &in)", asMETHOD(CScriptFile,Open), asCALL_THISCALL); assert( r >= 0 );
179 r = engine->RegisterObjectMethod("file", "int close()", asMETHOD(CScriptFile,Close), asCALL_THISCALL); assert( r >= 0 );
180 r = engine->RegisterObjectMethod("file", "int getSize() const", asMETHOD(CScriptFile,GetSize), asCALL_THISCALL); assert( r >= 0 );
181 r = engine->RegisterObjectMethod("file", "bool isEndOfFile() const", asMETHOD(CScriptFile,IsEOF), asCALL_THISCALL); assert( r >= 0 );
182 r = engine->RegisterObjectMethod("file", "string readString(uint)", asMETHOD(CScriptFile,ReadString), asCALL_THISCALL); assert( r >= 0 );
183 r = engine->RegisterObjectMethod("file", "string readLine()", asMETHOD(CScriptFile,ReadLine), asCALL_THISCALL); assert( r >= 0 );
184 r = engine->RegisterObjectMethod("file", "int64 readInt(uint)", asMETHOD(CScriptFile,ReadInt), asCALL_THISCALL); assert( r >= 0 );
185 r = engine->RegisterObjectMethod("file", "uint64 readUInt(uint)", asMETHOD(CScriptFile,ReadUInt), asCALL_THISCALL); assert( r >= 0 );
186 r = engine->RegisterObjectMethod("file", "float readFloat()", asMETHOD(CScriptFile,ReadFloat), asCALL_THISCALL); assert( r >= 0 );
187 r = engine->RegisterObjectMethod("file", "double readDouble()", asMETHOD(CScriptFile,ReadDouble), asCALL_THISCALL); assert( r >= 0 );
188 #if AS_WRITE_OPS == 1
189 r = engine->RegisterObjectMethod("file", "int writeString(const string &in)", asMETHOD(CScriptFile,WriteString), asCALL_THISCALL); assert( r >= 0 );
190 r = engine->RegisterObjectMethod("file", "int writeInt(int64, uint)", asMETHOD(CScriptFile,WriteInt), asCALL_THISCALL); assert( r >= 0 );
191 r = engine->RegisterObjectMethod("file", "int writeUInt(uint64, uint)", asMETHOD(CScriptFile,WriteUInt), asCALL_THISCALL); assert( r >= 0 );
192 r = engine->RegisterObjectMethod("file", "int writeFloat(float)", asMETHOD(CScriptFile,WriteFloat), asCALL_THISCALL); assert( r >= 0 );
193 r = engine->RegisterObjectMethod("file", "int writeDouble(double)", asMETHOD(CScriptFile,WriteDouble), asCALL_THISCALL); assert( r >= 0 );
194 #endif
195 r = engine->RegisterObjectMethod("file", "int getPos() const", asMETHOD(CScriptFile,GetPos), asCALL_THISCALL); assert( r >= 0 );
196 r = engine->RegisterObjectMethod("file", "int setPos(int)", asMETHOD(CScriptFile,SetPos), asCALL_THISCALL); assert( r >= 0 );
197 r = engine->RegisterObjectMethod("file", "int movePos(int)", asMETHOD(CScriptFile,MovePos), asCALL_THISCALL); assert( r >= 0 );
198
199 r = engine->RegisterObjectProperty("file", "bool mostSignificantByteFirst", asOFFSET(CScriptFile, mostSignificantByteFirst)); assert( r >= 0 );
200 }
201
RegisterScriptFile_Generic(asIScriptEngine * engine)202 void RegisterScriptFile_Generic(asIScriptEngine *engine)
203 {
204 int r;
205
206 r = engine->RegisterObjectType("file", 0, asOBJ_REF); assert( r >= 0 );
207 r = engine->RegisterObjectBehaviour("file", asBEHAVE_FACTORY, "file @f()", asFUNCTION(ScriptFile_Factory_Generic), asCALL_GENERIC); assert( r >= 0 );
208 r = engine->RegisterObjectBehaviour("file", asBEHAVE_ADDREF, "void f()", asFUNCTION(ScriptFile_AddRef_Generic), asCALL_GENERIC); assert( r >= 0 );
209 r = engine->RegisterObjectBehaviour("file", asBEHAVE_RELEASE, "void f()", asFUNCTION(ScriptFile_Release_Generic), asCALL_GENERIC); assert( r >= 0 );
210
211 r = engine->RegisterObjectMethod("file", "int open(const string &in, const string &in)", asFUNCTION(ScriptFile_Open_Generic), asCALL_GENERIC); assert( r >= 0 );
212 r = engine->RegisterObjectMethod("file", "int close()", asFUNCTION(ScriptFile_Close_Generic), asCALL_GENERIC); assert( r >= 0 );
213 r = engine->RegisterObjectMethod("file", "int getSize() const", asFUNCTION(ScriptFile_GetSize_Generic), asCALL_GENERIC); assert( r >= 0 );
214 r = engine->RegisterObjectMethod("file", "bool isEndOfFile() const", asFUNCTION(ScriptFile_IsEOF_Generic), asCALL_GENERIC); assert( r >= 0 );
215 r = engine->RegisterObjectMethod("file", "string readString(uint)", asFUNCTION(ScriptFile_ReadString_Generic), asCALL_GENERIC); assert( r >= 0 );
216 r = engine->RegisterObjectMethod("file", "string readLine()", asFUNCTION(ScriptFile_ReadLine_Generic), asCALL_GENERIC); assert( r >= 0 );
217 r = engine->RegisterObjectMethod("file", "int64 readInt(uint)", asFUNCTION(ScriptFile_ReadInt_Generic), asCALL_GENERIC); assert( r >= 0 );
218 r = engine->RegisterObjectMethod("file", "uint64 readUInt(uint)", asFUNCTION(ScriptFile_ReadUInt_Generic), asCALL_GENERIC); assert( r >= 0 );
219 r = engine->RegisterObjectMethod("file", "float readFloat()", asFUNCTION(ScriptFile_ReadFloat_Generic), asCALL_GENERIC); assert( r >= 0 );
220 r = engine->RegisterObjectMethod("file", "double readDouble()", asFUNCTION(ScriptFile_ReadDouble_Generic), asCALL_GENERIC); assert( r >= 0 );
221 #if AS_WRITE_OPS == 1
222 r = engine->RegisterObjectMethod("file", "int writeString(const string &in)", asFUNCTION(ScriptFile_WriteString_Generic), asCALL_GENERIC); assert( r >= 0 );
223 r = engine->RegisterObjectMethod("file", "int writeInt(int64, uint)", asFUNCTION(ScriptFile_WriteInt_Generic), asCALL_GENERIC); assert( r >= 0 );
224 r = engine->RegisterObjectMethod("file", "int writeUInt(uint64, uint)", asFUNCTION(ScriptFile_WriteUInt_Generic), asCALL_GENERIC); assert( r >= 0 );
225 r = engine->RegisterObjectMethod("file", "int writeFloat(float)", asFUNCTION(ScriptFile_WriteFloat_Generic), asCALL_GENERIC); assert( r >= 0 );
226 r = engine->RegisterObjectMethod("file", "int writeDouble(double)", asFUNCTION(ScriptFile_WriteDouble_Generic), asCALL_GENERIC); assert( r >= 0 );
227 #endif
228 r = engine->RegisterObjectMethod("file", "int getPos() const", asFUNCTION(ScriptFile_GetPos_Generic), asCALL_GENERIC); assert( r >= 0 );
229 r = engine->RegisterObjectMethod("file", "int setPos(int)", asFUNCTION(ScriptFile_SetPos_Generic), asCALL_GENERIC); assert( r >= 0 );
230 r = engine->RegisterObjectMethod("file", "int movePos(int)", asFUNCTION(ScriptFile_MovePos_Generic), asCALL_GENERIC); assert( r >= 0 );
231
232 r = engine->RegisterObjectProperty("file", "bool mostSignificantByteFirst", asOFFSET(CScriptFile, mostSignificantByteFirst)); assert( r >= 0 );
233 }
234
RegisterScriptFile(asIScriptEngine * engine)235 void RegisterScriptFile(asIScriptEngine *engine)
236 {
237 if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
238 RegisterScriptFile_Generic(engine);
239 else
240 RegisterScriptFile_Native(engine);
241 }
242
CScriptFile()243 CScriptFile::CScriptFile()
244 {
245 refCount = 1;
246 file = 0;
247 mostSignificantByteFirst = false;
248 }
249
~CScriptFile()250 CScriptFile::~CScriptFile()
251 {
252 Close();
253 }
254
AddRef() const255 void CScriptFile::AddRef() const
256 {
257 asAtomicInc(refCount);
258 }
259
Release() const260 void CScriptFile::Release() const
261 {
262 if( asAtomicDec(refCount) == 0 )
263 delete this;
264 }
265
Open(const std::string & filename,const std::string & mode)266 int CScriptFile::Open(const std::string &filename, const std::string &mode)
267 {
268 // Close the previously opened file handle
269 if( file )
270 Close();
271
272 std::string myFilename = filename;
273
274 // Validate the mode
275 string m;
276 #if AS_WRITE_OPS == 1
277 if( mode != "r" && mode != "w" && mode != "a" )
278 #else
279 if( mode != "r" )
280 #endif
281 return -1;
282 else
283 m = mode;
284
285 #ifdef _WIN32_WCE
286 // no relative pathing on CE
287 char buf[MAX_PATH];
288 static TCHAR apppath[MAX_PATH] = TEXT("");
289 if (!apppath[0])
290 {
291 GetModuleFileName(NULL, apppath, MAX_PATH);
292
293 int appLen = _tcslen(apppath);
294 while (appLen > 1)
295 {
296 if (apppath[appLen-1] == TEXT('\\'))
297 break;
298 appLen--;
299 }
300
301 // Terminate the string after the trailing backslash
302 apppath[appLen] = TEXT('\0');
303 }
304 #ifdef _UNICODE
305 wcstombs(buf, apppath, wcslen(apppath)+1);
306 #else
307 memcpy(buf, apppath, strlen(apppath));
308 #endif
309 myFilename = buf + myFilename;
310 #endif
311
312
313 // By default windows translates "\r\n" to "\n", but we want to read the file as-is.
314 m += "b";
315
316 // Open the file
317 #if _MSC_VER >= 1400 && !defined(__S3E__)
318 // MSVC 8.0 / 2005 introduced new functions
319 // Marmalade doesn't use these, even though it uses the MSVC compiler
320 fopen_s(&file, myFilename.c_str(), m.c_str());
321 #else
322 file = fopen(myFilename.c_str(), m.c_str());
323 #endif
324 if( file == 0 )
325 return -1;
326
327 return 0;
328 }
329
Close()330 int CScriptFile::Close()
331 {
332 if( file == 0 )
333 return -1;
334
335 fclose(file);
336 file = 0;
337
338 return 0;
339 }
340
GetSize() const341 int CScriptFile::GetSize() const
342 {
343 if( file == 0 )
344 return -1;
345
346 int pos = ftell(file);
347 fseek(file, 0, SEEK_END);
348 int size = ftell(file);
349 fseek(file, pos, SEEK_SET);
350
351 return size;
352 }
353
GetPos() const354 int CScriptFile::GetPos() const
355 {
356 if( file == 0 )
357 return -1;
358
359 return ftell(file);
360 }
361
SetPos(int pos)362 int CScriptFile::SetPos(int pos)
363 {
364 if( file == 0 )
365 return -1;
366
367 int r = fseek(file, pos, SEEK_SET);
368
369 // Return -1 on error
370 return r ? -1 : 0;
371 }
372
MovePos(int delta)373 int CScriptFile::MovePos(int delta)
374 {
375 if( file == 0 )
376 return -1;
377
378 int r = fseek(file, delta, SEEK_CUR);
379
380 // Return -1 on error
381 return r ? -1 : 0;
382 }
383
ReadString(unsigned int length)384 string CScriptFile::ReadString(unsigned int length)
385 {
386 if( file == 0 )
387 return "";
388
389 // Read the string
390 string str;
391 str.resize(length);
392 int size = (int)fread(&str[0], 1, length, file);
393 str.resize(size);
394
395 return str;
396 }
397
ReadLine()398 string CScriptFile::ReadLine()
399 {
400 if( file == 0 )
401 return "";
402
403 // Read until the first new-line character
404 string str;
405 char buf[256];
406
407 do
408 {
409 // Get the current position so we can determine how many characters were read
410 int start = ftell(file);
411
412 // Set the last byte to something different that 0, so that we can check if the buffer was filled up
413 buf[255] = 1;
414
415 // Read the line (or first 255 characters, which ever comes first)
416 char *r = fgets(buf, 256, file);
417 if( r == 0 ) break;
418
419 // Get the position after the read
420 int end = ftell(file);
421
422 // Add the read characters to the output buffer
423 str.append(buf, end-start);
424 }
425 while( !feof(file) && buf[255] == 0 && buf[254] != '\n' );
426
427 return str;
428 }
429
ReadInt(asUINT bytes)430 asINT64 CScriptFile::ReadInt(asUINT bytes)
431 {
432 if( file == 0 )
433 return 0;
434
435 if( bytes > 8 ) bytes = 8;
436 if( bytes == 0 ) return 0;
437
438 unsigned char buf[8];
439 size_t r = fread(buf, bytes, 1, file);
440 if( r == 0 ) return 0;
441
442 asINT64 val = 0;
443 if( mostSignificantByteFirst )
444 {
445 unsigned int n = 0;
446 for( ; n < bytes; n++ )
447 val |= asQWORD(buf[n]) << ((bytes-n-1)*8);
448
449 // Check the most significant byte to determine if the rest
450 // of the qword must be filled to give a negative value
451 if( buf[0] & 0x80 )
452 for( ; n < 8; n++ )
453 val |= asQWORD(0xFF) << (n*8);
454 }
455 else
456 {
457 unsigned int n = 0;
458 for( ; n < bytes; n++ )
459 val |= asQWORD(buf[n]) << (n*8);
460
461 // Check the most significant byte to determine if the rest
462 // of the qword must be filled to give a negative value
463 if( buf[bytes-1] & 0x80 )
464 for( ; n < 8; n++ )
465 val |= asQWORD(0xFF) << (n*8);
466 }
467
468 return val;
469 }
470
ReadUInt(asUINT bytes)471 asQWORD CScriptFile::ReadUInt(asUINT bytes)
472 {
473 if( file == 0 )
474 return 0;
475
476 if( bytes > 8 ) bytes = 8;
477 if( bytes == 0 ) return 0;
478
479 unsigned char buf[8];
480 size_t r = fread(buf, bytes, 1, file);
481 if( r == 0 ) return 0;
482
483 asQWORD val = 0;
484 if( mostSignificantByteFirst )
485 {
486 unsigned int n = 0;
487 for( ; n < bytes; n++ )
488 val |= asQWORD(buf[n]) << ((bytes-n-1)*8);
489 }
490 else
491 {
492 unsigned int n = 0;
493 for( ; n < bytes; n++ )
494 val |= asQWORD(buf[n]) << (n*8);
495 }
496
497 return val;
498 }
499
ReadFloat()500 float CScriptFile::ReadFloat()
501 {
502 if( file == 0 )
503 return 0;
504
505 unsigned char buf[4];
506 size_t r = fread(buf, 4, 1, file);
507 if( r == 0 ) return 0;
508
509 asUINT val = 0;
510 if( mostSignificantByteFirst )
511 {
512 unsigned int n = 0;
513 for( ; n < 4; n++ )
514 val |= asUINT(buf[n]) << ((3-n)*8);
515 }
516 else
517 {
518 unsigned int n = 0;
519 for( ; n < 4; n++ )
520 val |= asUINT(buf[n]) << (n*8);
521 }
522
523 return *reinterpret_cast<float*>(&val);
524 }
525
ReadDouble()526 double CScriptFile::ReadDouble()
527 {
528 if( file == 0 )
529 return 0;
530
531 unsigned char buf[8];
532 size_t r = fread(buf, 8, 1, file);
533 if( r == 0 ) return 0;
534
535 asQWORD val = 0;
536 if( mostSignificantByteFirst )
537 {
538 unsigned int n = 0;
539 for( ; n < 8; n++ )
540 val |= asQWORD(buf[n]) << ((7-n)*8);
541 }
542 else
543 {
544 unsigned int n = 0;
545 for( ; n < 8; n++ )
546 val |= asQWORD(buf[n]) << (n*8);
547 }
548
549 return *reinterpret_cast<double*>(&val);
550 }
551
IsEOF() const552 bool CScriptFile::IsEOF() const
553 {
554 if( file == 0 )
555 return true;
556
557 return feof(file) ? true : false;
558 }
559
560 #if AS_WRITE_OPS == 1
WriteString(const std::string & str)561 int CScriptFile::WriteString(const std::string &str)
562 {
563 if( file == 0 )
564 return -1;
565
566 // Write the entire string
567 size_t r = fwrite(&str[0], 1, str.length(), file);
568
569 return int(r);
570 }
571
WriteInt(asINT64 val,asUINT bytes)572 int CScriptFile::WriteInt(asINT64 val, asUINT bytes)
573 {
574 if( file == 0 )
575 return 0;
576
577 unsigned char buf[8];
578 if( mostSignificantByteFirst )
579 {
580 for( unsigned int n = 0; n < bytes; n++ )
581 buf[n] = (val >> ((bytes-n-1)*8)) & 0xFF;
582 }
583 else
584 {
585 for( unsigned int n = 0; n < bytes; n++ )
586 buf[n] = (val >> (n*8)) & 0xFF;
587 }
588
589 size_t r = fwrite(&buf, bytes, 1, file);
590 return int(r);
591 }
592
WriteUInt(asQWORD val,asUINT bytes)593 int CScriptFile::WriteUInt(asQWORD val, asUINT bytes)
594 {
595 if( file == 0 )
596 return 0;
597
598 unsigned char buf[8];
599 if( mostSignificantByteFirst )
600 {
601 for( unsigned int n = 0; n < bytes; n++ )
602 buf[n] = (val >> ((bytes-n-1)*8)) & 0xFF;
603 }
604 else
605 {
606 for( unsigned int n = 0; n < bytes; n++ )
607 buf[n] = (val >> (n*8)) & 0xFF;
608 }
609
610 size_t r = fwrite(&buf, bytes, 1, file);
611 return int(r);
612 }
613
WriteFloat(float f)614 int CScriptFile::WriteFloat(float f)
615 {
616 if( file == 0 )
617 return 0;
618
619 unsigned char buf[4];
620 asUINT val = *reinterpret_cast<asUINT*>(&f);
621 if( mostSignificantByteFirst )
622 {
623 for( unsigned int n = 0; n < 4; n++ )
624 buf[n] = (val >> ((3-n)*4)) & 0xFF;
625 }
626 else
627 {
628 for( unsigned int n = 0; n < 4; n++ )
629 buf[n] = (val >> (n*8)) & 0xFF;
630 }
631
632 size_t r = fwrite(&buf, 4, 1, file);
633 return int(r);
634 }
635
WriteDouble(double d)636 int CScriptFile::WriteDouble(double d)
637 {
638 if( file == 0 )
639 return 0;
640
641 unsigned char buf[8];
642 asQWORD val = *reinterpret_cast<asQWORD*>(&d);
643 if( mostSignificantByteFirst )
644 {
645 for( unsigned int n = 0; n < 8; n++ )
646 buf[n] = (val >> ((7-n)*8)) & 0xFF;
647 }
648 else
649 {
650 for( unsigned int n = 0; n < 8; n++ )
651 buf[n] = (val >> (n*8)) & 0xFF;
652 }
653
654 size_t r = fwrite(&buf, 8, 1, file);
655 return int(r);
656 }
657 #endif
658
659
660 END_AS_NAMESPACE
661