private void AddDataRun(long startLcn, long length)
        {
            var  runs     = _record.CookedDataRuns;
            long startVcn = 0;
            long prevLcn  = 0;

            if (runs.Count > 0)
            {
                CookedDataRun tailRun = runs[runs.Count - 1];
                startVcn = tailRun.StartVcn + tailRun.Length;
                prevLcn  = tailRun.StartLcn;

                // Continuation of last run...
                if (startLcn == prevLcn + tailRun.Length)
                {
                    tailRun.Length += length;
                    return;
                }
            }

            DataRun       newRun       = new DataRun(startLcn - prevLcn, length);
            CookedDataRun newCookedRun = new CookedDataRun(newRun, startVcn, prevLcn);

            _record.CookedDataRuns.Add(newCookedRun);
        }
Beispiel #2
0
        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;
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        public CookedDataRun(DataRun raw, long startVcn, long prevLcn)
        {
            _raw      = raw;
            _startVcn = startVcn;
            _startLcn = prevLcn + raw.RunOffset;

            if (startVcn < 0)
            {
                throw new ArgumentOutOfRangeException("startVcn", startVcn, "VCN must be >= 0");
            }
            if (_startLcn < 0)
            {
                throw new ArgumentOutOfRangeException("prevLcn", prevLcn, "LCN must be >= 0");
            }
        }
Beispiel #6
0
        public AttributeRecord Split(int suggestedSplitIdx)
        {
            int splitIdx;

            if (suggestedSplitIdx <= 0 || suggestedSplitIdx >= _dataRuns.Count)
            {
                splitIdx = _dataRuns.Count / 2;
            }
            else
            {
                splitIdx = suggestedSplitIdx;
            }

            long splitVcn = (long)_startingVCN;
            long splitLcn = 0;

            for (int i = 0; i < splitIdx; ++i)
            {
                splitVcn += _dataRuns[i].RunLength;
                splitLcn += _dataRuns[i].RunOffset;
            }

            List <DataRun> newRecordRuns = new List <DataRun>();

            while (_dataRuns.Count > splitIdx)
            {
                DataRun run = _dataRuns[splitIdx];

                _dataRuns.RemoveAt(splitIdx);
                newRecordRuns.Add(run);
            }

            // Each extent has implicit start LCN=0, so have to make stored runs match reality.
            // However, take care not to stomp on 'sparse' runs that may be at the start of the
            // new extent (indicated by Zero run offset).
            for (int i = 0; i < newRecordRuns.Count; ++i)
            {
                if (!newRecordRuns[i].IsSparse)
                {
                    newRecordRuns[i].RunOffset += splitLcn;
                    break;
                }
            }

            _lastVCN = (ulong)splitVcn - 1;

            return(new NonResidentAttributeRecord(_type, _name, 0, _flags, splitVcn, newRecordRuns));
        }
        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");
            }
        }
Beispiel #8
0
        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");
            }
        }
Beispiel #9
0
        public CookedDataRun(DataRun raw, long startVcn, long prevLcn, NonResidentAttributeRecord attributeExtent)
        {
            DataRun         = raw;
            StartVcn        = startVcn;
            StartLcn        = prevLcn + raw.RunOffset;
            AttributeExtent = attributeExtent;

            if (startVcn < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(startVcn), startVcn, "VCN must be >= 0");
            }

            if (StartLcn < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(prevLcn), prevLcn, "LCN must be >= 0");
            }
        }
        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));
            }
        }
Beispiel #11
0
        protected override void Read(byte[] buffer, int offset, out int length)
        {
            _cookedDataRuns = 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) != 0)
            {
                _compressedSize = Utilities.ToUInt64LittleEndian(buffer, offset + 0x40);
            }

            var 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;
            }
            _cookedDataRuns = CookedDataRun.Cook(dataRuns);
        }
        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 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 void Append(DataRun rawRun, NonResidentAttributeRecord attributeExtent)
 {
     CookedDataRun last = Last;
     _runs.Add(new CookedDataRun(rawRun, NextVirtualCluster, last == null ? 0 : last.StartLcn, attributeExtent));
 }
Beispiel #16
0
        public void Append(DataRun rawRun, NonResidentAttributeRecord attributeExtent)
        {
            CookedDataRun last = Last;

            _runs.Add(new CookedDataRun(rawRun, NextVirtualCluster, last == null ? 0 : last.StartLcn, attributeExtent));
        }
Beispiel #17
0
        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));
            }
        }
        private void AddDataRun(long startLcn, long length)
        {
            var runs = _record.CookedDataRuns;
            long startVcn = 0;
            long prevLcn = 0;
            if (runs.Count > 0)
            {
                CookedDataRun tailRun = runs[runs.Count - 1];
                startVcn = tailRun.StartVcn + tailRun.Length;
                prevLcn = tailRun.StartLcn;

                // Continuation of last run...
                if (startLcn == prevLcn + tailRun.Length)
                {
                    tailRun.Length += length;
                    return;
                }
            }

            DataRun newRun = new DataRun(startLcn - prevLcn, length);
            CookedDataRun newCookedRun = new CookedDataRun(newRun, startVcn, prevLcn);

            _record.CookedDataRuns.Add(newCookedRun);
        }
        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;
        }
        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;
            }
        }
Beispiel #21
0
 public void InsertRun(int index, DataRun newRun)
 {
     _dataRuns.Insert(index, newRun);
 }