When offsetLength is zero, it has special semantic meaning (= sparse file):
|
offsetBytes := dataRunData.Read(lengthLength, offsetLength) |
(source, see "Example 4 - Sparse, Unfragmented File")
This code decodes a sparse offset as 0, which would incorrectly read a fragment beginning from first cluster of volume (= VBR).
My initial naive idea was to mark sparse runs as having offset -1, but that's incorrect as each run's offset is relative to previous run, i.e. negative values are legal. I solved this issue in my code by making the offset a pointer to an integer, i.e. nil means it's sparse.
Directly related to this, DataRunsToFragments needs to take sparse runs into account. Data run offsets are relative previous non-sparse run, not previous run:
|
previousOffsetCluster = exactClusterOffset |
(link to "Example 4 - Sparse, Unfragmented File" explains this)
This assignment can only be done if current run is non-sparse. I suggest renaming the variable to e.g. previousNonSparseOffsetCluster.
Natural consequence of sparse run support is supporting sparse fragments, which I again marked as *int to discriminate between sparse and non-sparse runs. I had to re-write fragment.Reader in my project because alternating between actual disk-backed fragments vs sparse fragments would've been hackish to add without a re-write.
When
offsetLengthis zero, it has special semantic meaning (= sparse file):gomft/mft/mft.go
Line 365 in f64df39
(source, see "Example 4 - Sparse, Unfragmented File")
This code decodes a sparse offset as 0, which would incorrectly read a fragment beginning from first cluster of volume (= VBR).
My initial naive idea was to mark sparse runs as having offset -1, but that's incorrect as each run's offset is relative to previous run, i.e. negative values are legal. I solved this issue in my code by making the offset a pointer to an integer, i.e.
nilmeans it's sparse.Directly related to this,
DataRunsToFragmentsneeds to take sparse runs into account. Data run offsets are relative previous non-sparse run, not previous run:gomft/mft/mft.go
Line 390 in f64df39
(link to "Example 4 - Sparse, Unfragmented File" explains this)
This assignment can only be done if current run is non-sparse. I suggest renaming the variable to e.g.
previousNonSparseOffsetCluster.Natural consequence of sparse run support is supporting sparse fragments, which I again marked as
*intto discriminate between sparse and non-sparse runs. I had to re-writefragment.Readerin my project because alternating between actual disk-backed fragments vs sparse fragments would've been hackish to add without a re-write.