GithubHelp home page GithubHelp logo

cnschwarzer / endianbinaryio Goto Github PK

View Code? Open in Web Editor NEW

This project forked from kermalis/endianbinaryio

0.0 1.0 0.0 267 KB

A C# library that can read and write primitives, enums, arrays, and strings to streams and byte arrays with specified endianness, string encoding, and boolean sizes.

C# 100.00%

endianbinaryio's Introduction

๐Ÿ“– EndianBinaryIO

NuGet NuGet downloads

A C# library that can read and write primitives, enums, arrays, and strings to streams using specified endianness, string encoding, and boolean sizes. Objects can also be read from/written to streams via reflection and attributes.

The IBinarySerializable interface allows an object to be read and written in a customizable fashion. Also included are attributes that can make reading and writing objects less of a headache. For example, classes and structs in C# cannot have ignored members when marshalling, but EndianBinaryIO has a BinaryIgnoreAttribute that will ignore properties when reading and writing.

There is also an EndianBitConverter static class which resembles System.BitConverter. With it you can convert to/from data types using arrays rather than streams, all with specific endianness.


๐Ÿš€ Usage:

Add the EndianBinaryIO NuGet package to your project or download the .dll from the releases tab.


Examples:

Assume we have the following definitions:

C#:

enum ByteSizedEnum : byte
{
    Val1 = 0x20,
    Val2 = 0x80
}
enum ShortSizedEnum : short
{
    Val1 = 0x40,
    Val2 = 0x800
}

class MyBasicObj
{
    // Properties
    public ShortSizedEnum Type { get; set; }
    public short Version { get; set; }
    public DateTime Date { get; set; }

    // Property that is ignored when reading and writing
    [BinaryIgnore(true)]
    public ByteSizedEnum DoNotReadOrWrite { get; set; }

    // Arrays work as well
    [BinaryArrayFixedLength(16)]
    public uint[] ArrayWith16Elements { get; set; }

    // Boolean that occupies 4 bytes instead of one
    [BinaryBooleanSize(BooleanSize.U32)]
    public bool Bool32 { get; set; }

    // String encoded in ASCII
    // Reads chars until the stream encounters a '\0'
    // Writing will append a '\0' at the end of the string
    [BinaryEncoding("ASCII")]
    [BinaryStringNullTerminated(true)]
    public string NullTerminatedASCIIString { get; set; }

    // String encoded in UTF16-LE that will only read/write 10 chars
    // The BinaryStringTrimNullTerminatorsAttribute will indicate that every char from the first \0 will be removed from the string. This attribute also works with char arrays
    [BinaryEncoding("UTF-16")]
    [BinaryStringFixedLength(10)]
    [BinaryStringTrimNullTerminators(true)]
    public string UTF16String { get; set; }
}

And assume these are our input bytes (in little endian):

Input Bytes (Little Endian):

0x00, 0x08, // ShortSizedEnum.Val2
0xFF, 0x01, // (short)511
0x00, 0x00, 0x4A, 0x7A, 0x9E, 0x01, 0xC0, 0x08, // (DateTime)Dec. 30, 1998

0x00, 0x00, 0x00, 0x00, // (uint)0
0x01, 0x00, 0x00, 0x00, // (uint)1
0x02, 0x00, 0x00, 0x00, // (uint)2
0x03, 0x00, 0x00, 0x00, // (uint)3
0x04, 0x00, 0x00, 0x00, // (uint)4
0x05, 0x00, 0x00, 0x00, // (uint)5
0x06, 0x00, 0x00, 0x00, // (uint)6
0x07, 0x00, 0x00, 0x00, // (uint)7
0x08, 0x00, 0x00, 0x00, // (uint)8
0x09, 0x00, 0x00, 0x00, // (uint)9
0x0A, 0x00, 0x00, 0x00, // (uint)10
0x0B, 0x00, 0x00, 0x00, // (uint)11
0x0C, 0x00, 0x00, 0x00, // (uint)12
0x0D, 0x00, 0x00, 0x00, // (uint)13
0x0E, 0x00, 0x00, 0x00, // (uint)14
0x0F, 0x00, 0x00, 0x00, // (uint)15

0x00, 0x00, 0x00, 0x00, // (bool32)false

0x45, 0x6E, 0x64, 0x69, 0x61, 0x6E, 0x42, 0x69, 0x6E, 0x61, 0x72, 0x79, 0x49, 0x4F, 0x00, // (ASCII)"EndianBinaryIO\0"

0x4B, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6D, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x69, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, // (UTF16-LE)"Kermalis\0\0"

We can read/write the object manually or automatically (with reflection):

Reading Manually:

var reader = new EndianBinaryReader(stream, endianness: Endianness.LittleEndian, booleanSize: BooleanSize.U32);
var obj = new MyBasicObj();

obj.Type = reader.ReadEnum<ShortSizedEnum>(); // Reads the enum type based on the amount of bytes of the enum's underlying type (short/2 in this case)
obj.Version = reader.ReadInt16(); // Reads a 'short' (2 bytes)
obj.Date = reader.ReadDateTime(); // Reads a 'DateTime' (8 bytes)

obj.ArrayWith16Elements = reader.ReadUInt32s(16); // Reads 16 'uint's (4 bytes each)

obj.Bool32 = reader.ReadBoolean(); // Reads a 'bool' (4 bytes in this case, since the reader was initiated with a default of BooleanSize.U32, but there is an overload to pass in one)

obj.NullTerminatedASCIIString = reader.ReadStringNullTerminated(Encoding.ASCII); // Reads ASCII chars until a '\0' is read, then returns a 'string'
obj.UTF16String = reader.ReadString(10, true, Encoding.Unicode); // Reads 10 UTF16-LE chars as a 'string' with the '\0's removed

Reading Automatically (With Reflection):

var reader = new EndianBinaryReader(stream, endianness: Endianness.LittleEndian);
var obj = reader.ReadObject<MyBasicObj>(); // Create a 'MyBasicObj' and read all properties in order, ignoring any with a 'BinaryIgnoreAttribute'
                                           // Other objects that are properties in this object will also be read in the same way recursively

Writing Manually:

var obj = new MyBasicObj
{
    Type = ShortSizedEnum.Val2,
    Version = 511,
    Date = new DateTime(1998, 12, 30),

    DoNotReadOrWrite = ByteSizedEnum.Val1,

    ArrayWith16Elements = new uint[16]
    {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
    },

    Bool32 = false,

    NullTerminatedASCIIString = "EndianBinaryIO",
    UTF16String = "Kermalis"
};

var writer = new EndianBinaryWriter(stream, endianness: Endianness.LittleEndian, booleanSize: BooleanSize.U32);
writer.Write(obj.Type); // Writes the enum type based on the amount of bytes of the enum's underlying type (short/2 in this case)
writer.Write(obj.Version); // Writes a 'short' (2 bytes)
writer.Write(obj.Date); // Writes a 'DateTime' (8 bytes)
writer.Write(obj.ArrayWith16Elements); // Writes 16 'uint's (4 bytes each)
writer.Write(obj.Bool32); // Writes a 'bool' (4 bytes in this case, since the reader was initiated with a default of BooleanSize.U32, but there is an overload to pass in one)
writer.Write(obj.NullTerminatedASCIIString, true, Encoding.ASCII); // Writes the chars in the 'string' as ASCII and appends a '\0' at the end
writer.Write(obj.UTF16String, 10, Encoding.Unicode); // Writes 10 UTF16-LE chars as a 'string'. If the string has more than 10 chars, it is truncated; if it has less, it is padded with '\0'

Writing Automatically (With Reflection):

var obj = new MyBasicObj
{
    Type = ShortSizedEnum.Val2,
    Version = 511,
    Date = new DateTime(1998, 12, 30),

    DoNotReadOrWrite = ByteSizedEnum.Val1,

    ArrayWith16Elements = new uint[16]
    {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
    },

    Bool32 = false,

    NullTerminatedASCIIString = "EndianBinaryIO",
    UTF16String = "Kermalis"
};

var writer = new EndianBinaryWriter(stream, endianness: Endianness.LittleEndian);
writer.Write(obj); // Write all properties in the 'MyBasicObj' in order, ignoring any with a 'BinaryIgnoreAttribute'
                   // Other objects that are properties in this object will also be written in the same way recursively

EndianBitConverter Example:

byte[] bytes = new byte[] { 0xFF, 0x00, 0x00, 0x00 };
uint value = (uint)EndianBitConverter.BytesToInt32(bytes, 0, Endianness.LittleEndian); // Will return (int)255

value = 128;
bytes = EndianBitConverter.Int32ToBytes((int)value, Endianness.LittleEndian); // Will return (byte[]){ 0x80, 0x00, 0x00, 0x00 }

To Do:

  • Documentation

EndianBinaryIOTests Uses:

endianbinaryio's People

Contributors

kermalis avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.