private FakeFileStream CreateStream([NotNull] AbsolutePath path, FileAccess access, bool isReaderOnly, bool notifyTracker)
        {
            lock (readerWriterLock)
            {
                if (activeWriter != null)
                {
                    throw ErrorFactory.System.FileIsInUse(path.GetText());
                }

                if (!isReaderOnly && activeReaders.Any())
                {
                    throw ErrorFactory.System.FileIsInUse(path.GetText());
                }

                var stream = new FakeFileStream(this, access, notifyTracker);

                if (isReaderOnly)
                {
                    activeReaders.Add(stream);
                }
                else
                {
                    activeWriter = stream;
                }

                return(stream);
            }
        }
        public IFileStream Open(FileMode mode, FileAccess access, [NotNull] AbsolutePath path, bool isNewlyCreated, bool isAsync,
                                bool notifyTracker)
        {
            Guard.NotNull(path, nameof(path));

            bool isReaderOnly = access == FileAccess.Read;
            bool truncate     = false;
            bool seekToEnd    = false;

            switch (mode)
            {
            case FileMode.CreateNew:
            case FileMode.Create:
            case FileMode.Truncate:
            {
                truncate     = true;
                isReaderOnly = false;
                break;
            }

            case FileMode.Append:
            {
                seekToEnd    = true;
                isReaderOnly = false;
                break;
            }
            }

            FakeFileStream stream = CreateStream(path, access, isReaderOnly, notifyTracker);

            InitializeStream(stream, seekToEnd, truncate, isNewlyCreated);

            return(new FileStreamWrapper(stream, path.GetText, () => isAsync, stream.GetSafeFileHandle, _ => stream.Flush(),
                                         stream.Lock, stream.Unlock));
        }
            public void Add(long position, long length, [NotNull] FakeFileStream stream)
            {
                Guard.NotNull(owner, nameof(owner));

                lock (owner.readerWriterLock)
                {
                    if (rangesLocked.Any(range => range.IntersectsWith(position, length)))
                    {
                        throw ErrorFactory.System.CannotAccessFileProcessHasLocked();
                    }

                    rangesLocked.Add(new LockRange(position, length, stream));
                }
            }
            public void Release([NotNull] FakeFileStream stream)
            {
                Guard.NotNull(stream, nameof(stream));

                lock (owner.readerWriterLock)
                {
                    for (int index = rangesLocked.Count - 1; index >= 0; index--)
                    {
                        if (rangesLocked[index].Owner == stream)
                        {
                            rangesLocked.RemoveAt(index);
                        }
                    }
                }
            }
        private void CloseStream([NotNull] FakeFileStream stream)
        {
            lock (readerWriterLock)
            {
                if (activeWriter == stream)
                {
                    activeWriter = null;
                }

                activeReaders.Remove(stream);

                if (deleteOnClose && !IsOpen())
                {
                    Parent.DeleteFile(Name, true);
                }
            }
        }
        private static void InitializeStream([NotNull] FakeFileStream stream, bool seekToEnd, bool truncate, bool isNewlyCreated)
        {
            if (seekToEnd)
            {
                stream.Seek(0, SeekOrigin.End);
                stream.SetAppendOffsetToCurrentPosition();
            }

            if (truncate)
            {
                stream.SetLength(0);

                if (!isNewlyCreated)
                {
                    stream.EnableAccessKinds(FileAccessKinds.WriteRead);
                }
            }
        }
            public void Remove(long position, long length, [NotNull] FakeFileStream stream)
            {
                Guard.NotNull(stream, nameof(stream));

                lock (owner.readerWriterLock)
                {
                    for (int index = rangesLocked.Count - 1; index >= 0; index--)
                    {
                        LockRange range = rangesLocked[index];
                        if (range.Position == position && range.Length == length && range.Owner == stream)
                        {
                            rangesLocked.RemoveAt(index);
                            return;
                        }
                    }
                }

                throw ErrorFactory.System.SegmentIsAlreadyUnlocked();
            }
 public LockRange(long position, long length, [NotNull] FakeFileStream owner)
 {
     Position = position;
     Length   = length;
     Owner    = owner;
 }
            public bool UnsafeIsLocked(long position, long length, [NotNull] FakeFileStream stream)
            {
                Guard.NotNull(stream, nameof(stream));

                return(rangesLocked.Where(x => x.Owner != stream).Any(range => range.IntersectsWith(position, length)));
            }
Exemple #10
0
            public Stream GetStream(FileMode fileMode, FileAccess fileAccess, FileShare fileShare)
            {
                ValidateAccess(fileShare);

                switch (fileShare)
                {
                case FileShare.None:
                    if (_openStreams.Any())
                    {
                        throw new AccessViolationException();
                    }
                    break;

                case FileShare.Read:
                    if (_openStreams.Any(x => (x.FileAccess != FileAccess.Read) || (x.FileShare == FileShare.None)))
                    {
                        throw new AccessViolationException();
                    }
                    break;

                case FileShare.Write:
                    if (_openStreams.Any(x => (x.FileAccess != FileAccess.Write) || (x.FileShare == FileShare.None)))
                    {
                        throw new AccessViolationException();
                    }
                    break;

                case FileShare.ReadWrite:
                    if (_openStreams.Any(x => x.FileShare == FileShare.None))
                    {
                        throw new AccessViolationException();
                    }
                    break;

                case FileShare.Delete:
                    throw new NotSupportedException();

                case FileShare.Inheritable:
                    throw new NotSupportedException();

                default:
                    throw new ArgumentOutOfRangeException(nameof(fileShare), fileShare, null);
                }

                var stream = new FakeFileStream(
                    ContentAsBytes,
                    fileMode,
                    fileAccess,
                    fileShare,
                    () => LastWriteTimeUtc = _dateTimeProvider.Time(),
                    flushedContent =>
                {
                    switch (fileAccess)
                    {
                    case FileAccess.Write:
                    case FileAccess.ReadWrite:
                        ContentAsBytes = flushedContent;
                        break;
                    }
                },
                    s => _openStreams.Remove(s));

                _openStreams.Add(stream);

                return(stream);
            }