diff --git a/src/AddIns/DisplayBindings/HexEditor/Project/HexEditor.csproj b/src/AddIns/DisplayBindings/HexEditor/Project/HexEditor.csproj index 4e8905d59a..d9494fbf6e 100644 --- a/src/AddIns/DisplayBindings/HexEditor/Project/HexEditor.csproj +++ b/src/AddIns/DisplayBindings/HexEditor/Project/HexEditor.csproj @@ -69,7 +69,6 @@ - diff --git a/src/AddIns/DisplayBindings/HexEditor/Project/Src/Editor.cs b/src/AddIns/DisplayBindings/HexEditor/Project/Src/Editor.cs index d24443df1f..ab8113e888 100644 --- a/src/AddIns/DisplayBindings/HexEditor/Project/Src/Editor.cs +++ b/src/AddIns/DisplayBindings/HexEditor/Project/Src/Editor.cs @@ -169,7 +169,7 @@ namespace HexEditor case Keys.Up: case Keys.Left: case Keys.Right: - //case Keys.Tab: + case Keys.Tab: return true; } return false; @@ -1014,14 +1014,14 @@ namespace HexEditor buffer.RemoveBytes(start, Math.Abs(selection.End - selection.Start)); buffer.SetBytes(start, this.Encoding.GetBytes(text.ToCharArray()), false); - undoStack.AddOverwriteStep(caret.Offset, this.Encoding.GetBytes(text.ToCharArray()), old); + undoStack.AddOverwriteStep(start, this.Encoding.GetBytes(text.ToCharArray()), old); caret.Offset = start + ClipboardManager.Paste().Length; selection.Clear(); } else { buffer.SetBytes(caret.Offset, this.Encoding.GetBytes(text.ToCharArray()), false); - undoStack.AddInsertStep(caret.Offset, this.Encoding.GetBytes(text.ToCharArray())); + undoStack.AddRemoveStep(caret.Offset, this.Encoding.GetBytes(text.ToCharArray())); caret.Offset += ClipboardManager.Paste().Length; } @@ -1334,7 +1334,7 @@ namespace HexEditor buffer.RemoveByte(caret.Offset); - undoStack.AddRemoveStep(caret.Offset, new byte[] {b}); + undoStack.AddInsertStep(caret.Offset, new byte[] {b}); if (GetLineForOffset(caret.Offset) < this.topline) this.topline = GetLineForOffset(caret.Offset); if (GetLineForOffset(caret.Offset) > this.topline + this.GetMaxVisibleLines() - 2) this.topline = GetLineForOffset(caret.Offset) - this.GetMaxVisibleLines() + 2; @@ -1347,6 +1347,13 @@ namespace HexEditor case Keys.ShiftKey: case Keys.ControlKey: break; + case Keys.Tab: + if (this.activeView == this.hexView) + this.activeView = this.textView; + else + this.activeView = this.hexView; + this.handled = true; + break; default: byte asc = (byte)e.KeyValue; @@ -1421,11 +1428,10 @@ namespace HexEditor if (GetLineForOffset(caret.Offset) > this.topline + this.GetMaxVisibleLines() - 2) this.topline = GetLineForOffset(caret.Offset) - this.GetMaxVisibleLines() + 2; VScrollBar.Value = this.topline; - if (insertmode) { - undoStack.AddRemoveStep(caret.Offset, new byte[] {(byte)e.KeyChar}); - } else { - undoStack.AddOverwriteStep(caret.Offset, new byte[] {(byte)e.KeyChar}, old); - } + if (insertmode) + undoStack.AddRemoveStep(caret.Offset - 1, new byte[] {(byte)e.KeyChar}); + else + undoStack.AddOverwriteStep(caret.Offset - 1, new byte[] {(byte)e.KeyChar}, old); } caret.SetToPosition(GetPositionForOffset(caret.Offset, charwidth)); diff --git a/src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/BufferManager.cs b/src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/BufferManager.cs index 4f52960378..8b055e3cdd 100644 --- a/src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/BufferManager.cs +++ b/src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/BufferManager.cs @@ -7,10 +7,15 @@ using System; using System.IO; +using System.Collections; +using System.Text; using System.Windows.Forms; +using System.Diagnostics; +using System.ComponentModel; +using System.Threading; -using ICSharpCode.Core; using ICSharpCode.SharpDevelop; +using ICSharpCode.Core; namespace HexEditor.Util { @@ -19,19 +24,34 @@ namespace HexEditor.Util /// public class BufferManager { - Editor parent; + internal Control parent; OpenedFile currentFile; + Stream stream; - StreamedList data; + /// + /// Currently used, but not good for really big files (like 590 MB) + /// + private ArrayList buffer; /// /// Creates a new BufferManager and attaches it to a control. /// /// The parent control to attach to. - public BufferManager(Editor parent) + public BufferManager(Control parent) { this.parent = parent; - this.data = new StreamedList(); + + this.buffer = new ArrayList(); + } + + /// + /// Cleares the whole buffer. + /// + public void Clear() + { + this.buffer.Clear(); + parent.Invalidate(); + GC.Collect(); } /// @@ -40,32 +60,44 @@ namespace HexEditor.Util public void Load(OpenedFile file, Stream stream) { this.currentFile = file; + this.stream = stream; + this.buffer.Clear(); - this.data.Clear(); - this.data = new StreamedList(); - - stream.Position = 0; - byte[] bytes = new byte[512000]; + ((Editor)this.parent).Enabled = false; if (File.Exists(currentFile.FileName)) { - int count = 0; - do { - count = stream.Read(bytes, 0, bytes.Length); - if (count > 0) { - this.data.AddRange(bytes, count); - // Maybe not a good solution, but easier than implementing a complete thread - // A thread would need to reopen the file in the thread - // because it is closed after the CreateContentForFile() has - // finished. - Application.DoEvents(); - GC.Collect(); + try { + BinaryReader reader = new BinaryReader(this.stream, System.Text.Encoding.Default); + + while (reader.PeekChar() != -1) { + this.buffer.AddRange(reader.ReadBytes(524288)); + UpdateProgress((int)((this.buffer.Count * 100) / reader.BaseStream.Length)); } - } while (count > 0); + + reader.Close(); + } catch (Exception) { + MessageService.ShowErrorFormatted("${res:FileUtilityService.ErrorWhileLoading}", currentFile.FileName); + } } else { MessageService.ShowErrorFormatted("${res:Fileutility.CantFindFileError}", currentFile.FileName); } this.parent.Invalidate(); + + UpdateProgress(100); + + if (this.parent.InvokeRequired) + this.parent.Invoke(new MethodInvoker( + delegate() {this.parent.Cursor = Cursors.Default;} + )); + else {this.parent.Cursor = Cursors.Default;} + + + ((Editor)this.parent).LoadingFinished(); + + ((Editor)this.parent).Enabled = true; + + this.parent.Invalidate(); } /// @@ -73,43 +105,90 @@ namespace HexEditor.Util /// public void Save(OpenedFile file, Stream stream) { - this.data.ConcatenateTo(stream); + BinaryWriter writer = new BinaryWriter(stream); + writer.Write((byte[])this.buffer.ToArray( typeof (byte) )); + writer.Flush(); } /// - /// The size of the current buffer. + /// Used for threading to update the processbars and stuff. /// - public int BufferSize { + /// The current percentage of the process + private void UpdateProgress(int percentage) + { + Editor c = (Editor)this.parent; + + Application.DoEvents(); + + if (c.ProgressBar != null) { + if (percentage >= 100) { + if (c.InvokeRequired) + c.Invoke(new MethodInvoker( + delegate() {c.ProgressBar.Value = 100; c.ProgressBar.Visible = false;} + )); + else { + c.ProgressBar.Value = 100; + c.ProgressBar.Visible = false; } + } else { + if (c.InvokeRequired) + c.Invoke(new MethodInvoker( + delegate() {c.ProgressBar.Value = percentage; c.ProgressBar.Visible = true;} + )); + else { c.ProgressBar.Value = percentage; c.ProgressBar.Visible = true; } + } + } + } + + /// + /// Returns the current buffer as a byte[]. + /// + public byte[] Buffer { get { - return this.data.Count; + if (buffer == null) return new byte[0]; + return (byte[]) buffer.ToArray( typeof ( byte ) ); } } + + /// + /// The size of the current buffer. + /// + public int BufferSize { + get { return buffer.Count; } + } #region Methods + public byte[] GetBytes(int start, int count) { - if (this.BufferSize == 0) return new byte[] {}; + if (buffer.Count == 0) return new byte[] {}; if (start < 0) start = 0; - if (start >= this.BufferSize) start = this.BufferSize; + if (start >= buffer.Count) start = buffer.Count; if (count < 1) count = 1; - if (count >= (this.BufferSize - start)) count = (this.BufferSize - start); - - return this.data.GetRange(start, count); + if (count >= (buffer.Count - start)) count = (buffer.Count - start); + return (byte[])(buffer.GetRange(start, count).ToArray( typeof ( byte ) )); } public byte GetByte(int offset) { - if (this.BufferSize == 0) return 0; + if (buffer.Count == 0) return 0; if (offset < 0) offset = 0; - if (offset >= this.BufferSize) offset = this.BufferSize; - - return this.data[offset]; + if (offset >= buffer.Count) offset = buffer.Count - 1; + return (byte)buffer[offset]; + } + + public bool DeleteByte(int offset) + { + if ((offset < buffer.Count) & (offset > -1)) { + buffer.RemoveAt(offset); + return true; + } + return false; } public bool RemoveByte(int offset) { - if ((offset < this.BufferSize) & (offset > -1)) { - data.RemoveAt(offset); + if ((offset < buffer.Count) & (offset > -1)) { + buffer.RemoveAt(offset); return true; } return false; @@ -117,45 +196,34 @@ namespace HexEditor.Util public bool RemoveBytes(int offset, int length) { - if (((offset < this.BufferSize) && (offset > -1)) && ((offset + length) <= this.BufferSize)) { - if ((offset == 0) && (length == data.Count)) { - this.data.Clear(); - this.data = new StreamedList(); - } else { - this.data.RemoveRange(offset, length); - } + if (((offset < buffer.Count) && (offset > -1)) && ((offset + length) <= buffer.Count)) { + buffer.RemoveRange(offset, length); return true; } return false; } + /// Not Tested! public void SetBytes(int start, byte[] bytes, bool overwrite) { if (overwrite) { - foreach (byte b in bytes) - { - data[start] = b; - start++; - } + if (bytes.Length > buffer.Count) buffer.AddRange(new byte[bytes.Length - buffer.Count]); + buffer.SetRange(start, bytes); } else { - foreach (byte b in bytes) - { - data.Insert(start, b); - start++; - } + buffer.InsertRange(start, bytes); } } public void SetByte(int position, byte @byte, bool overwrite) { if (overwrite) { - data[position] = @byte; - } else { - if (position == data.Count) { - data.Add(@byte); + if (position > buffer.Count - 1) { + buffer.Add(@byte); } else { - data.Insert(position, @byte); + buffer[position] = @byte; } + } else { + buffer.Insert(position, @byte); } } #endregion diff --git a/src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/StreamedList.cs b/src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/StreamedList.cs deleted file mode 100644 index 4cb65df5ad..0000000000 --- a/src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/StreamedList.cs +++ /dev/null @@ -1,287 +0,0 @@ -// -// -// -// -// $Revision: 2995 $ -// - -using System; -using System.Collections.Generic; -using System.IO; - -using ICSharpCode.Core; - -namespace HexEditor.Util -{ - public class StreamedList : IList - { - List streams; - - int maxStreamLength = 25 * 1024 * 1024; - - public StreamedList() - { - this.streams = new List(); - this.streams.Add(new FileStream(Path.GetTempFileName(), FileMode.Create)); - } - - ~StreamedList() - { - this.Clear(); - } - - private long GetStreamPosition(long index, out int streamNumber) - { - streamNumber = -1; - - // Convert 0-based to 1-based. - index++; - - if (index > 255) { - Console.WriteLine("Test"); - } - for (int i = 0; i < streams.Count; i++) { - LoggingService.Info("Länge stream " + i + ": " + streams[i].Length + " current index: " + index); - if (index <= streams[i].Length) { - streamNumber = i; - return index - 1; - } else { - index -= streams[i].Length; - } - } - - LoggingService.Info("Fail!"); - return -1; - } - - private int GetIndex(int position, int stream) - { - int index = 0; - - for (int i = 0; i < stream; i++) { - index += (int)streams[i].Length; - } - return index + position; - } - - private long GetLength() - { - long length = 0; - foreach (FileStream stream in streams) - { - length += stream.Length; - } - - return length; - } - - public byte this[int index] - { - get { - int stream = -1; - int newIndex = (int)GetStreamPosition((long)index, out stream); - - this.streams[stream].Position = newIndex; - return (byte)this.streams[stream].ReadByte(); - } - set { - int stream = -1; - index = (int)GetStreamPosition((long)index, out stream); - - this.streams[stream].Position = index; - this.streams[stream].WriteByte(value); - } - } - - public byte[] GetRange(int index, int count) - { - if (count == 0) - return new byte[0]; - int stream = -1; - int newIndex = (int)GetStreamPosition((long)index, out stream); - - this.streams[stream].Position = newIndex; - - byte[] data = new byte[count]; - - if (newIndex + count < this.streams[stream].Length) { - this.streams[stream].Read(data, 0, count); - } else { - int offset = (int)this.streams[stream].Length - newIndex; - this.streams[stream].Read(data, 0, offset); - if (stream < this.streams.Count - 1) { - stream++; - this.streams[stream].Read(data, offset, count - offset); - } - } - - return data; - } - - public int Count { - get { - return (int)GetLength(); - } - } - - public bool IsReadOnly { - get { - return false; - } - } - - public int IndexOf(byte item) - { - for(int i = 0; i < streams.Count; i++) - { - for (int j = 0; j < streams[i].Length; j++) { - streams[i].Position = j; - if (streams[i].ReadByte() == item) { - return GetIndex(j, i); - } - } - } - - return -1; - } - - public void Insert(int index, byte item) - { - int stream = -1; - index = (int)GetStreamPosition(index, out stream); - byte[] bytes = CopyTo(stream, index, (int)this.streams[stream].Length - index - 1); - - this.streams[stream].Position = index; - this.streams[stream].WriteByte(item); - this.streams[stream].SetLength(this.streams[stream].Length + 1); - this.streams[stream].Write(bytes, 0, bytes.Length); - } - - public void RemoveAt(int index) - { - int stream = -1; - int newIndex = (int)GetStreamPosition(index, out stream); - if (index == 0) - newIndex = 0; - - byte[] bytes = CopyTo(stream, newIndex + 1, (int)this.streams[stream].Length - newIndex - 1); - - this.streams[stream].Position = newIndex; - this.streams[stream].SetLength(this.streams[stream].Length - 1); - this.streams[stream].Write(bytes, 0, bytes.Length); - } - - public void RemoveRange(int start, int count) - { - int stream = -1; - int newIndex = (int)GetStreamPosition(start, out stream); - if (start == 0) - newIndex = 0; - - byte[] bytes = CopyTo(stream, newIndex + count, (int)this.streams[stream].Length - newIndex - count); - - this.streams[stream].Position = newIndex; - this.streams[stream].SetLength(this.streams[stream].Length - count); - this.streams[stream].Write(bytes, 0, bytes.Length); - } - - public void Add(byte item) - { - if (this.streams[this.streams.Count - 1].Length > maxStreamLength) { - this.streams.Add(new FileStream(Path.GetTempFileName(), FileMode.Create)); - } - - this.streams[this.streams.Count - 1].Position - = this.streams[this.streams.Count - 1].Length; - this.streams[this.streams.Count - 1].WriteByte(item); - } - - public void Clear() - { - foreach (FileStream s in streams) - { - s.Close(); - File.Delete(s.Name); - } - this.streams.Clear(); - } - - public bool Contains(byte item) - { - throw new NotImplementedException(); - } - - public void CopyTo(byte[] array, int arrayIndex) - { - throw new NotImplementedException(); - } - - private byte[] CopyTo(int stream, int start, int count) - { - byte[] data = new byte[count]; - - this.streams[stream].Position = start; - this.streams[stream].Read(data, 0, count); - - return data; - } - - public bool Remove(byte item) - { - throw new NotImplementedException(); - } - - public IEnumerator GetEnumerator() - { - throw new NotImplementedException(); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - throw new NotImplementedException(); - } - - public void AddRange(byte[] data) - { - if (this.streams[this.streams.Count - 1].Length > maxStreamLength) { - LoggingService.Info("Stream added!"); - this.streams.Add(new FileStream(Path.GetTempFileName(), FileMode.Create)); - } - - this.streams[this.streams.Count - 1].Position - = this.streams[this.streams.Count - 1].Length; - this.streams[this.streams.Count - 1].SetLength(this.streams[this.streams.Count - 1].Length + data.Length); - this.streams[this.streams.Count - 1].Write(data, 0, data.Length); - LoggingService.Info("Wrote " + data.Length + " bytes"); - } - - internal void AddRange(byte[] data, int readBytes) - { - if (this.streams[this.streams.Count - 1].Length > maxStreamLength) { - LoggingService.Info("Stream added!"); - this.streams.Add(new FileStream(Path.GetTempFileName(), FileMode.Create)); - } - - this.streams[this.streams.Count - 1].Position - = this.streams[this.streams.Count - 1].Length; - this.streams[this.streams.Count - 1].SetLength(this.streams[this.streams.Count - 1].Length + readBytes); - this.streams[this.streams.Count - 1].Write(data, 0, readBytes); - LoggingService.Info("Wrote " + readBytes + " bytes"); - } - - public void ConcatenateTo(Stream stream) - { - stream.SetLength(this.Count); - foreach (FileStream fs in this.streams) - { - fs.Position = 0; - byte[] tmp = new byte[fs.Length]; - - fs.Read(tmp, 0, tmp.Length); - - stream.Write(tmp, 0, tmp.Length); - } - } - } -} -