public void UpdateReferences(bool closingFlag) { // we just need to ask Block Manager for the new Values for each header // there are 2 distinct cases here // 1. local file data is mapped . loaded and might have been changed in size and position // 2. local file data is not loaded and might have been changed only in position (not in size) foreach (IZipIOBlock block in _blockManager) { ZipIOLocalFileBlock localFileBlock = block as ZipIOLocalFileBlock; ZipIORawDataFileBlock rawDataFileBlock = block as ZipIORawDataFileBlock; if (localFileBlock != null) { // this is case 1 data is mapped and loaded, so we only need to find the matching // Centraldirectory record and update it Debug.Assert(CentralDirectoryDictionary.Contains(localFileBlock.FileName)); ZipIOCentralDirectoryFileHeader centralDirFileHeader = (ZipIOCentralDirectoryFileHeader)CentralDirectoryDictionary[localFileBlock.FileName]; if (centralDirFileHeader.UpdateIfNeeded(localFileBlock)) { //update was required let's mark ourselves as dirty _dirtyFlag = true; } } //check whether we deal with raw data block and it was moved else if (rawDataFileBlock != null) { long diskImageShift = rawDataFileBlock.DiskImageShift; if (diskImageShift != 0) { //this is case #2 data isn't loaded based on the shift in the RawData Block // we need to move all overlapping central directory references foreach (ZipIOCentralDirectoryFileHeader centralDirFileHeader in CentralDirectoryDictionary.Values) { // check whether central dir header points into the region of a moved RawDataBlock if (rawDataFileBlock.DiskImageContains(centralDirFileHeader.OffsetOfLocalHeader)) { centralDirFileHeader.MoveReference(diskImageShift); _dirtyFlag = true; } } } } } }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ internal static ZipIORawDataFileBlock Assign(ZipIOBlockManager blockManager, long offset, long size) { if (size <= 0) { throw new ArgumentOutOfRangeException("size"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset"); } ZipIORawDataFileBlock block = new ZipIORawDataFileBlock(blockManager); block._persistedOffset = offset; block._offset = offset; block._size = size; return(block); }
internal void SplitIntoPrefixSuffix(IZipIOBlock block, out ZipIORawDataFileBlock prefixBlock, out ZipIORawDataFileBlock suffixBlock) { // assert that current's block cache isn't loaded, if it is // we probably missed an opportunity to used this cache in order to parse the new block // and it might be based on the overriden data on disk // This block can only be in cached state as a part of single BlockManager.Save execution. // It can NOT be in cached state prior to BlockManager.Save function entry or after // BlockManager.Save execution completed Debug.Assert(_cachePrefixStream == null); // Assert that block is containe inside the current raw block Debug.Assert(DiskImageContains(block)); checked { prefixBlock = null; suffixBlock = null; if (block.Offset > _persistedOffset) { // we have a new non empty prefix; long newBlockOffset = _persistedOffset; long newBlockSize = block.Offset - _persistedOffset; prefixBlock = Assign(_blockManager, newBlockOffset, newBlockSize); } if (block.Offset + block.Size < _persistedOffset + _size) { // we have a new non empty suffix; long newBlockOffset = block.Offset + block.Size; long newBlockSize = _persistedOffset + _size - newBlockOffset; suffixBlock = Assign(_blockManager, newBlockOffset, newBlockSize); } } }
internal void SplitIntoPrefixSuffix(IZipIOBlock block, out ZipIORawDataFileBlock prefixBlock, out ZipIORawDataFileBlock suffixBlock) { // assert that current's block cache isn't loaded, if it is // we probably missed an opportunity to used this cache in order to parse the new block // and it might be based on the overriden data on disk // This block can only be in cached state as a part of single BlockManager.Save execution. // It can NOT be in cached state prior to BlockManager.Save function entry or after // BlockManager.Save execution completed Debug.Assert(_cachePrefixStream == null); // Assert that block is containe inside the current raw block Debug.Assert(DiskImageContains(block)); checked { prefixBlock = null; suffixBlock = null; if (block.Offset > _persistedOffset) { // we have a new non empty prefix; long newBlockOffset = _persistedOffset; long newBlockSize = block.Offset - _persistedOffset; prefixBlock = Assign(_blockManager, newBlockOffset , newBlockSize); } if (block.Offset + block.Size < _persistedOffset + _size) { // we have a new non empty suffix; long newBlockOffset = block.Offset + block.Size; long newBlockSize = _persistedOffset + _size - newBlockOffset; suffixBlock = Assign(_blockManager, newBlockOffset, newBlockSize); } } }
//----------------------------------------------------- // // Internal Methods // //----------------------------------------------------- internal static ZipIORawDataFileBlock Assign(ZipIOBlockManager blockManager, long offset, long size) { if (size <= 0) { throw new ArgumentOutOfRangeException ("size"); } if (offset < 0) { throw new ArgumentOutOfRangeException ("offset"); } ZipIORawDataFileBlock block = new ZipIORawDataFileBlock(blockManager); block._persistedOffset = offset; block._offset = offset; block._size = size; return block; }