v1.11.0 - Improved the filesystem library to buffer file reading.

This commit is contained in:
Ponali
2025-06-26 10:28:12 +02:00
parent 235db61a01
commit 9e2fc6bdbf
3 changed files with 99 additions and 5 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
local agcfg = { local agcfg = {
["halyde"] = { ["halyde"] = {
["maindir"] = "", ["maindir"] = "",
["version"] = "1.10.0", ["version"] = "1.11.0",
["description"] = "A universal, customizable and feature-packed operating system for OpenComputers.", ["description"] = "A universal, customizable and feature-packed operating system for OpenComputers.",
["directories"] = { ["directories"] = {
"halyde/apps", "halyde/apps",
+1 -1
View File
@@ -1,7 +1,7 @@
local loadfile = ... local loadfile = ...
local filesystem = loadfile("/halyde/lib/filesystem.lua")(loadfile) local filesystem = loadfile("/halyde/lib/filesystem.lua")(loadfile)
_G._OSVERSION = "Halyde 1.10.0" _G._OSVERSION = "Halyde 1.11.0"
_G._OSLOGO = "" _G._OSLOGO = ""
local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil
repeat repeat
+97 -3
View File
@@ -69,12 +69,60 @@ function filesystem.exists(path) -- check if path exists
return component.invoke(address, "exists", absPath) return component.invoke(address, "exists", absPath)
end end
function filesystem.open(path, mode) -- opens a file and returns its handle local function readUniChar(readByte)
local function inRange(min,max,...)
for _,v in ipairs({...}) do
if not (v and v>=min and v<max) then return false end
end
return true
end
local function readByte0() return readByte() or 0 end
local byte = readByte()
if byte < 0x80 then
-- ASCII character (0xxxxxxx)
return byte
elseif byte < 0xC0 then
-- Continuation byte (10xxxxxx), invalid at start position
return nil
elseif byte < 0xE0 then
-- 2-byte sequence (110xxxxx 10xxxxxx)
local byte2 = readByte0()
if inRange(0x80,0xC0,byte2) then
local code_point = ((byte & 0x1F) << 6) | (byte2 & 0x3F)
return code_point
end
elseif byte < 0xF0 then
-- 3-byte sequence (1110xxxx 10xxxxxx 10xxxxxx)
local byte2, byte3 = readByte0(), readByte0()
if inRange(0x80,0xC0,byte2,byte3)then
local code_point = ((byte & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F)
return code_point
end
elseif byte < 0xF8 then
-- 4-byte sequence (11110xxx 10xxxxxx 10xxxxxx 10xxxxxx)
local byte2, byte3, byte4 = readByte0(), readByte0(), readByte0()
if inRange(0x80,0xC0,byte2,byte3,byte4) then
local code_point = ((byte & 0x07) << 18) | ((byte2 & 0x3F) << 12) | ((byte3 & 0x3F) << 6) | (byte4 & 0x3F)
return code_point
end
end
-- Invalid UTF-8 byte sequence
return nil
end
function filesystem.open(path, mode, buffered) -- opens a file and returns its handle
checkArg(1, path, "string") checkArg(1, path, "string")
checkArg(2, mode, "string", "nil") checkArg(2, mode, "string", "nil")
checkArg(3, buffered, "boolean", "nil")
if not mode then if not mode then
mode = "r" mode = "r"
end end
if not buffered then
buffered = true
end
if not (mode == "r" or mode == "w" or mode == "rb" or mode == "wb") then if not (mode == "r" or mode == "w" or mode == "rb" or mode == "wb") then
return nil, "invalid handle type" return nil, "invalid handle type"
end end
@@ -88,16 +136,62 @@ function filesystem.open(path, mode) -- opens a file and returns its handle
local properHandle = {} local properHandle = {}
properHandle.handle = handle properHandle.handle = handle
properHandle.address = address properHandle.address = address
local content = nil
local readcursor = 1
if buffered and mode:sub(1,1)=="r" then
content=""
repeat
tmpdata = component.invoke(address, "read", handle, math.huge or math.maxinteger)
content = content .. (tmpdata or "")
until not tmpdata
component.invoke(address, "close", handle)
end
function properHandle.read(self, amount) function properHandle.read(self, amount)
checkArg(2, amount, "number") checkArg(2, amount, "number")
return component.invoke(self.address, "read", self.handle, amount) if buffered then
local limit = string.len(content)+1
local out = nil
-- error("amount "..amount..", limit "..limit)
if readcursor<limit then
if amount==math.huge then
out = string.sub(content,math.min(readcursor,limit))
else
out = string.sub(content,math.min(readcursor,limit),math.min(readcursor+amount-1,limit))
end
end
readcursor=readcursor+amount
if out=="" then
return nil
end
return out
else
return component.invoke(self.address, "read", self.handle, amount)
end
end
function properHandle.readBytes(self,n)
n = n or 1
if n==1 then return string.byte(self:read(1)) end
local bytes, res = {string.byte(self:read(n),1,n)}, 0
for i=1,#bytes do
res = (res<<8)&0xFFFFFFFF | bytes[i]
end
return res
end
function properHandle.readUnicodeChar(self)
return unicode.char(readUniChar(function()
return self:readBytes(1)
end))
end end
function properHandle.write(self, data) function properHandle.write(self, data)
checkArg(2, data, "string") checkArg(2, data, "string")
return component.invoke(self.address, "write", self.handle, data) return component.invoke(self.address, "write", self.handle, data)
end end
function properHandle.close(self) function properHandle.close(self)
return component.invoke(self.address, "close", self.handle) if buffered then
content = nil
else
return component.invoke(self.address, "close", self.handle)
end
end end
return properHandle return properHandle
end end