Esempio n. 1
0
        private static void CheckState(string baseDir, string syncDbDir, SyncDatabase syncDb)
        {
            var localFiles  = Directory.GetFiles(baseDir, "*", SearchOption.AllDirectories).ToList();
            var dbDirInBase = syncDbDir.StartsWith(baseDir);

            foreach (var stored in syncDb.Files)
            {
                var localFilePath = Path.Combine(baseDir, stored.RelativePath);
                var localFileIdx  = localFiles.IndexOf(localFilePath);
                if (localFileIdx < 0)
                {
                    stored.State = SyncFileState.Deleted;
                }
                else
                {
                    var localFile = localFiles[localFileIdx];
                    localFiles.RemoveAt(localFileIdx);

                    {
                        var hash = NetworkHelperSequential.HashFileAsync(new FileInfo(localFile)).Result;

                        var localFileHash = hash.ToHashString();
                        if (localFileHash != stored.HashStr)
                        {
                            stored.State   = SyncFileState.Modified;
                            stored.HashStr = localFileHash;
                        }
                    }
                }
            }

            var localInfos = localFiles.Select(localFile =>
            {
                if (dbDirInBase && localFile.StartsWith(syncDbDir))
                {
                    return(null);
                }

                var localFileRelativePath = localFile.Replace(baseDir, string.Empty);

                {
                    var hash = NetworkHelperSequential.HashFileAsync(new FileInfo(localFile)).Result;

                    return(new SyncFileInfo
                    {
                        HashStr = hash.ToHashString(),
                        RelativePath = localFileRelativePath.TrimStart(Path.DirectorySeparatorChar),
                        AbsolutePath = localFile,
                        State = SyncFileState.New,
                    });
                }
            }).Where(i => i != null).ToList();

            syncDb.Files.AddRange(localInfos);
        }
Esempio n. 2
0
        private SyncDatabase GetSyncDb(string baseDir, string syncDbDir, out string error)
        {
            error = null;
            var syncDb = SyncDatabase.Get(baseDir, syncDbDir);

            if (syncDb == null)
            {
                syncDb = SyncDatabase.Initialize(baseDir, syncDbDir);
                if (syncDb != null)
                {
                    return(syncDb);
                }

                error = "Unable to create sync database.";
                return(null);
            }

            CheckState(baseDir, syncDbDir, syncDb);

            return(syncDb);
        }
Esempio n. 3
0
        private async Task <bool> ReceiveFiles(Stream networkStream, IEnumerable <SyncFileInfo> dataToDownload, SyncDatabase syncDb)
        {
            foreach (var fileInfo in dataToDownload)
            {
                var data = new GetFileCommandData
                {
                    SessionId        = _sessionId,
                    RelativeFilePath = fileInfo.RelativePath,
                };
                var dataBytes = Serializer.Serialize(data);

                await NetworkHelperSequential.WriteCommandHeader(networkStream, Commands.GetFileCmd, dataBytes.Length);

                await NetworkHelperSequential.WriteBytes(networkStream, dataBytes);

                var cmdHeader = await NetworkHelperSequential.ReadCommandHeader(networkStream);

                if (cmdHeader.Command != Commands.GetFileCmd)
                {
                    return(false);
                }

                if (cmdHeader.PayloadLength == 0)
                {
                    return(false);
                }

                var fileLengthBytes = await NetworkHelperSequential.ReadBytes(networkStream, cmdHeader.PayloadLength);

                var fileLength = BitConverter.ToInt64(fileLengthBytes, 0);

                var tmpFilePath = Path.Combine(_newDir, fileInfo.RelativePath);
                var newHash     = await NetworkHelperSequential.ReadToFileAndHashAsync(networkStream, tmpFilePath, (int)fileLength);

                if (!string.Equals(newHash.ToHashString(), fileInfo.HashStr, StringComparison.OrdinalIgnoreCase))
                {
                    throw new InvalidOperationException("File copy error: hash mismatch");
                }

                _sessionFileHelper.AddNew(fileInfo.RelativePath);

                var fi = syncDb.Files.FirstOrDefault(x => x.RelativePath == fileInfo.RelativePath);
                if (fi == null)
                {
                    fi = new SyncFileInfo
                    {
                        RelativePath = fileInfo.RelativePath,
                    };

                    syncDb.Files.Add(fi);
                }

                fi.HashStr = newHash.ToHashString();
                fi.State   = SyncFileState.NotChanged;
            }

            return(true);
        }
Esempio n. 4
0
        private async Task <bool> SendFiles(NetworkStream networkStream, List <SyncFileInfo> dataToUpload, SyncDatabase syncDb)
        {
            foreach (var fileInfo in dataToUpload)
            {
                var filePath = Path.Combine(_baseDir, fileInfo.RelativePath);

                var fileLength = new FileInfo(filePath).Length;

                var data = new SendFileCommandData
                {
                    FileLength       = fileLength,
                    SessionId        = _sessionId,
                    RelativeFilePath = fileInfo.RelativePath,
                    HashStr          = syncDb.Files.First(x => x.RelativePath == fileInfo.RelativePath).HashStr,
                };
                var dataBytes = Serializer.Serialize(data);
                await NetworkHelperSequential.WriteCommandHeader(networkStream, Commands.SendFileCmd, dataBytes.Length);

                await NetworkHelperSequential.WriteBytes(networkStream, dataBytes);

                await NetworkHelperSequential.WriteFromFileAndHashAsync(networkStream, filePath, (int)fileLength);
            }

            return(true);
        }