System.Windows.Forms.DynamicFileByteProvider.ApplyChanges C# (CSharp) Method

ApplyChanges() public method

See IByteProvider.ApplyChanges for more information.
public ApplyChanges ( ) : void
return void
        public void ApplyChanges()
        {
            if (_readOnly)
                throw new OperationCanceledException("File is in read-only mode");

            // This method is implemented to efficiently save the changes to the same file stream opened for reading.
            // Saving to a separate file would be a much simpler implementation.

            // Firstly, extend the file length (if necessary) to ensure that there is enough disk space.
            if (_totalLength > _fileStream.Length)
            {
                _fileStream.SetLength(_totalLength);
            }

            // Secondly, shift around any file sections that have moved.
            long dataOffset = 0;
            for (DataBlock block = _dataMap.FirstBlock; block != null; block = block.NextBlock)
            {
                FileDataBlock fileBlock = block as FileDataBlock;
                if (fileBlock != null && fileBlock.FileOffset != dataOffset)
                {
                    MoveFileBlock(fileBlock, dataOffset);
                }
                dataOffset += block.Length;
            }

            // Next, write in-memory changes.
            dataOffset = 0;
            for (DataBlock block = _dataMap.FirstBlock; block != null; block = block.NextBlock)
            {
                MemoryDataBlock memoryBlock = block as MemoryDataBlock;
                if (memoryBlock != null)
                {
                    _fileStream.Position = dataOffset;
                    for (int memoryOffset = 0; memoryOffset < memoryBlock.Length; memoryOffset += COPY_BLOCK_SIZE)
                    {
                        _fileStream.Write(memoryBlock.Data, memoryOffset, (int)Math.Min(COPY_BLOCK_SIZE, memoryBlock.Length - memoryOffset));
                    }
                }
                dataOffset += block.Length;
            }

            // Finally, if the file has shortened, truncate the stream.
            _fileStream.SetLength(_totalLength);
            ReInitialize();
        }

Usage Example

        private void Apply()
        {
            if (hexBox1.ByteProvider == null)
            {
                return;
            }

            try
            {
                if (_section._isBSSSection != chkBSSSection.Checked || _section._isCodeSection != chkCodeSection.Checked)
                {
                    _section._isBSSSection  = chkBSSSection.Checked;
                    _section._isCodeSection = chkCodeSection.Checked;
                    _section.SignalPropertyChange();
                }

                if (_section.Root is RELNode)
                {
                    RELNode r = _section.Root as RELNode;

                    if (r._prologSect == _section.Index && r._prologIndex != _manager._constructorIndex)
                    {
                        //if (r._prologReloc != null)
                        //    r._prologReloc._prolog = false;

                        r._prologIndex = _manager._constructorIndex;
                        r.SignalPropertyChange();
                    }

                    if (r._prologSect == _section.Index && r._epilogIndex != _manager._destructorIndex)
                    {
                        //if (r._epilogReloc != null)
                        //    r._epilogReloc._epilog = false;

                        r._epilogIndex = _manager._destructorIndex;
                        r.SignalPropertyChange();
                    }

                    if (r._prologSect == _section.Index && r._unresIndex != _manager._unresolvedIndex)
                    {
                        //if (r._unresReloc != null)
                        //    r._unresReloc._unresolved = false;

                        r._unresIndex = _manager._unresolvedIndex;
                        r.SignalPropertyChange();
                    }
                }

                DynamicFileByteProvider d = hexBox1.ByteProvider as DynamicFileByteProvider;
                if (!d.HasChanges())
                {
                    return;
                }

                UnsafeBuffer newBuffer = new UnsafeBuffer((int)d.Length);

                int amt = Math.Min(_section._dataBuffer.Length, newBuffer.Length);
                if (amt > 0)
                {
                    Memory.Move(newBuffer.Address, _section._dataBuffer.Address, (uint)amt);
                    if (newBuffer.Length - amt > 0)
                    {
                        Memory.Fill(newBuffer.Address + amt, (uint)(newBuffer.Length - amt), 0);
                    }
                }

                if (d._stream != null)
                {
                    d._stream.Dispose();
                }
                d._stream = new UnmanagedMemoryStream((byte *)newBuffer.Address, newBuffer.Length, newBuffer.Length, FileAccess.ReadWrite);

                d.ApplyChanges();

                _section._dataBuffer.Dispose();
                _section._dataBuffer = newBuffer;
                _section.SignalPropertyChange();

                //if (_relocationsChanged)
                //{
                //    Relocation[] temp = new Relocation[_relocations.Count];
                //    _relocations.CopyTo(temp);
                //    List<Relocation> temp2 = temp.ToList();

                //    _section._relocations = temp2;
                //    _section._firstCommand = _firstCommand;

                //    ResourceNode a = _section.Root;
                //    if (a != null && a != _section.Root)
                //        a.SignalPropertyChange();
                //}

                hexBox1.Invalidate();
                hexBox1.Focus();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            finally
            {
                EnableButtons();
            }
        }