1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#include "Runtime/Lua/LuaHelper.h"
#include "Runtime/Debug/Log.h"
#include "Runtime/Common/DataBuffer.h"
#include "Runtime/FileSystem/FileJobs.h"
#include <fstream>
using namespace std;
using namespace LuaBind;
enum EFileMode
{
FileMode_Text,
FileMode_Binary,
};
// IO.ReadFiles({}, callback)
int ReadFilesAsync(lua_State* L)
{
LUA_BIND_STATE(L);
LUA_BIND_CHECK(L, "TF!");
std::vector<std::string> files;
for (int i = 1; true; ++i)
{
state.GetField(1, i);
if (lua_type(L, -1) != LUA_TSTRING)
{
lua_pop(L, 1);
break;
}
const char* f = lua_tostring(L, -1);
state.Pop(1);
files.push_back(f);
}
ReadFilesJob* job = new ReadFilesJob(state.GetVM());
job->files = files;
job->callback.SetRef(state, 2);
JobSystem::Instance()->AddJobAtEnd(job);
return 0;
}
// IO.ReadFile(path[,mode])
// return DataBuffer
int ReadFile(lua_State* L)
{
LUA_BIND_STATE(L);
LUA_BIND_CHECK(L, "SN!|S!");
const char* path = state.GetValue(1, "");
int mode = state.GetValue<int>(2, EFileMode::FileMode_Binary);
bool isTextFile = mode == EFileMode::FileMode_Text;
bool isBinaryFile = mode == EFileMode::FileMode_Binary;
int openMode = 0;
//if (isBinaryFile)
openMode |= ios::binary;
std::ifstream file = ifstream(path, openMode);
if (!file.is_open())
{
log_error(string("Can't read file. ") + path);
state.PushNil();
return 1;
}
std::streampos size = file.tellg();
file.seekg(0, std::ios::end);
size = file.tellg() - size;
if (size == 0)
{
log_error(string("File is Empty. ") + path);
state.PushNil();
return 1;
}
file.seekg(0, std::ios::beg);
int bufSize = size;
if (isTextFile)
bufSize += 1; // \0
DataBuffer* buffer = new DataBuffer(state.GetVM());
buffer->type = isBinaryFile ? EDataBufferType::DataBufferMode_Binary : EDataBufferType::DataBufferMode_Text;
buffer->data = new char[bufSize];
buffer->length = bufSize;
file.read(buffer->data, size);
file.close();
if (isTextFile)
buffer->data[bufSize - 1] = '\0';
buffer->PushUserdata(state);
return 1;
}
static luaL_Reg ioFuncs[] = {
{ "ReadFilesAsync", ReadFilesAsync },
{ "ReadFile", ReadFile },
{ 0, 0 }
};
int luaopen_GameLab_IO(lua_State* L)
{
log_info("Scripting", "luaopen_GameLab_IO()");
LUA_BIND_STATE(L);
state.PushGlobalNamespace();
state.PushNamespace("GameLab");
state.PushNamespace("IO");
state.RegisterMethods(ioFuncs);
LUA_BIND_REGISTER_ENUM(state, "EFileMode",
{ "Binary", EFileMode::FileMode_Binary},
{ "Text", EFileMode::FileMode_Text}
);
return 1;
}
|