using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
/* FROM: https://www.codeproject.com/Tips/674256/ByteArrayBuilder-a-StringBuilder-for-Bytes 2/9/2019 */
namespace ESCPOS_NET.Utilities
{
///
/// Provides similar functionality to a StringBuilder, but for bytes.
///
///
/// To fill the builder, construct a new, empty builder, and call the
/// appropriate Append method overloads.
/// To read data from the builder, either use Rewind on an existing
/// builder, or construct a new builder by passing it the byte array
/// from a previous builder - which you can get with the ToArray
/// method.
///
///
///
/// ByteArrayBuilder bab = new ByteArrayBuilder();
/// string[] lines = File.ReadAllLines(@"D:\Temp\myText.txt");
/// bab.Append(lines.Length);
/// foreach (string s in lines)
/// {
/// bab.Append(s);
/// }
/// byte[] data = bab.ToArray();
/// ...
/// ByteArrayBuilder babOut = new ByteArrayBuilder(data);
/// int count = bab.GetInt();
/// string[] linesOut = new string[count];
/// for (int lineNo = 0; lineNo < count; lineNo++)
/// {
/// linesOut[lineNo](babOut.GetString());
/// }
/// .
///
public class ByteArrayBuilder : IDisposable
{
///
/// True in a byte form of the Line.
///
private const byte StreamTrue = (byte)1;
///
/// False in the byte form of a line.
///
private const byte StreamFalse = (byte)0;
///
/// Holds the actual bytes.
///
private MemoryStream store = new MemoryStream();
///
/// Gets bytes in the store.
///
public int Length => (int)store.Length;
///
/// Create a new, empty builder ready to be filled.
///
public ByteArrayBuilder()
{
}
public ByteArrayBuilder Append(byte b)
{
AddBytes(new byte[] { b });
return this;
}
///
/// Adds an IEnumerable of bytes to an array.
///
/// Value to append to existing builder data.
///
public ByteArrayBuilder Append(IEnumerable b)
{
if (b is byte[])
{
AddBytes((byte[])b);
return this;
}
AddBytes(b.ToArray());
return this;
}
///
/// Clear all content from the builder.
///
public void Clear()
{
store.Close();
store.Dispose();
store = new MemoryStream();
}
///
/// Rewind the builder ready to read data.
///
public void Rewind()
{
store.Seek(0, SeekOrigin.Begin);
}
///
/// 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.
///
/// the position to seek.
public void Seek(int position)
{
store.Seek((long)position, SeekOrigin.Begin);
}
///
/// Returns the builder as an array of bytes.
///
/// An array.
public byte[] ToArray()
{
byte[] data = new byte[Length];
Array.Copy(store.GetBuffer(), data, Length);
return data;
}
///
/// Returns a text based (Base64) string version of the current content.
///
/// The converted string.
public override string ToString()
{
return Convert.ToBase64String(ToArray());
}
///
/// Add a string of raw bytes to the store.
///
/// the byte array.
private void AddBytes(byte[] byteArray)
{
store.Write(byteArray, 0, byteArray.Length);
}
///
/// Reads a specific number of bytes from the store.
///
/// The length.
/// The byte array.
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;
}
///
/// Dispose of this builder and its resources.
///
public void Dispose()
{
store.Close();
store.Dispose();
}
}
}