#### Benben
#### Copyright (C) 2023-2024 Remilia Scarlet <remilia@posteo.jp>
####
#### This program is free software: you can redistribute it and/or
#### modify it under the terms of the GNU Affero General Public
#### License as published by the Free Software Foundation, either
#### version 3 of the License, or (at your option) any later version.
####
#### This program is distributed in the hope that it will be useful,
#### but WITHOUT ANY WARRANTY; without even the implied warranty of
#### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#### Affero General Public License for more details.
####
#### You should have received a copy of the GNU Affero General Public License
#### along with this program. If not, see <https://www.gnu.org/licenses/>.
####
#### Simple wrapper for module files.
####
module Benben
# A simple wrapper for module files. This stores raw module data in RAM by
# reading it from a file. The file can optionally be compressed with Gzip,
# Bzip2, or ZStandard.
class ModuleFile
@data : Bytes = Bytes.new(0)
@filename : Path|String
def initialize(@filename : Path|String)
end
def data : Bytes
return @data if @data.size > 0
Benben.dlog!("Loading data for module file: #{@filename}")
io = IO::Memory.new
magic = Bytes.new(4)
File.open(@filename, "rb") do |file|
file.read(magic)
file.rewind
case
when magic[0] == 0x1F && magic[1] == 0x8B
Compress::Gzip::Reader.open(file) do |comp|
Benben.dlog!("Loading gzip-compressed raw module file data into RAM: #{@filename}")
IO.copy(comp, io)
end
when magic[0] == 'B'.ord &&
magic[1] == 'Z'.ord &&
magic[2] == 'h'.ord &&
(magic[3] >= '1'.ord && magic[3] <= '9'.ord)
RemiLib::Compression::BZip2::Reader.open(file) do |bz|
Benben.dlog!("Loading bzip2-compressed raw module file data into RAM: #{@filename}")
IO.copy(bz, io)
end
when magic[0] == 0x28 &&
magic[1] == 0xB5 &&
magic[2] == 0x2f &&
magic[3] == 0xFD
Zstd::Decompress::IO.open(file) do |zstd|
Benben.dlog!("Loading zstandard-compressed raw module file data into RAM: #{@filename}")
IO.copy(zstd, io)
end
else
Benben.dlog!("Loading raw module file data into RAM: #{@filename}")
IO.copy(file, io)
end
end
@data = io.to_slice
end
def unload : Nil
@data = Bytes.new(0) unless @data.empty?
end
end
end