Class: Fat32::FileData

Inherits:
Object
  • Object
show all
Defined in:
lib/fs/fat32/file_data.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dirEntry, bootSector) ⇒ FileData

Initialization



9
10
11
12
13
14
15
16
# File 'lib/fs/fat32/file_data.rb', line 9

def initialize(dirEntry, bootSector)
  raise "Nil directory entry" if dirEntry.nil?
  raise "Nil boot sector" if bootSector.nil?

  @bs = bootSector
  @de = dirEntry
  rewind
end

Instance Attribute Details

#posObject (readonly)

Returns the value of attribute pos.



6
7
8
# File 'lib/fs/fat32/file_data.rb', line 6

def pos
  @pos
end

Instance Method Details

#closeObject



113
114
115
# File 'lib/fs/fat32/file_data.rb', line 113

def close
  @de.close(@bs)
end

#firstClusterObject



22
23
24
25
# File 'lib/fs/fat32/file_data.rb', line 22

def firstCluster
  return -1 if !@clusterMap || @clusterMap.size == 0
  @clusterMap[0]
end

#getCluster(vcn) ⇒ Object



96
97
98
99
100
101
102
# File 'lib/fs/fat32/file_data.rb', line 96

def getCluster(vcn)
  lcn = getLCN(vcn)
  # puts "vcn=#{vcn}, lcn=#{lcn}" if $track_pos
  return MemoryBuffer.create(@bs.bytesPerCluster) if lcn == -1
  raise "LCN is nill" if lcn.nil?
  @bs.getCluster(lcn)
end

#getLCN(relClus) ⇒ Object



117
118
119
120
121
122
123
124
125
126
# File 'lib/fs/fat32/file_data.rb', line 117

def getLCN(relClus)
  return -1 if relClus >= @clusterMap.size || @clusterMap.size == 0
  lcn = @clusterMap[relClus]
  if lcn.nil?
    # puts "LCN is nil for VCN #{relClus}; Map size is #{@clusterMap.size}, cluster map follows:"
    # puts @clusterMap.inspect
    raise "Bad cluster map."
  end
  lcn
end

#putCluster(vcn, buf) ⇒ Object



104
105
106
107
108
109
110
111
# File 'lib/fs/fat32/file_data.rb', line 104

def putCluster(vcn, buf)
  lcn = getLCN(vcn)
  if lcn == -1
    lcn = @bs.allocClusters(@clusterMap.size == 0 ? 0 : @clusterMap[@clusterMap.size - 1])
    @clusterMap << lcn
  end
  @bs.writeClusters(lcn, buf)
end

#read(bytes = @de.length) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/fs/fat32/file_data.rb', line 38

def read(bytes = @de.length)
  return nil if @pos >= @de.length
  @clusterMap = @bs.mkClusterMap(@de.firstCluster) unless @clusterMap

  # Get start & end locs.
  bpc = @bs.bytesPerCluster
  startCluster, startOffset = @pos.divmod(bpc)
  endCluster, endOffset = (@pos + (bytes - 1)).divmod(bpc)

  # Single cluster.
  if startCluster == endCluster
    @pos += (endOffset - startOffset)
    return getCluster(startCluster)[startOffset..endOffset]
  end

  # Span clusters.
  out = MemoryBuffer.create(bytes)
  totalLen = 0
  (startCluster..endCluster).each do |clus|
    offset = 0; len = bpc
    if clus == startCluster
      offset = startOffset
      len -= offset
    end
    len -= (bpc - (endOffset + 1)) if clus == endCluster
    out[totalLen, len] = getCluster(clus)[offset, len]
    totalLen += len
    @pos += len
  end
  out[0..totalLen]
end

#rewindObject



18
19
20
# File 'lib/fs/fat32/file_data.rb', line 18

def rewind
  @pos = 0
end

#seek(offset, method = IO::SEEK_SET) ⇒ Object



27
28
29
30
31
32
33
34
35
36
# File 'lib/fs/fat32/file_data.rb', line 27

def seek(offset, method = IO::SEEK_SET)
  @pos = case method
         when IO::SEEK_SET then offset
         when IO::SEEK_CUR then @pos + offset
         when IO::SEEK_END then @de.length - offset
         end
  @pos = 0 if @pos < 0
  @pos = @de.length if @pos > @de.length
  @pos
end

#write(buf, bytes = buf.length) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/fs/fat32/file_data.rb', line 70

def write(buf, bytes = buf.length)
  @clusterMap = @bs.mkClusterMap(@de.firstCluster) unless @clusterMap

  # Get start & end locs.
  bytesWritten = 0; bpc = @bs.bytesPerCluster
  startCluster, startOffset = @pos.divmod(bpc)
  endCluster, endOffset = (@pos + (bytes - 1)).divmod(bpc)

  # For each cluster, read, deposit & write.
  (startCluster..endCluster).each do |clus|
    offset = 0; len = bpc
    if clus == startCluster
      offset = startOffset
      len -= offset
    end
    len -= (bpc - (endOffset + 1)) if clus == endCluster
    current = getCluster(clus)
    current[startOffset, len] = buf[bytesWritten, len]
    putCluster(clus, current)
    @pos += len; bytesWritten += len
  end
  @de.length = @pos if @pos > @de.length
  @de.firstCluster = @clusterMap[0] if @de.firstCluster == 0
  bytesWritten
end