{"id":28092435,"url":"https://github.com/relaxspirit/nanoframework.messagepack","last_synced_at":"2025-05-13T13:14:53.621Z","repository":{"id":286002548,"uuid":"960040224","full_name":"nanoframework/nanoFramework.MessagePack","owner":"nanoframework","description":":package: .NET nanoFramework MessagePack serealizer/deserializer library","archived":false,"fork":false,"pushed_at":"2025-05-02T13:01:31.000Z","size":130,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-13T13:14:43.886Z","etag":null,"topics":["chsarp","dotnet","esp32","hacktoberfest","mcu","nanoframework","serialization-library","stm32"],"latest_commit_sha":null,"homepage":"https://www.nanoframework.net","language":"C#","has_issues":false,"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/nanoframework.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,"zenodo":null},"funding":{"open_collective":"nanoframework","github":"nanoframework"}},"created_at":"2025-04-03T19:02:01.000Z","updated_at":"2025-05-02T13:01:34.000Z","dependencies_parsed_at":"2025-04-11T17:21:30.254Z","dependency_job_id":"31a19762-ff27-4d11-bbcc-3048d6254f9f","html_url":"https://github.com/nanoframework/nanoFramework.MessagePack","commit_stats":null,"previous_names":["relaxspirit/nanoframework.messagepack","nanoframework/nanoframework.messagepack"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanoframework%2FnanoFramework.MessagePack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanoframework%2FnanoFramework.MessagePack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanoframework%2FnanoFramework.MessagePack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanoframework%2FnanoFramework.MessagePack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nanoframework","download_url":"https://codeload.github.com/nanoframework/nanoFramework.MessagePack/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253948503,"owners_count":21988961,"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":["chsarp","dotnet","esp32","hacktoberfest","mcu","nanoframework","serialization-library","stm32"],"created_at":"2025-05-13T13:14:49.932Z","updated_at":"2025-05-13T13:14:53.612Z","avatar_url":"https://github.com/nanoframework.png","language":"C#","funding_links":["https://opencollective.com/nanoframework","https://github.com/sponsors/nanoframework"],"categories":[],"sub_categories":[],"readme":"﻿﻿[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=nanoframework_nanoFramework.MessagePack\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=nanoframework_nanoFramework.MessagePack) [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=nanoframework_nanoFramework.MessagePack\u0026metric=reliability_rating)](https://sonarcloud.io/dashboard?id=nanoframework_nanoFramework.MessagePack) [![NuGet](https://img.shields.io/nuget/dt/nanoFramework.MessagePack.svg?label=NuGet\u0026style=flat\u0026logo=nuget)](https://www.nuget.org/packages/nanoFramework.MessagePack/) [![#yourfirstpr](https://img.shields.io/badge/first--timers--only-friendly-blue.svg)](https://github.com/nanoframework/Home/blob/main/CONTRIBUTING.md) [![Discord](https://img.shields.io/discord/478725473862549535.svg?logo=discord\u0026logoColor=white\u0026label=Discord\u0026color=7289DA)](https://discord.gg/gCyBu8T)\n\n![nanoFramework logo](https://raw.githubusercontent.com/nanoframework/Home/main/resources/logo/nanoFramework-repo-logo.png)\n\n-----\n\n# Welcome to the .NET **nanoFramework** MessagePack repository\n\nThis repository contains the MessagePack library for the .NET **nanoFramework**. It provides high-performance serialization and deserialization with the smallest possible payload, [MessagePack](https://github.com/msgpack/msgpack) is an object serialization specification like JSON.\n\n## Build status\n\n| Component | Build Status | NuGet Package |\n|:-|---|---|\n| nanoFramework.MessagePack | [![Build Status](https://dev.azure.com/nanoframework/nanoFramework.MessagePack/_apis/build/status%2Fnanoframework.nanoFramework.MessagePack?branchName=main)](https://dev.azure.com/nanoframework/nanoFramework.MessagePack/_build/latest?definitionId=119\u0026branchName=main) | [![NuGet](https://img.shields.io/nuget/v/nanoFramework.MessagePack.svg?label=NuGet\u0026style=flat\u0026logo=nuget)](https://www.nuget.org/packages/nanoFramework.MessagePack/) |\n\n# nanoFramework.MessagePack\n\nMessagePack is a simple, lightweight serialization library, inspired by [MsgPack.Light](https://github.com/progaudi/MsgPack.Light), that can be used in .NET **nanoFramework** projects.\n\n## Usage\n\n### Serialization to byte array\n\n```csharp\nvar value = new TestClass();\nvar bytes = MessagePackSerializer.Serialize(value);\n```\n\n### Deserialization\n\n```csharp\nvar result = (TestClass)MessagePackSerializer.Deserialize(typeof(TestClass), bytes);\n```\n\n### Your type serialization/deserialization\n\nIf you want to work with your own types, first thing you need to add is a type converter. Although the library provides almost complete coverage of the serialization/deserialization of any objects, there are certain cases where it is difficult to do without a custom converter.\n\n#### The general principle of implementing a custom converter\n\n1) In the code of your project, you need to create a converter class that inherits the IConverter interface and implement the Read and Write interface methods:\n\n   ```csharp\n        public class SimpleCustomConverter : IConverter\n        {\n            #nullable enable\n            public void Write(object? value, [NotNull] IMessagePackWriter writer)\n            {\n                //TODO Your code is here\n            }\n    \n            public object? Read([NotNull] IMessagePackReader reader)\n            {\n               var yourObject = new YourObject();\n               //TODO Your code is here\n               return yourObject;\n            }\n        }\n   ```\n   \n2) Register your custom converter in the context of serialization:\n\n   ```csharp\n         public class Program\n         {\n             public static void Main()\n             {\n                   var simpleCustomConverter = new SimpleCustomConverter();\n                   ConverterContext.Add(typeof(YourObject), simpleCustomConverter);\n             }\n         }\n   ```\n   \nAfter completing these steps, the serialization/deserialization of the object for which your converter is added will occur in the methods of the custom converter.\n\n##### A few examples of the implementation of custom converters\n\n1. Case with enumeration elements as strings:\n   \n    ```csharp\n        namespace samples\n        {\n            public enum FieldType\n            {\n                _ = -1,\n                Str,\n                Num,\n                Any\n            }\n    \n            public class FieldTypeConverter : IConverter\n            {\n                internal FieldType Read(IMessagePackReader reader)\n                {\n                    var stringConverter = ConverterContext.GetConverter(typeof(string));\n        \n                    var enumString = (string)stringConverter.Read(reader);\n        \n                    return enumString switch\n                    {\n                        \"Str\" =\u003e FieldType.Str,\n                        \"Num\" =\u003e FieldType.Num,\n                        \"*\" =\u003e FieldType.Any,\n                        _ =\u003e throw new Exception($\"Unexpected enum {typeof(FieldType)} underlying type: {enumString}\"),\n                    };\n                }\n        \n                internal void Write(FieldType value, [NotNull] IMessagePackWriter writer)\n                {\n                    var stringConverter = ConverterContext.GetConverter(typeof(string));\n        \n                    switch (value)\n                    {\n                        case FieldType.Str:\n                            stringConverter.Write(\"Str\", writer);\n                            break;\n                        case FieldType.Num:\n                            stringConverter.Write(\"Num\", writer);\n                            break;\n                        case FieldType.Any:\n                            stringConverter.Write(\"*\", writer);\n                            break;\n                        default:\n                            throw new Exception($\"Enum {value.GetType()} value: {value} expected\");\n                    }\n                }\n        \n        #nullable enable\n                object? IConverter.Read([NotNull] IMessagePackReader reader)\n                {\n                    return Read(reader);\n                }\n        \n                public void Write(object? value, [NotNull] IMessagePackWriter writer)\n                {\n                    Write((FieldType)value!, writer);\n                }\n            }\n        }\n   ```\n\n2. Case compression or concealment of transmitted strings between sender and recipient if sender and recipient share the same vocabulary of words:\n\n    ```csharp\n        namespace samples\n        {\n            public static class SharedWordDictionary\n            {\n                static SharedWordDictionary()\n                {\n                    WordDictionary = new ArrayList\n                    {\n                        \"MessagePack\",\n                        \"Hello\",\n                        \"at\",\n                        \"nanoFramework!\",\n                        \" \"\n                    };\n                }\n        \n                public static ArrayList WordDictionary { get; }\n            }\n        \n            public class SecureMessage\n            {\n                public SecureMessage(string message)\n                {\n                    Message = message;\n                }\n        \n                public string Message { get; private set; }\n            }\n        \n            public class SecureMessageConverter : IConverter\n            {\n                public SecureMessage Read([NotNull] IMessagePackReader reader)\n                {\n                    StringBuilder sb = new();\n                    var length = reader.ReadArrayLength();\n                    var intConverter = ConverterContext.GetConverter(typeof(int));\n\n                    for (int i = 0; i \u003c length; i++)\n                    {\n                        int wordIndex = (int)intConverter.Read(reader)!;\n                        sb.Append(SharedWordDictionary.WordDictionary[wordIndex]);\n                        sb.Append(' ');\n                    }\n                    if (sb.Length \u003e 0)\n                        sb.Remove(sb.Length - 1, 1);\n\n                    return new SecureMessage(sb.ToString());\n                }\n\n                public void Write(SecureMessage value, [NotNull] IMessagePackWriter writer)\n                {\n                    var messageWords = value.Message.Split(' ');\n\n                    uint length = (uint)messageWords.Length;\n                    writer.WriteArrayHeader(length);\n\n                    var intConverter = ConverterContext.GetConverter(typeof(int));\n\n                    foreach (var word in messageWords)\n                    {\n                        int wordIndex = SharedWordDictionary.WordDictionary.IndexOf(word);\n                        intConverter.Write(wordIndex, writer);\n                    }\n                }\n        \n        #nullable enable\n                object? IConverter.Read([NotNull] IMessagePackReader reader)\n                {\n                    return Read(reader);\n                }\n        \n                public void Write(object? value, [NotNull] IMessagePackWriter writer)\n                {\n                    Write((SecureMessage)value!, writer);\n                }\n            }\n        \n            public class Program\n            {\n                public static void Main()\n                {\n                    var secureMessageConverter = new SecureMessageConverter();\n                    ConverterContext.Add(typeof(SecureMessage), secureMessageConverter);\n        \n                    var secureMessage = new SecureMessage(\"Hello MessagePack at nanoFramework!\");\n        \n                    //At sender\n                    var buffer = MessagePackSerializer.Serialize(secureMessage);\n                    Debug.WriteLine($\"The message:\\n{secureMessage.Message}\\nbeing sent has been serialized into {buffer.Length} bytes.\");\n                    //and sent to recipient\n                    //\n                    //..........................\n                    Debug.WriteLine(\"=============================================\");\n        \n                    //At recipient, after receiving the byte array\n                    Debug.WriteLine($\"Received {buffer.Length} bytes\");\n        \n                    var recipientSecureMessage = (SecureMessage)MessagePackSerializer.Deserialize(typeof(SecureMessage), buffer)!;\n        \n                    Debug.WriteLine($\"Message received:\\n{recipientSecureMessage.Message}\");\n                }\n            }\n        }\n   ```\n\n## Benchmarks\n\nThe measurements were carried out on the developer's local computer in a virtual nanoDevice:\n\n ```text\n===============================================================\n==========         Comparative benchmarks data       ==========\n==========                                           ==========\n========== Json string size:           3957 bytes    ==========\n========== BinaryFormatter array size: 1079 bytes    ==========\n========== MessagePack array size:     2444 bytes    ==========\n==========                                           ==========\n===============================================================\n\nConsole export: ComparativeDeserializationBenchmark benchmark class.\n\n| ------------------------------------------------------------------------------ |\n| MethodName                          | IterationCount | Mean    | Min   | Max   |\n| ------------------------------------------------------------------------------ |\n| JsonDeserializationBenchmark        | 10             | 27.5 ms | 22 ms | 37 ms |\n| BinaryDeserializationBenchmark      | 10             | 0.1 ms  | 0 ms  | 1 ms  |\n| MessagePackDeserializationBenchmark | 10             | 23.7 ms | 19 ms | 34 ms |\n| ------------------------------------------------------------------------------ |\n\nConsole export: ComparativeSerializationBenchmark benchmark class.\n\n\n| ---------------------------------------------------------------------------- |\n| MethodName                        | IterationCount | Mean    | Min   | Max   |\n| ---------------------------------------------------------------------------- |\n| JsonSerializationBenchmark        | 10             | 18.9 ms | 16 ms | 25 ms |\n| BinarySerializationBenchmark      | 10             | 0.1 ms  | 0 ms  | 1 ms  |\n| MessagePackSerializationBenchmark | 10             | 9.8 ms  | 9 ms  | 14 ms |\n| ---------------------------------------------------------------------------- |\n```\nAs it can be seen from the benchmark results above, in what concerns speed and compaction, `MessagePack` performs better than the Json serializer. Comming at no surprise, Binary serialization is the most performant one.\n\n## Acknowledgements\n\nThe initial version of the MessagePack library was coded by [Spirin Dmitriy](https://github.com/RelaxSpirit), who has kindly handed over the library to the .NET **nanoFramework** project.\n\n## Feedback and documentation\n\nFor documentation, providing feedback, issues, and finding out how to contribute, please refer to the [Home repo](https://github.com/nanoframework/Home).\n\nJoin our Discord community [here](https://discord.gg/gCyBu8T).\n\n## Credits\n\nThe list of contributors to this project can be found at [CONTRIBUTORS](https://github.com/nanoframework/Home/blob/main/CONTRIBUTORS.md).\n\n## License\n\nThe **nanoFramework** WebServer library is licensed under the [MIT license](LICENSE.md).\n\n## Code of Conduct\n\nThis project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behaviour in our community.\nFor more information see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).\n\n## .NET Foundation\n\nThis project is supported by the [.NET Foundation](https://dotnetfoundation.org).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frelaxspirit%2Fnanoframework.messagepack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frelaxspirit%2Fnanoframework.messagepack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frelaxspirit%2Fnanoframework.messagepack/lists"}