void CopyEntry( BlubbZipFile workFile, BlubbUpdate update ) { workFile.WriteLocalEntryHeader( update ); if( update.Entry.CompressedSize > 0 ) { const int NameLengthOffset = 26; long entryDataOffset = update.Entry.Offset + NameLengthOffset; // TODO: This wont work for SFX files! baseStream_.Seek( entryDataOffset, SeekOrigin.Begin ); uint nameLength = ReadLEUshort(); uint extraLength = ReadLEUshort(); baseStream_.Seek( nameLength + extraLength, SeekOrigin.Current ); CopyBytes( update, workFile.baseStream_, baseStream_, update.Entry.CompressedSize, false ); } CopyDescriptorBytes( update, workFile.baseStream_, baseStream_ ); }
void ModifyEntry( BlubbZipFile workFile, BlubbUpdate update ) { workFile.WriteLocalEntryHeader( update ); long dataStart = workFile.baseStream_.Position; // TODO: This is slow if the changes don't effect the data!! if( update.Entry.IsFile && ( update.Filename != null ) ) { using( Stream output = workFile.GetOutputStream( update.OutEntry ) ) { using( Stream source = this.GetInputStream( update.Entry ) ) { CopyBytes( update, output, source, source.Length, true ); } } } long dataEnd = workFile.baseStream_.Position; update.Entry.CompressedSize = dataEnd - dataStart; }
void CopyEntryDirect( BlubbZipFile workFile, BlubbUpdate update, ref long destinationPosition ) { bool skipOver = false; if( update.Entry.Offset == destinationPosition ) { skipOver = true; } if( !skipOver ) { baseStream_.Position = destinationPosition; workFile.WriteLocalEntryHeader( update ); destinationPosition = baseStream_.Position; } long sourcePosition = 0; const int NameLengthOffset = 26; // TODO: Add base for SFX friendly handling long entryDataOffset = update.Entry.Offset + NameLengthOffset; baseStream_.Seek( entryDataOffset, SeekOrigin.Begin ); // Clumsy way of handling retrieving the original name and extra data length for now. // TODO: Stop re-reading name and data length in CopyEntryDirect. uint nameLength = ReadLEUshort(); uint extraLength = ReadLEUshort(); sourcePosition = baseStream_.Position + nameLength + extraLength; if( skipOver ) { destinationPosition += ( sourcePosition - entryDataOffset ) + NameLengthOffset + // Header size update.Entry.CompressedSize + GetDescriptorSize( update ); } else { if( update.Entry.CompressedSize > 0 ) { CopyEntryDataDirect( update, baseStream_, false, ref destinationPosition, ref sourcePosition ); } CopyDescriptorBytesDirect( update, baseStream_, ref destinationPosition, sourcePosition ); } }
void AddEntry( BlubbZipFile workFile, BlubbUpdate update ) { Stream source = null; if( update.Entry.IsFile ) { source = update.GetSource(); if( source == null ) { source = updateDataSource_.GetSource( update.Entry, update.Filename ); } } if( source != null ) { using( source ) { long sourceStreamLength = source.Length; if( update.OutEntry.Size < 0 ) { update.OutEntry.Size = sourceStreamLength; } else { // Check for errant entries. if( update.OutEntry.Size != sourceStreamLength ) { throw new BlubbZipException( "Entry size/stream size mismatch" ); } } workFile.WriteLocalEntryHeader( update ); long dataStart = workFile.baseStream_.Position; using( Stream output = workFile.GetOutputStream( update.OutEntry ) ) { CopyBytes( update, output, source, sourceStreamLength, true ); } long dataEnd = workFile.baseStream_.Position; update.OutEntry.CompressedSize = dataEnd - dataStart; if( ( update.OutEntry.Flags & (int)GeneralBitFlags.Descriptor ) == (int)GeneralBitFlags.Descriptor ) { BlubbZipHelperStream helper = new BlubbZipHelperStream( workFile.baseStream_ ); helper.WriteDataDescriptor( update.OutEntry ); } } } else { workFile.WriteLocalEntryHeader( update ); update.OutEntry.CompressedSize = 0; } }