Browse Source

Reverted the old buffer system and fixed some bugs

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3430 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Siegfried Pammer 17 years ago
parent
commit
6bcc5a213f
  1. 1
      src/AddIns/DisplayBindings/HexEditor/Project/HexEditor.csproj
  2. 24
      src/AddIns/DisplayBindings/HexEditor/Project/Src/Editor.cs
  3. 186
      src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/BufferManager.cs
  4. 287
      src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/StreamedList.cs

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

@ -69,7 +69,6 @@ @@ -69,7 +69,6 @@
<Compile Include="Src\Util\Caret.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" />

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

@ -169,7 +169,7 @@ namespace HexEditor @@ -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 @@ -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 @@ -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 @@ -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 @@ -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));

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

@ -7,10 +7,15 @@ @@ -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 @@ -19,19 +24,34 @@ namespace HexEditor.Util
/// </summary>
public class BufferManager
{
Editor parent;
internal Control parent;
OpenedFile currentFile;
Stream stream;
StreamedList data;
/// <summary>
/// Currently used, but not good for really big files (like 590 MB)
/// </summary>
private ArrayList buffer;
/// <summary>
/// Creates a new BufferManager and attaches it to a control.
/// </summary>
/// <param name="parent">The parent control to attach to.</param>
public BufferManager(Editor parent)
public BufferManager(Control parent)
{
this.parent = parent;
this.data = new StreamedList();
this.buffer = new ArrayList();
}
/// <summary>
/// Cleares the whole buffer.
/// </summary>
public void Clear()
{
this.buffer.Clear();
parent.Invalidate();
GC.Collect();
}
/// <summary>
@ -40,32 +60,44 @@ namespace HexEditor.Util @@ -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();
}
/// <summary>
@ -73,43 +105,90 @@ namespace HexEditor.Util @@ -73,43 +105,90 @@ namespace HexEditor.Util
/// </summary>
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();
}
/// <summary>
/// The size of the current buffer.
/// Used for threading to update the processbars and stuff.
/// </summary>
public int BufferSize {
/// <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 {
return this.data.Count;
if (buffer == null) return new byte[0];
return (byte[]) buffer.ToArray( typeof ( byte ) );
}
}
/// <summary>
/// The size of the current buffer.
/// </summary>
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 @@ -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;
}
/// <remarks>Not Tested!</remarks>
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

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

@ -1,287 +0,0 @@ @@ -1,287 +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: 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);
}
}
}
}
Loading…
Cancel
Save