Пример #1
0
        public FilterResult Filter(
            IFileResource sourceResource,
            IEnumerable <IFileResource> targetResources,
            ITargetHistoryRepository targetHistoryRepository,
            IFileSystem source,
            IFileSystem target)
        {
            var primaryAncestor = FindPrimaryAncestorFolder(
                sourceResource.RelativePath
                );
            var shouldRecordOnly =
                ResourceExistsAtTarget(targetResources, sourceResource) ||
                ResourceExistsInHistory(targetHistoryRepository, sourceResource);

            if (shouldRecordOnly)
            {
                return(FilterResult.RecordOnly);
            }

            var shouldInclude =
                target.IsDirectory(primaryAncestor) ||
                RelativeBaseExistsInHistory(targetHistoryRepository, primaryAncestor);

            return(shouldInclude
                       ? FilterResult.Include
                       : FilterResult.Exclude);
        }
Пример #2
0
        private bool BytesMatch(long offset,
                                int toCheck,
                                Stream source,
                                Stream target,
                                IFileResource sourceResource,
                                IFileResource targetResource)
        {
            using var sourceResetter = new StreamResetter(source);
            using var sourceData     = BufferPool.Borrow(toCheck);
            if (!TryReadBytes(source, offset, toCheck, sourceData.Data, sourceResource))
            {
                Log($"can't read bytes {offset} - {toCheck} of source {sourceResource.RelativePath}");
                return(false);
            }

            using var targetResetter = new StreamResetter(target);
            using var targetData     = BufferPool.Borrow(toCheck);
            if (!TryReadBytes(target, offset, toCheck, targetData.Data, targetResource))
            {
                Log($"can't read bytes {offset} - {toCheck} of target {targetResource.RelativePath}");
                return(false);
            }

            // buffer-pool can give back a bigger buffer than required
            // -> have to ensure that we only check byte-for-byte against
            //    the tail {toCheck} bytes
            return(sourceData.Data
                   .Take(toCheck)
                   .SequenceEqual(
                       targetData.Data.Take(toCheck)
                       ));
        }
Пример #3
0
 public bool CanResume(IFileResource sourceResource,
                       IFileResource targetResource,
                       Stream source,
                       Stream target)
 {
     return(false);
 }
Пример #4
0
 public void NotifySyncStart(
     IFileResource sourceResource,
     IFileResource targetResource
     )
 {
     Clear();
     _reporter.NotifyOverall(
         new NotificationDetails()
     {
         Label                 = _batchLabel,
         CurrentItem           = ++_currentItem,
         TotalItems            = _totalBatchItems,
         TotalBytesTransferred = _batchBytesTransferred,
         TotalBytes            = _totalBatchBytes
     }
         );
     _currentSource = sourceResource;
     _currentTarget = targetResource;
     _reporter.NotifyCurrent(
         new NotificationDetails()
     {
         Label                   = sourceResource.RelativePath,
         CurrentItem             = _currentItem,
         TotalItems              = _totalBatchItems,
         CurrentBytesTransferred = 0,
         CurrentTotalBytes       = sourceResource.Size,
         TotalBytesTransferred   = _batchBytesTransferred,
         TotalBytes              = _totalBatchBytes
     }
         );
 }
Пример #5
0
            public void ShouldReturnNoSourceResources()
            {
                // Arrange
                var sources = GetRandomCollection <IFileResource>();
                var targets = new IFileResource[0];
                var targetHistoryRepository = Substitute.For <ITargetHistoryRepository>();

                targetHistoryRepository.FindAll(Arg.Any <string>())
                .Returns(new HistoryItem[0]);
                var source = Substitute.For <IFileSystem>();
                var target = Substitute.For <IFileSystem>();

                target.IsDirectory(Arg.Any <string>())
                .Returns(false);
                var sut = Create();
                // Act
                var results = sources.Select(
                    s => sut.Filter(
                        s,
                        targets,
                        targetHistoryRepository,
                        source,
                        target)
                    ).ToArray();

                // Assert
                Expect(results).To.Contain.All()
                .Matched.By(o => o == FilterResult.Exclude);
            }
Пример #6
0
        public FilterResult Filter(
            IFileResource sourceResource,
            IEnumerable <IFileResource> targetResources,
            ITargetHistoryRepository targetHistoryRepository,
            IFileSystem source,
            IFileSystem target)
        {
            return(HaveMatchingTargetResource() ||
                   HaveMatchingHistoryItem()
                       ? FilterResult.Ambivalent
                       : FilterResult.Include);

            bool HaveMatchingTargetResource()
            {
                var existing = targetResources.FirstOrDefault(
                    r => r.RelativePath == sourceResource.RelativePath
                    );

                return(existing?.Size == sourceResource.Size);
            }

            bool HaveMatchingHistoryItem()
            {
                var historyItem = targetHistoryRepository.Find(
                    sourceResource.RelativePath
                    );

                return(historyItem?.Size == sourceResource.Size);
            }
        }
Пример #7
0
        public bool CanResume(
            IFileResource sourceResource,
            IFileResource targetResource,
            Stream source,
            Stream target)
        {
            if (TargetIsLargerThanSource())
            {
                return(false);
            }

            if (SourceOrTargetAreZeroLength())
            {
                return(false);
            }

            var toCheck = (int)Math.Min(
                _options.ResumeCheckBytes,
                Math.Ceiling(targetResource.Size / 2M)
                );

            // most likely fail is at the tail (corruption from interruption of copy)
            return(TailBytesMatch() &&
                   // but also check lead, just for paranoia
                   LeadBytesMatch());

            bool TargetIsLargerThanSource()
            {
                var result = targetResource.Size > sourceResource.Size;

                Log($"{targetResource.RelativePath}: target is {(result ? "larger" : "smaller")} than source");
                return(result);
            }

            bool TailBytesMatch()
            {
                var toSeek = targetResource.Size - toCheck;
                var result = BytesMatch(toSeek, toCheck, source, target, sourceResource, targetResource);

                Log($"{targetResource.RelativePath} tail bytes {toSeek} - {toCheck} {(result ? "" : "do not ")}match");
                return(result);
            }

            bool LeadBytesMatch()
            {
                var result = BytesMatch(0, toCheck, source, target, sourceResource, targetResource);

                Log($"{targetResource.RelativePath} lead {toCheck} bytes {(result ? "" : "do not ")}match");
                return(result);
            }

            bool SourceOrTargetAreZeroLength()
            {
                Log($"{targetResource.RelativePath} sizes in bytes: source: {sourceResource.Size} vs target: {targetResource.Size}");
                return(sourceResource.Size == 0 ||
                       targetResource.Size == 0);
            }
        }
Пример #8
0
 private static bool ResourceExistsAtTarget(
     IEnumerable <IFileResource> targetResources,
     IFileResource sourceResource)
 {
     return(targetResources.Any(
                o => o.RelativePath == sourceResource.RelativePath &&
                o.Size == sourceResource.Size
                ));
 }
Пример #9
0
 public static HistoryItem AsHistoryItem(
     this IFileResource resource
     )
 {
     return(HistoryItemBuilder.Create()
            .WithRandomProps()
            .ForFileResource(resource)
            .Build());
 }
        private bool HistoryFileExists(
            ITargetHistoryRepository targetHistoryRepository,
            IFileResource sourceResource)
        {
            var existing = targetHistoryRepository.Find(
                sourceResource.RelativePath
                );

            return(existing?.Size == sourceResource.Size);
        }
Пример #11
0
 private static bool ResourceExistsInHistory(
     ITargetHistoryRepository targetHistoryRepository,
     IFileResource sourceResource)
 {
     return(targetHistoryRepository.Find(
                sourceResource.RelativePath
                )
            ?.Size ==
            sourceResource.Size);
 }
Пример #12
0
 public FilterResult Filter(IFileResource sourceResource,
                            IEnumerable <IFileResource> targetResources,
                            ITargetHistoryRepository targetHistoryRepository,
                            IFileSystem source,
                            IFileSystem target)
 {
     return(sourceResource.Name.StartsWith(".")
                ? FilterResult.Exclude
                : FilterResult.Ambivalent);
 }
Пример #13
0
 public FilterResult Filter(
     IFileResource sourceResource,
     IEnumerable <IFileResource> targetResources,
     ITargetHistoryRepository targetHistoryRepository,
     IFileSystem source,
     IFileSystem target)
 {
     return(_archiveFiles.Contains(sourceResource.RelativePath)
                ? FilterResult.Include
                : FilterResult.Exclude);
 }
Пример #14
0
 private void NotifySyncComplete(
     IFileResource sourceResource,
     IFileResource targetResource
     )
 {
     _notifiables.ForEach(
         notifiable => notifiable.NotifySyncComplete(
             sourceResource,
             targetResource)
         );
 }
        private static IFileResource SetBasePath(
            IFileResource fileResource,
            string basePath)
        {
            var relPath = fileResource.RelativePath;

            fileResource.Path.Returns(
                Path.Combine(basePath, relPath)
                );
            return(fileResource);
        }
 private bool TargetFileExists(
     IEnumerable <IFileResource> targetResources,
     IFileResource sourceResource)
 {
     return(targetResources.FirstOrDefault(
                t => t.RelativePath.Equals(
                    sourceResource.RelativePath,
                    StringComparison.CurrentCulture
                    )
                )
            ?.Size ==
            sourceResource.Size);
 }
Пример #17
0
 private void NotifyError(
     IFileResource source,
     IFileResource target,
     Exception ex)
 {
     _notifiables.ForEach(
         notifiable => notifiable.NotifyError(
             source,
             target,
             ex
             )
         );
 }
        public FilterResult Filter(IFileResource sourceResource,
                                   IEnumerable <IFileResource> targetResources,
                                   ITargetHistoryRepository targetHistoryRepository,
                                   IFileSystem source,
                                   IFileSystem target)
        {
            var shouldExclude =
                TargetFileExists(targetResources, sourceResource) ||
                HistoryFileExists(targetHistoryRepository, sourceResource);

            return(shouldExclude
                       ? FilterResult.Exclude
                       : FilterResult.Ambivalent);
        }
Пример #19
0
 public FilterResult Filter(
     IFileResource sourceResource,
     IEnumerable <IFileResource> targetResources,
     ITargetHistoryRepository targetHistoryRepository,
     IFileSystem source,
     IFileSystem target)
 {
     return(_filter(
                sourceResource,
                targetResources,
                targetHistoryRepository,
                source,
                target));
 }
Пример #20
0
        private int WriteOtherResource(IResource resource)
        {
            byte[] buffer = null;

            IEmbeddedResource embeddedResource = resource as IEmbeddedResource;

            if (embeddedResource != null)
            {
                buffer = embeddedResource.Value;
            }

            IFileResource fileResource = resource as IFileResource;

            if (fileResource != null)
            {
                string location = Path.Combine(Path.GetDirectoryName(fileResource.Module.Location), fileResource.Location);
                location = Environment.ExpandEnvironmentVariables(location);
                if (File.Exists(location))
                {
                    using (Stream stream = new FileStream(location, FileMode.Open, FileAccess.Read))
                    {
                        if (fileResource.Offset == 0)
                        {
                            buffer = new byte[stream.Length];
                            stream.Read(buffer, 0, buffer.Length);
                        }
                        else
                        {
                            BinaryReader reader = new BinaryReader(stream);
                            int          size   = reader.ReadInt32();
                            buffer = new byte[size];
                            stream.Read(buffer, 0, size);
                        }
                    }
                }
            }

            if (buffer != null)
            {
                string fileName = Path.Combine(_outputDirectory, GetResourceFileName(resource));
                using (Stream stream = File.Create(fileName))
                {
                    stream.Write(buffer, 0, buffer.Length);
                }
                WriteLine(fileName);
            }

            return(0);
        }
        private static IFileResource Duplicate(IFileResource arg)
        {
            var result = Substitute.For <IFileResource>();

            // NSubstitute does some dark, sneaky magick to achieve
            // it's end goals -- and provides a great library in the
            // process. However, I know that doing
            // .Returns({some other NSubstitute'd property})
            // doesn't work because of the magic, so we have to var off
            // values first
            var(path, relPath, size) = (arg.Path, arg.RelativePath, arg.Size);
            result.Path.Returns(path);
            result.RelativePath.Returns(relPath);
            result.Size.Returns(size);
            return(result);
        }
Пример #22
0
 public void NotifySyncComplete(
     IFileResource sourceResource,
     IFileResource targetResource)
 {
     _reporter.NotifyCurrent(
         new NotificationDetails()
     {
         Label                   = sourceResource.RelativePath,
         CurrentItem             = _currentItem,
         TotalItems              = _totalBatchItems,
         CurrentBytesTransferred = sourceResource.Size,
         CurrentTotalBytes       = sourceResource.Size,
         TotalBytesTransferred   = _batchBytesTransferred,
         TotalBytes              = _totalBatchBytes
     }
         );
     Clear();
 }
Пример #23
0
 public void NotifyError(
     IFileResource sourceResource,
     IFileResource targetResource,
     Exception ex)
 {
     _reporter.NotifyError(
         new NotificationDetails()
     {
         Label = sourceResource.RelativePath,
         CurrentBytesTransferred = _currentWritten,
         CurrentTotalBytes       = sourceResource.Size,
         CurrentItem             = _currentItem,
         TotalItems            = _totalBatchItems,
         TotalBytesTransferred = _batchBytesTransferred,
         TotalBytes            = _totalBatchBytes,
         Exception             = ex
     }
         );
 }
Пример #24
0
            public void ShouldIncludeSourcesMatchingTargetFolder()
            {
                // Arrange
                var sourceBase         = GetRandomPath(2);
                var source1            = FakeFileResource.For(sourceBase, GetRandomPath(2), GetRandomInt());
                var source2            = FakeFileResource.For(sourceBase, GetRandomPath(2), GetRandomInt());
                var sourceRelativeBase = source1
                                         .RelativePath.Split(
                    Path.DirectorySeparatorChar
                    )
                                         .First();
                var targets = new IFileResource[0];
                var targetHistoryRepository = Substitute.For <ITargetHistoryRepository>();

                targetHistoryRepository.FindAll(Arg.Is <string>(a => a == $"{sourceRelativeBase}/*"))
                .Returns(new[]
                {
                    new HistoryItem(
                        Path.Combine(sourceRelativeBase, GetRandomPath(2)),
                        GetRandomInt()
                        )
                });
                var sut = Create();
                // Act
                var result1 = sut.Filter(
                    source1,
                    targets,
                    targetHistoryRepository,
                    Substitute.For <IFileSystem>(),
                    Substitute.For <IFileSystem>());
                var result2 = sut.Filter(
                    source2,
                    targets,
                    targetHistoryRepository,
                    Substitute.For <IFileSystem>(),
                    Substitute.For <IFileSystem>());

                // Assert
                Expect(result1)
                .To.Equal(FilterResult.Include);
                Expect(result2)
                .To.Equal(FilterResult.Exclude);
            }
Пример #25
0
 private bool TryReadBytes(Stream stream,
                           long offset,
                           int count,
                           byte[] target,
                           IFileResource resource)
 {
     try
     {
         stream.Seek(offset, SeekOrigin.Begin);
         var read = stream.Read(target, 0, count);
         return(read == count);
     }
     catch (Exception ex)
     {
         _messageWriter.Write(
             $"Resume not supported: unable to read {count} bytes from offset {offset} of {resource.RelativePath}:\n  {ex.Message}"
             );
         return(false);
     }
 }
 internal static LinkedResource FindMatchingResource(AssemblyDefinition adef, IFileResource lres)
 {
     return((from resource in adef.MainModule.Resources
             where resource is LinkedResource && resource.Name.Equals(lres.Name)
             select resource as LinkedResource).FirstOrDefault());
 }
Пример #27
0
 public HistoryItemBuilder ForFileResource(
     IFileResource resource)
 {
     return(WithPath(resource.RelativePath)
            .WithSize(resource.Size));
 }
Пример #28
0
 public virtual void VisitFileResource(IFileResource value)
 {
 }
Пример #29
0
 private void Clear()
 {
     _currentSource  = null;
     _currentTarget  = null;
     _currentWritten = 0;
 }
Пример #30
0
 public virtual void VisitFileResource(IFileResource value)
 {
 }
 public virtual IResource TransformFileResource(IFileResource value)
 {
     return value;
 }