Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let MFile raise ClosedError instead of IO::Error #642

Merged
merged 2 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions spec/mfile_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
require "spec"
require "../src/lavinmq/mfile"

module MFileSpec
def self.with_file(&)
file = File.tempfile "mfile_spec"
yield file
ensure
file.delete unless file.nil?
end

describe MFile do
describe "#write" do
it "should raise ClosedError if closed" do
with_file do |file|
mfile = MFile.new file.path
mfile.close
expect_raises(MFile::ClosedError) { mfile.write "foo".to_slice }
end
end
end
describe "#read" do
it "should raise ClosedError if closed" do
with_file do |file|
mfile = MFile.new file.path
mfile.close
data = Bytes.new(1)
expect_raises(MFile::ClosedError) { mfile.read data }
end
end
end
describe "#to_slice" do
describe "without position and size" do
it "should raise ClosedError if closed" do
with_file do |file|
mfile = MFile.new file.path
mfile.close
expect_raises(MFile::ClosedError) { mfile.to_slice }
end
end
end
describe "with position and size" do
it "should raise ClosedError if closed" do
with_file do |file|
mfile = MFile.new file.path
mfile.close
expect_raises(MFile::ClosedError) { mfile.to_slice(1, 1) }
end
end
end
end
describe "#copy_to" do
it "should raise ClosedError if closed" do
with_file do |file|
mfile = MFile.new file.path
mfile.close
data = IO::Memory.new
expect_raises(MFile::ClosedError) { mfile.copy_to data }
end
end
end
end
end
15 changes: 11 additions & 4 deletions src/lavinmq/mfile.cr
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ end
# not `size` large, only on graceful close is the file truncated to its `size`.
# The file does not expand further than initial `capacity`, unless manually expanded.
class MFile < IO
class ClosedError < IO::Error
def initialize
super("MFile closed")
end
end

getter pos : Int64 = 0i64
getter? closed : Bool = false
getter size : Int64 = 0i64
Expand Down Expand Up @@ -136,6 +142,7 @@ class MFile < IO
# Copies the file to another IO
# Won't mmap the file if it's unmapped already
def copy_to(output : IO, size = @size) : Int64
raise ClosedError.new if @closed
if unmapped? # don't remap unmapped files
io = IO::FileDescriptor.new(@fd, blocking: true, close_on_finalize: false)
io.rewind
Expand Down Expand Up @@ -170,7 +177,7 @@ class MFile < IO
end

def write(slice : Bytes) : Nil
raise IO::Error.new("MFile closed") if @closed
raise ClosedError.new if @closed
size = @size
new_size = size + slice.size
raise IO::EOFError.new if new_size > @capacity
Expand All @@ -179,7 +186,7 @@ class MFile < IO
end

def read(slice : Bytes)
raise IO::Error.new("MFile closed") if @closed
raise ClosedError.new if @closed
pos = @pos
new_pos = pos + slice.size
raise IO::EOFError.new if new_pos > @size
Expand Down Expand Up @@ -225,12 +232,12 @@ class MFile < IO
end

def to_slice
raise IO::Error.new("MFile closed") if @closed
raise ClosedError.new if @closed
Bytes.new(buffer, @size, read_only: true)
end

def to_slice(pos, size)
raise IO::Error.new("MFile closed") if @closed
raise ClosedError.new if @closed
raise IO::EOFError.new if pos + size > @size
Bytes.new(buffer + pos, size, read_only: true)
end
Expand Down
Loading