Class: Resilience::FSDir::DirBase

Inherits:
Object
  • Object
show all
Includes:
OnImage
Defined in:
lib/resilience/fs_dir/dir_base.rb

Direct Known Subclasses

RootDir

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from OnImage

#image, image, included, restore_pos, #restore_pos, store_pos, #store_pos

Instance Attribute Details

#dirsObject

Returns the value of attribute dirs.



14
15
16
# File 'lib/resilience/fs_dir/dir_base.rb', line 14

def dirs
  @dirs
end

#filesObject

Returns the value of attribute files.



15
16
17
# File 'lib/resilience/fs_dir/dir_base.rb', line 15

def files
  @files
end

Instance Method Details

#filter_dir_record(record) ⇒ Object



63
64
65
66
67
# File 'lib/resilience/fs_dir/dir_base.rb', line 63

def filter_dir_record(record)
  # '4' seems to indicate a historical record or similar,
  # records w/ flags '0' or '8' are what we want
  record.flags == 4 ? filter_dir_record(Record.read) : record 
end

#parse_dir_branch(record, prefix) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/resilience/fs_dir/dir_base.rb', line 69

def parse_dir_branch(record, prefix)
  key          = record.key
  value        = record.value
  flags        = record.flags

  value_dwords = value.unpack('L*')
  value_qwords = value.unpack('Q*')

  page_id      = value_dwords[0]
  page_address = page_id * PAGE_SIZE
  checksum     = value_qwords[2]

  parse_dir_page page_address, prefix unless checksum == 0 || flags == 4
end

#parse_dir_obj(object_id, prefix) ⇒ Object



17
18
19
20
21
22
23
24
25
# File 'lib/resilience/fs_dir/dir_base.rb', line 17

def parse_dir_obj(object_id, prefix)
  object_table   = image.object_table
  @dirs        ||= Dirs.new
  @files       ||= Files.new

  page_id      = object_table.pages[object_id]
  page_address = page_id * PAGE_SIZE
  parse_dir_page page_address, prefix
end

#parse_dir_page(page_address, prefix) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/resilience/fs_dir/dir_base.rb', line 27

def parse_dir_page(page_address, prefix)
  # skip container/placeholder attribute
  image.seek(page_address + ADDRESSES[:first_attr])
  Attribute.read

  # start of table attr, pull out table length, type
  table_header_attr   = Attribute.read
  table_header_dwords = table_header_attr.unpack("L*")
  header_len          = table_header_dwords[0]
  table_len           = table_header_dwords[1]
  remaining_len       = table_len - header_len
  table_type          = table_header_dwords[3]

  until remaining_len == 0
    orig_pos = image.pos
    record   = Record.read

    # need to keep track of position locally as we
    # recursively call parse_dir via helpers
    pos = image.pos

    if table_type == DIR_TREE
      parse_dir_branch record, prefix

    else #if table_type == DIR_LIST
      record = filter_dir_record(record)
      pos = image.pos
      parse_dir_record record, prefix

    end

    image.seek pos
    remaining_len -= (image.pos - orig_pos)
  end
end

#parse_dir_record(record, prefix) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/resilience/fs_dir/dir_base.rb', line 84

def parse_dir_record(record, prefix)
  key        = record.key
  value      = record.value

  key_bytes  = key.unpack('C*')
  key_dwords = key.unpack('L*')
  entry_type = key_dwords.first

  if entry_type == DIR_ENTRY
    dir_name = key_bytes[4..-1].pack('L*')
    dir_obj = value.unpack('C*')[0...8]
    dirs << DirEntry.new(:prefix   => prefix,
                         :name     => dir_name,
                         :metadata => dir_obj,
                         :record   => record)

    dir_obj = [0, 0, 0, 0, 0, 0, 0, 0].concat(dir_obj)
    parse_dir_obj(dir_obj, "#{prefix}\\#{dir_name}")

  elsif entry_type == FILE_ENTRY
    filename = key_bytes[4..-1]
    filename.delete(0)
    filename = filename.pack('C*')

    files <<  FileEntry.new(:prefix   => prefix,
                            :name     => filename,
                            :metadata => value,
                            :record   => record)
  end
end