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