/usr/share/gocode/src/github.com/mitchellh/go-fs/fat/cluster_chain.go is in golang-github-mitchellh-go-fs-dev 0.0~git20161108.7bae45d-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | package fat
import (
"github.com/mitchellh/go-fs"
"io"
"math"
)
type ClusterChain struct {
device fs.BlockDevice
fat *FAT
startCluster uint32
readOffset uint32
writeOffset uint32
}
func (c *ClusterChain) Read(p []byte) (n int, err error) {
bpc := c.fat.bs.BytesPerCluster()
chain := c.fat.Chain(c.startCluster)
dataOffset := uint32(0)
for dataOffset < uint32(len(p)) {
chainIdx := c.readOffset / bpc
if int(chainIdx) >= len(chain) {
err = io.EOF
return
}
clusterOffset := c.fat.bs.ClusterOffset(int(chain[chainIdx]))
clusterOffset += c.readOffset % bpc
dataOffsetEnd := dataOffset + bpc
dataOffsetEnd -= c.readOffset % bpc
dataOffsetEnd = uint32(math.Min(float64(dataOffsetEnd), float64(len(p))))
var nw int
nw, err = c.device.ReadAt(p[dataOffset:dataOffsetEnd], int64(clusterOffset))
if err != nil {
return
}
c.readOffset += uint32(nw)
dataOffset += uint32(nw)
n += nw
}
return
}
// Write will write to the cluster chain, expanding it if necessary.
func (c *ClusterChain) Write(p []byte) (n int, err error) {
bpc := c.fat.bs.BytesPerCluster()
chain := c.fat.Chain(c.startCluster)
chainLength := uint32(len(chain)) * bpc
if chainLength < c.writeOffset+uint32(len(p)) {
// We need to grow the chain
bytesNeeded := (c.writeOffset + uint32(len(p))) - chainLength
clustersNeeded := int(math.Ceil(float64(bytesNeeded) / float64(bpc)))
chain, err = c.fat.ResizeChain(c.startCluster, len(chain)+clustersNeeded)
if err != nil {
return
}
// Write the FAT out
if err = c.fat.WriteToDevice(c.device); err != nil {
return
}
}
dataOffset := uint32(0)
for dataOffset < uint32(len(p)) {
chainIdx := c.writeOffset / bpc
clusterOffset := c.fat.bs.ClusterOffset(int(chain[chainIdx]))
clusterOffset += c.writeOffset % bpc
dataOffsetEnd := dataOffset + bpc
dataOffsetEnd -= c.writeOffset % bpc
dataOffsetEnd = uint32(math.Min(float64(dataOffsetEnd), float64(len(p))))
var nw int
nw, err = c.device.WriteAt(p[dataOffset:dataOffsetEnd], int64(clusterOffset))
if err != nil {
return
}
c.writeOffset += uint32(nw)
dataOffset += uint32(nw)
n += nw
}
return
}
|