예제 #1
0
파일: Directory.cs 프로젝트: ilf80/FS
        private int FindEmptyItem(int startIndex)
        {
            startIndex++;

            var emptyEntryIndex = default(int?);
            var maxCapacity     = index.SizeInBlocks * index.BlockSize;

            if (maxCapacity > startIndex)
            {
                var buffer = new DirectoryItem[maxCapacity - startIndex];
                blockStream.Read(startIndex, buffer);

                emptyEntryIndex = buffer
                                  .Where(x => x.Entry.Flags == DirectoryFlags.None || (x.Entry.Flags & DirectoryFlags.Deleted) != 0)
                                  .Select((x, entryIndex) => (int?)entryIndex)
                                  .FirstOrDefault();
            }

            if (emptyEntryIndex == null)
            {
                index.SetSizeInBlocks(index.SizeInBlocks + 1);
                return(startIndex);
            }

            return(startIndex + emptyEntryIndex.Value);
        }
예제 #2
0
파일: Directory.cs 프로젝트: ilf80/FS
        private void AddEntry(DirectoryItem directoryEntryItem)
        {
            blockStream.Write(firstEmptyItemOffset, new[] { directoryEntryItem });

            firstEmptyItemOffset = FindEmptyItem(firstEmptyItemOffset);
            itemsCount++;

            Flush();
        }
예제 #3
0
파일: Directory.cs 프로젝트: ilf80/FS
        private void UpdateHeader()
        {
            var directoryHeaderItem = new DirectoryItem
            {
                Header = new DirectoryHeader
                {
                    FirstEmptyItemOffset      = firstEmptyItemOffset,
                    NameBlockIndex            = nameBlockIndex,
                    ItemsCount                = itemsCount,
                    LastNameOffset            = lastNameOffset,
                    ParentDirectoryBlockIndex = parentDirectoryBlockId
                }
            };

            blockStream.Write(0, new[] { directoryHeaderItem });
        }
예제 #4
0
        public IUnsafeDirectory Read(int blockId)
        {
            if (blockId < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(blockId));
            }

            var indexBlockProvider = indexBlockProviderFactory.Create(blockId, directoryCache);
            var index       = directoryIndexFactory.Create(indexBlockProvider, directoryCache);
            var indexStream = directoryBlockStreamFactory.Create(index);

            var buffer = new DirectoryItem[1];

            indexStream.Read(0, buffer);
            var header = buffer[0].Header;

            return(directoryFactory.Create(index, directoryCache, header));
        }
예제 #5
0
파일: Directory.cs 프로젝트: ilf80/FS
 private void AddEntry(int blockId, string name, DirectoryFlags flags)
 {
     indexLock.EnterWriteLock();
     try
     {
         var directoryEntryItem = new DirectoryItem
         {
             Entry = new DirectoryEntryStruct
             {
                 BlockIndex = blockId,
                 Created    = DateTime.Now.Ticks,
                 Updated    = DateTime.Now.Ticks,
                 Size       = 0,
                 Flags      = flags,
                 NameOffset = StoreName(name)
             }
         };
         AddEntry(directoryEntryItem);
     }
     finally
     {
         indexLock.ExitWriteLock();
     }
 }
예제 #6
0
파일: Directory.cs 프로젝트: ilf80/FS
        public void UpdateEntry(int blockId, IDirectoryEntryInfoOverrides overrides)
        {
            if (overrides == null)
            {
                throw new ArgumentNullException(nameof(overrides));
            }

            if (blockId < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(blockId));
            }

            indexLock.EnterWriteLock();
            try
            {
                var buffer = new DirectoryItem[itemsCount];
                blockStream.Read(1, buffer);

                for (var i = 0; i < buffer.Length; i++)
                {
                    var entry = buffer[i];
                    if (entry.Entry.BlockIndex == blockId && (entry.Entry.Flags & DirectoryFlags.Deleted) == 0)
                    {
                        ApplyOverrides(ref entry.Entry, overrides);
                        blockStream.Write(i + 1, new[] { entry });
                        return;
                    }
                }
            }
            finally
            {
                indexLock.ExitWriteLock();
            }

            throw new Exception("Entry not found");
        }
예제 #7
0
파일: Directory.cs 프로젝트: ilf80/FS
        public IDirectoryEntryInfo[] GetDirectoryEntries()
        {
            indexLock.EnterReadLock();
            try
            {
                var result = new List <IDirectoryEntryInfo>(itemsCount);
                if (itemsCount > 0)
                {
                    var buffer = new DirectoryItem[itemsCount];
                    blockStream.Read(1, buffer);

                    var names = new short[lastNameOffset];
                    nameIndexBlockStream.Read(0, names);

                    foreach (var item in buffer.Where(x => (x.Entry.Flags & DirectoryFlags.Deleted) == 0))
                    {
                        var entry = item.Entry;

                        var nameLength = names[entry.NameOffset];
                        var nameBuffer = new char[nameLength];
                        for (var i = 0; i < nameLength; i++)
                        {
                            nameBuffer[i] = (char)names[entry.NameOffset + 1 + i];
                        }

                        result.Add(new DirectoryEntryInfo(entry, new string(nameBuffer)));
                    }
                }

                return(result.ToArray());
            }
            finally
            {
                indexLock.ExitReadLock();
            }
        }