|
50 | 50 | struct |
51 | 51 | ) |
52 | 52 |
|
53 | | - local function POSIX_TIME(time: number) |
| 53 | + local function POSIX_TIME(time: number): number |
54 | 54 | return tonumber(time / 10000000 - 11644473600) |
55 | 55 | end |
56 | 56 |
|
|
73 | 73 | temporary = 0x100, -- A file that is being used for temporary storage. File systems avoid writing data back to mass storage if sufficient cache memory is available, because typically, an application deletes a temporary file after the handle is closed. In that scenario, the system can entirely avoid writing the data. Otherwise, the data is written after the handle is closed. |
74 | 74 | virtual = 0x10000, -- This value is reserved for system use. |
75 | 75 | } |
| 76 | + local box = ffi.typeof("$[1]", struct) |
76 | 77 |
|
77 | 78 | function fs.get_attributes(path, follow_link) |
78 | | - local info = ffi.new("$[1]", struct) |
| 79 | + local info = box() |
79 | 80 |
|
80 | 81 | if ffi.C.GetFileAttributesExA(path, 0, info) ~= 0 then |
| 82 | + local s = assert(info[0]) |
81 | 83 | return { |
82 | | - creation_time = POSIX_TIME(info[0].ftCreationTime), |
83 | | - last_accessed = POSIX_TIME(info[0].ftLastAccessTime), |
84 | | - last_modified = POSIX_TIME(info[0].ftLastWriteTime), |
| 84 | + creation_time = POSIX_TIME(s.ftCreationTime), |
| 85 | + last_accessed = POSIX_TIME(s.ftLastAccessTime), |
| 86 | + last_modified = POSIX_TIME(s.ftLastWriteTime), |
85 | 87 | last_changed = -1, -- last permission changes |
86 | | - size = tonumber(info[0].nFileSize), |
87 | | - type = bit.band(info[0].dwFileAttributes, flags.directory) == flags.directory and |
| 88 | + size = assert(tonumber(s.nFileSize)), |
| 89 | + type = bit.band(s.dwFileAttributes, flags.directory) == flags.directory and |
88 | 90 | "directory" or |
89 | 91 | "file", |
90 | 92 | } |
|
122 | 124 | ) |
123 | 125 | local dot = string.byte(".") |
124 | 126 |
|
125 | | - local function is_dots(ptr: {[number] = number}) -- todo: maybe FFIArray<|12, number|> should be ok to pass when the argument contract is FFIArray<|3, number|> , because it's at least 3 in length |
| 127 | + local function is_dots(ptr: ffi.new("const char *")) -- todo: maybe FFIArray<|12, number|> should be ok to pass when the argument contract is FFIArray<|3, number|> , because it's at least 3 in length |
126 | 128 | if ptr[0] == dot then |
127 | 129 | if ptr[1] == dot and ptr[2] == 0 then return true end |
128 | 130 |
|
|
133 | 135 | end |
134 | 136 |
|
135 | 137 | local INVALID_FILE = ffi.cast("void *", 0xFFFFFFFFFFFFFFFFULL) |
| 138 | + local box = ffi.typeof("$[1]", struct) |
136 | 139 |
|
137 | 140 | function fs.get_files(path) |
138 | 141 | if path == "" then path = "." end |
139 | 142 |
|
140 | 143 | if path:sub(-1) ~= "/" then path = path .. "/" end |
141 | 144 |
|
142 | | - local data = ffi.new("$[1]", struct) |
| 145 | + local data = box() |
143 | 146 | local handle = ffi.C.FindFirstFileA(path .. "*", data) |
144 | 147 |
|
145 | 148 | if handle == nil then return nil, last_error() end |
|
170 | 173 | ]]) |
171 | 174 |
|
172 | 175 | function fs.set_current_directory(path) |
173 | | - if ffi.C.chdir(path) == 0 then return true end |
| 176 | + if ffi.C.SetCurrentDirectoryA(path) == 0 then return true end |
174 | 177 |
|
175 | 178 | return nil, last_error() |
176 | 179 | end |
|
0 commit comments