Example #1
0
        /// <summary>
        /// Appends a file to the content and signature archives, watching the content archive file size.
        /// Returns the partial file entry if the volume size was exceeded. 
        /// Returns null if the file was written entirely.
        /// </summary>
        /// <param name="entry">The entry that describes the partial file</param>
        /// <param name="contentfile">The content archive file</param>
        /// <param name="signaturefile">The signature archive file</param>
        /// <param name="volumesize">The max allowed volumesize</param>
        /// <returns>The partial file entry if the volume size was exceeded. Returns null if the file was written entirely.</returns>
        private PartialFileEntry WritePossiblePartial(PartialFileEntry entry, Library.Interface.ICompression contentfile, Library.Interface.ICompression signaturefile, long volumesize)
        {
            long startPos = entry.Stream.Position;

            //Protect against writing this file if there is not enough space to hold the INCOMPLETE_FILE
            if (startPos == 0 && contentfile.Size + contentfile.FlushBufferSize + (entry.ExtraSize * 2) > volumesize)
                return entry;

            PartialFileEntry pe = WritePossiblePartialInternal(entry, contentfile, volumesize);

            if (pe != null)
            {
                //The record is (still) partial
                string[] tmplines = new PartialEntryRecord(entry.relativeName, startPos, entry.Stream.Position - startPos, entry.Stream.Length).Serialize();
                contentfile.WriteAllLines(INCOMPLETE_FILE, tmplines);
                signaturefile.WriteAllLines(INCOMPLETE_FILE, tmplines);

                //If we are debugging, this can be nice to have
                Logging.Log.WriteMessage(string.Format(Strings.RSyncDir.PartialFileAddedLogMessage, entry.relativeName, startPos), XervBackup.Library.Logging.LogMessageType.Information);
            }
            else
            {
                //If the file was partial before, mark the file as completed
                if (startPos != 0)
                {
                    string[] tmplines = new PartialEntryRecord(entry.relativeName, startPos, entry.Stream.Position - startPos, entry.Stream.Length).Serialize();
                    contentfile.WriteAllLines(COMPLETED_FILE, tmplines);
                    signaturefile.WriteAllLines(COMPLETED_FILE, tmplines);
                }

                //Add signature AFTER content is completed.
                //If content is present, it is restoreable, if signature is missing, file will be backed up on next run
                //If signature is present, but not content, the entire differential sequence will be unable to recover the file
                if (!entry.DumpSignature(signaturefile))
                {
                    if (m_stat != null)
                        m_stat.LogWarning(string.Format(Strings.RSyncDir.FileChangedWhileReadWarning, entry.fullname), null);
                }

                entry.Dispose();
            }
            return pe;
        }