3838// exception statement from your version.
3939
4040// HISTORY
41- // 22-12-2009 DavidPierson Added AES support
41+ // 2009-12-22 Z-1649 Added AES support
42+ // 2010-03-02 Z-1650 Fixed updating ODT archives in memory. Exposed exceptions in updating.
4243
4344using System ;
4445using System . Collections ;
@@ -1423,6 +1424,18 @@ public void BeginUpdate(IArchiveStorage archiveStorage, IDynamicDataSource dataS
14231424 updateIndex_ . Add ( entry . Name , index ) ;
14241425 }
14251426
1427+ // We must sort by offset before using offset's calculated sizes
1428+ updates_ . Sort ( new UpdateComparer ( ) ) ;
1429+
1430+ int idx = 0 ;
1431+ foreach ( ZipUpdate update in updates_ ) {
1432+ //If last entry, there is no next entry offset to use
1433+ if ( idx == updates_ . Count - 1 )
1434+ break ;
1435+
1436+ update . OffsetBasedSize = ( ( ZipUpdate ) updates_ [ idx + 1 ] ) . Entry . Offset - update . Entry . Offset ;
1437+ idx ++ ;
1438+ }
14261439 updateCount_ = updates_ . Count ;
14271440
14281441 contentsEdited_ = false ;
@@ -2502,10 +2515,16 @@ void CopyEntryDirect(ZipFile workFile, ZipUpdate update, ref long destinationPos
25022515
25032516 sourcePosition = baseStream_ . Position + nameLength + extraLength ;
25042517
2505- if ( skipOver ) {
2506- destinationPosition +=
2507- ( sourcePosition - entryDataOffset ) + NameLengthOffset + // Header size
2508- update . Entry . CompressedSize + GetDescriptorSize ( update ) ;
2518+ if ( skipOver ) {
2519+ if ( update . OffsetBasedSize != - 1 )
2520+ destinationPosition += update . OffsetBasedSize ;
2521+ else
2522+ // TODO: Find out why this calculation comes up 4 bytes short on some entries in ODT (Office Document Text) archives.
2523+ // WinZip produces a warning on these entries:
2524+ // "caution: value of lrec.csize (compressed size) changed from ..."
2525+ destinationPosition +=
2526+ ( sourcePosition - entryDataOffset ) + NameLengthOffset + // Header size
2527+ update . Entry . CompressedSize + GetDescriptorSize ( update ) ;
25092528 }
25102529 else {
25112530 if ( update . Entry . CompressedSize > 0 ) {
@@ -2674,7 +2693,6 @@ void RunUpdates()
26742693 {
26752694 long sizeEntries = 0 ;
26762695 long endOfStream = 0 ;
2677- bool allOk = true ;
26782696 bool directUpdate = false ;
26792697 long destinationPosition = 0 ; // NOT SFX friendly
26802698
@@ -2780,38 +2798,23 @@ void RunUpdates()
27802798 }
27812799 }
27822800 }
2783- catch ( Exception ) {
2784- // TODO Catching exceptions here is rumoured to allow invalid archives to be created with no warning?
2785- allOk = false ;
2786- }
2787- finally {
2788- if ( directUpdate ) {
2789- if ( allOk ) {
2790- workFile . baseStream_ . Flush ( ) ;
2791- workFile . baseStream_ . SetLength ( endOfStream ) ;
2792- }
2793- }
2794- else {
2795- workFile . Close ( ) ;
2801+ catch {
2802+ workFile . Close ( ) ;
2803+ if ( ! directUpdate && ( workFile . Name != null ) ) {
2804+ File . Delete ( workFile . Name ) ;
27962805 }
2806+ throw ;
27972807 }
27982808
2799- if ( allOk ) {
2800- if ( directUpdate ) {
2801- isNewArchive_ = false ;
2802- workFile . baseStream_ . Flush ( ) ;
2803- ReadEntries ( ) ;
2804- }
2805- else {
2806- baseStream_ . Close ( ) ;
2807- Reopen ( archiveStorage_ . ConvertTemporaryToFinal ( ) ) ;
2808- }
2809+ if ( directUpdate ) {
2810+ workFile . baseStream_ . SetLength ( endOfStream ) ;
2811+ workFile . baseStream_ . Flush ( ) ;
2812+ isNewArchive_ = false ;
2813+ ReadEntries ( ) ;
28092814 }
28102815 else {
2811- workFile . Close ( ) ;
2812- if ( ! directUpdate && ( workFile . Name != null ) ) {
2813- File . Delete ( workFile . Name ) ;
2814- }
2816+ baseStream_ . Close ( ) ;
2817+ Reopen ( archiveStorage_ . ConvertTemporaryToFinal ( ) ) ;
28152818 }
28162819 }
28172820
@@ -2955,6 +2958,16 @@ public long CrcPatchOffset
29552958 set { crcPatchOffset_ = value ; }
29562959 }
29572960
2961+ /// <summary>
2962+ /// Get/set the size calculated by offset.
2963+ /// Specifically, the difference between this and next entry's starting offset.
2964+ /// </summary>
2965+ public long OffsetBasedSize
2966+ {
2967+ get { return _offsetBasedSize ; }
2968+ set { _offsetBasedSize = value ; }
2969+ }
2970+
29582971 public Stream GetSource ( )
29592972 {
29602973 Stream result = null ;
@@ -2973,6 +2986,7 @@ public Stream GetSource()
29732986 string filename_ ;
29742987 long sizePatchOffset_ = - 1 ;
29752988 long crcPatchOffset_ = - 1 ;
2989+ long _offsetBasedSize = - 1 ;
29762990 #endregion
29772991 }
29782992
0 commit comments