public class ByteArrayBuilder : IDisposable
{
#region Constants
/// <summary>
/// True in a byte form of the Line
/// </summary>
const byte streamTrue = (byte)1;
/// <summary>
/// False in the byte form of a line
/// </summary>
const byte streamFalse = (byte)0;
#endregion #region Fields
#region Internal
/// <summary>
/// Holds the actual bytes.
/// </summary>
MemoryStream store = new MemoryStream(); /// <summary>
/// Is Little Endian
/// True - little endian
/// False - big endian
/// </summary>
bool isLittleEndian;
#endregion #region Property bases
#endregion
#endregion #region Properties
/// <summary>
/// Bytes in the store.
/// </summary>
public int Length
{
get { return (int)store.Length; }
}
#endregion #region Regular Expressions
#endregion #region Enums
#endregion #region Constructors
/// <summary>
/// Create a new, empty builder ready to be filled.
/// </summary>
public ByteArrayBuilder(bool isLittleEndian = true)
{
this.isLittleEndian = isLittleEndian;
}
/// <summary>
/// Create a new builder from a set of data
/// </summary>
/// <param name="data">Data to preset the builder from</param>
public ByteArrayBuilder(byte[] data, bool isLittleEndian = true)
{
store.Close();
store.Dispose();
store = new MemoryStream(data);
this.isLittleEndian = isLittleEndian;
}
/// <summary>
/// Create a new builder from the Base64 string representation of an
/// existing instance.
/// The Base64 representation can be retrieved using the ToString override
/// </summary>
/// <param name="base64">Base64 string representation of an
/// existing instance.</param>
public ByteArrayBuilder(string base64, bool isLittleEndian = true)
{
store.Close();
store.Dispose();
store = new MemoryStream(Convert.FromBase64String(base64));
this.isLittleEndian = isLittleEndian;
}
#endregion #region Events
#region Event Constructors
#endregion #region Event Handlers
#endregion
#endregion #region Public Methods
#region Append overloads
/// <summary>
/// Adds a bool to an array
/// </summary>
/// <param name="b">Value to append to existing builder data</param>
public void Append(bool b)
{
store.WriteByte(b ? streamTrue : streamFalse);
}
/// <summary>
/// Adds a byte to an array
/// </summary>
/// <param name="b">Value to append to existing builder data</param>
public void Append(byte b)
{
store.WriteByte(b);
}
/// <summary>
/// Adds an array of bytes to an array
/// </summary>
/// <param name="b">Value to append to existing builder data</param>
/// <param name="addLength">
/// If true, the length is added before the value.
/// This allows extraction of individual elements back to the original input form.
/// </param>
public void Append(byte[] b, bool addLength = false)
{
if (b != null)
{
if (addLength) Append(b.Length);
AddBytes(b);
}
}
/// <summary>
/// Adds a char to an array
/// </summary>
/// <param name="c">Value to append to existing builder data</param>
public void Append(char c)
{
store.WriteByte((byte)c);
}
/// <summary>
/// Adds an array of characters to an array
/// </summary>
/// <param name="c">Value to append to existing builder data</param>
/// <param name="addLength">
/// If true, the length is added before the value.
/// This allows extraction of individual elements back to the original input form.
/// </param>
public void Append(char[] c, bool addLength = false)
{
if (c != null)
{
if (addLength) Append(c.Length);
Append(System.Text.Encoding.Unicode.GetBytes(c));
}
}
/// <summary>
/// Adds a DateTime to an array
/// </summary>
/// <param name="dt">Value to append to existing builder data</param>
public void Append(DateTime dt)
{
Append(dt.Ticks);
}
/// <summary>
/// Adds a decimal value to an array
/// </summary>
/// <param name="d">Value to append to existing builder data</param>
public void Append(decimal d)
{
// GetBits always returns four ints.
// We store them in a specific order so that they can be recovered later.
int[] bits = decimal.GetBits(d); if (isLittleEndian)
{
Append(bits[0]);
Append(bits[1]);
Append(bits[2]);
Append(bits[3]);
}
else
{
Append(bits[3]);
Append(bits[2]);
Append(bits[1]);
Append(bits[0]);
}
}
/// <summary>
/// Adds a double to an array
/// </summary>
/// <param name="d">Value to append to existing builder data</param>
public void Append(double d)
{
byte[] data = BitConverter.GetBytes(d);
if (!isLittleEndian)
{
Array.Reverse(data);
} AddBytes(data);
}
/// <summary>
/// Adds a float to an array
/// </summary>
/// <param name="f">Value to append to existing builder data</param>
public void Append(float f)
{
byte[] data = BitConverter.GetBytes(f);
if (!isLittleEndian)
{
Array.Reverse(data);
} AddBytes(data);
}
/// <summary>
/// Adds a Guid to an array
/// </summary>
/// <param name="g">Value to append to existing builder data</param>
public void Append(Guid g)
{
Append(g.ToByteArray());
}
/// <summary>
/// Adds an integer to an array
/// </summary>
/// <param name="i">Value to append to existing builder data</param>
public void Append(int i)
{
byte[] data = BitConverter.GetBytes(i);
if (!isLittleEndian)
{
Array.Reverse(data);
} AddBytes(data);
}
/// <summary>
/// Adds a long integer to an array
/// </summary>
/// <param name="l">Value to append to existing builder data</param>
public void Append(long l)
{
byte[] data = BitConverter.GetBytes(l);
if (!isLittleEndian)
{
Array.Reverse(data);
} AddBytes(data);
}
/// <summary>
/// Adds a short integer to an array
/// </summary>
/// <param name="i">Value to append to existing builder data</param>
public void Append(short s)
{
byte[] data = BitConverter.GetBytes(s);
if (!isLittleEndian)
{
Array.Reverse(data);
} AddBytes(data);
}
/// <summary>
/// Adds a string to an array
/// </summary>
/// <param name="s">Value to append to existing builder data</param>
/// <param name="addLength">
/// If true, the length is added before the value.
/// This allows extraction of individual elements back to the original input form.
/// </param>
public void Append(string s, bool addLength = false)
{
if (!string.IsNullOrEmpty(s))
{
byte[] data = System.Text.Encoding.Unicode.GetBytes(s);
if (addLength) Append(data.Length);
AddBytes(data);
}
}
/// <summary>
/// Adds an unsigned integer to an array
/// </summary>
/// <param name="ui">Value to append to existing builder data</param>
public void Append(uint ui)
{
byte[] data = BitConverter.GetBytes(ui);
if (!isLittleEndian)
{
Array.Reverse(data);
} AddBytes(data);
}
/// <summary>
/// Adds a unsigned long integer to an array
/// </summary>
/// <param name="ul">Value to append to existing builder data</param>
public void Append(ulong ul)
{
byte[] data = BitConverter.GetBytes(ul);
if (!isLittleEndian)
{
Array.Reverse(data);
} AddBytes(data);
}
/// <summary>
/// Adds a unsigned short integer to an array
/// </summary>
/// <param name="us">Value to append to existing builder data</param>
public void Append(ushort us)
{
byte[] data = BitConverter.GetBytes(us);
if (!isLittleEndian)
{
Array.Reverse(data);
} AddBytes(data);
}
#endregion #region Extraction
/// <summary>
/// Gets a bool from an array
/// </summary>
/// <returns></returns>
public bool GetBool()
{
return store.ReadByte() == streamTrue;
}
/// <summary>
/// Gets a byte from an array
/// </summary>
/// <returns></returns>
public byte GetByte()
{
return (byte)store.ReadByte();
}
/// <summary>
/// Gets an array of bytes from an array
/// </summary>
/// <returns></returns>
public byte[] GetByteArray()
{
int length = GetInt();
return GetBytes(length);
}
/// <summary>
/// Gets a char from an array
/// </summary>
/// <returns></returns>
public char GetChar()
{
return (char)store.ReadByte();
}
/// <summary>
/// Gets an array of characters from an array
/// </summary>
/// <returns></returns>
public char[] GetCharArray()
{
int length = GetInt();
return System.Text.Encoding.Unicode.GetChars(GetBytes(length));
}
/// <summary>
/// Gets a DateTime value from an array
/// </summary>
/// <returns></returns>
public DateTime GetDateTime()
{
return new DateTime(GetLong());
}
/// <summary>
/// Gets a decimal value from an array
/// </summary>
/// <returns></returns>
public decimal GetDecimal()
{
// GetBits always returns four ints.
// We store them in a specific order so that they can be recovered later.
int[] bits = new int[] { GetInt(), GetInt(), GetInt(), GetInt() };
if(!isLittleEndian)
{
Array.Reverse(bits);
}
return new decimal(bits);
}
/// <summary>
/// Gets a double from an array
/// </summary>
/// <returns></returns>
public double GetDouble()
{
byte[] data = GetBytes(8);
if (!isLittleEndian)
{
Array.Reverse(data);
}
return BitConverter.ToDouble(data, 0);
}
/// <summary>
/// Gets a float from an array
/// </summary>
/// <returns></returns>
public float GetFloat()
{
byte[] data = GetBytes(4);
if (!isLittleEndian)
{
Array.Reverse(data);
}
return BitConverter.ToSingle(data, 0);
}
/// <summary>
/// Gets a Guid from an array
/// </summary>
/// <returns></returns>
public Guid GetGuid()
{
return new Guid(GetByteArray());
}
/// <summary>
/// Gets an integer from an array
/// </summary>
/// <returns></returns>
public int GetInt()
{
byte[] data = GetBytes(4);
if (!isLittleEndian)
{
Array.Reverse(data);
}
return BitConverter.ToInt32(data, 0);
}
/// <summary>
/// Gets a long integer from an array
/// </summary>
/// <returns></returns>
public long GetLong()
{
byte[] data = GetBytes(8);
if (!isLittleEndian)
{
Array.Reverse(data);
}
return BitConverter.ToInt64(data, 0);
}
/// <summary>
/// Gets a short integer from an array
/// </summary>
/// <returns></returns>
public short GetShort()
{
byte[] data = GetBytes(2);
if (!isLittleEndian)
{
Array.Reverse(data);
}
return BitConverter.ToInt16(data, 0);
}
/// <summary>
/// Gets a string from an array
/// </summary>
/// <returns></returns>
public string GetString()
{
int length = GetInt();
return System.Text.Encoding.Unicode.GetString(GetBytes(length));
}
/// <summary>
/// Gets an unsigned integer from an array
/// </summary>
/// <returns></returns>
public uint GetUint()
{
byte[] data = GetBytes(4);
if (!isLittleEndian)
{
Array.Reverse(data);
}
return BitConverter.ToUInt32(data, 0);
}
/// <summary>
/// Gets a unsigned long integer from an array
/// </summary>
/// <returns></returns>
public ulong GetUlong()
{
byte[] data = GetBytes(8);
if (!isLittleEndian)
{
Array.Reverse(data);
}
return BitConverter.ToUInt64(data, 0);
}
/// <summary>
/// Gets a unsigned short integer from an array
/// </summary>
/// <returns></returns>
public ushort GetUshort()
{
byte[] data = GetBytes(2);
if (!isLittleEndian)
{
Array.Reverse(data);
}
return BitConverter.ToUInt16(data, 0);
}
#endregion #region Interaction
/// <summary>
/// Clear all content from the builder
/// </summary>
public void Clear()
{
store.Close();
store.Dispose();
store = new MemoryStream();
}
/// <summary>
/// Rewind the builder ready to read data
/// </summary>
public void Rewind()
{
store.Seek(0, SeekOrigin.Begin);
}
/// <summary>
/// Set an absolute position in the builder.
/// **WARNING**
/// If you add any variable size objects to the builder, the results of
/// reading after a Seek to a non-zero value are unpredictable.
/// A builder does not store just objects - for some it stores additional
/// information as well.
/// </summary>
/// <param name="position"></param>
public void Seek(int position)
{
store.Seek((long)position, SeekOrigin.Begin);
}
/// <summary>
/// Returns the builder as an array of bytes
/// </summary>
/// <returns></returns>
public byte[] ToArray()
{
byte[] data = new byte[Length];
Array.Copy(store.GetBuffer(), data, Length);
return data;
}
#endregion
#endregion #region Overrides
/// <summary>
/// Returns a text based (Base64) string version of the current content
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Convert.ToBase64String(ToArray());
}
#endregion #region Private Methods
/// <summary>
/// Add a string of raw bytes to the store
/// </summary>
/// <param name="b"></param>
private void AddBytes(byte[] b)
{
if (b != null)
{
store.Write(b, 0, b.Length);
}
}
/// <summary>
/// Reads a specific number of bytes from the store
/// </summary>
/// <param name="length"></param>
/// <returns></returns>
private byte[] GetBytes(int length)
{
byte[] data = new byte[length];
if (length > 0)
{
int read = store.Read(data, 0, length);
if (read != length)
{
throw new ApplicationException("Buffer did not contain " + length + " bytes");
}
}
return data;
}
#endregion #region IDisposable Implememntation
/// <summary>
/// Dispose of this builder and it's resources
/// </summary>
public void Dispose()
{
store.Close();
store.Dispose();
}
#endregion
}

  

ByteArrayBuilder的更多相关文章

  1. Android WebKit 内核

    一.WebKit简介 WebKit是一个开源的浏览器网页排版引擎,包含WebCore排版引擎和JSCore引擎.WebCore和JSCore引擎来自于KDE项目的KHTML和KJS开源项目.Andro ...

  2. ObjectMapper对象的使用 Object2JSON

    // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler ...

  3. webKit 内核浏览器 源码分析

    如需转载,请注明出处! WebSite: http://www.jjos.org/ 作者: 姜江 linuxemacs@gmail.com QQ: 457283 这是一篇自己写于一年前的工作文档,分享 ...

随机推荐

  1. maven 使用tomcat插件 自动化部署war

    1.相关环境变量 idea tomcat8 maven3 2.增加tomcat user, 修改 $CATALINA_HOME/conf/tomcat-users.xml <tomcat-use ...

  2. 调用微信JsAPI端获取位置

    public partial class test : BasePage { protected test() { AccessPage = PageWebType.WX; } protected s ...

  3. angularjs指令系统系列课程(5):控制器controller

    这一节我们来说一下controller这个参数 一.指令控制器的配置方法: 对于指令我有两种配置路由的方式:1.在html中直接引用,2,在指令的controller参数里定义 第一种:在html中直 ...

  4. windos系统定时执行批处理文件(bat文件)

    Win7怎么设置定时自动执行任务? 点击开始按钮,依次选择打开“所有程序—附件—系统工具”,找到“任务计划程序”即可打开Win7系统的任务计划设置面板.也可以点击Win7开始按钮,在多功能搜索框中输入 ...

  5. 程序设计入门——C语言 第7周编程练习 2 鞍点(5分)(5分)

    2 鞍点(5分) 题目内容: 给定一个n*n矩阵A.矩阵A的鞍点是一个位置(i,j),在该位置上的元素是第i行上的最大数,第j列上的最小数.一个矩阵A也可能没有鞍点. 你的任务是找出A的鞍点. 输入格 ...

  6. HBase 的表结构

    HBase 的表结构 2016-10-13 杜亦舒 HBase 是一个NoSQL数据库,用于处理海量数据,可以支持10亿行百万列的大表,下面就了解一下数据是如何存放在HBase表中的 关系型数据库的表 ...

  7. javadoc相关问题

    欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...

  8. AX2012 XppCompiler create method动态创建方法并运行

    在用友系列的软件中经常可以看到可配置的计算公式,AX中其实也有可配置的公式,如call center呼叫中心的欺诈Fraud rule的配置,AX后台可以根据配置规则,变量,条件来动态产生方法并执行, ...

  9. VHDL学习之模块调用

    http://wenku.baidu.com/link?url=SsRPUVQAOKDR8yWfDhQlceCwfZQkI-KQMLFKTDGAh3KAPr2NwEgvj0d_EZjdnsB99Upp ...

  10. Oracle 数据库简单操作

    现在大型企业一般都用Oracle数据库,Oracle数据库在一般采用expdp,impdp 导出导入数据,但是在操作中经常会遇到一些问题.下面来浅析这些问题. 1. 导出数据 一般导出数据的时候需要建 ...