Browse Source

Improved buffer management of the hex editor. Now it uses a "StreamedList" --> a list with a file split up in single stream files.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3085 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Siegfried Pammer 18 years ago
parent
commit
46796f4daf
  1. 8
      src/AddIns/DisplayBindings/HexEditor/HexEditor.sln
  2. 2
      src/AddIns/DisplayBindings/HexEditor/Project/HexEditor.csproj
  3. 127
      src/AddIns/DisplayBindings/HexEditor/Project/Src/Editor.cs
  4. 221
      src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/BufferManager.cs
  5. 134
      src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/Change.cs
  6. 51
      src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/ClipboardManager.cs
  7. 287
      src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/StreamedList.cs
  8. 2
      src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/UndoAction.cs
  9. 20
      src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/UndoManager.cs
  10. 2
      src/AddIns/DisplayBindings/HexEditor/Project/Src/View/HexEditContainer.cs
  11. 5
      src/AddIns/DisplayBindings/HexEditor/Project/changes.txt

8
src/AddIns/DisplayBindings/HexEditor/HexEditor.sln

@ -1,13 +1,15 @@ @@ -1,13 +1,15 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
# SharpDevelop 3.0.0.2956
# SharpDevelop 3.0.0.3014
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HexEditor", "Project\HexEditor.csproj", "{E618A9CD-A39F-4925-A538-E8A3FEF24E54}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop", "..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj", "{2748AD25-9C63-4E12-877B-4DCE96FBED54}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core", "..\..\..\Main\Core\Project\ICSharpCode.Core.csproj", "{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HexEditor.Tests", "..\..\..\..\..\HexEditor.Tests\HexEditor.Tests.csproj", "{65F6998A-98F4-48BA-AE98-0CB5B38FDC58}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -26,5 +28,9 @@ Global @@ -26,5 +28,9 @@ Global
{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Release|Any CPU.Build.0 = Release|Any CPU
{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65F6998A-98F4-48BA-AE98-0CB5B38FDC58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65F6998A-98F4-48BA-AE98-0CB5B38FDC58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{65F6998A-98F4-48BA-AE98-0CB5B38FDC58}.Release|Any CPU.Build.0 = Release|Any CPU
{65F6998A-98F4-48BA-AE98-0CB5B38FDC58}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
EndGlobal

2
src/AddIns/DisplayBindings/HexEditor/Project/HexEditor.csproj

@ -67,9 +67,9 @@ @@ -67,9 +67,9 @@
</Compile>
<Compile Include="Src\Util\BufferManager.cs" />
<Compile Include="Src\Util\Caret.cs" />
<Compile Include="Src\Util\Change.cs" />
<Compile Include="Src\Util\ClipboardManager.cs" />
<Compile Include="Src\Util\Settings.cs" />
<Compile Include="Src\Util\StreamedList.cs" />
<Compile Include="Src\Util\UndoAction.cs" />
<Compile Include="Src\Util\UndoEventArgs.cs" />
<Compile Include="Src\Util\UndoStep.cs" />

127
src/AddIns/DisplayBindings/HexEditor/Project/Src/Editor.cs

@ -42,6 +42,8 @@ namespace HexEditor @@ -42,6 +42,8 @@ namespace HexEditor
int underscorewidth, underscorewidth3, fontheight;
bool insertmode, hexinputmode, selectionmode, handled, moved;
Point oldMousePos = new Point(0,0);
Settings settings;
Rectangle[] selregion;
@ -52,6 +54,7 @@ namespace HexEditor @@ -52,6 +54,7 @@ namespace HexEditor
public Caret Caret {
get { return caret; }
}
SelectionManager selection;
UndoManager undoStack;
@ -135,10 +138,6 @@ namespace HexEditor @@ -135,10 +138,6 @@ namespace HexEditor
}
#region Measure functions
/*
* Code from SharpDevelop TextEditor
* */
static int GetFontHeight(Font font)
{
int height1 = TextRenderer.MeasureText("_", font).Height;
@ -148,18 +147,10 @@ namespace HexEditor @@ -148,18 +147,10 @@ namespace HexEditor
static int MeasureStringWidth(Graphics g, string word, Font font)
{
// This code here provides better results than MeasureString!
// Example line that is measured wrong:
// txt.GetPositionFromCharIndex(txt.SelectionStart)
// (Verdana 10, highlighting makes GetP... bold) -> note the space between 'x' and '('
// this also fixes "jumping" characters when selecting in non-monospace fonts
// [...]
// Replaced GDI+ measurement with GDI measurement: faster and even more exact
return TextRenderer.MeasureText(g, word, font, new Size(short.MaxValue, short.MaxValue),
TextFormatFlags.NoPadding | TextFormatFlags.NoPrefix |
TextFormatFlags.PreserveGraphicsClipping).Width;
}
#endregion
/// <summary>
@ -412,8 +403,6 @@ namespace HexEditor @@ -412,8 +403,6 @@ namespace HexEditor
protected override void OnMouseWheel(MouseEventArgs e)
{
base.OnMouseWheel(e);
if (!this.VScrollBar.Enabled) return;
@ -458,13 +447,7 @@ namespace HexEditor @@ -458,13 +447,7 @@ namespace HexEditor
moved = false;
return;
}
} else {
this.Invalidate();
}
caret.Offset = this.GetOffsetForPosition(e.Location, 3);
caret.SetToPosition(GetPositionForOffset(caret.Offset, 3));
this.Invalidate();
}
/// <summary>
@ -496,9 +479,6 @@ namespace HexEditor @@ -496,9 +479,6 @@ namespace HexEditor
this.charwidth = 1;
this.caret.Width = 1;
if (!insertmode) this.caret.Width = underscorewidth;
caret.Offset = this.GetOffsetForPosition(e.Location, 1);
caret.SetToPosition(GetPositionForOffset(caret.Offset, 1));
this.Invalidate();
}
#endregion
@ -1034,19 +1014,15 @@ namespace HexEditor @@ -1034,19 +1014,15 @@ namespace HexEditor
if (selection.Start > selection.End) start = selection.End;
buffer.RemoveBytes(start, Math.Abs(selection.End - selection.Start));
buffer.SetBytes(start, this.Encoding.GetBytes(text.ToCharArray()), false);
UndoAction action = UndoAction.Overwrite;
undoStack.AddUndoStep(new UndoStep(this.Encoding.GetBytes(text.ToCharArray()), old, caret.Offset, action));
undoStack.AddOverwriteStep(caret.Offset, 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);
UndoAction action = UndoAction.Remove;
undoStack.AddUndoStep(new UndoStep(this.Encoding.GetBytes(text.ToCharArray()), null, caret.Offset, action));
undoStack.AddInsertStep(caret.Offset, this.Encoding.GetBytes(text.ToCharArray()));
caret.Offset += ClipboardManager.Paste().Length;
}
@ -1072,9 +1048,7 @@ namespace HexEditor @@ -1072,9 +1048,7 @@ namespace HexEditor
buffer.RemoveBytes(selection.Start, Math.Abs(selection.End - selection.Start));
caret.Offset = selection.Start;
UndoAction action = UndoAction.Add;
undoStack.AddUndoStep(new UndoStep(old, null, selection.Start, action));
undoStack.AddInsertStep(selection.Start, old);
selection.Clear();
}
@ -1084,7 +1058,6 @@ namespace HexEditor @@ -1084,7 +1058,6 @@ namespace HexEditor
OnDocumentChanged(e2);
}
#endregion
#region TextProcessing
/// <summary>
@ -1327,9 +1300,7 @@ namespace HexEditor @@ -1327,9 +1300,7 @@ namespace HexEditor
buffer.RemoveBytes(start, Math.Abs(end - start));
caret.Offset = start;
UndoAction action = UndoAction.Add;
undoStack.AddUndoStep(new UndoStep(bytes, null, start, action));
undoStack.AddInsertStep(start, bytes);
selection.Clear();
} else {
@ -1341,9 +1312,7 @@ namespace HexEditor @@ -1341,9 +1312,7 @@ namespace HexEditor
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;
UndoAction action = UndoAction.Add;
undoStack.AddUndoStep(new UndoStep(new byte[] {b}, null, caret.Offset, action));
undoStack.AddInsertStep(caret.Offset, new byte[] {b});
}
}
@ -1357,10 +1326,8 @@ namespace HexEditor @@ -1357,10 +1326,8 @@ namespace HexEditor
byte[] old = selection.GetSelectionBytes();
buffer.RemoveBytes(start, Math.Abs(selection.End - selection.Start));
caret.Offset = selection.Start;
UndoAction action = UndoAction.Add;
undoStack.AddUndoStep(new UndoStep(old, null, selection.Start, action));
undoStack.AddInsertStep(selection.Start, old);
selection.Clear();
} else {
@ -1368,9 +1335,7 @@ namespace HexEditor @@ -1368,9 +1335,7 @@ namespace HexEditor
buffer.RemoveByte(caret.Offset);
UndoAction action = UndoAction.Remove;
undoStack.AddUndoStep(new UndoStep(new byte[] {b}, null, caret.Offset, action));
undoStack.AddRemoveStep(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;
@ -1457,16 +1422,11 @@ namespace HexEditor @@ -1457,16 +1422,11 @@ namespace HexEditor
if (GetLineForOffset(caret.Offset) > this.topline + this.GetMaxVisibleLines() - 2) this.topline = GetLineForOffset(caret.Offset) - this.GetMaxVisibleLines() + 2;
VScrollBar.Value = this.topline;
UndoAction action;
if (insertmode) {
action = UndoAction.Remove;
old = null;
undoStack.AddRemoveStep(caret.Offset, new byte[] {(byte)e.KeyChar});
} else {
action = UndoAction.Overwrite;
undoStack.AddOverwriteStep(caret.Offset, new byte[] {(byte)e.KeyChar}, old);
}
undoStack.AddUndoStep(new UndoStep(new byte[] {(byte)e.KeyChar}, old, caret.Offset - 1, action));
}
caret.SetToPosition(GetPositionForOffset(caret.Offset, charwidth));
@ -1581,9 +1541,7 @@ namespace HexEditor @@ -1581,9 +1541,7 @@ namespace HexEditor
// if @in is like 4 or A then make 04 or 0A out of it.
if (@in.Length == 1) @in = "0" + @in;
UndoAction action = UndoAction.Overwrite;
undoStack.AddUndoStep(new UndoStep(new byte[] {(byte)(Convert.ToInt32(@in.Remove(1) + ((char)(input.KeyValue)).ToString(), 16))}, buffer.GetBytes(caret.Offset, 1), caret.Offset, action));
undoStack.AddOverwriteStep(caret.Offset, new byte[] {(byte)(Convert.ToInt32(@in.Remove(1) + ((char)(input.KeyValue)).ToString(), 16))}, buffer.GetBytes(caret.Offset, 1));
@in = @in.Remove(1) + ((char)(input.KeyValue)).ToString();
hexinputmodepos = 0;
@ -1621,6 +1579,7 @@ namespace HexEditor @@ -1621,6 +1579,7 @@ namespace HexEditor
if (hexinputmodepos == 1) {
byte[] _old = buffer.GetBytes(caret.Offset, 1);
@in = string.Format("{0:X}", buffer.GetByte(caret.Offset));
if (@in.Length == 1) @in = "0" + @in;
@in = @in.Remove(1) + ((char)(input.KeyValue)).ToString();
hexinputmodepos = 0;
hexinputmode = false;
@ -1628,7 +1587,7 @@ namespace HexEditor @@ -1628,7 +1587,7 @@ namespace HexEditor
caret.Offset++;
if (insertmode) {
action = UndoAction.Add;
action = UndoAction.Insert;
_old = null;
} else {
action = UndoAction.Overwrite;
@ -1645,7 +1604,7 @@ namespace HexEditor @@ -1645,7 +1604,7 @@ namespace HexEditor
hexinputmodepos = 1;
if (insertmode) {
action = UndoAction.Add;
action = UndoAction.Insert;
_old = null;
} else {
action = UndoAction.Overwrite;
@ -1719,7 +1678,6 @@ namespace HexEditor @@ -1719,7 +1678,6 @@ namespace HexEditor
/// </summary>
private void HexEditGotFocus(object sender, EventArgs e)
{
//LoadSettings();
this.Invalidate();
}
@ -1732,35 +1690,31 @@ namespace HexEditor @@ -1732,35 +1690,31 @@ namespace HexEditor
void TextViewMouseDown(object sender, MouseEventArgs e)
{
this.activeView = this.textView;
this.hexinputmode = false;
this.hexinputmodepos = 0;
if (e.Button == MouseButtons.Left) {
if (selection.HasSomethingSelected) {
selection.Start = 0;
selection.End = 0;
PaintText(this.textView.CreateGraphics(), this.topline);
}
selectionmode = true;
selection.Start = GetOffsetForPosition(e.Location, 1);
}
caret.Offset = GetOffsetForPosition(e.Location, 1);
caret.SetToPosition(GetPositionForOffset(caret.Offset, this.charwidth));
}
void TextViewMouseMove(object sender, MouseEventArgs e)
{
if ((e.Button == MouseButtons.Left) & selectionmode) {
if ((e.Button == MouseButtons.Left) && selectionmode && (e.Location != oldMousePos)) {
int end = selection.End;
selection.End = GetOffsetForPosition(e.Location, 1);
this.activeView = this.textView;
moved = true;
selection.HasSomethingSelected = true;
if (end != selection.End) this.Invalidate();
caret.Offset = GetOffsetForPosition(e.Location, 1);
caret.SetToPosition(GetPositionForOffset(caret.Offset, this.charwidth));
this.Invalidate();
}
oldMousePos = e.Location;
}
void TextViewMouseUp(object sender, MouseEventArgs e)
@ -1772,7 +1726,6 @@ namespace HexEditor @@ -1772,7 +1726,6 @@ namespace HexEditor
selection.HasSomethingSelected = false;
selectionmode = false;
}
this.Invalidate();
} else {
if (!moved) {
selection.HasSomethingSelected = false;
@ -1785,38 +1738,36 @@ namespace HexEditor @@ -1785,38 +1738,36 @@ namespace HexEditor
caret.SetToPosition(GetPositionForOffset(caret.Offset, this.charwidth));
selectionmode = false;
this.Invalidate();
}
void HexViewMouseDown(object sender, MouseEventArgs e)
{
this.activeView = this.hexView;
this.hexinputmode = false;
this.hexinputmodepos = 0;
if (e.Button == MouseButtons.Left) {
selectionmode = true;
selection.Start = GetOffsetForPosition(e.Location, 3);
selection.End = GetOffsetForPosition(e.Location, 3);
this.Invalidate();
caret.Offset = GetOffsetForPosition(e.Location, 3);
caret.SetToPosition(GetPositionForOffset(caret.Offset, this.charwidth));
}
}
void HexViewMouseMove(object sender, MouseEventArgs e)
{
if ((e.Button == MouseButtons.Left) & selectionmode) {
if ((e.Button == MouseButtons.Left) && selectionmode && (e.Location != oldMousePos)) {
int end = selection.End;
selection.End = GetOffsetForPosition(e.Location, 3);
selection.HasSomethingSelected = true;
this.activeView = this.hexView;
moved = true;
caret.SetToPosition(GetPositionForOffset(GetOffsetForPosition(e.Location, 3), 3));
if (end != selection.End) this.Invalidate();
caret.Offset = GetOffsetForPosition(e.Location, 3);
caret.SetToPosition(GetPositionForOffset(caret.Offset, this.charwidth));
this.Invalidate();
}
oldMousePos = e.Location;
}
void HexViewMouseUp(object sender, MouseEventArgs e)
@ -1829,7 +1780,6 @@ namespace HexEditor @@ -1829,7 +1780,6 @@ namespace HexEditor
selection.HasSomethingSelected = false;
selectionmode = false;
}
this.Invalidate();
} else {
if (!moved) {
selection.HasSomethingSelected = false;
@ -1841,6 +1791,8 @@ namespace HexEditor @@ -1841,6 +1791,8 @@ namespace HexEditor
caret.Offset = GetOffsetForPosition(e.Location, 3);
caret.SetToPosition(GetPositionForOffset(caret.Offset, this.charwidth));
selectionmode = false;
this.Invalidate();
}
#endregion
@ -1902,12 +1854,25 @@ namespace HexEditor @@ -1902,12 +1854,25 @@ namespace HexEditor
line++;
// calculate the char: horizontal position (X) divided by the width of one char
int ch = (int)Math.Round((float)position.X / (float)(charwidth * underscorewidth));
float col = ((float)position.X / (float)(charwidth * underscorewidth));
float diff = (float)col - (float)((int)col);
int ch = diff >= 0.75f ? (int)col + 1 : (int)col;
if (ch > this.BytesPerLine) ch = this.BytesPerLine;
if (ch < 0) ch = 0;
// calculate offset
int offset = line * this.BytesPerLine + ch;
if ((diff > 0.35f) && (diff < 0.75f)) {
this.hexinputmodepos = 1;
this.hexinputmode = true;
} else {
this.hexinputmodepos = 0;
this.hexinputmode = false;
}
// check
if (offset < 0) return 0;
if (offset < this.buffer.BufferSize) {
@ -2009,4 +1974,4 @@ namespace HexEditor @@ -2009,4 +1974,4 @@ namespace HexEditor
this.Invalidate();
}
}
}
}

221
src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/BufferManager.cs

@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
@ -24,34 +25,19 @@ namespace HexEditor.Util @@ -24,34 +25,19 @@ namespace HexEditor.Util
/// </summary>
public class BufferManager
{
internal Control parent;
Editor parent;
OpenedFile currentFile;
Stream stream;
/// <summary>
/// Currently used, but not good for really big files (like 590 MB)
/// </summary>
private ArrayList buffer;
StreamedList data;
/// <summary>
/// Creates a new BufferManager and attaches it to a control.
/// </summary>
/// <param name="parent">The parent control to attach to.</param>
public BufferManager(Control parent)
public BufferManager(Editor parent)
{
this.parent = parent;
this.buffer = new ArrayList();
}
/// <summary>
/// Cleares the whole buffer.
/// </summary>
public void Clear()
{
this.buffer.Clear();
parent.Invalidate();
GC.Collect();
this.data = new StreamedList();
}
/// <summary>
@ -60,46 +46,32 @@ namespace HexEditor.Util @@ -60,46 +46,32 @@ namespace HexEditor.Util
public void Load(OpenedFile file, Stream stream)
{
this.currentFile = file;
this.stream = stream;
this.buffer.Clear();
((Editor)this.parent).Enabled = false;
this.data.Clear();
this.data = new StreamedList();
stream.Position = 0;
byte[] bytes = new byte[512000];
if (File.Exists(currentFile.FileName)) {
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));
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();
}
reader.Close();
} catch (IOException ex) {
MessageService.ShowError(ex, ex.Message);
} catch (ArgumentException ex) {
MessageService.ShowError(ex, ex.Message + "\n\n" + ex.StackTrace);
}
} while (count > 0);
} else {
MessageService.ShowError(new FileNotFoundException("The file " + currentFile.FileName + " doesn't exist!", currentFile.FileName), "The file " + currentFile.FileName + " doesn't exist!");
}
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();
}
/// <summary>
@ -107,129 +79,43 @@ namespace HexEditor.Util @@ -107,129 +79,43 @@ namespace HexEditor.Util
/// </summary>
public void Save(OpenedFile file, Stream stream)
{
BinaryWriter writer = new BinaryWriter(stream);
writer.Write((byte[])this.buffer.ToArray( typeof (byte) ));
writer.Flush();
}
/// <summary>
/// Intern method used to load data in a separate thread.
/// </summary>
/// <remarks>Currently not in use.</remarks>
private void Load()
{
((Editor)this.parent).Enabled = false;
if (File.Exists(currentFile.FileName)) {
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));
}
reader.Close();
} catch (IOException ex) {
MessageService.ShowError(ex, ex.Message);
} catch (ArgumentException ex) {
MessageService.ShowError(ex, ex.Message + "\n\n" + ex.StackTrace);
}
} else {
MessageService.ShowError(new FileNotFoundException("The file " + currentFile.FileName + " doesn't exist!", currentFile.FileName), "The file " + currentFile.FileName + " doesn't exist!");
}
this.parent.Invalidate();
UpdateProgress(100);
if (this.parent.InvokeRequired)
this.parent.Invoke(new MethodInvoker(
delegate() {this.parent.Cursor = Cursors.Default;}
));
((Editor)this.parent).Enabled = true;
}
/// <summary>
/// Used for threading to update the processbars and stuff.
/// </summary>
/// <param name="percentage">The current percentage of the process</param>
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; }
}
}
}
/// <summary>
/// Returns the current buffer as a byte[].
/// </summary>
public byte[] Buffer {
get {
if (buffer == null) return new byte[0];
return (byte[]) buffer.ToArray( typeof ( byte ) );
}
this.data.ConcatenateTo(stream);
}
/// <summary>
/// The size of the current buffer.
/// </summary>
public int BufferSize {
get { return buffer.Count; }
get {
return this.data.Count;
}
}
#region Methods
public byte[] GetBytes(int start, int count)
{
if (buffer.Count == 0) return new byte[] {};
if (this.BufferSize == 0) return new byte[] {};
if (start < 0) start = 0;
if (start >= buffer.Count) start = buffer.Count;
if (start >= this.BufferSize) start = this.BufferSize;
if (count < 1) count = 1;
if (count >= (buffer.Count - start)) count = (buffer.Count - start);
return (byte[])(buffer.GetRange(start, count).ToArray( typeof ( byte ) ));
if (count >= (this.BufferSize - start)) count = (this.BufferSize - start);
return this.data.GetRange(start, count);
}
public byte GetByte(int offset)
{
if (buffer.Count == 0) return 0;
if (this.BufferSize == 0) return 0;
if (offset < 0) offset = 0;
if (offset >= buffer.Count) offset = buffer.Count;
return (byte)buffer[offset];
}
public bool DeleteByte(int offset)
{
if ((offset < buffer.Count) & (offset > -1)) {
buffer.RemoveAt(offset);
return true;
}
return false;
if (offset >= this.BufferSize) offset = this.BufferSize;
return this.data[offset];
}
public bool RemoveByte(int offset)
{
if ((offset < buffer.Count) & (offset > -1)) {
buffer.RemoveAt(offset);
if ((offset < this.BufferSize) & (offset > -1)) {
data.RemoveAt(offset);
return true;
}
return false;
@ -237,34 +123,45 @@ namespace HexEditor.Util @@ -237,34 +123,45 @@ namespace HexEditor.Util
public bool RemoveBytes(int offset, int length)
{
if (((offset < buffer.Count) && (offset > -1)) && ((offset + length) <= buffer.Count)) {
buffer.RemoveRange(offset, 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);
}
return true;
}
return false;
}
/// <remarks>Not Tested!</remarks>
public void SetBytes(int start, byte[] bytes, bool overwrite)
{
if (overwrite) {
if (bytes.Length > buffer.Count) buffer.AddRange(new byte[bytes.Length - buffer.Count]);
buffer.SetRange(start, bytes);
foreach (byte b in bytes)
{
data[start] = b;
start++;
}
} else {
buffer.InsertRange(start, bytes);
foreach (byte b in bytes)
{
data.Insert(start, b);
start++;
}
}
}
public void SetByte(int position, byte @byte, bool overwrite)
{
if (overwrite) {
if (position > buffer.Count - 1) {
buffer.Add(@byte);
data[position] = @byte;
} else {
if (position == data.Count) {
data.Add(@byte);
} else {
buffer[position] = @byte;
data.Insert(position, @byte);
}
} else {
buffer.Insert(position, @byte);
}
}
#endregion

134
src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/Change.cs

@ -1,134 +0,0 @@ @@ -1,134 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
// <version>$Revision: 2984 $</version>
// </file>
using System;
namespace HexEditor.Util
{
/// <summary>
/// Description of Change.
/// </summary>
public class Change
{
int start, end;
byte[] data;
ChangeType type;
public Change(int start, int end, byte[] data, ChangeType type)
{
this.start = start;
this.end = end;
this.data = data;
this.type = type;
}
public int Start {
get { return start; }
set { start = value; }
}
public int End {
get { return end; }
set { end = value; }
}
public byte[] Data {
get { return data; }
set { data = value; }
}
public ChangeType Type {
get { return type; }
set { type = value; }
}
public void Merge(Change change)
{
byte[] tmp = new byte[0];
switch (change.type) {
case ChangeType.Delete:
break;
case ChangeType.Insert:
if ((change.start + change.data.Length) < this.start)
this.Prepend(change);
else
if ((change.start + change.data.Length) > this.end)
this.Append(change);
else {
tmp = new byte[change.data.Length + this.data.Length];
for (int i = 0; i < (int)Math.Abs(change.start - this.start); i++)
{
tmp[i] = this.data[i];
}
int offset = (int)Math.Abs(change.start - this.start);
for (int i = offset; i < offset + change.data.Length; i++)
{
tmp[i] = change.data[i - offset];
}
for (int i = offset + change.data.Length; i < (this.data.Length + offset + change.data.Length); i++)
{
tmp[i] = this.data[i - (offset + change.data.Length)];
}
}
break;
case ChangeType.Overwrite:
break;
}
this.data = tmp;
}
public void Append(Change change)
{
byte[] tmp = new byte[change.data.Length + this.data.Length];
for (int i = 0; i < this.data.Length; i++)
{
tmp[i] = this.data[i];
}
for (int i = 0; i < change.data.Length; i++)
{
tmp[i + this.data.Length] = change.data[i];
}
this.end = change.end;
this.data = tmp;
}
public void Prepend(Change change)
{
byte[] tmp = new byte[change.data.Length + this.data.Length];
for (int i = 0; i < change.data.Length; i++)
{
tmp[i] = change.data[i];
}
for (int i = 0; i < this.data.Length; i++)
{
tmp[i + change.data.Length] = this.data[i];
}
this.start = change.start;
this.data = tmp;
}
}
public enum ChangeType {
Delete, Insert, Overwrite
}
}

51
src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/ClipboardManager.cs

@ -1,51 +0,0 @@ @@ -1,51 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Windows.Forms;
namespace HexEditor.Util
{
/// <summary>
/// Manages the clipboard actions.
/// </summary>
public static class ClipboardManager
{
/// <summary>
/// Used to determine if text is in the clipboard or not.
/// </summary>
public static bool ContainsText {
get { return Clipboard.ContainsText(); }
}
/// <summary>
/// Cleares the Clipboard.
/// </summary>
public static void Clear()
{
Clipboard.Clear();
}
/// <summary>
/// Copies text into the clipboard.
/// </summary>
/// <param name="text">The text to be copied to the clipboard.</param>
public static void Copy(string text)
{
Clipboard.SetText(text);
}
/// <summary>
/// Pastes the text.
/// </summary>
/// <returns>the text in the clipboard.</returns>
public static string Paste()
{
return Clipboard.GetText();
}
}
}

287
src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/StreamedList.cs

@ -0,0 +1,287 @@ @@ -0,0 +1,287 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
// <version>$Revision: 2995 $</version>
// </file>
using System;
using System.Collections.Generic;
using System.IO;
using ICSharpCode.Core;
namespace HexEditor.Util
{
public class StreamedList : IList<byte>
{
List<FileStream> streams;
int maxStreamLength = 25 * 1024 * 1024;
public StreamedList()
{
this.streams = new List<FileStream>();
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<byte> 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);
}
}
}
}

2
src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/UndoAction.cs

@ -14,6 +14,6 @@ namespace HexEditor.Util @@ -14,6 +14,6 @@ namespace HexEditor.Util
/// </summary>
public enum UndoAction
{
Add, Remove, Overwrite
Insert, Remove, Overwrite
}
}

20
src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/UndoManager.cs

@ -45,7 +45,6 @@ namespace HexEditor.Util @@ -45,7 +45,6 @@ namespace HexEditor.Util
/// Adds a step to the stack.
/// </summary>
/// <param name="step">The step to add.</param>
/// <remarks>Used internally, don't use!</remarks>
internal void AddUndoStep(UndoStep step)
{
UndoStack.Push(step);
@ -56,6 +55,21 @@ namespace HexEditor.Util @@ -56,6 +55,21 @@ namespace HexEditor.Util
temp(this, new UndoEventArgs(step, false));
}
internal void AddOverwriteStep(int start, byte[] bytes, byte[] oldBytes)
{
this.AddUndoStep(new UndoStep(bytes, oldBytes, start, UndoAction.Overwrite));
}
internal void AddInsertStep(int start, byte[] bytes)
{
this.AddUndoStep(new UndoStep(bytes, null, start, UndoAction.Insert));
}
internal void AddRemoveStep(int start, byte[] bytes)
{
this.AddUndoStep(new UndoStep(bytes, null, start, UndoAction.Remove));
}
/// <summary>
/// Undoes the last step.
/// </summary>
@ -68,7 +82,7 @@ namespace HexEditor.Util @@ -68,7 +82,7 @@ namespace HexEditor.Util
RedoStack.Push(step);
UndoStack.Pop();
switch (step.Action) {
case UndoAction.Add :
case UndoAction.Insert :
buffer.SetBytes(step.Start, step.GetBytes(), false);
break;
case UndoAction.Remove :
@ -99,7 +113,7 @@ namespace HexEditor.Util @@ -99,7 +113,7 @@ namespace HexEditor.Util
UndoStack.Push(step);
RedoStack.Pop();
switch (step.Action) {
case UndoAction.Add :
case UndoAction.Insert :
buffer.RemoveBytes(step.Start, step.GetBytes().Length);
break;
case UndoAction.Remove :

2
src/AddIns/DisplayBindings/HexEditor/Project/Src/View/HexEditContainer.cs

@ -44,6 +44,8 @@ namespace HexEditor.View @@ -44,6 +44,8 @@ namespace HexEditor.View
ToolStripControlHost viewMode = new ToolStripControlHost(tCBViewMode);
this.toolStrip1.Items.Insert(3, viewMode);
tSTBCharsPerLine.Text = hexEditControl.BytesPerLine.ToString();
this.hexEditControl.ContextMenuStrip = MenuService.CreateContextMenu(this.hexEditControl, "/AddIns/HexEditor/Editor/ContextMenu");
tCBViewMode.SelectedIndex = 0;

5
src/AddIns/DisplayBindings/HexEditor/Project/changes.txt

@ -19,7 +19,6 @@ version: 0.0.2 @@ -19,7 +19,6 @@ version: 0.0.2
Known bugs/Problems:
1) Might be good to be able to change individual hex parts of a byte.
2) Might be good if the next hex value to be typed in was highlighted
1) Might be good if the next hex value to be typed in was highlighted
in the hex display.
3) Change data structures (crashes when opening big files)
2) Change data structures (crashes when opening big files)
Loading…
Cancel
Save