ed
This commit is contained in:
parent
9b77c2d36a
commit
e4383f34d2
3902 changed files with 27282 additions and 525887 deletions
|
@ -0,0 +1,155 @@
|
|||
-- Credit: https://github.com/citizenfx/lua/blob/luaglm-dev/cfx/libs/scripts/examples/dataview.lua
|
||||
local dataView = setmetatable({
|
||||
EndBig = ">",
|
||||
EndLittle = "<",
|
||||
Types = {
|
||||
Int8 = { code = "i1" },
|
||||
Uint8 = { code = "I1" },
|
||||
Int16 = { code = "i2" },
|
||||
Uint16 = { code = "I2" },
|
||||
Int32 = { code = "i4" },
|
||||
Uint32 = { code = "I4" },
|
||||
Int64 = { code = "i8" },
|
||||
Uint64 = { code = "I8" },
|
||||
Float32 = { code = "f", size = 4 }, -- a float (native size)
|
||||
Float64 = { code = "d", size = 8 }, -- a double (native size)
|
||||
|
||||
LuaInt = { code = "j" }, -- a lua_Integer
|
||||
UluaInt = { code = "J" }, -- a lua_Unsigned
|
||||
LuaNum = { code = "n" }, -- a lua_Number
|
||||
String = { code = "z", size = -1, }, -- zero terminated string
|
||||
},
|
||||
|
||||
FixedTypes = {
|
||||
String = { code = "c" }, -- a fixed-sized string with n bytes
|
||||
Int = { code = "i" }, -- a signed int with n bytes
|
||||
Uint = { code = "I" }, -- an unsigned int with n bytes
|
||||
},
|
||||
}, {
|
||||
__call = function(_, length)
|
||||
return dataView.ArrayBuffer(length)
|
||||
end
|
||||
})
|
||||
dataView.__index = dataView
|
||||
|
||||
--[[ Create an ArrayBuffer with a size in bytes --]]
|
||||
function dataView.ArrayBuffer(length)
|
||||
return setmetatable({
|
||||
blob = string.blob(length),
|
||||
length = length,
|
||||
offset = 1,
|
||||
cangrow = true,
|
||||
}, dataView)
|
||||
end
|
||||
|
||||
--[[ Wrap a non-internalized string --]]
|
||||
function dataView.Wrap(blob)
|
||||
return setmetatable({
|
||||
blob = blob,
|
||||
length = blob:len(),
|
||||
offset = 1,
|
||||
cangrow = true,
|
||||
}, dataView)
|
||||
end
|
||||
|
||||
--[[ Return the underlying bytebuffer --]]
|
||||
function dataView:Buffer() return self.blob end
|
||||
function dataView:ByteLength() return self.length end
|
||||
function dataView:ByteOffset() return self.offset end
|
||||
function dataView:SubView(offset, length)
|
||||
return setmetatable({
|
||||
blob = self.blob,
|
||||
length = length or self.length,
|
||||
offset = 1 + offset,
|
||||
cangrow = false,
|
||||
}, dataView)
|
||||
end
|
||||
|
||||
--[[ Return the Endianness format character --]]
|
||||
function ef(big) return (big and dataView.EndBig) or dataView.EndLittle end
|
||||
|
||||
--[[ Helper function for setting fixed datatypes within a buffer --]]
|
||||
function packblob(self, offset, value, code)
|
||||
-- If cangrow is false the dataview represents a subview, i.e., a subset
|
||||
-- of some other string view. Ensure the references are the same before
|
||||
-- updating the subview
|
||||
local packed = self.blob:blob_pack(offset, code, value)
|
||||
if self.cangrow or packed == self.blob then
|
||||
self.blob = packed
|
||||
self.length = packed:len()
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
Create the API by using dataView.Types
|
||||
--]]
|
||||
for label,datatype in pairs(dataView.Types) do
|
||||
if not datatype.size then -- cache fixed encoding size
|
||||
datatype.size = string.packsize(datatype.code)
|
||||
elseif datatype.size >= 0 and string.packsize(datatype.code) ~= datatype.size then
|
||||
local msg = "Pack size of %s (%d) does not match cached length: (%d)"
|
||||
error(msg:format(label, string.packsize(datatype.code), datatype.size))
|
||||
return nil
|
||||
end
|
||||
|
||||
dataView["Get" .. label] = function(self, offset, endian)
|
||||
offset = offset or 0
|
||||
if offset >= 0 then
|
||||
local o = self.offset + offset
|
||||
local v,_ = self.blob:blob_unpack(o, ef(endian) .. datatype.code)
|
||||
return v
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
dataView["Set" .. label] = function(self, offset, value, endian)
|
||||
if offset >= 0 and value then
|
||||
local o = self.offset + offset
|
||||
local v_size = (datatype.size < 0 and value:len()) or datatype.size
|
||||
if self.cangrow or ((o + (v_size - 1)) <= self.length) then
|
||||
if not packblob(self, o, value, ef(endian) .. datatype.code) then
|
||||
error("cannot grow subview")
|
||||
end
|
||||
else
|
||||
error("cannot grow dataview")
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
end
|
||||
|
||||
for label,datatype in pairs(dataView.FixedTypes) do
|
||||
datatype.size = -1 -- Ensure cached encoding size is invalidated
|
||||
|
||||
dataView["GetFixed" .. label] = function(self, offset, typelen, endian)
|
||||
if offset >= 0 then
|
||||
local o = self.offset + offset
|
||||
if (o + (typelen - 1)) <= self.length then
|
||||
local code = ef(endian) .. "c" .. tostring(typelen)
|
||||
local v,_ = self.blob:blob_unpack(o, code)
|
||||
return v
|
||||
end
|
||||
end
|
||||
return nil -- Out of bounds
|
||||
end
|
||||
|
||||
dataView["SetFixed" .. label] = function(self, offset, typelen, value, endian)
|
||||
if offset >= 0 and value then
|
||||
local o = self.offset + offset
|
||||
if self.cangrow or ((o + (typelen - 1)) <= self.length) then
|
||||
local code = ef(endian) .. "c" .. tostring(typelen)
|
||||
if not packblob(self, o, value, code) then
|
||||
error("cannot grow subview")
|
||||
end
|
||||
else
|
||||
error("cannot grow dataview")
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
end
|
||||
|
||||
return dataView
|
Loading…
Add table
Add a link
Reference in a new issue