forked from mirrors/NBTExplorer
Added read-only hex editor support for byte-array and int-array tags.
This commit is contained in:
parent
5191805a22
commit
afb61389bb
35 changed files with 8444 additions and 10 deletions
34
Form1.cs
34
Form1.cs
|
@ -419,8 +419,6 @@ namespace NBTExplorer
|
|||
_buttonDelete.Enabled = tag != null && node.Tag is TagNode;
|
||||
_buttonEdit.Enabled = tag != null
|
||||
&& node.Tag is TagNode
|
||||
&& tag.GetTagType() != TagType.TAG_BYTE_ARRAY
|
||||
&& tag.GetTagType() != TagType.TAG_INT_ARRAY
|
||||
&& tag.GetTagType() != TagType.TAG_COMPOUND
|
||||
&& tag.GetTagType() != TagType.TAG_LIST;
|
||||
|
||||
|
@ -889,19 +887,35 @@ namespace NBTExplorer
|
|||
if (tag == null)
|
||||
return;
|
||||
|
||||
if (tag.GetTagType() == TagType.TAG_BYTE_ARRAY ||
|
||||
tag.GetTagType() == TagType.TAG_LIST ||
|
||||
if (tag.GetTagType() == TagType.TAG_LIST ||
|
||||
tag.GetTagType() == TagType.TAG_COMPOUND)
|
||||
return;
|
||||
|
||||
EditValue form = new EditValue(tag);
|
||||
if (form.ShowDialog() == DialogResult.OK) {
|
||||
TreeNode baseNode = BaseNode(node);
|
||||
if (baseNode != null) {
|
||||
(baseNode.Tag as DataNode).Modified = true;
|
||||
if (tag.GetTagType() == TagType.TAG_BYTE_ARRAY) {
|
||||
HexEditor form = new HexEditor(GetTagNodeName(node), tag.ToTagByteArray().Data);
|
||||
form.ShowDialog();
|
||||
}
|
||||
else if (tag.GetTagType() == TagType.TAG_INT_ARRAY) {
|
||||
TagNodeIntArray iatag = tag.ToTagIntArray();
|
||||
byte[] data = new byte[iatag.Length * 4];
|
||||
for (int i = 0; i < iatag.Length; i++) {
|
||||
byte[] buf = BitConverter.GetBytes(iatag.Data[i]);
|
||||
Array.Copy(buf, 0, data, 4 * i, 4);
|
||||
}
|
||||
|
||||
node.Text = GetNodeText(node);
|
||||
HexEditor form = new HexEditor(GetTagNodeName(node), data);
|
||||
form.ShowDialog();
|
||||
}
|
||||
else {
|
||||
EditValue form = new EditValue(tag);
|
||||
if (form.ShowDialog() == DialogResult.OK) {
|
||||
TreeNode baseNode = BaseNode(node);
|
||||
if (baseNode != null) {
|
||||
(baseNode.Tag as DataNode).Modified = true;
|
||||
}
|
||||
|
||||
node.Text = GetNodeText(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
106
HexEditor.Designer.cs
generated
Normal file
106
HexEditor.Designer.cs
generated
Normal file
|
@ -0,0 +1,106 @@
|
|||
namespace NBTExplorer
|
||||
{
|
||||
partial class HexEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose (bool disposing)
|
||||
{
|
||||
if (disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent ()
|
||||
{
|
||||
this.hexBox1 = new Be.Windows.Forms.HexBox();
|
||||
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
||||
this._curPositionLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this._buttonClose = new System.Windows.Forms.Button();
|
||||
this.statusStrip1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// hexBox1
|
||||
//
|
||||
this.hexBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.hexBox1.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.hexBox1.LineInfoForeColor = System.Drawing.Color.Empty;
|
||||
this.hexBox1.LineInfoVisible = true;
|
||||
this.hexBox1.Location = new System.Drawing.Point(12, 12);
|
||||
this.hexBox1.Name = "hexBox1";
|
||||
this.hexBox1.ReadOnly = true;
|
||||
this.hexBox1.ShadowSelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(60)))), ((int)(((byte)(188)))), ((int)(((byte)(255)))));
|
||||
this.hexBox1.Size = new System.Drawing.Size(492, 289);
|
||||
this.hexBox1.TabIndex = 0;
|
||||
this.hexBox1.VScrollBarVisible = true;
|
||||
//
|
||||
// statusStrip1
|
||||
//
|
||||
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this._curPositionLabel});
|
||||
this.statusStrip1.Location = new System.Drawing.Point(0, 333);
|
||||
this.statusStrip1.Name = "statusStrip1";
|
||||
this.statusStrip1.Size = new System.Drawing.Size(516, 22);
|
||||
this.statusStrip1.TabIndex = 1;
|
||||
this.statusStrip1.Text = "statusStrip1";
|
||||
//
|
||||
// _curPositionLabel
|
||||
//
|
||||
this._curPositionLabel.AutoSize = false;
|
||||
this._curPositionLabel.Name = "_curPositionLabel";
|
||||
this._curPositionLabel.Size = new System.Drawing.Size(100, 17);
|
||||
this._curPositionLabel.Text = "0000";
|
||||
//
|
||||
// _buttonClose
|
||||
//
|
||||
this._buttonClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this._buttonClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this._buttonClose.Location = new System.Drawing.Point(429, 307);
|
||||
this._buttonClose.Name = "_buttonClose";
|
||||
this._buttonClose.Size = new System.Drawing.Size(75, 23);
|
||||
this._buttonClose.TabIndex = 2;
|
||||
this._buttonClose.Text = "Close";
|
||||
this._buttonClose.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// HexEditor
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this._buttonClose;
|
||||
this.ClientSize = new System.Drawing.Size(516, 355);
|
||||
this.Controls.Add(this._buttonClose);
|
||||
this.Controls.Add(this.statusStrip1);
|
||||
this.Controls.Add(this.hexBox1);
|
||||
this.Name = "HexEditor";
|
||||
this.Text = "HexEditor";
|
||||
this.statusStrip1.ResumeLayout(false);
|
||||
this.statusStrip1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Be.Windows.Forms.HexBox hexBox1;
|
||||
private System.Windows.Forms.StatusStrip statusStrip1;
|
||||
private System.Windows.Forms.ToolStripStatusLabel _curPositionLabel;
|
||||
private System.Windows.Forms.Button _buttonClose;
|
||||
}
|
||||
}
|
49
HexEditor.cs
Normal file
49
HexEditor.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using Be.Windows.Forms;
|
||||
|
||||
namespace NBTExplorer
|
||||
{
|
||||
public partial class HexEditor : Form
|
||||
{
|
||||
public HexEditor (string tagName, byte[] data)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Text = "Editing: " + tagName + " (Read Only)";
|
||||
|
||||
hexBox1.ByteProvider = new DynamicByteProvider(data);
|
||||
|
||||
hexBox1.HorizontalByteCountChanged += HexBox_HorizontalByteCountChanged;
|
||||
hexBox1.CurrentLineChanged += HexBox_CurrentLineChanged;
|
||||
hexBox1.CurrentPositionInLineChanged += HexBox_CurrentPositionInLineChanged;
|
||||
}
|
||||
|
||||
private void HexBox_HorizontalByteCountChanged (object sender, EventArgs e)
|
||||
{
|
||||
UpdatePosition();
|
||||
}
|
||||
|
||||
private void HexBox_CurrentLineChanged (object sender, EventArgs e)
|
||||
{
|
||||
UpdatePosition();
|
||||
}
|
||||
|
||||
private void HexBox_CurrentPositionInLineChanged (object sender, EventArgs e)
|
||||
{
|
||||
UpdatePosition();
|
||||
}
|
||||
|
||||
private void UpdatePosition ()
|
||||
{
|
||||
long pos = (hexBox1.CurrentLine - 1) * hexBox1.HorizontalByteCount + hexBox1.CurrentPositionInLine;
|
||||
|
||||
_curPositionLabel.Text = pos.ToString();
|
||||
}
|
||||
}
|
||||
}
|
123
HexEditor.resx
Normal file
123
HexEditor.resx
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
|
@ -43,8 +43,10 @@
|
|||
<HintPath>..\Substrate\SubstrateCS\bin\Release\NET2\Substrate.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="About.cs">
|
||||
|
@ -71,6 +73,12 @@
|
|||
<Compile Include="Form1.Designer.cs">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="HexEditor.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="HexEditor.Designer.cs">
|
||||
<DependentUpon>HexEditor.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="About.resx">
|
||||
|
@ -86,6 +94,9 @@
|
|||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="HexEditor.resx">
|
||||
<DependentUpon>HexEditor.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
|
@ -101,6 +112,12 @@
|
|||
<ItemGroup>
|
||||
<Content Include="dead_bush.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="Vendor\Be.Windows.Forms.HexBox\Be.Windows.Forms.HexBox.csproj">
|
||||
<Project>{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}</Project>
|
||||
<Name>Be.Windows.Forms.HexBox</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
|
|
@ -3,16 +3,38 @@ Microsoft Visual Studio Solution File, Format Version 11.00
|
|||
# Visual C# Express 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NBTExplorer", "NBTExplorer.csproj", "{8A458245-8176-4599-95CD-3CA39F2435CE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Be.Windows.Forms.HexBox", "Vendor\Be.Windows.Forms.HexBox\Be.Windows.Forms.HexBox.csproj", "{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|Mixed Platforms = Debug|Mixed Platforms
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|Mixed Platforms = Release|Mixed Platforms
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8A458245-8176-4599-95CD-3CA39F2435CE}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{8A458245-8176-4599-95CD-3CA39F2435CE}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{8A458245-8176-4599-95CD-3CA39F2435CE}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{8A458245-8176-4599-95CD-3CA39F2435CE}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{8A458245-8176-4599-95CD-3CA39F2435CE}.Debug|x86.Build.0 = Debug|x86
|
||||
{8A458245-8176-4599-95CD-3CA39F2435CE}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{8A458245-8176-4599-95CD-3CA39F2435CE}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{8A458245-8176-4599-95CD-3CA39F2435CE}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{8A458245-8176-4599-95CD-3CA39F2435CE}.Release|x86.ActiveCfg = Release|x86
|
||||
{8A458245-8176-4599-95CD-3CA39F2435CE}.Release|x86.Build.0 = Release|x86
|
||||
{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
BIN
Resources/document-attribute-b.png
Normal file
BIN
Resources/document-attribute-b.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 612 B |
BIN
Resources/document-attribute-i.png
Normal file
BIN
Resources/document-attribute-i.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 587 B |
BIN
Resources/edit-code-b.png
Normal file
BIN
Resources/edit-code-b.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 388 B |
BIN
Resources/edit-code-i.png
Normal file
BIN
Resources/edit-code-i.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 380 B |
BIN
Resources/edit-code.png
Normal file
BIN
Resources/edit-code.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 308 B |
70
Vendor/Be.Windows.Forms.HexBox/AssemblyInfo.cs
vendored
Normal file
70
Vendor/Be.Windows.Forms.HexBox/AssemblyInfo.cs
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security.Permissions;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
//
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
//
|
||||
[assembly: AssemblyTitle("Be.Windows.Forms.HexBox")]
|
||||
[assembly: AssemblyDescription("hex edit control (C# DOTNET)")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Be")]
|
||||
[assembly: AssemblyProduct("Be.Windows.Forms.HexBox")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
//
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("1.4.7.*")]
|
||||
|
||||
//
|
||||
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||
// Microsoft .NET Framework documentation for more information on assembly signing.
|
||||
//
|
||||
// Use the attributes below to control which key is used for signing.
|
||||
//
|
||||
// Notes:
|
||||
// (*) If no key is specified, the assembly is not signed.
|
||||
// (*) KeyName refers to a key that has been installed in the Crypto Service
|
||||
// Provider (CSP) on your machine. KeyFile refers to a file which contains
|
||||
// a key.
|
||||
// (*) If the KeyFile and the KeyName values are both specified, the
|
||||
// following processing occurs:
|
||||
// (1) If the KeyName can be found in the CSP, that key is used.
|
||||
// (2) If the KeyName does not exist and the KeyFile does exist, the key
|
||||
// in the KeyFile is installed into the CSP and used.
|
||||
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
|
||||
// When specifying the KeyFile, the location of the KeyFile should be
|
||||
// relative to the project output directory which is
|
||||
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
|
||||
// located in the project directory, you would specify the AssemblyKeyFile
|
||||
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
|
||||
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
|
||||
// documentation for more information on this.
|
||||
//
|
||||
[assembly: AssemblyDelaySign(false)]
|
||||
|
||||
//[assembly: AssemblyKeyFile("../../HexBox.snk")]
|
||||
//[assembly: AssemblyKeyName("")]
|
||||
|
||||
//[assembly:IsolatedStorageFilePermission(SecurityAction.RequestRefuse, UserQuota=1048576)]
|
||||
//[assembly:SecurityPermission(SecurityAction.RequestRefuse, UnmanagedCode=true)]
|
||||
//[assembly:FileIOPermission(SecurityAction.RequestOptional, Unrestricted=true)]
|
||||
|
||||
[assembly:CLSCompliant(true)]
|
||||
|
||||
[assembly:ComVisible(false)]
|
207
Vendor/Be.Windows.Forms.HexBox/Be.Windows.Forms.HexBox.csproj
vendored
Normal file
207
Vendor/Be.Windows.Forms.HexBox/Be.Windows.Forms.HexBox.csproj
vendored
Normal file
|
@ -0,0 +1,207 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<ProjectType>Local</ProjectType>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ApplicationIcon>
|
||||
</ApplicationIcon>
|
||||
<AssemblyKeyContainerName>
|
||||
</AssemblyKeyContainerName>
|
||||
<AssemblyName>Be.Windows.Forms.HexBox</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>HexBox.snk</AssemblyOriginatorKeyFile>
|
||||
<DefaultClientScript>JScript</DefaultClientScript>
|
||||
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
|
||||
<DefaultTargetSchema>IE50</DefaultTargetSchema>
|
||||
<DelaySign>false</DelaySign>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Be.Windows.Forms</RootNamespace>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>Be.Windows.Forms.HexBox.xml</DocumentationFile>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>false</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>full</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>true</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>none</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>BasicCorrectnessRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System">
|
||||
<Name>System</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<Name>System.Data</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing.Design" />
|
||||
<Reference Include="System.Windows.Forms">
|
||||
<Name>System.Windows.Forms</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<Name>System.XML</Name>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BuiltInContextMenu.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ByteCollection.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BytePositionInfo.cs" />
|
||||
<Compile Include="DataBlock.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DataMap.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DynamicByteProvider.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DynamicFileByteProvider.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="FileByteProvider.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="FileDataBlock.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="HexBox.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="HexCasing.cs" />
|
||||
<Compile Include="ByteCharConverters.cs" />
|
||||
<Compile Include="IByteProvider.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MemoryDataBlock.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="NativeMethods.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Util.cs" />
|
||||
<EmbeddedResource Include="HexBox.bmp" />
|
||||
<EmbeddedResource Include="HexBox.resx">
|
||||
<DependentUpon>HexBox.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="HexBox.snk" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
1616
Vendor/Be.Windows.Forms.HexBox/Be.Windows.Forms.HexBox.xml
vendored
Normal file
1616
Vendor/Be.Windows.Forms.HexBox/Be.Windows.Forms.HexBox.xml
vendored
Normal file
File diff suppressed because it is too large
Load diff
220
Vendor/Be.Windows.Forms.HexBox/BuiltInContextMenu.cs
vendored
Normal file
220
Vendor/Be.Windows.Forms.HexBox/BuiltInContextMenu.cs
vendored
Normal file
|
@ -0,0 +1,220 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a build-in ContextMenuStrip manager for HexBox control to show Copy, Cut, Paste menu in contextmenu of the control.
|
||||
/// </summary>
|
||||
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
|
||||
public sealed class BuiltInContextMenu : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains the HexBox control.
|
||||
/// </summary>
|
||||
HexBox _hexBox;
|
||||
/// <summary>
|
||||
/// Contains the ContextMenuStrip control.
|
||||
/// </summary>
|
||||
ContextMenuStrip _contextMenuStrip;
|
||||
/// <summary>
|
||||
/// Contains the "Cut"-ToolStripMenuItem object.
|
||||
/// </summary>
|
||||
ToolStripMenuItem _cutToolStripMenuItem;
|
||||
/// <summary>
|
||||
/// Contains the "Copy"-ToolStripMenuItem object.
|
||||
/// </summary>
|
||||
ToolStripMenuItem _copyToolStripMenuItem;
|
||||
/// <summary>
|
||||
/// Contains the "Paste"-ToolStripMenuItem object.
|
||||
/// </summary>
|
||||
ToolStripMenuItem _pasteToolStripMenuItem;
|
||||
/// <summary>
|
||||
/// Contains the "Select All"-ToolStripMenuItem object.
|
||||
/// </summary>
|
||||
ToolStripMenuItem _selectAllToolStripMenuItem;
|
||||
/// <summary>
|
||||
/// Initializes a new instance of BuildInContextMenu class.
|
||||
/// </summary>
|
||||
/// <param name="hexBox">the HexBox control</param>
|
||||
internal BuiltInContextMenu(HexBox hexBox)
|
||||
{
|
||||
_hexBox = hexBox;
|
||||
_hexBox.ByteProviderChanged += new EventHandler(HexBox_ByteProviderChanged);
|
||||
}
|
||||
/// <summary>
|
||||
/// If ByteProvider
|
||||
/// </summary>
|
||||
/// <param name="sender">the sender object</param>
|
||||
/// <param name="e">the event data</param>
|
||||
void HexBox_ByteProviderChanged(object sender, EventArgs e)
|
||||
{
|
||||
CheckBuiltInContextMenu();
|
||||
}
|
||||
/// <summary>
|
||||
/// Assigns the ContextMenuStrip control to the HexBox control.
|
||||
/// </summary>
|
||||
void CheckBuiltInContextMenu()
|
||||
{
|
||||
if (Util.DesignMode)
|
||||
return;
|
||||
|
||||
if (this._contextMenuStrip == null)
|
||||
{
|
||||
ContextMenuStrip cms = new ContextMenuStrip();
|
||||
_cutToolStripMenuItem = new ToolStripMenuItem(CutMenuItemTextInternal, CutMenuItemImage, new EventHandler(CutMenuItem_Click));
|
||||
cms.Items.Add(_cutToolStripMenuItem);
|
||||
_copyToolStripMenuItem = new ToolStripMenuItem(CopyMenuItemTextInternal, CopyMenuItemImage, new EventHandler(CopyMenuItem_Click));
|
||||
cms.Items.Add(_copyToolStripMenuItem);
|
||||
_pasteToolStripMenuItem = new ToolStripMenuItem(PasteMenuItemTextInternal, PasteMenuItemImage, new EventHandler(PasteMenuItem_Click));
|
||||
cms.Items.Add(_pasteToolStripMenuItem);
|
||||
|
||||
cms.Items.Add(new ToolStripSeparator());
|
||||
|
||||
_selectAllToolStripMenuItem = new ToolStripMenuItem(SelectAllMenuItemTextInternal, SelectAllMenuItemImage, new EventHandler(SelectAllMenuItem_Click));
|
||||
cms.Items.Add(_selectAllToolStripMenuItem);
|
||||
cms.Opening += new CancelEventHandler(BuildInContextMenuStrip_Opening);
|
||||
|
||||
_contextMenuStrip = cms;
|
||||
}
|
||||
|
||||
if (this._hexBox.ByteProvider == null && this._hexBox.ContextMenuStrip != null)
|
||||
this._hexBox.ContextMenuStrip = null;
|
||||
else if (this._hexBox.ByteProvider != null && this._hexBox.ContextMenuStrip == null)
|
||||
this._hexBox.ContextMenuStrip = _contextMenuStrip;
|
||||
}
|
||||
/// <summary>
|
||||
/// Before opening the ContextMenuStrip, we manage the availability of the items.
|
||||
/// </summary>
|
||||
/// <param name="sender">the sender object</param>
|
||||
/// <param name="e">the event data</param>
|
||||
void BuildInContextMenuStrip_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
_cutToolStripMenuItem.Enabled = this._hexBox.CanCut();
|
||||
_copyToolStripMenuItem.Enabled = this._hexBox.CanCopy();
|
||||
_pasteToolStripMenuItem.Enabled = this._hexBox.CanPaste();
|
||||
_selectAllToolStripMenuItem.Enabled = this._hexBox.CanSelectAll();
|
||||
}
|
||||
/// <summary>
|
||||
/// The handler for the "Cut"-Click event
|
||||
/// </summary>
|
||||
/// <param name="sender">the sender object</param>
|
||||
/// <param name="e">the event data</param>
|
||||
void CutMenuItem_Click(object sender, EventArgs e) { this._hexBox.Cut(); }
|
||||
/// <summary>
|
||||
/// The handler for the "Copy"-Click event
|
||||
/// </summary>
|
||||
/// <param name="sender">the sender object</param>
|
||||
/// <param name="e">the event data</param>
|
||||
void CopyMenuItem_Click(object sender, EventArgs e) { this._hexBox.Copy(); }
|
||||
/// <summary>
|
||||
/// The handler for the "Paste"-Click event
|
||||
/// </summary>
|
||||
/// <param name="sender">the sender object</param>
|
||||
/// <param name="e">the event data</param>
|
||||
void PasteMenuItem_Click(object sender, EventArgs e) { this._hexBox.Paste(); }
|
||||
/// <summary>
|
||||
/// The handler for the "Select All"-Click event
|
||||
/// </summary>
|
||||
/// <param name="sender">the sender object</param>
|
||||
/// <param name="e">the event data</param>
|
||||
void SelectAllMenuItem_Click(object sender, EventArgs e) { this._hexBox.SelectAll(); }
|
||||
/// <summary>
|
||||
/// Gets or sets the custom text of the "Copy" ContextMenuStrip item.
|
||||
/// </summary>
|
||||
[Category("BuiltIn-ContextMenu"), DefaultValue(null), Localizable(true)]
|
||||
public string CopyMenuItemText
|
||||
{
|
||||
get { return _copyMenuItemText; }
|
||||
set { _copyMenuItemText = value; }
|
||||
} string _copyMenuItemText;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the custom text of the "Cut" ContextMenuStrip item.
|
||||
/// </summary>
|
||||
[Category("BuiltIn-ContextMenu"), DefaultValue(null), Localizable(true)]
|
||||
public string CutMenuItemText
|
||||
{
|
||||
get { return _cutMenuItemText; }
|
||||
set { _cutMenuItemText = value; }
|
||||
} string _cutMenuItemText;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the custom text of the "Paste" ContextMenuStrip item.
|
||||
/// </summary>
|
||||
[Category("BuiltIn-ContextMenu"), DefaultValue(null), Localizable(true)]
|
||||
public string PasteMenuItemText
|
||||
{
|
||||
get { return _pasteMenuItemText; }
|
||||
set { _pasteMenuItemText = value; }
|
||||
} string _pasteMenuItemText;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the custom text of the "Select All" ContextMenuStrip item.
|
||||
/// </summary>
|
||||
[Category("BuiltIn-ContextMenu"), DefaultValue(null), Localizable(true)]
|
||||
public string SelectAllMenuItemText
|
||||
{
|
||||
get { return _selectAllMenuItemText; }
|
||||
set { _selectAllMenuItemText = value; }
|
||||
} string _selectAllMenuItemText = null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the text of the "Cut" ContextMenuStrip item.
|
||||
/// </summary>
|
||||
internal string CutMenuItemTextInternal { get { return !string.IsNullOrEmpty(CutMenuItemText) ? CutMenuItemText : "Cut"; } }
|
||||
/// <summary>
|
||||
/// Gets the text of the "Copy" ContextMenuStrip item.
|
||||
/// </summary>
|
||||
internal string CopyMenuItemTextInternal { get { return !string.IsNullOrEmpty(CopyMenuItemText) ? CopyMenuItemText : "Copy"; } }
|
||||
/// <summary>
|
||||
/// Gets the text of the "Paste" ContextMenuStrip item.
|
||||
/// </summary>
|
||||
internal string PasteMenuItemTextInternal { get { return !string.IsNullOrEmpty(PasteMenuItemText) ? PasteMenuItemText : "Paste"; } }
|
||||
/// <summary>
|
||||
/// Gets the text of the "Select All" ContextMenuStrip item.
|
||||
/// </summary>
|
||||
internal string SelectAllMenuItemTextInternal { get { return !string.IsNullOrEmpty(SelectAllMenuItemText) ? SelectAllMenuItemText : "SelectAll"; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the image of the "Cut" ContextMenuStrip item.
|
||||
/// </summary>
|
||||
[Category("BuiltIn-ContextMenu"), DefaultValue(null)]
|
||||
public Image CutMenuItemImage
|
||||
{
|
||||
get { return _cutMenuItemImage; }
|
||||
set { _cutMenuItemImage = value; }
|
||||
} Image _cutMenuItemImage = null;
|
||||
/// <summary>
|
||||
/// Gets or sets the image of the "Copy" ContextMenuStrip item.
|
||||
/// </summary>
|
||||
[Category("BuiltIn-ContextMenu"), DefaultValue(null)]
|
||||
public Image CopyMenuItemImage
|
||||
{
|
||||
get { return _copyMenuItemImage; }
|
||||
set { _copyMenuItemImage = value; }
|
||||
} Image _copyMenuItemImage = null;
|
||||
/// <summary>
|
||||
/// Gets or sets the image of the "Paste" ContextMenuStrip item.
|
||||
/// </summary>
|
||||
[Category("BuiltIn-ContextMenu"), DefaultValue(null)]
|
||||
public Image PasteMenuItemImage
|
||||
{
|
||||
get { return _pasteMenuItemImage; }
|
||||
set { _pasteMenuItemImage = value; }
|
||||
} Image _pasteMenuItemImage = null;
|
||||
/// <summary>
|
||||
/// Gets or sets the image of the "Select All" ContextMenuStrip item.
|
||||
/// </summary>
|
||||
[Category("BuiltIn-ContextMenu"), DefaultValue(null)]
|
||||
public Image SelectAllMenuItemImage
|
||||
{
|
||||
get { return _selectAllMenuItemImage; }
|
||||
set { _selectAllMenuItemImage = value; }
|
||||
} Image _selectAllMenuItemImage = null;
|
||||
}
|
||||
}
|
104
Vendor/Be.Windows.Forms.HexBox/ByteCharConverters.cs
vendored
Normal file
104
Vendor/Be.Windows.Forms.HexBox/ByteCharConverters.cs
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// The interface for objects that can translate between characters and bytes.
|
||||
/// </summary>
|
||||
public interface IByteCharConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the character to display for the byte passed across.
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
/// <returns></returns>
|
||||
char ToChar(byte b);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the byte to use when the character passed across is entered during editing.
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
byte ToByte(char c);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The default <see cref="IByteCharConverter"/> implementation.
|
||||
/// </summary>
|
||||
public class DefaultByteCharConverter : IByteCharConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the character to display for the byte passed across.
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
/// <returns></returns>
|
||||
public virtual char ToChar(byte b)
|
||||
{
|
||||
return b > 0x1F && !(b > 0x7E && b < 0xA0) ? (char)b : '.';
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the byte to use for the character passed across.
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
public virtual byte ToByte(char c)
|
||||
{
|
||||
return (byte)c;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a description of the byte char provider.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "Default";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A byte char provider that can translate bytes encoded in codepage 500 EBCDIC
|
||||
/// </summary>
|
||||
public class EbcdicByteCharProvider : IByteCharConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// The IBM EBCDIC code page 500 encoding. Note that this is not always supported by .NET,
|
||||
/// the underlying platform has to provide support for it.
|
||||
/// </summary>
|
||||
private Encoding _ebcdicEncoding = Encoding.GetEncoding(500);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the EBCDIC character corresponding to the byte passed across.
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
/// <returns></returns>
|
||||
public virtual char ToChar(byte b)
|
||||
{
|
||||
string encoded = _ebcdicEncoding.GetString(new byte[] { b });
|
||||
return encoded.Length > 0 ? encoded[0] : '.';
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the byte corresponding to the EBCDIC character passed across.
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
public virtual byte ToByte(char c)
|
||||
{
|
||||
byte[] decoded = _ebcdicEncoding.GetBytes(new char[] { c });
|
||||
return decoded.Length > 0 ? decoded[0] : (byte)0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a description of the byte char provider.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "EBCDIC (Code Page 500)";
|
||||
}
|
||||
}
|
||||
}
|
127
Vendor/Be.Windows.Forms.HexBox/ByteCollection.cs
vendored
Normal file
127
Vendor/Be.Windows.Forms.HexBox/ByteCollection.cs
vendored
Normal file
|
@ -0,0 +1,127 @@
|
|||
using System;
|
||||
|
||||
using System.Collections;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a collection of bytes.
|
||||
/// </summary>
|
||||
public class ByteCollection : CollectionBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of ByteCollection class.
|
||||
/// </summary>
|
||||
public ByteCollection() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of ByteCollection class.
|
||||
/// </summary>
|
||||
/// <param name="bs">an array of bytes to add to collection</param>
|
||||
public ByteCollection(byte[] bs)
|
||||
{ AddRange(bs); }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value of a byte
|
||||
/// </summary>
|
||||
public byte this[int index]
|
||||
{
|
||||
get { return (byte)List[index]; }
|
||||
set { List[index] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a byte into the collection.
|
||||
/// </summary>
|
||||
/// <param name="b">the byte to add</param>
|
||||
public void Add(byte b)
|
||||
{ List.Add(b); }
|
||||
|
||||
/// <summary>
|
||||
/// Adds a range of bytes to the collection.
|
||||
/// </summary>
|
||||
/// <param name="bs">the bytes to add</param>
|
||||
public void AddRange(byte[] bs)
|
||||
{ InnerList.AddRange(bs); }
|
||||
|
||||
/// <summary>
|
||||
/// Removes a byte from the collection.
|
||||
/// </summary>
|
||||
/// <param name="b">the byte to remove</param>
|
||||
public void Remove(byte b)
|
||||
{ List.Remove(b); }
|
||||
|
||||
/// <summary>
|
||||
/// Removes a range of bytes from the collection.
|
||||
/// </summary>
|
||||
/// <param name="index">the index of the start byte</param>
|
||||
/// <param name="count">the count of the bytes to remove</param>
|
||||
public void RemoveRange(int index, int count)
|
||||
{ InnerList.RemoveRange(index, count); }
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a range of bytes to the collection.
|
||||
/// </summary>
|
||||
/// <param name="index">the index of start byte</param>
|
||||
/// <param name="bs">an array of bytes to insert</param>
|
||||
public void InsertRange(int index, byte[] bs)
|
||||
{ InnerList.InsertRange(index, bs); }
|
||||
|
||||
/// <summary>
|
||||
/// Gets all bytes in the array
|
||||
/// </summary>
|
||||
/// <returns>an array of bytes.</returns>
|
||||
public byte[] GetBytes()
|
||||
{
|
||||
byte[] bytes = new byte[Count];
|
||||
InnerList.CopyTo(0, bytes, 0, bytes.Length);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a byte to the collection.
|
||||
/// </summary>
|
||||
/// <param name="index">the index</param>
|
||||
/// <param name="b">a byte to insert</param>
|
||||
public void Insert(int index, byte b)
|
||||
{
|
||||
InnerList.Insert(index, b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the given byte.
|
||||
/// </summary>
|
||||
public int IndexOf(byte b)
|
||||
{
|
||||
return InnerList.IndexOf(b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true, if the byte exists in the collection.
|
||||
/// </summary>
|
||||
public bool Contains(byte b)
|
||||
{
|
||||
return InnerList.Contains(b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the content of the collection into the given array.
|
||||
/// </summary>
|
||||
public void CopyTo(byte[] bs, int index)
|
||||
{
|
||||
InnerList.CopyTo(bs, index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the content of the collection into an array.
|
||||
/// </summary>
|
||||
/// <returns>the array containing all bytes.</returns>
|
||||
public byte[] ToArray()
|
||||
{
|
||||
byte[] data = new byte[this.Count];
|
||||
this.CopyTo(data, 0);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
28
Vendor/Be.Windows.Forms.HexBox/BytePositionInfo.cs
vendored
Normal file
28
Vendor/Be.Windows.Forms.HexBox/BytePositionInfo.cs
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a position in the HexBox control
|
||||
/// </summary>
|
||||
struct BytePositionInfo
|
||||
{
|
||||
public BytePositionInfo(long index, int characterPosition)
|
||||
{
|
||||
_index = index;
|
||||
_characterPosition = characterPosition;
|
||||
}
|
||||
|
||||
public int CharacterPosition
|
||||
{
|
||||
get { return _characterPosition; }
|
||||
} int _characterPosition;
|
||||
|
||||
public long Index
|
||||
{
|
||||
get { return _index; }
|
||||
} long _index;
|
||||
}
|
||||
}
|
42
Vendor/Be.Windows.Forms.HexBox/DataBlock.cs
vendored
Normal file
42
Vendor/Be.Windows.Forms.HexBox/DataBlock.cs
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
internal abstract class DataBlock
|
||||
{
|
||||
internal DataMap _map;
|
||||
internal DataBlock _nextBlock;
|
||||
internal DataBlock _previousBlock;
|
||||
|
||||
public abstract long Length
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
public DataMap Map
|
||||
{
|
||||
get
|
||||
{
|
||||
return _map;
|
||||
}
|
||||
}
|
||||
|
||||
public DataBlock NextBlock
|
||||
{
|
||||
get
|
||||
{
|
||||
return _nextBlock;
|
||||
}
|
||||
}
|
||||
|
||||
public DataBlock PreviousBlock
|
||||
{
|
||||
get
|
||||
{
|
||||
return _previousBlock;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void RemoveBytes(long position, long count);
|
||||
}
|
||||
}
|
318
Vendor/Be.Windows.Forms.HexBox/DataMap.cs
vendored
Normal file
318
Vendor/Be.Windows.Forms.HexBox/DataMap.cs
vendored
Normal file
|
@ -0,0 +1,318 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
internal class DataMap : ICollection, IEnumerable
|
||||
{
|
||||
readonly object _syncRoot = new object();
|
||||
internal int _count;
|
||||
internal DataBlock _firstBlock;
|
||||
internal int _version;
|
||||
|
||||
public DataMap()
|
||||
{
|
||||
}
|
||||
|
||||
public DataMap(IEnumerable collection)
|
||||
{
|
||||
if (collection == null)
|
||||
{
|
||||
throw new ArgumentNullException("collection");
|
||||
}
|
||||
|
||||
foreach (DataBlock item in collection)
|
||||
{
|
||||
AddLast(item);
|
||||
}
|
||||
}
|
||||
|
||||
public DataBlock FirstBlock
|
||||
{
|
||||
get
|
||||
{
|
||||
return _firstBlock;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddAfter(DataBlock block, DataBlock newBlock)
|
||||
{
|
||||
AddAfterInternal(block, newBlock);
|
||||
}
|
||||
|
||||
public void AddBefore(DataBlock block, DataBlock newBlock)
|
||||
{
|
||||
AddBeforeInternal(block, newBlock);
|
||||
}
|
||||
|
||||
public void AddFirst(DataBlock block)
|
||||
{
|
||||
if (_firstBlock == null)
|
||||
{
|
||||
AddBlockToEmptyMap(block);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddBeforeInternal(_firstBlock, block);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddLast(DataBlock block)
|
||||
{
|
||||
if (_firstBlock == null)
|
||||
{
|
||||
AddBlockToEmptyMap(block);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddAfterInternal(GetLastBlock(), block);
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove(DataBlock block)
|
||||
{
|
||||
RemoveInternal(block);
|
||||
}
|
||||
|
||||
public void RemoveFirst()
|
||||
{
|
||||
if (_firstBlock == null)
|
||||
{
|
||||
throw new InvalidOperationException("The collection is empty.");
|
||||
}
|
||||
RemoveInternal(_firstBlock);
|
||||
}
|
||||
|
||||
public void RemoveLast()
|
||||
{
|
||||
if (_firstBlock == null)
|
||||
{
|
||||
throw new InvalidOperationException("The collection is empty.");
|
||||
}
|
||||
RemoveInternal(GetLastBlock());
|
||||
}
|
||||
|
||||
public DataBlock Replace(DataBlock block, DataBlock newBlock)
|
||||
{
|
||||
AddAfterInternal(block, newBlock);
|
||||
RemoveInternal(block);
|
||||
return newBlock;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
DataBlock block = FirstBlock;
|
||||
while (block != null)
|
||||
{
|
||||
DataBlock nextBlock = block.NextBlock;
|
||||
InvalidateBlock(block);
|
||||
block = nextBlock;
|
||||
}
|
||||
_firstBlock = null;
|
||||
_count = 0;
|
||||
_version++;
|
||||
}
|
||||
|
||||
void AddAfterInternal(DataBlock block, DataBlock newBlock)
|
||||
{
|
||||
newBlock._previousBlock = block;
|
||||
newBlock._nextBlock = block._nextBlock;
|
||||
newBlock._map = this;
|
||||
|
||||
if (block._nextBlock != null)
|
||||
{
|
||||
block._nextBlock._previousBlock = newBlock;
|
||||
}
|
||||
block._nextBlock = newBlock;
|
||||
|
||||
this._version++;
|
||||
this._count++;
|
||||
}
|
||||
|
||||
void AddBeforeInternal(DataBlock block, DataBlock newBlock)
|
||||
{
|
||||
newBlock._nextBlock = block;
|
||||
newBlock._previousBlock = block._previousBlock;
|
||||
newBlock._map = this;
|
||||
|
||||
if (block._previousBlock != null)
|
||||
{
|
||||
block._previousBlock._nextBlock = newBlock;
|
||||
}
|
||||
block._previousBlock = newBlock;
|
||||
|
||||
if (_firstBlock == block)
|
||||
{
|
||||
_firstBlock = newBlock;
|
||||
}
|
||||
this._version++;
|
||||
this._count++;
|
||||
}
|
||||
|
||||
void RemoveInternal(DataBlock block)
|
||||
{
|
||||
DataBlock previousBlock = block._previousBlock;
|
||||
DataBlock nextBlock = block._nextBlock;
|
||||
|
||||
if (previousBlock != null)
|
||||
{
|
||||
previousBlock._nextBlock = nextBlock;
|
||||
}
|
||||
|
||||
if (nextBlock != null)
|
||||
{
|
||||
nextBlock._previousBlock = previousBlock;
|
||||
}
|
||||
|
||||
if (_firstBlock == block)
|
||||
{
|
||||
_firstBlock = nextBlock;
|
||||
}
|
||||
|
||||
InvalidateBlock(block);
|
||||
|
||||
_count--;
|
||||
_version++;
|
||||
}
|
||||
|
||||
DataBlock GetLastBlock()
|
||||
{
|
||||
DataBlock lastBlock = null;
|
||||
for (DataBlock block = FirstBlock; block != null; block = block.NextBlock)
|
||||
{
|
||||
lastBlock = block;
|
||||
}
|
||||
return lastBlock;
|
||||
}
|
||||
|
||||
void InvalidateBlock(DataBlock block)
|
||||
{
|
||||
block._map = null;
|
||||
block._nextBlock = null;
|
||||
block._previousBlock = null;
|
||||
}
|
||||
|
||||
void AddBlockToEmptyMap(DataBlock block)
|
||||
{
|
||||
block._map = this;
|
||||
block._nextBlock = null;
|
||||
block._previousBlock = null;
|
||||
|
||||
_firstBlock = block;
|
||||
_version++;
|
||||
_count++;
|
||||
}
|
||||
|
||||
#region ICollection Members
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
DataBlock[] blockArray = array as DataBlock[];
|
||||
for (DataBlock block = FirstBlock; block != null; block = block.NextBlock)
|
||||
{
|
||||
blockArray[index++] = block;
|
||||
}
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public object SyncRoot
|
||||
{
|
||||
get
|
||||
{
|
||||
return _syncRoot;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IEnumerable Members
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Enumerator Nested Type
|
||||
internal class Enumerator : IEnumerator, IDisposable
|
||||
{
|
||||
DataMap _map;
|
||||
DataBlock _current;
|
||||
int _index;
|
||||
int _version;
|
||||
|
||||
internal Enumerator(DataMap map)
|
||||
{
|
||||
_map = map;
|
||||
_version = map._version;
|
||||
_current = null;
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_index < 0 || _index > _map.Count)
|
||||
{
|
||||
throw new InvalidOperationException("Enumerator is positioned before the first element or after the last element of the collection.");
|
||||
}
|
||||
return _current;
|
||||
}
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (this._version != _map._version)
|
||||
{
|
||||
throw new InvalidOperationException("Collection was modified after the enumerator was instantiated.");
|
||||
}
|
||||
|
||||
if (_index >= _map.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (++_index == 0)
|
||||
{
|
||||
_current = _map.FirstBlock;
|
||||
}
|
||||
else
|
||||
{
|
||||
_current = _current.NextBlock;
|
||||
}
|
||||
|
||||
return (_index < _map.Count);
|
||||
}
|
||||
|
||||
void IEnumerator.Reset()
|
||||
{
|
||||
if (this._version != this._map._version)
|
||||
{
|
||||
throw new InvalidOperationException("Collection was modified after the enumerator was instantiated.");
|
||||
}
|
||||
|
||||
this._index = -1;
|
||||
this._current = null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
177
Vendor/Be.Windows.Forms.HexBox/DynamicByteProvider.cs
vendored
Normal file
177
Vendor/Be.Windows.Forms.HexBox/DynamicByteProvider.cs
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Byte provider for a small amount of data.
|
||||
/// </summary>
|
||||
public class DynamicByteProvider : IByteProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information about changes.
|
||||
/// </summary>
|
||||
bool _hasChanges;
|
||||
/// <summary>
|
||||
/// Contains a byte collection.
|
||||
/// </summary>
|
||||
List<byte> _bytes;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the DynamicByteProvider class.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
public DynamicByteProvider(byte[] data) : this(new List<Byte>(data))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the DynamicByteProvider class.
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
public DynamicByteProvider(List<Byte> bytes)
|
||||
{
|
||||
_bytes = bytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the Changed event.
|
||||
/// </summary>
|
||||
void OnChanged(EventArgs e)
|
||||
{
|
||||
_hasChanges = true;
|
||||
|
||||
if(Changed != null)
|
||||
Changed(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the LengthChanged event.
|
||||
/// </summary>
|
||||
void OnLengthChanged(EventArgs e)
|
||||
{
|
||||
if(LengthChanged != null)
|
||||
LengthChanged(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the byte collection.
|
||||
/// </summary>
|
||||
public List<Byte> Bytes
|
||||
{
|
||||
get { return _bytes; }
|
||||
}
|
||||
|
||||
#region IByteProvider Members
|
||||
/// <summary>
|
||||
/// True, when changes are done.
|
||||
/// </summary>
|
||||
public bool HasChanges()
|
||||
{
|
||||
return _hasChanges;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies changes.
|
||||
/// </summary>
|
||||
public void ApplyChanges()
|
||||
{
|
||||
_hasChanges = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs, when the write buffer contains new changes.
|
||||
/// </summary>
|
||||
public event EventHandler Changed;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs, when InsertBytes or DeleteBytes method is called.
|
||||
/// </summary>
|
||||
public event EventHandler LengthChanged;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads a byte from the byte collection.
|
||||
/// </summary>
|
||||
/// <param name="index">the index of the byte to read</param>
|
||||
/// <returns>the byte</returns>
|
||||
public byte ReadByte(long index)
|
||||
{ return _bytes[(int)index]; }
|
||||
|
||||
/// <summary>
|
||||
/// Write a byte into the byte collection.
|
||||
/// </summary>
|
||||
/// <param name="index">the index of the byte to write.</param>
|
||||
/// <param name="value">the byte</param>
|
||||
public void WriteByte(long index, byte value)
|
||||
{
|
||||
_bytes[(int)index] = value;
|
||||
OnChanged(EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes bytes from the byte collection.
|
||||
/// </summary>
|
||||
/// <param name="index">the start index of the bytes to delete.</param>
|
||||
/// <param name="length">the length of bytes to delete.</param>
|
||||
public void DeleteBytes(long index, long length)
|
||||
{
|
||||
int internal_index = (int)Math.Max(0, index);
|
||||
int internal_length = (int)Math.Min((int)Length, length);
|
||||
_bytes.RemoveRange(internal_index, internal_length);
|
||||
|
||||
OnLengthChanged(EventArgs.Empty);
|
||||
OnChanged(EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts byte into the byte collection.
|
||||
/// </summary>
|
||||
/// <param name="index">the start index of the bytes in the byte collection</param>
|
||||
/// <param name="bs">the byte array to insert</param>
|
||||
public void InsertBytes(long index, byte[] bs)
|
||||
{
|
||||
_bytes.InsertRange((int)index, bs);
|
||||
|
||||
OnLengthChanged(EventArgs.Empty);
|
||||
OnChanged(EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of the bytes in the byte collection.
|
||||
/// </summary>
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return _bytes.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true
|
||||
/// </summary>
|
||||
public bool SupportsWriteByte()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true
|
||||
/// </summary>
|
||||
public bool SupportsInsertBytes()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true
|
||||
/// </summary>
|
||||
public bool SupportsDeleteBytes()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
569
Vendor/Be.Windows.Forms.HexBox/DynamicFileByteProvider.cs
vendored
Normal file
569
Vendor/Be.Windows.Forms.HexBox/DynamicFileByteProvider.cs
vendored
Normal file
|
@ -0,0 +1,569 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements a fully editable byte provider for file data of any size.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only changes to the file are stored in memory with reads from the
|
||||
/// original data occurring as required.
|
||||
/// </remarks>
|
||||
public sealed class DynamicFileByteProvider : IByteProvider, IDisposable
|
||||
{
|
||||
const int COPY_BLOCK_SIZE = 4096;
|
||||
|
||||
string _fileName;
|
||||
Stream _stream;
|
||||
DataMap _dataMap;
|
||||
long _totalLength;
|
||||
bool _readOnly;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="DynamicFileByteProvider" /> instance.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the file from which bytes should be provided.</param>
|
||||
public DynamicFileByteProvider(string fileName) : this(fileName, false) { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="DynamicFileByteProvider" /> instance.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the file from which bytes should be provided.</param>
|
||||
/// <param name="readOnly">True, opens the file in read-only mode.</param>
|
||||
public DynamicFileByteProvider(string fileName, bool readOnly)
|
||||
{
|
||||
_fileName = fileName;
|
||||
|
||||
if (!readOnly)
|
||||
{
|
||||
_stream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
|
||||
}
|
||||
else
|
||||
{
|
||||
_stream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
}
|
||||
|
||||
_readOnly = readOnly;
|
||||
|
||||
ReInitialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="DynamicFileByteProvider" /> instance.
|
||||
/// </summary>
|
||||
/// <param name="stream">the stream containing the data.</param>
|
||||
/// <remarks>
|
||||
/// The stream must supported seek operations.
|
||||
/// </remarks>
|
||||
public DynamicFileByteProvider(Stream stream)
|
||||
{
|
||||
if (stream == null)
|
||||
throw new ArgumentNullException("stream");
|
||||
if (!stream.CanSeek)
|
||||
throw new ArgumentException("stream must supported seek operations(CanSeek)");
|
||||
|
||||
_stream = stream;
|
||||
_readOnly = !stream.CanWrite;
|
||||
ReInitialize();
|
||||
}
|
||||
|
||||
#region IByteProvider Members
|
||||
/// <summary>
|
||||
/// See <see cref="IByteProvider.LengthChanged" /> for more information.
|
||||
/// </summary>
|
||||
public event EventHandler LengthChanged;
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="IByteProvider.Changed" /> for more information.
|
||||
/// </summary>
|
||||
public event EventHandler Changed;
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="IByteProvider.ReadByte" /> for more information.
|
||||
/// </summary>
|
||||
public byte ReadByte(long index)
|
||||
{
|
||||
long blockOffset;
|
||||
DataBlock block = GetDataBlock(index, out blockOffset);
|
||||
FileDataBlock fileBlock = block as FileDataBlock;
|
||||
if (fileBlock != null)
|
||||
{
|
||||
return ReadByteFromFile(fileBlock.FileOffset + index - blockOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
MemoryDataBlock memoryBlock = (MemoryDataBlock)block;
|
||||
return memoryBlock.Data[index - blockOffset];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="IByteProvider.WriteByte" /> for more information.
|
||||
/// </summary>
|
||||
public void WriteByte(long index, byte value)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Find the block affected.
|
||||
long blockOffset;
|
||||
DataBlock block = GetDataBlock(index, out blockOffset);
|
||||
|
||||
// If the byte is already in a memory block, modify it.
|
||||
MemoryDataBlock memoryBlock = block as MemoryDataBlock;
|
||||
if (memoryBlock != null)
|
||||
{
|
||||
memoryBlock.Data[index - blockOffset] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
FileDataBlock fileBlock = (FileDataBlock)block;
|
||||
|
||||
// If the byte changing is the first byte in the block and the previous block is a memory block, extend that.
|
||||
if (blockOffset == index && block.PreviousBlock != null)
|
||||
{
|
||||
MemoryDataBlock previousMemoryBlock = block.PreviousBlock as MemoryDataBlock;
|
||||
if (previousMemoryBlock != null)
|
||||
{
|
||||
previousMemoryBlock.AddByteToEnd(value);
|
||||
fileBlock.RemoveBytesFromStart(1);
|
||||
if (fileBlock.Length == 0)
|
||||
{
|
||||
_dataMap.Remove(fileBlock);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If the byte changing is the last byte in the block and the next block is a memory block, extend that.
|
||||
if (blockOffset + fileBlock.Length - 1 == index && block.NextBlock != null)
|
||||
{
|
||||
MemoryDataBlock nextMemoryBlock = block.NextBlock as MemoryDataBlock;
|
||||
if (nextMemoryBlock != null)
|
||||
{
|
||||
nextMemoryBlock.AddByteToStart(value);
|
||||
fileBlock.RemoveBytesFromEnd(1);
|
||||
if (fileBlock.Length == 0)
|
||||
{
|
||||
_dataMap.Remove(fileBlock);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Split the block into a prefix and a suffix and place a memory block in-between.
|
||||
FileDataBlock prefixBlock = null;
|
||||
if (index > blockOffset)
|
||||
{
|
||||
prefixBlock = new FileDataBlock(fileBlock.FileOffset, index - blockOffset);
|
||||
}
|
||||
|
||||
FileDataBlock suffixBlock = null;
|
||||
if (index < blockOffset + fileBlock.Length - 1)
|
||||
{
|
||||
suffixBlock = new FileDataBlock(
|
||||
fileBlock.FileOffset + index - blockOffset + 1,
|
||||
fileBlock.Length - (index - blockOffset + 1));
|
||||
}
|
||||
|
||||
block = _dataMap.Replace(block, new MemoryDataBlock(value));
|
||||
|
||||
if (prefixBlock != null)
|
||||
{
|
||||
_dataMap.AddBefore(block, prefixBlock);
|
||||
}
|
||||
|
||||
if (suffixBlock != null)
|
||||
{
|
||||
_dataMap.AddAfter(block, suffixBlock);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
OnChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="IByteProvider.InsertBytes" /> for more information.
|
||||
/// </summary>
|
||||
public void InsertBytes(long index, byte[] bs)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Find the block affected.
|
||||
long blockOffset;
|
||||
DataBlock block = GetDataBlock(index, out blockOffset);
|
||||
|
||||
// If the insertion point is in a memory block, just insert it.
|
||||
MemoryDataBlock memoryBlock = block as MemoryDataBlock;
|
||||
if (memoryBlock != null)
|
||||
{
|
||||
memoryBlock.InsertBytes(index - blockOffset, bs);
|
||||
return;
|
||||
}
|
||||
|
||||
FileDataBlock fileBlock = (FileDataBlock)block;
|
||||
|
||||
// If the insertion point is at the start of a file block, and the previous block is a memory block, append it to that block.
|
||||
if (blockOffset == index && block.PreviousBlock != null)
|
||||
{
|
||||
MemoryDataBlock previousMemoryBlock = block.PreviousBlock as MemoryDataBlock;
|
||||
if (previousMemoryBlock != null)
|
||||
{
|
||||
previousMemoryBlock.InsertBytes(previousMemoryBlock.Length, bs);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Split the block into a prefix and a suffix and place a memory block in-between.
|
||||
FileDataBlock prefixBlock = null;
|
||||
if (index > blockOffset)
|
||||
{
|
||||
prefixBlock = new FileDataBlock(fileBlock.FileOffset, index - blockOffset);
|
||||
}
|
||||
|
||||
FileDataBlock suffixBlock = null;
|
||||
if (index < blockOffset + fileBlock.Length)
|
||||
{
|
||||
suffixBlock = new FileDataBlock(
|
||||
fileBlock.FileOffset + index - blockOffset,
|
||||
fileBlock.Length - (index - blockOffset));
|
||||
}
|
||||
|
||||
block = _dataMap.Replace(block, new MemoryDataBlock(bs));
|
||||
|
||||
if (prefixBlock != null)
|
||||
{
|
||||
_dataMap.AddBefore(block, prefixBlock);
|
||||
}
|
||||
|
||||
if (suffixBlock != null)
|
||||
{
|
||||
_dataMap.AddAfter(block, suffixBlock);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_totalLength += bs.Length;
|
||||
OnLengthChanged(EventArgs.Empty);
|
||||
OnChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="IByteProvider.DeleteBytes" /> for more information.
|
||||
/// </summary>
|
||||
public void DeleteBytes(long index, long length)
|
||||
{
|
||||
try
|
||||
{
|
||||
long bytesToDelete = length;
|
||||
|
||||
// Find the first block affected.
|
||||
long blockOffset;
|
||||
DataBlock block = GetDataBlock(index, out blockOffset);
|
||||
|
||||
// Truncate or remove each block as necessary.
|
||||
while ((bytesToDelete > 0) && (block != null))
|
||||
{
|
||||
long blockLength = block.Length;
|
||||
DataBlock nextBlock = block.NextBlock;
|
||||
|
||||
// Delete the appropriate section from the block (this may result in two blocks or a zero length block).
|
||||
long count = Math.Min(bytesToDelete, blockLength - (index - blockOffset));
|
||||
block.RemoveBytes(index - blockOffset, count);
|
||||
|
||||
if (block.Length == 0)
|
||||
{
|
||||
_dataMap.Remove(block);
|
||||
if (_dataMap.FirstBlock == null)
|
||||
{
|
||||
_dataMap.AddFirst(new MemoryDataBlock(new byte[0]));
|
||||
}
|
||||
}
|
||||
|
||||
bytesToDelete -= count;
|
||||
blockOffset += block.Length;
|
||||
block = (bytesToDelete > 0) ? nextBlock : null;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_totalLength -= length;
|
||||
OnLengthChanged(EventArgs.Empty);
|
||||
OnChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="IByteProvider.Length" /> for more information.
|
||||
/// </summary>
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return _totalLength;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="IByteProvider.HasChanges" /> for more information.
|
||||
/// </summary>
|
||||
public bool HasChanges()
|
||||
{
|
||||
if (_readOnly)
|
||||
return false;
|
||||
|
||||
if (_totalLength != _stream.Length)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
long offset = 0;
|
||||
for (DataBlock block = _dataMap.FirstBlock; block != null; block = block.NextBlock)
|
||||
{
|
||||
FileDataBlock fileBlock = block as FileDataBlock;
|
||||
if (fileBlock == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fileBlock.FileOffset != offset)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
offset += fileBlock.Length;
|
||||
}
|
||||
return (offset != _stream.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="IByteProvider.ApplyChanges" /> for more information.
|
||||
/// </summary>
|
||||
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 > _stream.Length)
|
||||
{
|
||||
_stream.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)
|
||||
{
|
||||
_stream.Position = dataOffset;
|
||||
for (int memoryOffset = 0; memoryOffset < memoryBlock.Length; memoryOffset += COPY_BLOCK_SIZE)
|
||||
{
|
||||
_stream.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.
|
||||
_stream.SetLength(_totalLength);
|
||||
ReInitialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="IByteProvider.SupportsWriteByte" /> for more information.
|
||||
/// </summary>
|
||||
public bool SupportsWriteByte()
|
||||
{
|
||||
return !_readOnly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="IByteProvider.SupportsInsertBytes" /> for more information.
|
||||
/// </summary>
|
||||
public bool SupportsInsertBytes()
|
||||
{
|
||||
return !_readOnly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="IByteProvider.SupportsDeleteBytes" /> for more information.
|
||||
/// </summary>
|
||||
public bool SupportsDeleteBytes()
|
||||
{
|
||||
return !_readOnly;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
/// <summary>
|
||||
/// See <see cref="Object.Finalize" /> for more information.
|
||||
/// </summary>
|
||||
~DynamicFileByteProvider()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="IDisposable.Dispose" /> for more information.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (_stream != null)
|
||||
{
|
||||
_stream.Close();
|
||||
_stream = null;
|
||||
}
|
||||
_fileName = null;
|
||||
_dataMap = null;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value, if the file is opened in read-only mode.
|
||||
/// </summary>
|
||||
public bool ReadOnly
|
||||
{
|
||||
get { return _readOnly; }
|
||||
}
|
||||
|
||||
void OnLengthChanged(EventArgs e)
|
||||
{
|
||||
if (LengthChanged != null)
|
||||
LengthChanged(this, e);
|
||||
}
|
||||
|
||||
void OnChanged(EventArgs e)
|
||||
{
|
||||
if (Changed != null)
|
||||
{
|
||||
Changed(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
DataBlock GetDataBlock(long findOffset, out long blockOffset)
|
||||
{
|
||||
if (findOffset < 0 || findOffset > _totalLength)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("findOffset");
|
||||
}
|
||||
|
||||
// Iterate over the blocks until the block containing the required offset is encountered.
|
||||
blockOffset = 0;
|
||||
for (DataBlock block = _dataMap.FirstBlock; block != null; block = block.NextBlock)
|
||||
{
|
||||
if ((blockOffset <= findOffset && blockOffset + block.Length > findOffset) || block.NextBlock == null)
|
||||
{
|
||||
return block;
|
||||
}
|
||||
blockOffset += block.Length;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
FileDataBlock GetNextFileDataBlock(DataBlock block, long dataOffset, out long nextDataOffset)
|
||||
{
|
||||
// Iterate over the remaining blocks until a file block is encountered.
|
||||
nextDataOffset = dataOffset + block.Length;
|
||||
block = block.NextBlock;
|
||||
while (block != null)
|
||||
{
|
||||
FileDataBlock fileBlock = block as FileDataBlock;
|
||||
if (fileBlock != null)
|
||||
{
|
||||
return fileBlock;
|
||||
}
|
||||
nextDataOffset += block.Length;
|
||||
block = block.NextBlock;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
byte ReadByteFromFile(long fileOffset)
|
||||
{
|
||||
// Move to the correct position and read the byte.
|
||||
if (_stream.Position != fileOffset)
|
||||
{
|
||||
_stream.Position = fileOffset;
|
||||
}
|
||||
return (byte)_stream.ReadByte();
|
||||
}
|
||||
|
||||
void MoveFileBlock(FileDataBlock fileBlock, long dataOffset)
|
||||
{
|
||||
// First, determine whether the next file block needs to move before this one.
|
||||
long nextDataOffset;
|
||||
FileDataBlock nextFileBlock = GetNextFileDataBlock(fileBlock, dataOffset, out nextDataOffset);
|
||||
if (nextFileBlock != null && dataOffset + fileBlock.Length > nextFileBlock.FileOffset)
|
||||
{
|
||||
// The next block needs to move first, so do that now.
|
||||
MoveFileBlock(nextFileBlock, nextDataOffset);
|
||||
}
|
||||
|
||||
// Now, move the block.
|
||||
if (fileBlock.FileOffset > dataOffset)
|
||||
{
|
||||
// Move the section to earlier in the file stream (done in chunks starting at the beginning of the section).
|
||||
byte[] buffer = new byte[COPY_BLOCK_SIZE];
|
||||
for (long relativeOffset = 0; relativeOffset < fileBlock.Length; relativeOffset += buffer.Length)
|
||||
{
|
||||
long readOffset = fileBlock.FileOffset + relativeOffset;
|
||||
int bytesToRead = (int)Math.Min(buffer.Length, fileBlock.Length - relativeOffset);
|
||||
_stream.Position = readOffset;
|
||||
_stream.Read(buffer, 0, bytesToRead);
|
||||
|
||||
long writeOffset = dataOffset + relativeOffset;
|
||||
_stream.Position = writeOffset;
|
||||
_stream.Write(buffer, 0, bytesToRead);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Move the section to later in the file stream (done in chunks starting at the end of the section).
|
||||
byte[] buffer = new byte[COPY_BLOCK_SIZE];
|
||||
for (long relativeOffset = 0; relativeOffset < fileBlock.Length; relativeOffset += buffer.Length)
|
||||
{
|
||||
int bytesToRead = (int)Math.Min(buffer.Length, fileBlock.Length - relativeOffset);
|
||||
long readOffset = fileBlock.FileOffset + fileBlock.Length - relativeOffset - bytesToRead;
|
||||
_stream.Position = readOffset;
|
||||
_stream.Read(buffer, 0, bytesToRead);
|
||||
|
||||
long writeOffset = dataOffset + fileBlock.Length - relativeOffset - bytesToRead;
|
||||
_stream.Position = writeOffset;
|
||||
_stream.Write(buffer, 0, bytesToRead);
|
||||
}
|
||||
}
|
||||
|
||||
// This block now points to a different position in the file.
|
||||
fileBlock.SetFileOffset(dataOffset);
|
||||
}
|
||||
|
||||
void ReInitialize()
|
||||
{
|
||||
_dataMap = new DataMap();
|
||||
_dataMap.AddFirst(new FileDataBlock(0, _stream.Length));
|
||||
_totalLength = _stream.Length;
|
||||
}
|
||||
}
|
||||
}
|
271
Vendor/Be.Windows.Forms.HexBox/FileByteProvider.cs
vendored
Normal file
271
Vendor/Be.Windows.Forms.HexBox/FileByteProvider.cs
vendored
Normal file
|
@ -0,0 +1,271 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Byte provider for (big) files.
|
||||
/// </summary>
|
||||
public class FileByteProvider : IByteProvider, IDisposable
|
||||
{
|
||||
#region WriteCollection class
|
||||
/// <summary>
|
||||
/// Represents the write buffer class
|
||||
/// </summary>
|
||||
class WriteCollection : DictionaryBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a byte in the collection
|
||||
/// </summary>
|
||||
public byte this[long index]
|
||||
{
|
||||
get { return (byte)this.Dictionary[index]; }
|
||||
set { Dictionary[index] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a byte into the collection
|
||||
/// </summary>
|
||||
/// <param name="index">the index of the byte</param>
|
||||
/// <param name="value">the value of the byte</param>
|
||||
public void Add(long index, byte value)
|
||||
{ Dictionary.Add(index, value); }
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a byte with the given index exists.
|
||||
/// </summary>
|
||||
/// <param name="index">the index of the byte</param>
|
||||
/// <returns>true, if the is in the collection</returns>
|
||||
public bool Contains(long index)
|
||||
{ return Dictionary.Contains(index); }
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Occurs, when the write buffer contains new changes.
|
||||
/// </summary>
|
||||
public event EventHandler Changed;
|
||||
|
||||
/// <summary>
|
||||
/// Contains all changes
|
||||
/// </summary>
|
||||
WriteCollection _writes = new WriteCollection();
|
||||
|
||||
/// <summary>
|
||||
/// Contains the file name.
|
||||
/// </summary>
|
||||
string _fileName;
|
||||
/// <summary>
|
||||
/// Contains the file stream.
|
||||
/// </summary>
|
||||
FileStream _fileStream;
|
||||
/// <summary>
|
||||
/// Read-only access.
|
||||
/// </summary>
|
||||
bool _readOnly;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the FileByteProvider class.
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
public FileByteProvider(string fileName)
|
||||
{
|
||||
_fileName = fileName;
|
||||
|
||||
try
|
||||
{
|
||||
// try to open in write mode
|
||||
_fileStream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// write mode failed, try to open in read-only and fileshare friendly mode.
|
||||
try
|
||||
{
|
||||
_fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
_readOnly = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Terminates the instance of the FileByteProvider class.
|
||||
/// </summary>
|
||||
~FileByteProvider()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the Changed event.
|
||||
/// </summary>
|
||||
/// <remarks>Never used.</remarks>
|
||||
void OnChanged(EventArgs e)
|
||||
{
|
||||
if(Changed != null)
|
||||
Changed(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the file the byte provider is using.
|
||||
/// </summary>
|
||||
public string FileName
|
||||
{
|
||||
get { return _fileName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value if there are some changes.
|
||||
/// </summary>
|
||||
/// <returns>true, if there are some changes</returns>
|
||||
public bool HasChanges()
|
||||
{
|
||||
return (_writes.Count > 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the file with all changes the write buffer contains.
|
||||
/// </summary>
|
||||
public void ApplyChanges()
|
||||
{
|
||||
if (this._readOnly)
|
||||
{
|
||||
throw new Exception("File is in read-only mode.");
|
||||
}
|
||||
|
||||
if(!HasChanges())
|
||||
return;
|
||||
|
||||
IDictionaryEnumerator en = _writes.GetEnumerator();
|
||||
while(en.MoveNext())
|
||||
{
|
||||
long index = (long)en.Key;
|
||||
byte value = (byte)en.Value;
|
||||
if(_fileStream.Position != index)
|
||||
_fileStream.Position = index;
|
||||
_fileStream.Write(new byte[] { value }, 0, 1);
|
||||
}
|
||||
_writes.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the write buffer and reject all changes made.
|
||||
/// </summary>
|
||||
public void RejectChanges()
|
||||
{
|
||||
_writes.Clear();
|
||||
}
|
||||
|
||||
#region IByteProvider Members
|
||||
/// <summary>
|
||||
/// Never used.
|
||||
/// </summary>
|
||||
public event EventHandler LengthChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Reads a byte from the file.
|
||||
/// </summary>
|
||||
/// <param name="index">the index of the byte to read</param>
|
||||
/// <returns>the byte</returns>
|
||||
public byte ReadByte(long index)
|
||||
{
|
||||
if(_writes.Contains(index))
|
||||
return _writes[index];
|
||||
|
||||
if(_fileStream.Position != index)
|
||||
_fileStream.Position = index;
|
||||
|
||||
byte res = (byte)_fileStream.ReadByte();
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of the file.
|
||||
/// </summary>
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return _fileStream.Length;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a byte into write buffer
|
||||
/// </summary>
|
||||
public void WriteByte(long index, byte value)
|
||||
{
|
||||
if(_writes.Contains(index))
|
||||
_writes[index] = value;
|
||||
else
|
||||
_writes.Add(index, value);
|
||||
|
||||
OnChanged(EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not supported
|
||||
/// </summary>
|
||||
public void DeleteBytes(long index, long length)
|
||||
{
|
||||
throw new NotSupportedException("FileByteProvider.DeleteBytes");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not supported
|
||||
/// </summary>
|
||||
public void InsertBytes(long index, byte[] bs)
|
||||
{
|
||||
throw new NotSupportedException("FileByteProvider.InsertBytes");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true
|
||||
/// </summary>
|
||||
public bool SupportsWriteByte()
|
||||
{
|
||||
return !_readOnly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns false
|
||||
/// </summary>
|
||||
public bool SupportsInsertBytes()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns false
|
||||
/// </summary>
|
||||
public bool SupportsDeleteBytes()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
/// <summary>
|
||||
/// Releases the file handle used by the FileByteProvider.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if(_fileStream != null)
|
||||
{
|
||||
_fileName = null;
|
||||
|
||||
_fileStream.Close();
|
||||
_fileStream = null;
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
96
Vendor/Be.Windows.Forms.HexBox/FileDataBlock.cs
vendored
Normal file
96
Vendor/Be.Windows.Forms.HexBox/FileDataBlock.cs
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
using System;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
internal sealed class FileDataBlock : DataBlock
|
||||
{
|
||||
long _length;
|
||||
long _fileOffset;
|
||||
|
||||
public FileDataBlock(long fileOffset, long length)
|
||||
{
|
||||
_fileOffset = fileOffset;
|
||||
_length = length;
|
||||
}
|
||||
|
||||
public long FileOffset
|
||||
{
|
||||
get
|
||||
{
|
||||
return _fileOffset;
|
||||
}
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFileOffset(long value)
|
||||
{
|
||||
_fileOffset = value;
|
||||
}
|
||||
|
||||
public void RemoveBytesFromEnd(long count)
|
||||
{
|
||||
if (count > _length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("count");
|
||||
}
|
||||
|
||||
_length -= count;
|
||||
}
|
||||
|
||||
public void RemoveBytesFromStart(long count)
|
||||
{
|
||||
if (count > _length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("count");
|
||||
}
|
||||
|
||||
_fileOffset += count;
|
||||
_length -= count;
|
||||
}
|
||||
|
||||
public override void RemoveBytes(long position, long count)
|
||||
{
|
||||
if (position > _length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("position");
|
||||
}
|
||||
|
||||
if (position + count > _length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("count");
|
||||
}
|
||||
|
||||
long prefixLength = position;
|
||||
long prefixFileOffset = _fileOffset;
|
||||
|
||||
long suffixLength = _length - count - prefixLength;
|
||||
long suffixFileOffset = _fileOffset + position + count;
|
||||
|
||||
if (prefixLength > 0 && suffixLength > 0)
|
||||
{
|
||||
_fileOffset = prefixFileOffset;
|
||||
_length = prefixLength;
|
||||
_map.AddAfter(this, new FileDataBlock(suffixFileOffset, suffixLength));
|
||||
return;
|
||||
}
|
||||
|
||||
if (prefixLength > 0)
|
||||
{
|
||||
_fileOffset = prefixFileOffset;
|
||||
_length = prefixLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fileOffset = suffixFileOffset;
|
||||
_length = suffixLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
Vendor/Be.Windows.Forms.HexBox/HexBox.bmp
vendored
Normal file
BIN
Vendor/Be.Windows.Forms.HexBox/HexBox.bmp
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 246 B |
3701
Vendor/Be.Windows.Forms.HexBox/HexBox.cs
vendored
Normal file
3701
Vendor/Be.Windows.Forms.HexBox/HexBox.cs
vendored
Normal file
File diff suppressed because it is too large
Load diff
126
Vendor/Be.Windows.Forms.HexBox/HexBox.resx
vendored
Normal file
126
Vendor/Be.Windows.Forms.HexBox/HexBox.resx
vendored
Normal file
|
@ -0,0 +1,126 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
BIN
Vendor/Be.Windows.Forms.HexBox/HexBox.snk
vendored
Normal file
BIN
Vendor/Be.Windows.Forms.HexBox/HexBox.snk
vendored
Normal file
Binary file not shown.
21
Vendor/Be.Windows.Forms.HexBox/HexCasing.cs
vendored
Normal file
21
Vendor/Be.Windows.Forms.HexBox/HexCasing.cs
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the case of hex characters in the HexBox control
|
||||
/// </summary>
|
||||
public enum HexCasing
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts all characters to uppercase.
|
||||
/// </summary>
|
||||
Upper = 0,
|
||||
/// <summary>
|
||||
/// Converts all characters to lowercase.
|
||||
/// </summary>
|
||||
Lower = 1
|
||||
}
|
||||
}
|
75
Vendor/Be.Windows.Forms.HexBox/IByteProvider.cs
vendored
Normal file
75
Vendor/Be.Windows.Forms.HexBox/IByteProvider.cs
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
using System;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a byte provider for HexBox control
|
||||
/// </summary>
|
||||
public interface IByteProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a byte from the provider
|
||||
/// </summary>
|
||||
/// <param name="index">the index of the byte to read</param>
|
||||
/// <returns>the byte to read</returns>
|
||||
byte ReadByte(long index);
|
||||
/// <summary>
|
||||
/// Writes a byte into the provider
|
||||
/// </summary>
|
||||
/// <param name="index">the index of the byte to write</param>
|
||||
/// <param name="value">the byte to write</param>
|
||||
void WriteByte(long index, byte value);
|
||||
/// <summary>
|
||||
/// Inserts bytes into the provider
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="bs"></param>
|
||||
/// <remarks>This method must raise the LengthChanged event.</remarks>
|
||||
void InsertBytes(long index, byte[] bs);
|
||||
/// <summary>
|
||||
/// Deletes bytes from the provider
|
||||
/// </summary>
|
||||
/// <param name="index">the start index of the bytes to delete</param>
|
||||
/// <param name="length">the length of the bytes to delete</param>
|
||||
/// <remarks>This method must raise the LengthChanged event.</remarks>
|
||||
void DeleteBytes(long index, long length);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the total length of bytes the byte provider is providing.
|
||||
/// </summary>
|
||||
long Length { get; }
|
||||
/// <summary>
|
||||
/// Occurs, when the Length property changed.
|
||||
/// </summary>
|
||||
event EventHandler LengthChanged;
|
||||
|
||||
/// <summary>
|
||||
/// True, when changes are done.
|
||||
/// </summary>
|
||||
bool HasChanges();
|
||||
/// <summary>
|
||||
/// Applies changes.
|
||||
/// </summary>
|
||||
void ApplyChanges();
|
||||
/// <summary>
|
||||
/// Occurs, when bytes are changed.
|
||||
/// </summary>
|
||||
event EventHandler Changed;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value if the WriteByte methods is supported by the provider.
|
||||
/// </summary>
|
||||
/// <returns>True, when it´s supported.</returns>
|
||||
bool SupportsWriteByte();
|
||||
/// <summary>
|
||||
/// Returns a value if the InsertBytes methods is supported by the provider.
|
||||
/// </summary>
|
||||
/// <returns>True, when it´s supported.</returns>
|
||||
bool SupportsInsertBytes();
|
||||
/// <summary>
|
||||
/// Returns a value if the DeleteBytes methods is supported by the provider.
|
||||
/// </summary>
|
||||
/// <returns>True, when it´s supported.</returns>
|
||||
bool SupportsDeleteBytes();
|
||||
}
|
||||
}
|
87
Vendor/Be.Windows.Forms.HexBox/MemoryDataBlock.cs
vendored
Normal file
87
Vendor/Be.Windows.Forms.HexBox/MemoryDataBlock.cs
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
using System;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
internal sealed class MemoryDataBlock : DataBlock
|
||||
{
|
||||
byte[] _data;
|
||||
|
||||
public MemoryDataBlock(byte data)
|
||||
{
|
||||
_data = new byte[] { data };
|
||||
}
|
||||
|
||||
public MemoryDataBlock(byte[] data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
throw new ArgumentNullException("data");
|
||||
}
|
||||
|
||||
_data = (byte[])data.Clone();
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return _data.LongLength;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] Data
|
||||
{
|
||||
get
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddByteToEnd(byte value)
|
||||
{
|
||||
byte[] newData = new byte[_data.LongLength + 1];
|
||||
_data.CopyTo(newData, 0);
|
||||
newData[newData.LongLength - 1] = value;
|
||||
_data = newData;
|
||||
}
|
||||
|
||||
public void AddByteToStart(byte value)
|
||||
{
|
||||
byte[] newData = new byte[_data.LongLength + 1];
|
||||
newData[0] = value;
|
||||
_data.CopyTo(newData, 1);
|
||||
_data = newData;
|
||||
}
|
||||
|
||||
public void InsertBytes(long position, byte[] data)
|
||||
{
|
||||
byte[] newData = new byte[_data.LongLength + data.LongLength];
|
||||
if (position > 0)
|
||||
{
|
||||
Array.Copy(_data, 0, newData, 0, position);
|
||||
}
|
||||
Array.Copy(data, 0, newData, position, data.LongLength);
|
||||
if (position < _data.LongLength)
|
||||
{
|
||||
Array.Copy(_data, position, newData, position + data.LongLength, _data.LongLength - position);
|
||||
}
|
||||
_data = newData;
|
||||
}
|
||||
|
||||
public override void RemoveBytes(long position, long count)
|
||||
{
|
||||
byte[] newData = new byte[_data.LongLength - count];
|
||||
|
||||
if (position > 0)
|
||||
{
|
||||
Array.Copy(_data, 0, newData, 0, position);
|
||||
}
|
||||
if (position + count < _data.LongLength)
|
||||
{
|
||||
Array.Copy(_data, position + count, newData, position, newData.LongLength - position);
|
||||
}
|
||||
|
||||
_data = newData;
|
||||
}
|
||||
}
|
||||
}
|
27
Vendor/Be.Windows.Forms.HexBox/NativeMethods.cs
vendored
Normal file
27
Vendor/Be.Windows.Forms.HexBox/NativeMethods.cs
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
internal static class NativeMethods
|
||||
{
|
||||
// Caret definitions
|
||||
[DllImport("user32.dll", SetLastError=true)]
|
||||
public static extern bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight);
|
||||
|
||||
[DllImport("user32.dll", SetLastError=true)]
|
||||
public static extern bool ShowCaret(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError=true)]
|
||||
public static extern bool DestroyCaret();
|
||||
|
||||
[DllImport("user32.dll", SetLastError=true)]
|
||||
public static extern bool SetCaretPos(int X, int Y);
|
||||
|
||||
// Key definitions
|
||||
public const int WM_KEYDOWN = 0x100;
|
||||
public const int WM_KEYUP = 0x101;
|
||||
public const int WM_CHAR = 0x102;
|
||||
}
|
||||
}
|
63
Vendor/Be.Windows.Forms.HexBox/Properties/Resources.Designer.cs
generated
vendored
Normal file
63
Vendor/Be.Windows.Forms.HexBox/Properties/Resources.Designer.cs
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Be.Windows.Forms.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Be.Windows.Forms.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
120
Vendor/Be.Windows.Forms.HexBox/Properties/Resources.resx
vendored
Normal file
120
Vendor/Be.Windows.Forms.HexBox/Properties/Resources.resx
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
38
Vendor/Be.Windows.Forms.HexBox/Util.cs
vendored
Normal file
38
Vendor/Be.Windows.Forms.HexBox/Util.cs
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Be.Windows.Forms
|
||||
{
|
||||
static class Util
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains true, if we are in design mode of Visual Studio
|
||||
/// </summary>
|
||||
private static bool _designMode;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of Util class
|
||||
/// </summary>
|
||||
static Util()
|
||||
{
|
||||
_designMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName.ToLower() == "devenv");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets true, if we are in design mode of Visual Studio
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// In Visual Studio 2008 SP1 the designer is crashing sometimes on windows forms.
|
||||
/// The DesignMode property of Control class is buggy and cannot be used, so use our own implementation instead.
|
||||
/// </remarks>
|
||||
public static bool DesignMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return _designMode;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue