Class: SlowFat::FileAllocationTable

Inherits:
Object
  • Object
show all
Defined in:
lib/slowfat/file_alloc_table.rb

Overview

FileAllocationTable represents one FAT (of two on a disk, most commonly)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(backing:, base:, size:) ⇒ FileAllocationTable

Initialize a new FileAllocatinTable object (normally only called from Filesystem)

Parameters:

  • backing (IO)

    the storage containing the filesystem (e.g. open file)

  • base (Integer)

    the location of the beginning of this FAT structure within the backing device

  • size (Integer)

    the total size of this FAT



12
13
14
15
16
# File 'lib/slowfat/file_alloc_table.rb', line 12

def initialize(backing:, base:, size:)
  @backing = backing
  @base = base
  @size = size
end

Instance Attribute Details

#baseObject (readonly)

Returns the value of attribute base.



5
6
7
# File 'lib/slowfat/file_alloc_table.rb', line 5

def base
  @base
end

#chainsObject (readonly)

Returns the value of attribute chains.



5
6
7
# File 'lib/slowfat/file_alloc_table.rb', line 5

def chains
  @chains
end

#sizeObject (readonly)

Returns the value of attribute size.



5
6
7
# File 'lib/slowfat/file_alloc_table.rb', line 5

def size
  @size
end

Instance Method Details

#chain_starting_at(start_cluster) ⇒ Array<Integer>

Retrieve a full chain of cluster numbers, starting at a given cluster

Parameters:

  • start_cluster (Integer)

    the cluster number to retrieve a chain starting from

Returns:

  • (Array<Integer>)

    a list of clusters in the chain, starting from the cluster provided



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/slowfat/file_alloc_table.rb', line 22

def chain_starting_at(start_cluster)
  current_cluster = start_cluster
  current_chain = []
  while current_cluster < @size/2
    @backing.seek base + current_cluster * 2
    (next_cluster, junk) = @backing.read(2).unpack('v')
    if(current_cluster+1 == size/2) then
      #printf("current: 0x%02X next: FAT END\n", current_cluster)
      current_chain << current_cluster
      return current_chain == [] ? [start_cluster] : current_chain
    elsif(next_cluster >= 0xFFF8 and next_cluster <= 0xFFFF) then
      # end of cluster marker
      #printf("current: 0x%02X next: EOC (0x%02X)\n", current_cluster, current_cluster+1)
      current_chain << current_cluster
      return current_chain == [] ? [start_cluster] : current_chain
    elsif(next_cluster == 0x0000) then
      #printf("current: 0x%02X next: FREE (0x%02X)\n", current_cluster, current_cluster+1)
      current_cluster = current_cluster + 1
    else
      # link to next cluster
      #printf("current: 0x%02X next: 0x%02X\n", current_cluster, next_cluster)
      current_chain << current_cluster
      current_cluster = next_cluster
    end
  end
end