/// <summary> /// /// </summary> /// <param name="freeSpaceBitmap"></param> /// <param name="blockIndexOffset"></param> /// <param name="freeSpaceMapLength"></param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> /// <exception cref="ArgumentException"></exception> public FreeBlockManagerBitArrayBased(BitArray freeSpaceBitmap, int blockIndexOffset, int freeSpaceMapLength) { MethodArgumentValidator.ThrowIfNull(freeSpaceBitmap, "freeSpaceBitmap"); MethodArgumentValidator.ThrowIfNegative(blockIndexOffset, "blockIndexOffset"); if (freeSpaceBitmap.Length != freeSpaceMapLength) { throw new ArgumentException("В Bitmap для разметки свободного места должно быть следующее число бит: {0}".FormatWith(freeSpaceMapLength)); } _freeSpaceBitmap = freeSpaceBitmap; _blockIndexOffset = blockIndexOffset; _freeSpaceMapLength = freeSpaceMapLength; int freeBlocksCount = 0; for (int i = 0; i < freeSpaceBitmap.Length; i++) { if (!freeSpaceBitmap[i]) { freeBlocksCount++; } } _freeBlockCount = freeBlocksCount; }
/// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> /// <exception cref="InvalidOperationException"></exception> public void WriteBytes(byte[] array, int startingPosition, int length) { MethodArgumentValidator.ThrowIfNull(array, "array"); MethodArgumentValidator.ThrowIfNegative(startingPosition, "startingPosition"); MethodArgumentValidator.ThrowIfNegative(length, "length"); if ((startingPosition + length) > array.Length) { throw new ArgumentException("В массиве, начиная с позиции {0}, не найдется следующего числа байт для записи: {1}".FormatWith(startingPosition, length)); } if (this.IsAtEndOfBlock) { throw new InvalidOperationException("Запись за пределами границ блока не разрешена"); } int positionAfterWriting = this.Position + length; if (positionAfterWriting > this.SizeInBytes) { throw new ArgumentException("Запись невозможна: попытка записи за пределами массива"); } _disk.WriteBytesToBlock(BlockIndex, array, startingPosition, _position, length); if ((positionAfterWriting > this.OccupiedSpaceInBytes) && (this.OccupiedSpaceInBytes < this.SizeInBytes)) { this.OccupiedSpaceInBytes += (positionAfterWriting - this.OccupiedSpaceInBytes); } this.Position = positionAfterWriting; }
public FolderNode(string name, Guid id, int diskBlockIndex, int parentFolderBlockReference, DataStreamDefinition fileReferencesStreamDefinition, DataStreamDefinition folderReferencesStreamDefinition, DateTime creationTime, Guid version) : base(name, id, diskBlockIndex, version, creationTime) { MethodArgumentValidator.ThrowIfNull(fileReferencesStreamDefinition, "fileReferencesStream"); MethodArgumentValidator.ThrowIfNull(folderReferencesStreamDefinition, "folderReferencesStream"); MethodArgumentValidator.ThrowIfNegative(parentFolderBlockReference, "parentFolderBlockReference"); MethodArgumentValidator.ThrowIfNegative(diskBlockIndex, "diskBlockIndex"); MethodArgumentValidator.ThrowIfIsDefault(id, "id"); _fileReferencesStreamDefinition = fileReferencesStreamDefinition; _folderReferencesStreamDefinition = folderReferencesStreamDefinition; _parentFolderBlockReference = parentFolderBlockReference; }
public static bool ContainsLetters(this IEnumerable <char> characters) { MethodArgumentValidator.ThrowIfNull(characters, "characters"); foreach (char character in characters) { if (Char.IsLetter(character)) { return(true); } } return(false); }
/// <summary> /// /// </summary> /// <param name="parentFolder"></param> /// <param name="newFolderName"></param> /// <returns></returns> /// <exception cref="InsufficientSpaceException"></exception> /// <exception cref="MaximumFileSizeReachedException"></exception> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="FolderAlreadyExistsException"></exception> private FolderNode CreateFolder(FolderNode parentFolder, string newFolderName) { MethodArgumentValidator.ThrowIfNull(parentFolder, "parentFolder"); MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(newFolderName, "newFolderName"); var subfolders = _nodeResolver.GetAllFoldersFrom(parentFolder); var folderWithSameName = subfolders.FirstOrDefault(subfolder => _namesComparer.Equals(subfolder.Name, newFolderName)); if (folderWithSameName != null) { throw new FolderAlreadyExistsException("Подпапка с именем \"{0}\" уже существует в папке \"{1}\"".FormatWith(newFolderName, parentFolder.Name)); } var freeBlocks = _freeBlockManager.AcquireFreeBlocks(3); int blockToStoreFileReferencesIn = freeBlocks[0]; int blockToStoreFolderNodeIn = freeBlocks[1]; int blockToStoreSubfolderReferencesIn = freeBlocks[2]; var fileReferencesStreamDefinition = new DataStreamDefinition(blockToStoreFileReferencesIn, 0); var folderReferencesStreamDefinition = new DataStreamDefinition(blockToStoreSubfolderReferencesIn, 0); try { // Note: может стать последней каплей для переполненного диска, и тогда блоки придется отпустить _blockReferenceListsEditor.AddBlockReference(blockToStoreFolderNodeIn, parentFolder.FolderReferencesStreamDefinition, parentFolder); } catch (Exception) { _freeBlockManager.MarkBlocksAsFree(freeBlocks); throw; } var creationTime = DateTime.UtcNow; var newNode = new FolderNode(newFolderName, Guid.NewGuid(), blockToStoreFolderNodeIn, parentFolder.DiskBlockIndex, fileReferencesStreamDefinition, folderReferencesStreamDefinition, creationTime, Guid.NewGuid()); _fileSystemNodeStorage.WriteNode(newNode); return(newNode); }
/// <summary> /// /// </summary> /// <param name="blockIndex"></param> /// <param name="bytesToWrite"></param> /// <param name="arrayOffset"></param> /// <param name="blockOffset"></param> /// <param name="numberOfBytesToWrite"></param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> /// <exception cref="ObjectDisposedException"></exception> public void WriteBytesToBlock(int blockIndex, byte[] bytesToWrite, int arrayOffset, int blockOffset, int numberOfBytesToWrite) { lock (_diskAccessCriticalSection) { ThrowIfDisposed(); MethodArgumentValidator.ThrowIfNull(bytesToWrite, "bytesToWrite"); MethodArgumentValidator.ThrowIfNegative(blockOffset, "blockOffset"); MethodArgumentValidator.ThrowIfNegative(numberOfBytesToWrite, "numberOfBytesToWrite"); MethodArgumentValidator.ThrowIfNegative(arrayOffset, "arrayOffset"); this.MakeSureBlockIndexArgumentIsSane(blockIndex, "blockIndex"); if (blockOffset >= this.BlockSizeInBytes) { throw new ArgumentOutOfRangeException("blockOffset"); } if (arrayOffset > bytesToWrite.Length) { throw new ArgumentOutOfRangeException("arrayOffset"); } if (numberOfBytesToWrite > this.BlockSizeInBytes) { throw new ArgumentOutOfRangeException("numberOfBytesToWrite"); } if ((blockOffset + numberOfBytesToWrite) > this.BlockSizeInBytes) { throw new ArgumentOutOfRangeException("blockOffset, numberOfBytesToWrite"); } if (bytesToWrite.Length < numberOfBytesToWrite) { throw new ArgumentOutOfRangeException("numberOfBytesToWrite", "Массиве данных слишком мал, чтобы из него можно было считать следующее число байт: {0}.".FormatWith(numberOfBytesToWrite)); } this.SeekToBlockStartWithInBlockOffset(blockIndex, blockOffset); _backingStream.Write(bytesToWrite, arrayOffset, numberOfBytesToWrite); } }
/// <exception cref="ArgumentNullException"></exception> /// <exception cref="FileAlreadyExistsException"></exception> /// <exception cref="NoFreeBlocksException"></exception> /// <exception cref="InsufficientSpaceException"></exception> /// <exception cref="MaximumFileSizeReachedException"></exception> private FileNode CreateFile(FolderNode parentFolder, string fileName) { MethodArgumentValidator.ThrowIfNull(parentFolder, "parentFolder"); MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(fileName, "fileName"); var filesInTheFolder = _nodeResolver.GetAllFilesFrom(parentFolder); var fileWithSameName = filesInTheFolder.FirstOrDefault(file => _namesComparer.Equals(file.Name, fileName)); if (fileWithSameName != null) { throw new FileAlreadyExistsException("Файл с именем \"{0}\" уже существует в папке \"{1}\"".FormatWith(fileName, parentFolder.Name)); } var freeBlocks = _freeBlockManager.AcquireFreeBlocks(2); int blockToStoreDefinitionIn = freeBlocks[0]; int blockToStoreFileNodeIn = freeBlocks[1]; var fileContentsStreamDefinition = new DataStreamDefinition(blockToStoreDefinitionIn, 0); try { // Note: это добавление ссылки может стать последней каплей для заполненного диска, тогда блоки придется отпустить _blockReferenceListsEditor.AddBlockReference(blockToStoreFileNodeIn, parentFolder.FileReferencesStreamDefinition, parentFolder); } catch (Exception) { _freeBlockManager.MarkBlocksAsFree(freeBlocks); throw; } var creationTime = DateTime.UtcNow; var fileNode = new FileNode(fileName, Guid.NewGuid(), blockToStoreFileNodeIn, fileContentsStreamDefinition, creationTime, creationTime, Guid.NewGuid()); _fileSystemNodeStorage.WriteNode(fileNode); return(fileNode); }
/// <summary> /// Note: case sensitive /// </summary> /// <param name="stringToCheck"></param> /// <param name="characters"></param> /// <param name="characterFound"></param> /// <returns></returns> public static bool ContainsAny(this string stringToCheck, IEnumerable <char> characters, out Nullable <char> characterFound) { MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(stringToCheck, "stringToCheck"); MethodArgumentValidator.ThrowIfNull(characters, "characters"); var charactersSeenSoFar = new HashSet <char>(); var charactersToCheckFor = new HashSet <char>(characters); foreach (char character in stringToCheck) { if (!charactersSeenSoFar.Contains(character) && charactersToCheckFor.Contains(character)) { characterFound = character; return(true); } charactersSeenSoFar.Add(character); } characterFound = null; return(false); }
/// <summary> /// /// </summary> /// <param name="indexOfBlockToWriteTo"></param> /// <param name="bytesToWrite"></param> /// <param name="startingPosition"></param> /// <param name="numberOfBytesToWrite"></param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> /// <exception cref="ArgumentException"></exception> private void WriteBytesToBlock(int indexOfBlockToWriteTo, byte[] bytesToWrite, int startingPosition, int numberOfBytesToWrite) { MethodArgumentValidator.ThrowIfNull(bytesToWrite, "bytesToWrite"); MethodArgumentValidator.ThrowIfNegative(indexOfBlockToWriteTo, "indexOfBlockToWriteTo"); MethodArgumentValidator.ThrowIfNegative(startingPosition, "startingPosition"); MethodArgumentValidator.ThrowIfNegative(numberOfBytesToWrite, "numberOfBytesToWrite"); if ((startingPosition + numberOfBytesToWrite) > bytesToWrite.Length) { throw new ArgumentException("Не получится записать {0} байтов, начиная с позиции {1}. В массиве всего следующее число байт: {2}.".FormatWith(numberOfBytesToWrite, startingPosition, bytesToWrite.Length)); } if (bytesToWrite.Length > BlockSizeInBytes) { throw new ArgumentException("Невозможно записать данные в блок: в блок можно записать, максимум, {0} байт.".FormatWith(BlockSizeInBytes), "bytesToWrite"); } this.MakeSureBlockIndexArgumentIsSane(indexOfBlockToWriteTo, "indexOfBlockToWriteTo"); this.SeekToBlockStart(indexOfBlockToWriteTo); _backingStream.Write(bytesToWrite, startingPosition, numberOfBytesToWrite); }
public static bool IsEmpty <T>(this IEnumerable <T> enumerable) { MethodArgumentValidator.ThrowIfNull(enumerable, "enumerable"); return(!enumerable.Any()); }