//Refactoring OK++ public async Task<DiffStampAdapter> TryMakeDiffStamp( FileEntityAggregator targetFile, String diffStampDescription) { //Download source file IO.MemoryStream fileMemoryStream = await TryDownloadFileToStream(targetFile); if (fileMemoryStream == default(IO.MemoryStream)) { //Failed to download return default(DiffStampAdapter); } else { //Download present diff stamps List<DiffStampAdapter> diffStamps = await TryDownloadAllDiffstampsForFile(targetFile); //OK //Apply all of them (memory hungry section) Byte[] latestData = fileMemoryStream.ToArray(); fileMemoryStream.Dispose(); //As there is a temp stream to apply patches foreach (DiffStampAdapter diffStamp in diffStamps) { using (IO.MemoryStream outputStream = new IO.MemoryStream()) { using (IO.MemoryStream currentPatchedMemoryStream = new IO.MemoryStream(latestData)) { //Apply a patch BinaryPatchUtility.Apply( currentPatchedMemoryStream, diffStamp.OpenMemoryStreamForPatching, outputStream); //Prepare applied data for next iteration patching outputStream.Position = 0; latestData = outputStream.ToArray(); } } } //When all patches are applied, make new one with the difference between last on cloud and on PC IO.FileStream fileStream = default(IO.FileStream); IO.MemoryStream latestPatchMemoryStream = new IO.MemoryStream(); DiffStampAdapter resultPatch = default(DiffStampAdapter); try { //Read a file to byte array fileStream = new IO.FileStream(targetFile.LocalFilePath, IO.FileMode.Open); Byte[] lastFromUserPC = new Byte[fileStream.Length]; fileStream.Read(lastFromUserPC, 0, Convert.ToInt32(fileStream.Length)); //Get bytes from latest patched from cloud BinaryPatchUtility.Create(latestData, lastFromUserPC, latestPatchMemoryStream); //Create new binary patch instance resultPatch = new DiffStampAdapter( latestPatchMemoryStream.ToArray(), diffStampDescription, DateTime.Now); } catch (Exception) { //Patching failed } finally { fileStream.Dispose(); latestPatchMemoryStream.Dispose(); } return resultPatch; } }
//Refactoring OK++ public async Task<FileEntityAggregator> TryUploadDiffStampForFileAsync( FileEntityAggregator targetFile, DiffStampAdapter diffStamp) { DriveService driveService = await TryGetAuthorizer(); //Instantiate file entity File fileToUpload = new File { Title = String.Format("{0}.{1}", diffStamp.Description, BsdiffStampExtension), Parents = new ParentReference[] { new ParentReference { Id = targetFile.GoogleDriveParentId } } }; //Instantiate request IUploadProgress uploadProgress = default(IUploadProgress); FileEntityAggregator result = default(FileEntityAggregator); using (IO.MemoryStream uploadFileStream = new IO.MemoryStream()) { BinaryFormatter binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(uploadFileStream, diffStamp); uploadFileStream.Position = 0; var insertUploadRequest = driveService.Files.Insert( fileToUpload, uploadFileStream, BsdiffStampMIMEType); insertUploadRequest.ChunkSize = FilesResource.InsertMediaUpload.MinimumChunkSize * 2; //Start uploading task uploadProgress = await insertUploadRequest.UploadAsync(); //Return data according to upload completion state if (uploadProgress.Status == UploadStatus.Completed) { result = new FileEntityAggregator { LocalFilePath = String.Empty, GoogleDriveId = insertUploadRequest.ResponseBody.Id, GoogleDrivePath = insertUploadRequest.ResponseBody.DownloadUrl, GoogleDriveParentId = targetFile.GoogleDriveParentId, MIMEType = BsdiffStampMIMEType }; } else { result = default(FileEntityAggregator); } } return result; }