https://github.com/relaxspirit/nanoframework.messagepack
:package: .NET nanoFramework MessagePack serealizer/deserializer library
https://github.com/relaxspirit/nanoframework.messagepack
chsarp dotnet esp32 hacktoberfest mcu nanoframework serialization-library stm32
Last synced: about 1 year ago
JSON representation
:package: .NET nanoFramework MessagePack serealizer/deserializer library
- Host: GitHub
- URL: https://github.com/relaxspirit/nanoframework.messagepack
- Owner: nanoframework
- License: mit
- Created: 2025-04-03T19:02:01.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-05-02T13:01:31.000Z (about 1 year ago)
- Last Synced: 2025-05-13T13:14:43.886Z (about 1 year ago)
- Topics: chsarp, dotnet, esp32, hacktoberfest, mcu, nanoframework, serialization-library, stm32
- Language: C#
- Homepage: https://www.nanoframework.net
- Size: 127 KB
- Stars: 2
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
[](https://sonarcloud.io/dashboard?id=nanoframework_nanoFramework.MessagePack) [](https://sonarcloud.io/dashboard?id=nanoframework_nanoFramework.MessagePack) [](https://www.nuget.org/packages/nanoFramework.MessagePack/) [](https://github.com/nanoframework/Home/blob/main/CONTRIBUTING.md) [](https://discord.gg/gCyBu8T)

-----
# Welcome to the .NET **nanoFramework** MessagePack repository
This 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.
## Build status
| Component | Build Status | NuGet Package |
|:-|---|---|
| nanoFramework.MessagePack | [](https://dev.azure.com/nanoframework/nanoFramework.MessagePack/_build/latest?definitionId=119&branchName=main) | [](https://www.nuget.org/packages/nanoFramework.MessagePack/) |
# nanoFramework.MessagePack
MessagePack is a simple, lightweight serialization library, inspired by [MsgPack.Light](https://github.com/progaudi/MsgPack.Light), that can be used in .NET **nanoFramework** projects.
## Usage
### Serialization to byte array
```csharp
var value = new TestClass();
var bytes = MessagePackSerializer.Serialize(value);
```
### Deserialization
```csharp
var result = (TestClass)MessagePackSerializer.Deserialize(typeof(TestClass), bytes);
```
### Your type serialization/deserialization
If 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.
#### The general principle of implementing a custom converter
1) 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:
```csharp
public class SimpleCustomConverter : IConverter
{
#nullable enable
public void Write(object? value, [NotNull] IMessagePackWriter writer)
{
//TODO Your code is here
}
public object? Read([NotNull] IMessagePackReader reader)
{
var yourObject = new YourObject();
//TODO Your code is here
return yourObject;
}
}
```
2) Register your custom converter in the context of serialization:
```csharp
public class Program
{
public static void Main()
{
var simpleCustomConverter = new SimpleCustomConverter();
ConverterContext.Add(typeof(YourObject), simpleCustomConverter);
}
}
```
After completing these steps, the serialization/deserialization of the object for which your converter is added will occur in the methods of the custom converter.
##### A few examples of the implementation of custom converters
1. Case with enumeration elements as strings:
```csharp
namespace samples
{
public enum FieldType
{
_ = -1,
Str,
Num,
Any
}
public class FieldTypeConverter : IConverter
{
internal FieldType Read(IMessagePackReader reader)
{
var stringConverter = ConverterContext.GetConverter(typeof(string));
var enumString = (string)stringConverter.Read(reader);
return enumString switch
{
"Str" => FieldType.Str,
"Num" => FieldType.Num,
"*" => FieldType.Any,
_ => throw new Exception($"Unexpected enum {typeof(FieldType)} underlying type: {enumString}"),
};
}
internal void Write(FieldType value, [NotNull] IMessagePackWriter writer)
{
var stringConverter = ConverterContext.GetConverter(typeof(string));
switch (value)
{
case FieldType.Str:
stringConverter.Write("Str", writer);
break;
case FieldType.Num:
stringConverter.Write("Num", writer);
break;
case FieldType.Any:
stringConverter.Write("*", writer);
break;
default:
throw new Exception($"Enum {value.GetType()} value: {value} expected");
}
}
#nullable enable
object? IConverter.Read([NotNull] IMessagePackReader reader)
{
return Read(reader);
}
public void Write(object? value, [NotNull] IMessagePackWriter writer)
{
Write((FieldType)value!, writer);
}
}
}
```
2. Case compression or concealment of transmitted strings between sender and recipient if sender and recipient share the same vocabulary of words:
```csharp
namespace samples
{
public static class SharedWordDictionary
{
static SharedWordDictionary()
{
WordDictionary = new ArrayList
{
"MessagePack",
"Hello",
"at",
"nanoFramework!",
" "
};
}
public static ArrayList WordDictionary { get; }
}
public class SecureMessage
{
public SecureMessage(string message)
{
Message = message;
}
public string Message { get; private set; }
}
public class SecureMessageConverter : IConverter
{
public SecureMessage Read([NotNull] IMessagePackReader reader)
{
StringBuilder sb = new();
var length = reader.ReadArrayLength();
var intConverter = ConverterContext.GetConverter(typeof(int));
for (int i = 0; i < length; i++)
{
int wordIndex = (int)intConverter.Read(reader)!;
sb.Append(SharedWordDictionary.WordDictionary[wordIndex]);
sb.Append(' ');
}
if (sb.Length > 0)
sb.Remove(sb.Length - 1, 1);
return new SecureMessage(sb.ToString());
}
public void Write(SecureMessage value, [NotNull] IMessagePackWriter writer)
{
var messageWords = value.Message.Split(' ');
uint length = (uint)messageWords.Length;
writer.WriteArrayHeader(length);
var intConverter = ConverterContext.GetConverter(typeof(int));
foreach (var word in messageWords)
{
int wordIndex = SharedWordDictionary.WordDictionary.IndexOf(word);
intConverter.Write(wordIndex, writer);
}
}
#nullable enable
object? IConverter.Read([NotNull] IMessagePackReader reader)
{
return Read(reader);
}
public void Write(object? value, [NotNull] IMessagePackWriter writer)
{
Write((SecureMessage)value!, writer);
}
}
public class Program
{
public static void Main()
{
var secureMessageConverter = new SecureMessageConverter();
ConverterContext.Add(typeof(SecureMessage), secureMessageConverter);
var secureMessage = new SecureMessage("Hello MessagePack at nanoFramework!");
//At sender
var buffer = MessagePackSerializer.Serialize(secureMessage);
Debug.WriteLine($"The message:\n{secureMessage.Message}\nbeing sent has been serialized into {buffer.Length} bytes.");
//and sent to recipient
//
//..........................
Debug.WriteLine("=============================================");
//At recipient, after receiving the byte array
Debug.WriteLine($"Received {buffer.Length} bytes");
var recipientSecureMessage = (SecureMessage)MessagePackSerializer.Deserialize(typeof(SecureMessage), buffer)!;
Debug.WriteLine($"Message received:\n{recipientSecureMessage.Message}");
}
}
}
```
## Benchmarks
The measurements were carried out on the developer's local computer in a virtual nanoDevice:
```text
===============================================================
========== Comparative benchmarks data ==========
========== ==========
========== Json string size: 3957 bytes ==========
========== BinaryFormatter array size: 1079 bytes ==========
========== MessagePack array size: 2444 bytes ==========
========== ==========
===============================================================
Console export: ComparativeDeserializationBenchmark benchmark class.
| ------------------------------------------------------------------------------ |
| MethodName | IterationCount | Mean | Min | Max |
| ------------------------------------------------------------------------------ |
| JsonDeserializationBenchmark | 10 | 27.5 ms | 22 ms | 37 ms |
| BinaryDeserializationBenchmark | 10 | 0.1 ms | 0 ms | 1 ms |
| MessagePackDeserializationBenchmark | 10 | 23.7 ms | 19 ms | 34 ms |
| ------------------------------------------------------------------------------ |
Console export: ComparativeSerializationBenchmark benchmark class.
| ---------------------------------------------------------------------------- |
| MethodName | IterationCount | Mean | Min | Max |
| ---------------------------------------------------------------------------- |
| JsonSerializationBenchmark | 10 | 18.9 ms | 16 ms | 25 ms |
| BinarySerializationBenchmark | 10 | 0.1 ms | 0 ms | 1 ms |
| MessagePackSerializationBenchmark | 10 | 9.8 ms | 9 ms | 14 ms |
| ---------------------------------------------------------------------------- |
```
As 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.
## Acknowledgements
The 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.
## Feedback and documentation
For documentation, providing feedback, issues, and finding out how to contribute, please refer to the [Home repo](https://github.com/nanoframework/Home).
Join our Discord community [here](https://discord.gg/gCyBu8T).
## Credits
The list of contributors to this project can be found at [CONTRIBUTORS](https://github.com/nanoframework/Home/blob/main/CONTRIBUTORS.md).
## License
The **nanoFramework** WebServer library is licensed under the [MIT license](LICENSE.md).
## Code of Conduct
This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behaviour in our community.
For more information see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
## .NET Foundation
This project is supported by the [.NET Foundation](https://dotnetfoundation.org).