public CookedDataRun(DataRun raw, long startVcn, long prevLcn, NonResidentAttributeRecord attributeExtent) { _raw = raw; _startVcn = startVcn; _startLcn = prevLcn + raw.RunOffset; _attributeExtent = attributeExtent; if (startVcn < 0) { throw new ArgumentOutOfRangeException("startVcn", startVcn, "VCN must be >= 0"); } if (_startLcn < 0) { throw new ArgumentOutOfRangeException("prevLcn", prevLcn, "LCN must be >= 0"); } }
protected override void Read(byte[] buffer, int offset, out int length) { _dataRuns = null; base.Read(buffer, offset, out length); _startingVCN = Utilities.ToUInt64LittleEndian(buffer, offset + 0x10); _lastVCN = Utilities.ToUInt64LittleEndian(buffer, offset + 0x18); _dataRunsOffset = Utilities.ToUInt16LittleEndian(buffer, offset + 0x20); _compressionUnitSize = Utilities.ToUInt16LittleEndian(buffer, offset + 0x22); _dataAllocatedSize = Utilities.ToUInt64LittleEndian(buffer, offset + 0x28); _dataRealSize = Utilities.ToUInt64LittleEndian(buffer, offset + 0x30); _initializedDataSize = Utilities.ToUInt64LittleEndian(buffer, offset + 0x38); if ((Flags & (AttributeFlags.Compressed | AttributeFlags.Sparse)) != 0 && _dataRunsOffset > 0x40) { _compressedSize = Utilities.ToUInt64LittleEndian(buffer, offset + 0x40); } _dataRuns = new List<DataRun>(); int pos = _dataRunsOffset; while (pos < length) { DataRun run = new DataRun(); int len = run.Read(buffer, offset + pos); // Length 1 means there was only a header byte (i.e. terminator) if (len == 1) { break; } _dataRuns.Add(run); pos += len; } }
public override void ExpandToClusters(long numVirtualClusters, NonResidentAttributeRecord extent, bool allocate) { long totalVirtualClusters = _cookedRuns.NextVirtualCluster; if (totalVirtualClusters < numVirtualClusters) { NonResidentAttributeRecord realExtent = extent; if (realExtent == null) { realExtent = _cookedRuns.Last.AttributeExtent; } DataRun newRun = new DataRun(0, numVirtualClusters - totalVirtualClusters, true); realExtent.DataRuns.Add(newRun); _cookedRuns.Append(newRun, extent); realExtent.LastVcn = numVirtualClusters - 1; } if (allocate) { AllocateClusters(totalVirtualClusters, (int)(numVirtualClusters - totalVirtualClusters)); } }
public void InsertRun(int index, DataRun newRun) { _dataRuns.Insert(index, newRun); }
public void InsertRun(DataRun existingRun, DataRun newRun) { int idx = _dataRuns.IndexOf(existingRun); if (idx < 0) { throw new ArgumentException("Attempt to replace non-existant run", "existingRun"); } _dataRuns.Insert(idx + 1, newRun); }
public int RemoveRun(DataRun run) { int idx = _dataRuns.IndexOf(run); if (idx < 0) { throw new ArgumentException("Attempt to remove non-existant run", "run"); } _dataRuns.RemoveAt(idx); return idx; }
public void ReplaceRun(DataRun oldRun, DataRun newRun) { int idx = _dataRuns.IndexOf(oldRun); if (idx < 0) { throw new ArgumentException("Attempt to replace non-existant run", "oldRun"); } _dataRuns[idx] = newRun; }
public void Append(DataRun rawRun, NonResidentAttributeRecord attributeExtent) { CookedDataRun last = Last; _runs.Add(new CookedDataRun(rawRun, NextVirtualCluster, last == null ? 0 : last.StartLcn, attributeExtent)); }