using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Raw2Picture
{
public partial class HexViewForm : Form
{
BinaryView bv = null;
FileStream fs = null;
BinaryReader br = null;
public HexViewForm(string filename)
{
InitializeComponent();
try
{
if (filename == null)
{
handleError("HexView: no input file");
return;
}
if (!File.Exists(filename))
{
handleError("HexView: input file not found: " + filename);
return;
}
fs = new FileStream(filename, FileMode.Open);
if (fs.Length == 0)
{
handleError("HexView: input file length is zero");
return;
}
br = new BinaryReader(fs);
bv = new BinaryView();
vScrollBar1.Minimum = 0;
vScrollBar1.Maximum = (int)Math.Sqrt(fs.Length);
update();
textBox1.SelectionStart = 0;
textBox1.SelectionLength = 0;
}
catch (Exception ex)
{
handleError(ex.Message);
}
}
public void cleanup()
{
if (br != null)
{
br.Close();
}
if (fs != null)
{
fs.Close();
fs.Dispose();
}
}
private void handleError(string s)
{
textBox1.Text = s;
}
private void update()
{
if (br == null || fs == null)
{
return;
}
long offset = (int)Math.Pow(vScrollBar1.Value, 2.0);
int count = vScrollBar1.Height * 2;
if (offset + count > fs.Length)
{
count = (int)(fs.Length - offset);
}
if (count <= 0)
{
return;
}
if (offset > fs.Length - textBox1.Height)
{
return;
}
fs.Seek(offset, SeekOrigin.Begin);
byte[] data = br.ReadBytes(count);
textBox1.Text = bv.GenerateText(data, (int)offset);
}
private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
{
update();
}
}
/// <summary>
/// BinaryView class. It is used to calculate hex view parameters.
/// </summary>
public class BinaryView
{
private int offsetWidth = 6;
private int dataWidth = 16;
private int totalWidth;
private int hexWidth;
/// <summary>
/// Default constructor.
/// </summary>
public BinaryView()
{
CalculatePar();
}
/// <summary>
/// Set hex view parameters. It calls <see cref="CalculatePar"/> to get the parameters.
/// <code>
/// Parameters Definition:
/// 000000 30 82 05 32 30 82 04 1A A0 03 02 01 02 02 0A 1F 0..20...........
/// 000010 CE 8F 20 00 00 00 00 00 22 30 0D 06 09 2A 86 48 .. ....."0...*.H
/// |----|offsetWidth |--dataWidth --|
/// |----- hexWidth ---------------------------------------|
/// |----- totalWidth -------------------------------------------------------|
/// </code>
/// </summary>
/// <param name="offsetWidth">input</param>
/// <param name="dataWidth">input</param>
public void SetPar(int offsetWidth, int dataWidth)
{
this.offsetWidth = offsetWidth;
this.dataWidth = dataWidth;
CalculatePar();
}
/// <summary>
/// Constructor, it calls <see cref="SetPar"/> to set the parameters.
/// </summary>
/// <param name="offsetWidth">input</param>
/// <param name="dataWidth">input</param>
public BinaryView(int offsetWidth, int dataWidth)
{
SetPar(offsetWidth, dataWidth);
}
/// <summary>
/// Get offsetWidth.
/// </summary>
public int OffsetWidth
{
get
{
return offsetWidth;
}
}
/// <summary>
/// Get dataWidth.
/// </summary>
public int DataWidth
{
get
{
return dataWidth;
}
}
/// <summary>
/// Get totalWidth.
/// </summary>
public int TotalWidth
{
get
{
return totalWidth;
}
}
/// <summary>
/// Get hexWidth.
/// </summary>
public int HexWidth
{
get
{
return hexWidth;
}
}
/// <summary>
/// Calculate hex view parameters.
/// </summary>
protected void CalculatePar()
{
totalWidth = offsetWidth + 2 + dataWidth * 3 + ((dataWidth / 8) - 1) + 1 + dataWidth;
hexWidth = totalWidth - dataWidth;
}
/// <summary>
/// Generate hex view text string by calling <see cref="GetBinaryViewText"/>.
/// </summary>
/// <param name="data">source byte array.</param>
/// <returns>output string.</returns>
public string GenerateText(byte[] data, int seekOffset)
{
return GetBinaryViewText(data, offsetWidth, dataWidth, seekOffset);
}
/// <summary>
/// Calculate the byte <see cref="ByteLocation"/> by offset.
/// </summary>
/// <param name="byteOffset"></param>
/// <param name="loc"></param>
public void GetLocation(int byteOffset, ByteLocation loc)
{
int colOff = byteOffset - byteOffset / dataWidth * dataWidth;
int line = byteOffset / dataWidth;
int col = offsetWidth + 2 + colOff * 3;
int colLen = 3;
int totOff = line * totalWidth + line + col;
int col2 = hexWidth + colOff;
int totOff2 = line * totalWidth + line + col2;
int colLen2 = 1;
loc.hexOffset = totOff;
loc.hexColLen = colLen;
loc.line = line;
loc.chOffset = totOff2;
loc.chColLen = colLen2;
}
/// <summary>
/// Generate "Detail" hex view text.
/// </summary>
/// <param name="data">source byte array.</param>
/// <param name="offsetWidth">offset text width.</param>
/// <param name="dataWidth">data text width</param>
/// <returns>detail hex view string.</returns>
public static string GetBinaryViewText(byte[] data, int offsetWidth, int dataWidth, int seekOffset)
{
string retval = "";
string offForm = "{0:X" + offsetWidth + "} ";
int i, lineStart, lineEnd;
int line = 0, offset = 0;
int totalWidth = offsetWidth + 2 + dataWidth * 3 + ((dataWidth / 8) - 1) + 1 + dataWidth;
int hexWidth = totalWidth - dataWidth;
string dumpStr = "";
string lineStr = "";
for (offset = 0; offset < data.Length; )
{
lineStr = String.Format(offForm, (line++) * dataWidth + seekOffset);
lineStart = offset;
for (i = 0; i < dataWidth; i++)
{
lineStr += String.Format("{0:X2} ", data[offset++]);
if (offset >= data.Length) break;
if ((i + 1) % 8 == 0 && i != 0 && (i + 1) < dataWidth) lineStr += " ";
}
lineStr += " ";
lineEnd = offset;
lineStr = lineStr.PadRight(hexWidth, ' ');
for (i = lineStart; i < lineEnd; i++)
{
if (data[i] < 32 || data[i] > 128)
lineStr += '.';
else
lineStr += (char)data[i];
}
lineStr = lineStr.PadRight(totalWidth, ' ');
dumpStr += lineStr + "\r\n";
}
retval = dumpStr;
return retval;
}
}
/// <summary>
/// ByteLocation class is used by <see cref="BinaryView"/> to transfer
/// location parameters.
/// </summary>
public class ByteLocation
{
/// <summary>
/// line number.
/// </summary>
public int line = 0;
/// <summary>
/// Hex encoded data length.
/// </summary>
public int hexColLen = 3;
/// <summary>
/// Hex encoded data offset.
/// </summary>
public int hexOffset = 0;
/// <summary>
/// Character length.
/// </summary>
public int chColLen = 1;
/// <summary>
/// Character offset.
/// </summary>
public int chOffset = 0;
/// <summary>
/// Constructor.
/// </summary>
public ByteLocation()
{
}
}
}