예제 #1
0
파일: ZipPacker.cs 프로젝트: johnwtt/UUP
        /// <summary>
        /// Moves to the next archive in the sequence if necessary.
        /// </summary>
        private void CheckArchiveWriteStream(
            IPackStreamContext streamContext,
            long maxArchiveSize,
            long requiredSize,
            ref Stream archiveStream)
        {
            if (archiveStream != null &&
                archiveStream.Length > 0 && maxArchiveSize > 0)
            {
                long sizeRemaining = maxArchiveSize - archiveStream.Length;
                if (sizeRemaining < requiredSize)
                {
                    string nextArchiveName = streamContext.GetArchiveName(
                        this.currentArchiveNumber + 1);

                    if (string.IsNullOrWhiteSpace(nextArchiveName))
                    {
                        throw new FileNotFoundException("No name provided for archive #" +
                                                        this.currentArchiveNumber + 1);
                    }

                    this.currentArchiveTotalBytes     = archiveStream.Position;
                    this.currentArchiveBytesProcessed = this.currentArchiveTotalBytes;

                    streamContext.CloseArchiveWriteStream(
                        this.currentArchiveNumber,
                        nextArchiveName,
                        archiveStream);
                    archiveStream = null;

                    this.OnProgress(ArchiveProgressType.FinishArchive);

                    this.currentArchiveNumber++;
                    this.totalArchives++;
                    this.currentArchiveBytesProcessed = 0;
                    this.currentArchiveTotalBytes     = 0;
                }
            }

            if (archiveStream == null)
            {
                if (this.currentArchiveNumber > 0)
                {
                    this.OnProgress(ArchiveProgressType.StartArchive);
                }

                archiveStream = streamContext.OpenArchiveWriteStream(
                    this.currentArchiveNumber, this.mainArchiveName, true, this);

                if (archiveStream == null)
                {
                    throw new FileNotFoundException("Stream not provided for archive #" +
                                                    this.currentArchiveNumber);
                }
            }
        }
예제 #2
0
        internal override int CabOpenStreamEx(string path, int openFlags, int shareMode, out int err, IntPtr pv)
        {
            if (CabNumbers.ContainsKey(path))
            {
                Stream stream = CabStream;
                if (stream == null)
                {
                    short cabNumber = CabNumbers[path];

                    currentFolderTotalBytes = 0;

                    stream = context.OpenArchiveWriteStream(cabNumber, path, true, CabEngine);
                    if (stream == null)
                    {
                        throw new FileNotFoundException(
                                  String.Format(CultureInfo.InvariantCulture, "Cabinet {0} not provided.", cabNumber));
                    }

                    currentArchiveName = path;

                    currentArchiveTotalBytes = Math.Min(
                        totalFolderBytesProcessedInCurrentCab, maxCabBytes);
                    currentArchiveBytesProcessed = 0;

                    OnProgress(ArchiveProgressType.StartArchive);
                    CabStream = stream;
                }

                path = CabStreamName;
            }
            else if (path == TempStreamName)
            {
                // Opening memory stream for a temp file.
                Stream stream = new MemoryStream();
                tempStreams.Add(stream);
                int streamHandle = StreamHandles.AllocHandle(stream);
                err = 0;
                return(streamHandle);
            }
            else if (path != CabStreamName)
            {
                // Opening a file on disk for a temp file.
                path = Path.Combine(Path.GetTempPath(), path);
                Stream stream = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
                tempStreams.Add(stream);
                stream = new DuplicateStream(stream);
                int streamHandle = StreamHandles.AllocHandle(stream);
                err = 0;
                return(streamHandle);
            }

            return(base.CabOpenStreamEx(path, openFlags, shareMode, out err, pv));
        }
예제 #3
0
 internal override int CabOpenStreamEx(string path, int openFlags, int shareMode, out int err, IntPtr pv)
 {
     if (base.CabNumbers.ContainsKey(path))
     {
         Stream cabStream = base.CabStream;
         if (cabStream == null)
         {
             short num = base.CabNumbers[path];
             currentFolderTotalBytes = 0L;
             cabStream = context.OpenArchiveWriteStream(num, path, truncate: true, base.CabEngine);
             if (cabStream == null)
             {
                 throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, "Cabinet {0} not provided.", num));
             }
             currentArchiveName           = path;
             currentArchiveTotalBytes     = Math.Min(totalFolderBytesProcessedInCurrentCab, maxCabBytes);
             currentArchiveBytesProcessed = 0L;
             OnProgress(ArchiveProgressType.StartArchive);
             base.CabStream = cabStream;
         }
         path = "%%CAB%%";
     }
     else
     {
         if (path == "%%TEMP%%")
         {
             Stream stream = new MemoryStream();
             tempStreams.Add(stream);
             int result = base.StreamHandles.AllocHandle(stream);
             err = 0;
             return(result);
         }
         if (path != "%%CAB%%")
         {
             path = Path.Combine(Path.GetTempPath(), path);
             Stream stream2 = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
             tempStreams.Add(stream2);
             stream2 = new DuplicateStream(stream2);
             int result2 = base.StreamHandles.AllocHandle(stream2);
             err = 0;
             return(result2);
         }
     }
     return(base.CabOpenStreamEx(path, openFlags, shareMode, out err, pv));
 }
예제 #4
0
        /// <summary>
        /// Adds one file to a zip archive in the process of being created.
        /// </summary>
        private ZipFileHeader PackOneFile(
            IPackStreamContext streamContext,
            string file,
            long maxArchiveSize,
            bool forceZip64,
            ref Stream archiveStream)
        {
            Stream fileStream = null;
            int headerArchiveNumber = 0;
            try
            {
                // TODO: call GetOption to get compression method for the specific file
                ZipCompressionMethod compressionMethod = ZipCompressionMethod.Deflate;
                if (this.CompressionLevel == CompressionLevel.None)
                {
                    compressionMethod = ZipCompressionMethod.Store;
                }

                Converter<Stream, Stream> compressionStreamCreator;
                if (!ZipEngine.compressionStreamCreators.TryGetValue(
                    compressionMethod, out compressionStreamCreator))
                {
                    return null;
                }

                FileAttributes attributes;
                DateTime lastWriteTime;
                fileStream = streamContext.OpenFileReadStream(
                    file, out attributes, out lastWriteTime);
                if (fileStream == null)
                {
                    return null;
                }

                this.currentFileName = file;
                this.currentFileNumber++;

                this.currentFileTotalBytes = fileStream.Length;
                this.currentFileBytesProcessed = 0;
                this.OnProgress(ArchiveProgressType.StartFile);

                ZipFileInfo fileInfo = new ZipFileInfo(
                    file,
                    this.currentArchiveNumber,
                    attributes,
                    lastWriteTime,
                    fileStream.Length,
                    0,
                    compressionMethod);

                bool zip64 = forceZip64 || fileStream.Length >= (long) UInt32.MaxValue;
                ZipFileHeader fileHeader = new ZipFileHeader(fileInfo, zip64);

                this.CheckArchiveWriteStream(
                    streamContext,
                    maxArchiveSize,
                    fileHeader.GetSize(false),
                    ref archiveStream);

                long headerPosition = archiveStream.Position;
                fileHeader.Write(archiveStream, false);
                headerArchiveNumber = this.currentArchiveNumber;

                uint crc;
                long bytesWritten = this.PackFileBytes(
                    streamContext,
                    fileStream,
                    maxArchiveSize,
                    compressionStreamCreator,
                    ref archiveStream,
                    out crc);

                fileHeader.Update(
                    bytesWritten,
                    fileStream.Length,
                    crc,
                    headerPosition,
                    headerArchiveNumber);

                streamContext.CloseFileReadStream(file, fileStream);
                fileStream = null;

                // Go back and rewrite the updated file header.
                if (this.currentArchiveNumber == headerArchiveNumber)
                {
                    long fileEndPosition = archiveStream.Position;
                    archiveStream.Seek(headerPosition, SeekOrigin.Begin);
                    fileHeader.Write(archiveStream, false);
                    archiveStream.Seek(fileEndPosition, SeekOrigin.Begin);
                }
                else
                {
                    // The file spanned archives, so temporarily reopen
                    // the archive where it started.
                    string headerArchiveName = streamContext.GetArchiveName(
                        headerArchiveNumber + 1);
                    Stream headerStream = null;
                    try
                    {
                        headerStream = streamContext.OpenArchiveWriteStream(
                            headerArchiveNumber, headerArchiveName, false, this);
                        headerStream.Seek(headerPosition, SeekOrigin.Begin);
                        fileHeader.Write(headerStream, false);
                    }
                    finally
                    {
                        if (headerStream != null)
                        {
                            streamContext.CloseArchiveWriteStream(
                                headerArchiveNumber, headerArchiveName, headerStream);
                        }
                    }
                }

                this.OnProgress(ArchiveProgressType.FinishFile);

                return fileHeader;
            }
            finally
            {
                if (fileStream != null)
                {
                    streamContext.CloseFileReadStream(
                        this.currentFileName, fileStream);
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Moves to the next archive in the sequence if necessary.
        /// </summary>
        private void CheckArchiveWriteStream(
            IPackStreamContext streamContext,
            long maxArchiveSize,
            long requiredSize,
            ref Stream archiveStream)
        {
            if (archiveStream != null &&
                archiveStream.Length > 0 && maxArchiveSize > 0)
            {
                long sizeRemaining = maxArchiveSize - archiveStream.Length;
                if (sizeRemaining < requiredSize)
                {
                    string nextArchiveName = streamContext.GetArchiveName(
                        this.currentArchiveNumber + 1);

                    if (string.IsNullOrWhiteSpace(nextArchiveName))
                    {
                        throw new FileNotFoundException("No name provided for archive #" +
                            this.currentArchiveNumber + 1);
                    }

                    this.currentArchiveTotalBytes = archiveStream.Position;
                    this.currentArchiveBytesProcessed = this.currentArchiveTotalBytes;

                    streamContext.CloseArchiveWriteStream(
                        this.currentArchiveNumber,
                        nextArchiveName,
                        archiveStream);
                    archiveStream = null;

                    this.OnProgress(ArchiveProgressType.FinishArchive);

                    this.currentArchiveNumber++;
                    this.totalArchives++;
                    this.currentArchiveBytesProcessed = 0;
                    this.currentArchiveTotalBytes = 0;
                }
            }

            if (archiveStream == null)
            {
                if (this.currentArchiveNumber > 0)
                {
                    this.OnProgress(ArchiveProgressType.StartArchive);
                }

                archiveStream = streamContext.OpenArchiveWriteStream(
                    this.currentArchiveNumber, this.mainArchiveName, true, this);

                if (archiveStream == null)
                {
                    throw new FileNotFoundException("Stream not provided for archive #" +
                        this.currentArchiveNumber);
                }
            }
        }
예제 #6
0
파일: ZipPacker.cs 프로젝트: johnwtt/UUP
        /// <summary>
        /// Adds one file to a zip archive in the process of being created.
        /// </summary>
        private ZipFileHeader PackOneFile(
            IPackStreamContext streamContext,
            string file,
            long maxArchiveSize,
            bool forceZip64,
            ref Stream archiveStream)
        {
            Stream fileStream          = null;
            int    headerArchiveNumber = 0;

            try
            {
                // TODO: call GetOption to get compression method for the specific file
                ZipCompressionMethod compressionMethod = ZipCompressionMethod.Deflate;
                if (this.CompressionLevel == CompressionLevel.None)
                {
                    compressionMethod = ZipCompressionMethod.Store;
                }

                Func <Stream, Stream> compressionStreamCreator;
                if (!ZipEngine.compressionStreamCreators.TryGetValue(
                        compressionMethod, out compressionStreamCreator))
                {
                    return(null);
                }

                FileAttributes attributes;
                DateTime       lastWriteTime;
                fileStream = streamContext.OpenFileReadStream(
                    file, out attributes, out lastWriteTime);
                if (fileStream == null)
                {
                    return(null);
                }

                this.currentFileName = file;
                this.currentFileNumber++;

                this.currentFileTotalBytes     = fileStream.Length;
                this.currentFileBytesProcessed = 0;
                this.OnProgress(ArchiveProgressType.StartFile);

                ZipFileInfo fileInfo = new ZipFileInfo(
                    file,
                    this.currentArchiveNumber,
                    attributes,
                    lastWriteTime,
                    fileStream.Length,
                    0,
                    compressionMethod);

                bool          zip64      = forceZip64 || fileStream.Length >= (long)UInt32.MaxValue;
                ZipFileHeader fileHeader = new ZipFileHeader(fileInfo, zip64);

                this.CheckArchiveWriteStream(
                    streamContext,
                    maxArchiveSize,
                    fileHeader.GetSize(false),
                    ref archiveStream);

                long headerPosition = archiveStream.Position;
                fileHeader.Write(archiveStream, false);
                headerArchiveNumber = this.currentArchiveNumber;

                uint crc;
                long bytesWritten = this.PackFileBytes(
                    streamContext,
                    fileStream,
                    maxArchiveSize,
                    compressionStreamCreator,
                    ref archiveStream,
                    out crc);

                fileHeader.Update(
                    bytesWritten,
                    fileStream.Length,
                    crc,
                    headerPosition,
                    headerArchiveNumber);

                streamContext.CloseFileReadStream(file, fileStream);
                fileStream = null;

                // Go back and rewrite the updated file header.
                if (this.currentArchiveNumber == headerArchiveNumber)
                {
                    long fileEndPosition = archiveStream.Position;
                    archiveStream.Seek(headerPosition, SeekOrigin.Begin);
                    fileHeader.Write(archiveStream, false);
                    archiveStream.Seek(fileEndPosition, SeekOrigin.Begin);
                }
                else
                {
                    // The file spanned archives, so temporarily reopen
                    // the archive where it started.
                    string headerArchiveName = streamContext.GetArchiveName(
                        headerArchiveNumber + 1);
                    Stream headerStream = null;
                    try
                    {
                        headerStream = streamContext.OpenArchiveWriteStream(
                            headerArchiveNumber, headerArchiveName, false, this);
                        headerStream.Seek(headerPosition, SeekOrigin.Begin);
                        fileHeader.Write(headerStream, false);
                    }
                    finally
                    {
                        if (headerStream != null)
                        {
                            streamContext.CloseArchiveWriteStream(
                                headerArchiveNumber, headerArchiveName, headerStream);
                        }
                    }
                }

                this.OnProgress(ArchiveProgressType.FinishFile);

                return(fileHeader);
            }
            finally
            {
                if (fileStream != null)
                {
                    streamContext.CloseFileReadStream(
                        this.currentFileName, fileStream);
                }
            }
        }