public override void Delete(string path) { string streamName = GetStreamName(path); path = GetFilePath(path); FileRecord fileRecord = m_volume.GetFileRecord(path); if (streamName == String.Empty) { m_volume.DeleteFile(fileRecord); } else { // We only delete the named stream AttributeRecord dataRecord = fileRecord.GetAttributeRecord(AttributeType.Data, streamName); if (dataRecord == null) { throw new FileNotFoundException(String.Format("The file '{0}' does not contain a stream named '{1}'", path, streamName)); } AttributeData attributeData = new AttributeData(m_volume, fileRecord, dataRecord); attributeData.Truncate(0); fileRecord.RemoveAttributeRecord(AttributeType.Data, streamName); m_volume.UpdateFileRecord(fileRecord); } }
public void Extend(ulong additionalLengthInBytes) { ulong currentSize = this.Length; if (m_attributeRecord is NonResidentAttributeRecord) { NonResidentAttributeData attributeData = new NonResidentAttributeData(m_volume, m_fileRecord, (NonResidentAttributeRecord)m_attributeRecord); attributeData.Extend(additionalLengthInBytes); } else { byte[] data = ((ResidentAttributeRecord)m_attributeRecord).Data; ulong finalDataLength = (uint)data.Length + additionalLengthInBytes; ulong finalRecordLength = (uint)m_attributeRecord.RecordLength + additionalLengthInBytes; if (finalRecordLength >= (ulong)m_volume.AttributeRecordLengthToMakeNonResident && m_attributeRecord.AttributeType != AttributeType.AttributeList) // We will create an attribute list with the right attribute form in advance. { // Convert the attribute to non-resident long clustersToAllocate = (long)Math.Ceiling((double)finalDataLength / m_volume.BytesPerCluster); if (clustersToAllocate > m_volume.NumberOfFreeClusters) { throw new DiskFullException(); } NonResidentAttributeRecord attributeRecord = NonResidentAttributeRecord.Create(m_attributeRecord.AttributeType, m_attributeRecord.Name); NonResidentAttributeData attributeData = new NonResidentAttributeData(m_volume, null, attributeRecord); attributeData.Extend(finalDataLength); if (data.Length % m_volume.BytesPerCluster > 0) { int fillDataLength = m_volume.BytesPerCluster - (data.Length % m_volume.BytesPerCluster); if ((uint)data.Length + (uint)fillDataLength < finalDataLength) { // Only the last cluster can be partially used, if this is not the last cluster, zero-fill it data = ByteUtils.Concatenate(data, new byte[fillDataLength]); } } attributeData.WriteClusters(0, data); // Note that we overwrite the old attribute only after writing the non-resident data if (m_fileRecord != null) { m_fileRecord.RemoveAttributeRecord(m_attributeRecord.AttributeType, m_attributeRecord.Name); FileRecordHelper.InsertSorted(m_fileRecord.Attributes, attributeRecord); } m_attributeRecord = attributeRecord; } else { int currentLength = data.Length; byte[] temp = new byte[currentLength + (int)additionalLengthInBytes]; Array.Copy(data, temp, data.Length); ((ResidentAttributeRecord)m_attributeRecord).Data = temp; } if (m_fileRecord != null) { m_volume.UpdateFileRecord(m_fileRecord); } } }