{"id":15036290,"url":"https://github.com/kermalis/endianbinaryio","last_synced_at":"2025-04-09T23:23:23.880Z","repository":{"id":51605580,"uuid":"147242825","full_name":"Kermalis/EndianBinaryIO","owner":"Kermalis","description":"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.","archived":false,"fork":false,"pushed_at":"2024-06-08T04:59:32.000Z","size":237,"stargazers_count":31,"open_issues_count":3,"forks_count":5,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-05T19:19:21.622Z","etag":null,"topics":["big-endian","csharp","csharp-library","endian","endianbinaryio","endianness","little-endian","serialization","serialization-library","serialize-objects","serializer"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Kermalis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-03T18:59:59.000Z","updated_at":"2025-02-01T06:01:10.000Z","dependencies_parsed_at":"2024-06-08T05:46:46.244Z","dependency_job_id":null,"html_url":"https://github.com/Kermalis/EndianBinaryIO","commit_stats":{"total_commits":90,"total_committers":1,"mean_commits":90.0,"dds":0.0,"last_synced_commit":"a9d774b53b6f88ebccb66879c0c4831453f752bb"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kermalis%2FEndianBinaryIO","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kermalis%2FEndianBinaryIO/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kermalis%2FEndianBinaryIO/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kermalis%2FEndianBinaryIO/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kermalis","download_url":"https://codeload.github.com/Kermalis/EndianBinaryIO/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248126862,"owners_count":21052067,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["big-endian","csharp","csharp-library","endian","endianbinaryio","endianness","little-endian","serialization","serialization-library","serialize-objects","serializer"],"created_at":"2024-09-24T20:30:43.105Z","updated_at":"2025-04-09T23:23:23.856Z","avatar_url":"https://github.com/Kermalis.png","language":"C#","readme":"﻿# 📖 EndianBinaryIO\n\n[![NuGet](https://img.shields.io/nuget/v/EndianBinaryIO.svg)](https://www.nuget.org/packages/EndianBinaryIO)\n[![NuGet downloads](https://img.shields.io/nuget/dt/EndianBinaryIO)](https://www.nuget.org/packages/EndianBinaryIO)\n\nThis .NET library provides a simple API to read/write bytes from/to streams and spans using user-specified endianness.\nBy default, supported types include primitives, enums, arrays, strings, and some common .NET struct types.\nObjects can also be read/written from/to streams via reflection and attributes.\nThe developer can use the API even if their target behavior or data is not directly supported by using the `IBinarySerializable` interface, inheritting from the reader/writer, or using the manual `Span\u003cT\u003e`/`ReadOnlySpan\u003cT\u003e` methods without streams.\nPerformance is the focus when not using reflection; no allocations unless absolutely necessary!\n\nThe `IBinarySerializable` interface allows an object to be read and written in a customizable fashion during reflection.\nAlso included are attributes that can make reading and writing objects less of a headache.\nFor 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.\n\nThe `EndianBinaryPrimitives` static class which resembles `System.Buffers.Binary.BinaryPrimitives` is an API that converts to/from data types using `Span\u003cT\u003e`/`ReadOnlySpan\u003cT\u003e` with specific endianness, rather than streams.\n\n----\n## Changelog For v2.1.1\nCheck the comment on [the release page](https://github.com/Kermalis/EndianBinaryIO/releases/tag/v2.1.0)!\n\n----\n## 🚀 Usage:\nAdd the [EndianBinaryIO](https://www.nuget.org/packages/EndianBinaryIO) NuGet package to your project or download the .dll from [the releases tab](https://github.com/Kermalis/EndianBinaryIO/releases).\n\n----\n## Examples:\nAssume we have the following definitions:\n### C#:\n```cs\nenum ByteSizedEnum : byte\n{\n\tVal1 = 0x20,\n\tVal2 = 0x80,\n}\nenum ShortSizedEnum : short\n{\n\tVal1 = 0x40,\n\tVal2 = 0x800,\n}\n\nclass MyBasicObj\n{\n\t// Properties\n\tpublic ShortSizedEnum Type { get; set; }\n\tpublic short Version { get; set; }\n\tpublic DateTime Date { get; set; }\n\tpublic Int128 Int128 { get; set; }\n\n\t// Property that is ignored when reading and writing\n\t[BinaryIgnore]\n\tpublic ByteSizedEnum DoNotReadOrWrite { get; set; }\n\n\t// Arrays work as well\n\t[BinaryArrayFixedLength(16)]\n\tpublic uint[] ArrayWith16Elements { get; set; }\n\n\t// Boolean that occupies 4 bytes instead of one\n\t[BinaryBooleanSize(BooleanSize.U32)]\n\tpublic bool Bool32 { get; set; }\n\n\t// String encoded in ASCII\n\t// Reads chars until the stream encounters a '\\0'\n\t// Writing will append a '\\0' at the end of the string\n\t[BinaryASCII]\n\t[BinaryStringNullTerminated]\n\tpublic string NullTerminatedASCIIString { get; set; }\n\n\t// String encoded in UTF16-LE that will only read/write 10 chars\n\t// The BinaryStringTrimNullTerminatorsAttribute will indicate that every char from the first \\0 will be removed from the string. This attribute also works with char arrays\n\t[BinaryStringFixedLength(10)]\n\t[BinaryStringTrimNullTerminators]\n\tpublic string UTF16String { get; set; }\n}\n```\nAnd assume these are our input bytes (in little endian):\n### Input Bytes (Little Endian):\n```cs\n0x00, 0x08, // ShortSizedEnum.Val2\n0xFF, 0x01, // (short)511\n0x00, 0x00, 0x4A, 0x7A, 0x9E, 0x01, 0xC0, 0x08, // (DateTime)Dec. 30, 1998\n0x48, 0x49, 0x80, 0x44, 0x82, 0x44, 0x88, 0xC0, 0x42, 0x24, 0x88, 0x12, 0x44, 0x44, 0x25, 0x24, // (Int128)48,045,707,429,126,174,655,160,174,263,614,327,112\n\n0x00, 0x00, 0x00, 0x00, // (uint)0\n0x01, 0x00, 0x00, 0x00, // (uint)1\n0x02, 0x00, 0x00, 0x00, // (uint)2\n0x03, 0x00, 0x00, 0x00, // (uint)3\n0x04, 0x00, 0x00, 0x00, // (uint)4\n0x05, 0x00, 0x00, 0x00, // (uint)5\n0x06, 0x00, 0x00, 0x00, // (uint)6\n0x07, 0x00, 0x00, 0x00, // (uint)7\n0x08, 0x00, 0x00, 0x00, // (uint)8\n0x09, 0x00, 0x00, 0x00, // (uint)9\n0x0A, 0x00, 0x00, 0x00, // (uint)10\n0x0B, 0x00, 0x00, 0x00, // (uint)11\n0x0C, 0x00, 0x00, 0x00, // (uint)12\n0x0D, 0x00, 0x00, 0x00, // (uint)13\n0x0E, 0x00, 0x00, 0x00, // (uint)14\n0x0F, 0x00, 0x00, 0x00, // (uint)15\n\n0x00, 0x00, 0x00, 0x00, // (bool32)false\n\n0x45, 0x6E, 0x64, 0x69, 0x61, 0x6E, 0x42, 0x69, 0x6E, 0x61, 0x72, 0x79, 0x49, 0x4F, 0x00, // (ASCII)\"EndianBinaryIO\\0\"\n\n0x4B, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6D, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x69, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, // (UTF16-LE)\"Kermalis\\0\\0\"\n```\n\nWe can read/write the object manually or automatically (with reflection):\n### Reading Manually:\n```cs\nvar reader = new EndianBinaryReader(stream, endianness: Endianness.LittleEndian, booleanSize: BooleanSize.U32);\nvar obj = new MyBasicObj();\n\nobj.Type = reader.ReadEnum\u003cShortSizedEnum\u003e(); // Reads the enum type based on the amount of bytes of the enum's underlying type (short/2 in this case)\nobj.Version = reader.ReadInt16(); // Reads a 'short' (2 bytes)\nobj.Date = reader.ReadDateTime(); // Reads a 'DateTime' (8 bytes)\nobj.Int128 = reader.ReadInt128(); // Reads an 'Int128' (16 bytes)\n\nobj.ArrayWith16Elements = new uint[16];\nreader.ReadUInt32s(obj.ArrayWith16Elements); // Reads 16 'uint's (4 bytes each)\n\nobj.Bool32 = reader.ReadBoolean(); // Reads a 'bool' (4 bytes in this case, since the reader's current bool state is BooleanSize.U32)\n\nreader.ASCII = true; // Set the reader's ASCII state to true\nobj.NullTerminatedASCIIString = reader.ReadString_NullTerminated(); // Reads ASCII chars until a '\\0' is read, then returns a 'string'\n\nreader.ASCII = false; // Set the reader's ASCII state to false (UTF16-LE)\nobj.UTF16String = reader.ReadString_Count_TrimNullTerminators(10); // Reads 10 UTF16-LE chars as a 'string' with the '\\0's removed\n```\n### Reading Automatically (With Reflection):\n```cs\nvar reader = new EndianBinaryReader(stream, endianness: Endianness.LittleEndian);\nvar obj = reader.ReadObject\u003cMyBasicObj\u003e(); // Create a 'MyBasicObj' and read all properties in order, ignoring any with a 'BinaryIgnoreAttribute'\n// Other objects that are properties in this object will also be read in the same way recursively\n```\n\n### Writing Manually:\n```cs\nvar obj = new MyBasicObj\n{\n\tType = ShortSizedEnum.Val2,\n\tVersion = 511,\n\tDate = new DateTime(1998, 12, 30),\n\tInt128 = Int128.Parse(\"48,045,707,429,126,174,655,160,174,263,614,327,112\", NumberStyles.AllowThousands, NumberFormatInfo.InvariantInfo),\n\n\tDoNotReadOrWrite = ByteSizedEnum.Val1,\n\n\tArrayWith16Elements = new uint[16]\n\t{\n\t\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\n\t},\n\n\tBool32 = false,\n\n\tNullTerminatedASCIIString = \"EndianBinaryIO\",\n\tUTF16String = \"Kermalis\",\n};\n\nvar writer = new EndianBinaryWriter(stream, endianness: Endianness.LittleEndian, booleanSize: BooleanSize.U32);\nwriter.WriteEnum(obj.Type); // Writes the enum type based on the amount of bytes of the enum's underlying type (short/2 in this case)\nwriter.WriteInt16(obj.Version); // Writes a 'short' (2 bytes)\nwriter.WriteDateTime(obj.Date); // Writes a 'DateTime' (8 bytes)\nwriter.WriteInt128(obj.Int128); // Writes an 'Int128' (16 bytes)\nwriter.WriteUInt32s(obj.ArrayWith16Elements); // Writes 16 'uint's (4 bytes each)\nwriter.WriteBoolean(obj.Bool32); // Writes a 'bool' (4 bytes in this case, since the reader's current bool state is BooleanSize.U32)\n\nwriter.ASCII = true; // Set the reader's ASCII state to true\nwriter.WriteChars_NullTerminated(obj.NullTerminatedASCIIString); // Writes the chars in the 'string' as ASCII and appends a '\\0' at the end\n\nwriter.ASCII = false; // Set the reader's ASCII state to false (UTF16-LE)\nwriter.WriteChars_Count(obj.UTF16String, 10); // 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'\n```\n### Writing Automatically (With Reflection):\n```cs\nvar writer = new EndianBinaryWriter(stream, endianness: Endianness.LittleEndian);\nwriter.Write(obj); // Write all properties in the 'MyBasicObj' in order, ignoring any with a 'BinaryIgnoreAttribute'\n// Other objects that are properties in this object will also be written in the same way recursively\n```\n\n### EndianBinaryPrimitives Example:\n```cs\nbyte[] bytes = new byte[] { 0xFF, 0x00, 0x00, 0x00, 0xBB, 0xEE, 0xEE, 0xFF };\nuint value = EndianBinaryPrimitives.ReadUInt32(bytes, Endianness.LittleEndian); // Will return 255\n\nvalue = 128;\nEndianBinaryPrimitives.WriteUInt32(bytes.AsSpan(4, 4), value, Endianness.LittleEndian); // bytes is now { 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }\n```\n\n----\n## EndianBinaryIOTests Uses:\n* [xUnit.net](https://github.com/xunit/xunit)","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkermalis%2Fendianbinaryio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkermalis%2Fendianbinaryio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkermalis%2Fendianbinaryio/lists"}