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(); } } }