Class: PEROBS::StackFile

Inherits:
Object
  • Object
show all
Defined in:
lib/perobs/StackFile.rb

Overview

This class implements a file based stack. All entries must have the same size.

Instance Method Summary collapse

Constructor Details

#initialize(dir, name, entry_bytes) ⇒ StackFile

Create a new stack file in the given directory with the given file name.

Parameters:

  • dir (String)

    Directory

  • name (String)

    File name

  • entry_bytes (Fixnum)

    Number of bytes each entry must have



40
41
42
43
44
# File 'lib/perobs/StackFile.rb', line 40

def initialize(dir, name, entry_bytes)
  @file_name = File.join(dir, name + '.stack')
  @entry_bytes = entry_bytes
  @f = nil
end

Instance Method Details

#clearObject

Remove all entries from the stack.



113
114
115
116
# File 'lib/perobs/StackFile.rb', line 113

def clear
  @f.truncate(0)
  @f.flush
end

#closeObject

Close the stack file. This method must be called before the program is terminated to avoid data loss.



61
62
63
64
65
66
67
68
# File 'lib/perobs/StackFile.rb', line 61

def close
  begin
    @f.flush
    @f.close
  rescue IOError => e
    PEROBS.log.fatal "Cannot close stack file #{@file_name}: #{e.message}"
  end
end

#eachObject

Iterate over all entries in the stack and call the given block for the bytes.



120
121
122
123
124
125
# File 'lib/perobs/StackFile.rb', line 120

def each
  @f.seek(0)
  while !@f.eof
    yield(@f.read(@entry_bytes))
  end
end

#openObject

Open the stack file.



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/perobs/StackFile.rb', line 47

def open
  begin
    if File.exist?(@file_name)
      @f = File.open(@file_name, 'rb+')
    else
      @f = File.open(@file_name, 'wb+')
    end
  rescue => e
    PEROBS.log.fatal "Cannot open stack file #{@file_name}: #{e.message}"
  end
end

#popString or nil

Pop the last entry from the stack file.

Returns:

  • (String or nil)

    Popped entry or nil if stack is already empty.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/perobs/StackFile.rb', line 96

def pop
  begin
    return nil if @f.size == 0

    @f.seek(-@entry_bytes, IO::SEEK_END)
    bytes = @f.read(@entry_bytes)
    @f.truncate(@f.size - @entry_bytes)
    @f.flush
  rescue => e
    PEROBS.log.fatal "Cannot pop from stack file #{@file_name}: " +
      e.message
  end

  bytes
end

#push(bytes) ⇒ Object

Push the given bytes onto the stack file.

Parameters:

  • bytes (String)

    Bytes to write.



81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/perobs/StackFile.rb', line 81

def push(bytes)
  if bytes.length != @entry_bytes
    PEROBS.log.fatal "All stack entries must be #{@entry_bytes} " +
      "long. This entry is #{bytes.length} bytes long."
  end
  begin
    @f.seek(0, IO::SEEK_END)
    @f.write(bytes)
  rescue => e
    PEROBS.log.fatal "Cannot push to stack file #{@file_name}: #{e.message}"
  end
end

#syncObject

Flush out unwritten data to file.



71
72
73
74
75
76
77
# File 'lib/perobs/StackFile.rb', line 71

def sync
  begin
    @f.flush
  rescue IOError => e
    PEROBS.log.fatal "Cannot sync stack file #{@file_name}: #{e.message}"
  end
end

#to_aryArray

Return the content of the stack as an Array.

Returns:



129
130
131
132
133
# File 'lib/perobs/StackFile.rb', line 129

def to_ary
  a = []
  each { |bytes| a << bytes }
  a
end