alec1o / Byter

Byter: C# library for serializing and deserializing data to and from bytes, supporting unlimited complexity and depth.⚑
MIT License
6 stars 2 forks source link
alec1o byter c-sharp csharp decode deserializer dotnet encode netly object parser primitive serialization serialize serializer

⭐ Your star is the light at the end of our tunnel.
Lead us out of the darkness by starring Byter on GitHub.
Star me please, I beg you! πŸ’™


Byter

powered by ALEC1O
byter logo
Project

Get basic information about this project called Byter

Overview
Byter is a C# serialization library for primitive data types, including booleans, numbers, chars, enums, strings, DateTime, BigInteger, bytes, and complex types like classes, structs, arrays, and lists, supporting unlimited complexity and depth.

Website
Repository: github.com/alec1o/byter


Installing

Official publisher

Nuget .NET CLI Netly
Install on Nuget
```rb dotnet add package Byter --version 3.0.0 ```
Embedded, Since version 2.x.x


Versions

Notable changes

v1.x.x v2.x.x v3.x.x
Stable Stable Stable
Main (Reader & Writer) Types:
  byte   bool   byte[]
  short   ushort   int
  uint   long   ulong
  float   double   char
  string
New (Reader & Writer) Types:
Float2 (Vector2)
Float3 (Vector3)
Float4 (Vector4 / Quaternion)
Bug Fix. (Reader & Writer)

Support: *Primitive

New usage paradigms *Primitive

*Primitive Types:
  bool   byte
  char   short   ushort
  int   uint   float
  long   byte[]   ulong   double
  string
   *highlights
  enum*   sbyte*   DateTime*
  decimal*   class*   struct*
  array*   list*   BigInteger*
Used by. Netly v2 Used by. Netly v3 Used by. Netly v4


Usage

Integration and interaction example codes

v1.x.x
v2.x.x
πŸ“„ Writer ### Constructor - ###### () : ``Writer``
Create instance with empty internal buffer - ###### (``Writer`` writer) : ``Writer``
Create instance and copy buffer of (Writer) as internal buffer - ###### (ref ``Writer`` writer) : ``Writer``
Create instance and copy buffer of (ref Writer) as internal buffer ### Proprieties - ###### Length : ``int``
Return buffer length. ### Methods - ###### Write(T value) : ``void``
Write content in internal buffer - ###### GetBytes() : ``byte[]``
Return buffer from (Writer) instance as byte[]) - ###### GetList() : ``List``
Return buffer from (Writer) instance as List<byte> - ###### Clear(): ``void``
Clear internal buffer from (Writer) instance
πŸ“„ Reader ### Constructor - ###### (``byte[]`` buffer) : ``Reader``
Create instance using (Byte[]) as internal buffer - ###### (``Writer`` writer) : ``Reader``
Create instance using (Writer) as internal buffer - ###### (ref ``Writer`` writer) : ``Reader``
Create instance using (ref Writer) as internal buffer ### Proprieties - ###### Success : ``bool``
Return true if deserialized successful. - ###### Position : ``int``
Return current read index. - ###### Length : ``int``
Return buffer length. ### Methods - ###### Seek(``int`` position) : ``void``
Move position (internal buffer index) - ###### Read<``T``>() : ``T``
Read content from iternal buffer. - ###### Read<``string``>(``Encoding`` encoding) : ``string``
Read custom encoding string.
πŸ“„ Example - ###### Writer ```csharp using Byter; Writer w = new(); // write data w.Write("Powered by ALEC1O"); w.Write("η”± ALEC1O ζδΎ›ζ”―ζŒ", Encoding.UTF32); w.Write((int)1000000);` // 1.000.000 w.Write((char)'A'); w.Write((long)-1000000000); // -100.0000.000 w.Write((byte[])[0, 1, 2, 3]); // Float(1|2|3) only available in version 2 w.Write(new Float2(-100F, 300F)); w.Write(new Float3(-100F, 300F, 600F)); w.Write(new Float4(-100F, 300F, 600F, 900F)); // get buffer byte[] buffer = w.GetBytes(); // example send buffer Magic.Send(buffer); ``` - ###### Reader ```csharp using Byter; // example receive buffer byte[] buffer = Magic.Receive(); // create instance Reader r = new() // read data string noticeInEnglish = r.Read(); // Powered by ALEC1O string noticeInChinese = r.Read(Encoding.UTF32); // η”± ALEC1O ζδΎ›ζ”―ζŒ int myInt = r.Read(); // 1.000.000 char myChar = r.Read(); // 'A' long myLong = r.Read(); // -100.0000.000 byte[] myBytes = r.Read(); // [0, 1, 2, 3] // Float(1|2|3) only available in version 2 Float2 myFloat2 = r.Read(); // [x: -100F] [y: 300F] Float3 myFloat3 = r.Read(); // [x: -100F] [y: 300F] [z: 600F] Float4 myFloat4 = r.Read(); // [x: -100F] [y: 300F] [z: 600F] [w: 900F] if (r.Sucess) { // sucess on read all data } else { // one or more data isn't found when deserialize. Might ignore this buffer! } ``` - ###### Dynamic Read Technical ```csharp var r = new Reader(...); var topic = r.Read(Encoding.ASCII); if(!r.Sucess) return; // ignore this if (topic == "login") { string username = r.Read(Encoding.UTF32); string password = r.Read(Encoding.ASCII); if (!r.Sucess) return; // ignore this // login user... } else if(topic == "get user address") { ulong userId = r.Read(); string token = r.Read(Encoding.ASCII); if (!r.Sucess) return; // ignore this // get user adress... } ... else { // ignore this. (Topic not found) } ```
v3.x.x
πŸ“„ Primitive ### Constructor - ###### () : ``Primitive``
Create instance with empty internal buffer - ###### (``byte[]`` buffer) : ``Primitive``
Create instance using (Byte[]) as internal buffer ### Proprieties - ###### Position : ``int``
Return internal reading index/position. - ###### IsValid : ``bool``
Return (true) if data was read successful. otherwise (false) - ###### Add : ``IPrimitiveAdd``
Object used to (read/get) content from internal (Primitive) buffer - ###### Get : ``IPrimitiveGet``
Object used to (write/add) content in internal (Primitive) buffer ### Methods - ###### GetBytes() : ``byte[]``
Return buffer from (Primitive) instance as byte[]) - ###### GetList() : ``List``
Return buffer from (Primitive) instance as List<byte> - ###### Reset(): ``void``
Clear internal buffer from (Primitive) instance
πŸ“„ IPrimitiveAdd ### Methods - ###### Bool(``bool`` value) ``void``
(Write/Add) element typeof(bool) in internal buffer - ###### Byte(``byte`` value) ``void``
(Write/Add) element typeof(byte) in internal buffer - ###### SByte(``sbyte`` value) ``void``
(Write/Add) element typeof(sbyte) in internal buffer - ###### Char(``char`` value) ``void``
(Write/Add) element typeof(char) in internal buffer - ###### Short(``short`` value) ``void``
(Write/Add) element typeof(short) in internal buffer - ###### UShort(``ushort`` value) ``void``
(Write/Add) element typeof(ushort) in internal buffer - ###### Int(``int`` value) ``void``
(Write/Add) element typeof(int) in internal buffer - ###### UInt(``uint`` value) ``void``
(Write/Add) element typeof(uint) in internal buffer - ###### Float(``float`` value) ``void``
(Write/Add) element typeof(float) in internal buffer - ###### Enum<``T``>(``T`` value) ``void``
(Write/Add) element typeof(enum) in internal buffer - ###### Long(``long`` value) ``void``
(Write/Add) element typeof(long) in internal buffer - ###### ULong(``ulong`` value) ``void``
(Write/Add) element typeof(ulong) in internal buffer - ###### Double(``double`` value) ``void``
(Write/Add) element typeof(double) in internal buffer - ###### DateTime(``DateTime`` value) ``void``
(Write/Add) element typeof(DateTime) in internal buffer - ###### Decimal(``decimal`` value) ``void``
(Write/Add) element typeof(decimal) in internal buffer - ###### String(``string`` value) ``void``
(Write/Add) element typeof(string) in internal buffer - ###### Class<``T``>(``T`` value) ``void``
(Write/Add) element typeof(T) in internal buffer - ###### Struct<``T``>(``T`` value) ``void``
(Write/Add) element typeof(T) in internal buffer - ###### Array<``T``>(``T`` value) ``void``
(Write/Add) element typeof(T[]) in internal buffer - ###### List<``T``>(``List`` value) ``void``
(Write/Add) element typeof(List) in internal buffer - ###### BigInteger(``BigInteger`` value) ``void``
(Write/Add) element typeof(BigInteger) in internal buffer - ###### Bytes(``byte[]`` value) ``void``
(Write/Add) element typeof(byte[]) in internal buffer
πŸ“„ IPrimitiveGet ### Methods - ###### Bool() ``bool``
(Read/Get) element typeof(bool) from internal buffer - ###### Byte() ``byte``
(Read/Get) element typeof(byte) from internal buffer - ###### SByte() ``sbyte``
(Read/Get) element typeof(sbyte) from internal buffer - ###### Char() ``char``
(Read/Get) element typeof(char) from internal buffer - ###### Short() ``short``
(Read/Get) element typeof(short) from internal buffer - ###### UShort() ``ushort``
(Read/Get) element typeof(ushort) from internal buffer - ###### Int() ``int``
(Read/Get) element typeof(int) from internal buffer - ###### UInt() ``uint``
(Read/Get) element typeof(uint) from internal buffer - ###### Float() ``float``
(Read/Get) element typeof(float) from internal buffer - ###### Enum<``T``>() ``T``
(Read/Get) element typeof(enum) from internal buffer - ###### Long() ``long``
(Read/Get) element typeof(long) from internal buffer - ###### ULong() ``ulong``
(Read/Get) element typeof(ulong) from internal buffer - ###### Double() ``double``
(Read/Get) element typeof(double) from internal buffer - ###### DateTime() ``DateTime``
(Read/Get) element typeof(DateTime) from internal buffer - ###### Decimal() ``decimal``
(Read/Get) element typeof(decimal) from internal buffer - ###### String() ``string``
(Read/Get) element typeof(string) from internal buffer - ###### Class<``T``> () ``T``
(Read/Get) element typeof(T) from internal buffer - ###### Struct<``T``>() ``T``
(Read/Get) element typeof(T) from internal buffer - ###### Array<``T``>() ``T[]``
(Read/Get) element typeof(T[]) from internal buffer - ###### List<``T``>() ``List``
(Read/Get) element typeof(List - ###### BigInteger() ``BigInteger``
(Read/Get) element typeof(BigInteger) from internal buffer - ###### Bytes() ``byte[]``
(Read/Get) element typeof(byte[]) from internal buffer
πŸ“„ Example - ###### Add Element ```csharp using Byter; Primitive primitive = new(); // write elements primitive.Add.Class(myCharacterInfoClass); primitive.Add.Array(myCharacterArray); primitive.Add.List(myLogList); primitive.Add.Struct(myDeviceStruct); primitive.Add.DateTime(DateTime.UtcNow); primitive.Add.Enum(MyEnum.Option1); primitive.Add.Bytes(myImageBuffer); // send buffer byte[] buffer = primitive.GetBytes(); Magic.Send(buffer); // EXAMPLE! ``` - ###### Get Element ```csharp using Byter; // receive bugger byte[] buffer = Magic.Receive(); // EXAMPLE! Primitive primitive = new(buffer); // read elements var myCharacterInfoClass = primitive.Get.Class(); var myCharacterArray = primitive.Get.Array(); var myLogList = primitive.Get.List(); var myDeviceStruct = primitive.Get.Struct(); var myTime = primitive.Get.DateTime(); var myEnum = primitive.Get.Enum(); var myImageBuffer = primitive.Get.Bytes(); if (primitive.IsValid) { // sucess on read all data } else { // one or more data isn't found when deserialize. Might ignore this buffer! } ``` - ###### Dynamic Read Technical ```csharp Primitive primitive = new(...); var topic = primitive.Get.String(); if(!primitive.IsValid) return; // ignore this if (topic == "login") { var loginInfo = primitive.Get.Class(); if (!primitive.IsValid) return; // ignore this // login user... } else if (topic == "get user address") { var getUserAddressInfo = primitive.Get.Class(); if (!primitive.IsValid) return; // ignore this // get user adress... } ... else { // ignore this. (Topic not found) } ```


Overhead (supported types list)

Byter overhead information

Type Primitive (overhead + size = total) Writer/Reader (overhead + size = total)
Bool βœ”οΈ (1 + 1 = 2 bytes) βœ”οΈ (2 + 1 = 3 bytes)
Byte βœ”οΈ (1 + 1 = 2 bytes) βœ”οΈ (2 + 1 = 3 bytes)
SByte βœ”οΈ (1 + 2 = 2 bytes) 🚫
Char βœ”οΈ (1 + 2 = 3 bytes) βœ”οΈ (2 + 2 = 4 bytes)
Short βœ”οΈ (1 + 2 = 3 bytes) βœ”οΈ (2 + 2 = 4 bytes)
UShort βœ”οΈ (1 + 2 = 3 bytes) βœ”οΈ (2 + 2 = 4 bytes)
Int βœ”οΈ (1 + 4 = 5 bytes) βœ”οΈ (2 + 4 = 6 bytes)
UInt βœ”οΈ (1 + 4 = 5 bytes) βœ”οΈ (2 + 4 = 6 bytes)
Float βœ”οΈ (1 + 4 = 5 bytes) βœ”οΈ (2 + 4 = 6 bytes)
Enum βœ”οΈ (1 + 4 = 5 bytes) 🚫
Long βœ”οΈ (1 + 8 = 9 bytes) βœ”οΈ (2 + 8 = 10 bytes)
ULong βœ”οΈ (1 + 8 = 9 bytes) βœ”οΈ (2 + 8 = 10 bytes)
Double βœ”οΈ (1 + 8 = 9 bytes) βœ”οΈ (2 + 8 = 10 bytes)
DateTime βœ”οΈ (1 + 8 = 9 bytes) 🚫
Decimal βœ”οΈ (1 + 16 = 17 bytes) 🚫
String βœ”οΈ (5 + ? = +5 bytes) *UTF8 βœ”οΈ (6 + ? = +6 bytes)
Class βœ”οΈ (2 + 0 = 2 bytes) 🚫
Struct βœ”οΈ (2 + 0 = 2 bytes) 🚫
Array βœ”οΈ (3 + ? = +3 bytes) *Max. 65535 🚫
List βœ”οΈ (3 + ? = +3 bytes) *Max. 65535 🚫
BigInteger βœ”οΈ (3 + ? = +3 bytes) 🚫
Bytes βœ”οΈ (5 + ? = +5 bytes) Max. 4.294.967.295 (~4billions) βœ”οΈ (6 + ? = +6 bytes) Max. 2.147.483.647 (~2billions)


Encoding Extension

using Byter;
Legacy Docs (v1.x.x - v2.x.x) # Byter Byter is a bytes serializer. It can serialize and deserialize from primitive type. > ###### Byter is very stable, super easy to learn, extremely fast and inexpensive (2 bytes or ``sizeof(char)`` of overhead per data written) and ``100%`` written in ``C#`` and it's FREE!


## Install - #### Nuget [SEE HERE](https://www.nuget.org/packages/Byter) ###### .NET CLI ```rb dotnet add package Byter --version 2.0 ``` ###### Git submodule See how add as git submodule? See on bottom of this docs

## Usage #### Namespace ```csharp using Byter ``` #### Types ```ts [ `byte`, `bool`, `byte[]`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `float`, `double`, `char`, `string`, `Float2`(Vector2), `Float3`(Vector3), `Float4`(Vector4 / Quaternion), ] ```
## Writer > Constructor - ```cs _ = new Writer(); // Create default instance _ = new Writer(new Writer()); // Create instance and copy from existing Writer _ = new Writer(ref new Writer()); // Create instance and copy from existing Writer (using ref) ```
> Proprietary - #### ``Length`` ```cs using Byter; var w = new Writer(); // Get lenght of buffer int lenght = w.Length; ```
> Methods - #### ``Write(dynamic value)`` ```cs using Byter; // Create writer instance; using var w = new Writer(); // Write string w.Write("KEZERO"); // Write char w.Write('K'); // Write Float3 (Vector3) w.Write(new Float3(10F, 10F, 10F)); // Get bytes (buffer) byte[] buffer = w.GetBytes(); // Get byte list (buffer) List bytes = w.GetList(); ``` - #### ``GetBytes()`` ```cs using Byter; var w = new Writer(); // Return buffer on instance byte[] buffer = w.GetBytes(); ``` - #### ``GetList()`` ```cs using Byter; var w = new Writer(); // Return buffer on instance as byte list List bytes = w.GetList(); ``` - #### ``Clear()`` ```cs using Byter; var w = new Writer(); w.Write((int)1000); w.Write((float)100f); // Clear internal buffer and reset internal index w.Clear(); ```
## Reader > Constructor - ```cs _ = new Reader(new Writer()); // Create instance and copy buffer from existing Writer _ = new Reader(ref new Writer()); // Create instance and copy buffer from existing Writer (ref Writer) _ = new Reader(new byte[] { 1, 1, 1, 1 }); // Create instance from buffer (bytes (byte[])) ```
> Proprietary - #### ``Length`` ```cs using Byter; byte[] buffer = ...; var r = new Reader(buffer); // Get lenght of buffer int lenght = r.Length; ``` - #### ``Position`` ```cs using Byter; byte[] buffer = ...; var r = new Reader(buffer); // return current index of readed buffer int position = r.Position; ``` - #### ``Success`` ```cs using Byter; byte[] buffer = ...; var r = new Reader(buffer); string name = r.Read(); int age = r.Read(); // return true if not exist problem on read values. // return false when have any error on read values; bool success = r.Success; ``` - ###### WARNING Internally, before data is written a prefix is added in front of it, so when reading it always compares the prefix of the (data type) you want to read with the strings in the read buffer. if the prefixes do not match then o ( Reader. Success = False), eg. If you write an (int) and try to read a float (Reader.Success = False) because the prefix of an (int) is different from that of a (float), it is recommended to read all the data and at the end check the success, if it is (Reader.Success = False) then one or more data is corrupt. This means that Writer and Reader add dipping to your write and read data.
> Methods - #### ``Read()`` ``Read(Encoding encoding)``; ```cs using Byter; byte[] buffer = ...; // Create reader instance using r = new Reader(buffer); string name = r.Read(); char firstLatter = r.Read(); Float3 position = r.Read(); // Check if is success if (r.Success) { Console.WriteLine($"Name: {name}"); Console.WriteLine($"First Latter: {firstLatter}"); Console.WriteLine($"Position: {position}"); } else { Console.WriteLine("Error on get data"); } ``` - #### ``Seek(int position)``; ```cs using Byter; using var w = new Writer(); w.Write("KEZERO"); w.Write((int) 1024); using var r = new Reader(ref w); string name = r.Read(); // name: KEZERO int age = r.Read(); // age: 1024 // Move index (Reader.Position) for target value "MIN VALUE IS 0"; r.Seek(10); // move current index for read for 10 (when start read using .Read will start read on 10 index from buffer); // Reset internal position r.Seek(0); string name2 = r.Read(); // name: KEZERO (because the start index of this string on buffer is 0) int age2 = r.Read(); age: 1024; // NEED READ LAST INT r.Seek(r.Position - sizeof(int) + sizeof(char) /* int size is 4 + char size is 2. The 2 bytes is overhead of protocol */); int age3 = r.Read(); age: 1024 (because i return 4bytes before old current value) ```


#### Sample ```csharp using Byter; // writing Writer writer = new(); writer.Write(1000); // index writer.Write("{JSON}"); // content writer.Write(new byte[]{ 1, 1, 1, 1 }); // image // geting buffer byte[] buffer = writer.GetBytes(); writer.Dispose(); // Destroy Writer // reading Reader reader = new(buffer); int index = reader.Read(); string json = reader.Read(); byte[] image = reader.Read(); // Check error if (!reader.Success) // IS FALSE { Console.WriteLine("*** ERROR ****"); return; } // Check success Console.WriteLine("*** SUCCESS ****"); // Output Console.WriteLine($"Index: {index}"); // output: 1000 Console.WriteLine($"JSON : {json }"); // output: JSON Console.WriteLine($"Image: {image.Length}"); // output: 4 Console.WriteLine($"Status: {reader.Success}"); // output: True // Making error float delay = reader.Read(); /* WARNING: if you reverse the reading order or try to read more data than added (Reader.Succes = False), Remembering does not return exception when trying to read data that does not exist it just returns the default construction, and (Reader.Success) will be assigned (False) */ if (reader.Success) // IS FALSE, THE IS NOT WRITED IN BUFFER Console.WriteLine($"Delay: {delay}"); else // IS TRUE, THE DELAY NOT EXIST Console.WriteLine($"Delay not exist"); // Output of status Console.WriteLine($"Status: {reader.Success}"); // output: False reader.Dispose(); // Destroy Reader ```


#### Install using git submodule ```rb # Install - recommend a stable branch e.g. "1.x" or use a fork repository, --depth clone last sources git submodule add --name byter --depth 1 --branch main "https://github.com/alec1o/byter" vendor/byter # Rebuilding - Download repository and link it in file location, must add this step in dotnet.yaml if using git submodule update --init # Update submodule - Update and load new repository updates git submodule update --remote # PATH # |__ vendor # | |__ byter # | |__ src # | |__ Byter.csproj # | # |__ app # | |__ app.csproj # | # |__ app.sln # |__ .git # |__ .gitignore # |__ .gitmodules # .NET link on .sln cd dotnet sln add vendor/byter/src/Byter.csproj # .NET link on .csproj cd app/ dotnet add reference ../vendor/byter/src/Byter.csproj # Rebuild dependencies to be linked in the project dotnet restore ```