Skip to content

Commit

Permalink
Adding msg-pack
Browse files Browse the repository at this point in the history
  • Loading branch information
pjotrp committed Aug 16, 2023
1 parent f2d23bd commit 61a1736
Show file tree
Hide file tree
Showing 57 changed files with 8,758 additions and 0 deletions.
12 changes: 12 additions & 0 deletions BioD/contrib/msgpack-d/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
dub.selections.json
.dub
tests/*/tests
__test__*__
*.obj
*.[oa]
*.so
*.lib
*.dll
*.sublime-project
*.sublime-workspace
msgpack-d-test-unittest
23 changes: 23 additions & 0 deletions BioD/contrib/msgpack-d/LICENSE_1_0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003

Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:

The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
199 changes: 199 additions & 0 deletions BioD/contrib/msgpack-d/README.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
[![CI](https://github.com/msgpack/msgpack-d/actions/workflows/d.yml/badge.svg)](https://github.com/msgpack/msgpack-d/actions/workflows/d.yml)

# MessagePack for D

MessagePack is a binary-based JSON-like serialization library.

MessagePack for D is a pure D implementation of MessagePack.

# Features

* Small size and High performance
* Zero copy serialization / deserialization
* Streaming deserializer for non-contiguous IO situation
* Supports D features (Ranges, Tuples, real type)

Note: The `real` type is only supported in D.
Don't use the `real` type when communicating with other programming languages.
Note that `Unpacker` will raise an exception if a loss of precision occurs.

## Current Limitations

* No circular references support
* If you want to use the LDC compiler, you need at least version 0.15.2 beta2

# Install

Use dub to add it as a dependency:

```sh
% dub install msgpack-d
```

# Usage

Example code can be found in the `example` directory.

The documentation can be found [here](http://msgpack.github.io/msgpack-d/)

## pack / unpack

msgpack-d is very simple to use. Use `pack` for serialization, and `unpack` for deserialization:

```D
import std.file;
import msgpack;
struct S { int x; float y; string z; }
void main()
{
S input = S(10, 25.5, "message");
// serialize data
ubyte[] inData = pack(input);
// write data to a file
write("file.dat", inData);
// read data from a file
ubyte[] outData = cast(ubyte[])read("file.dat");
// unserialize the data
S target = outData.unpack!S();
// verify data is the same
assert(target.x == input.x);
assert(target.y == input.y);
assert(target.z == input.z);
}
```

### Feature: Skip serialization/deserialization of a specific field.

Use the `@nonPacked` attribute:

```d
struct User
{
string name;
@nonPacked int level; // pack / unpack will ignore the 'level' field
}
```

### Feature: Use your own serialization/deserialization routines for custom class and struct types.

msgpack-d provides the functions `registerPackHandler` / `registerUnpackHandler` to allow you
to use custom routines during the serialization or deserialization of user-defined class and struct types.
This feature is especially useful when serializing a derived class object when that object is statically
typed as a base class object.

For example:

```d
class Document { }
class XmlDocument : Document
{
this() { }
this(string name) { this.name = name; }
string name;
}
void xmlPackHandler(ref Packer p, ref XmlDocument xml)
{
p.pack(xml.name);
}
void xmlUnpackHandler(ref Unpacker u, ref XmlDocument xml)
{
u.unpack(xml.name);
}
void main()
{
/// Register the 'xmlPackHandler' and 'xmlUnpackHandler' routines for
/// XmlDocument object instances.
registerPackHandler!(XmlDocument, xmlPackHandler);
registerUnpackHandler!(XmlDocument, xmlUnpackHandler);
/// Now we can serialize/deserialize XmlDocument object instances via a
/// base class reference.
Document doc = new XmlDocument("test.xml");
auto data = pack(doc);
XmlDocument xml = unpack!XmlDocument(data);
assert(xml.name == "test.xml"); // xml.name is "test.xml"
}
```

In addition, here is also a method using `@serializedAs` attribute:

```d
import std.datetime: Clock, SysTime;
static struct SysTimePackProxy
{
static void serialize(ref Packer p, ref in SysTime tim)
{
p.pack(tim.toISOExtString());
}
static void deserialize(ref Unpacker u, ref SysTime tim)
{
string tmp;
u.unpack(tmp);
tim = SysTime.fromISOExtString(tmp);
}
}
static struct LogData
{
string msg;
string file;
ulong line;
@serializedAs!SysTimePackProxy SysTime timestamp;
this(string message, string file = __FILE__, ulong line = __LINE__)
{
this.msg = message;
this.file = file;
this.line = line;
this.timestamp = Clock.currTime();
}
}
void main()
{
/// Now we can serialize/deserialize LogData
LogData[] logs;
logs ~= LogData("MessagePack is nice!");
auto data = pack(logs);
LogData[] datas = unpack!(LogData[])(data);
assert(datas[0].timestamp.toString() == datas[0].timestamp.toString());
}
```

## The PackerImpl / Unpacker / StreamingUnpacker types

These types are used by the `pack` and `unpack` functions.

See the documentation of [PackerImpl](http://msgpack.github.io/msgpack-d/#PackerImpl), [Unpacker](http://msgpack.github.io/msgpack-d/#Unpacker) and [StreamingUnpacker](http://msgpack.github.io/msgpack-d/#StreamingUnpacker) for more details.

# Links

* [The MessagePack Project](http://msgpack.org/)

The official MessagePack protocol website.

* [msgpack-d's issue tracker](https://github.com/msgpack/msgpack-d/issues)

Use this issue tracker to review and file bugs in msgpack-d.

* [MessagePack's Github](http://github.com/msgpack/)

Other language bindings and implementations of the msgpack protocol can be found here.

# Copyright

Copyright (c) 2010- Masahiro Nakagawa

# License

Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/users/license.html).
19 changes: 19 additions & 0 deletions BioD/contrib/msgpack-d/dub.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "msgpack-d",
"description": "MessagePack for D.",
"authors": ["Masahiro Nakagawa"],
"homepage": "https://github.com/msgpack/msgpack-d",
"license": "Boost Software License, Version 1.0",
"copyright": "Copyright (c) 2010- Masahiro Nakagawa",

"configurations": [
{
"name": "default",
"targetType": "library"
},
{
"name": "unittest",
"dflags": ["-dip25", "-dip1000"]
}
]
}
39 changes: 39 additions & 0 deletions BioD/contrib/msgpack-d/example/array_test.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import std.conv;
import std.stdio;
import std.datetime;
import msgpack;

struct A {
int x;
}

struct Foo
{
A[] a;
}

void main()
{
Foo foo;
foreach (a; 'a' .. 'z')
foreach (b; 'a' .. 'z')
foreach (c; 'a' .. 'z')
foo.a ~= A();

auto sw = StopWatch(AutoStart.yes);
ubyte[] data = msgpack.pack(foo);
writeln(sw.peek.usecs);

auto sw2 = StopWatch(AutoStart.yes);
Foo foo1 = msgpack.unpack(data).as!(typeof(foo));
writeln(sw2.peek.usecs);

assert(foo == foo1);

Foo foo2;
auto sw3 = StopWatch(AutoStart.yes);
msgpack.unpack(data, foo2);
writeln(sw3.peek.usecs);

assert(foo == foo2);
}
24 changes: 24 additions & 0 deletions BioD/contrib/msgpack-d/example/attribute.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Written in the D programming language.

/**
* Attribute usage
*/

import msgpack;

struct Hoge
{
string f1;
@nonPacked int f2;
}

void main()
{
Hoge hoge = Hoge("hoge", 10);
Hoge fuga;

unpack(pack(hoge), fuga);
assert(hoge.f1 == fuga.f1);
assert(hoge.f2 != fuga.f2);
assert(fuga.f2 == int.init);
}
55 changes: 55 additions & 0 deletions BioD/contrib/msgpack-d/example/compare_direct_stream.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Written in the D programming language.

/**
* Compares direct conversion with stream.
*/

import std.datetime;
import std.stdio;
import std.typecons;

import msgpack;


void main()
{
// tuple
auto test1 = tuple(new int[](100), "MessagePack!", [1:2.0, 3:4.0, 5:6.0, 7:8.0]);
auto data1 = pack(test1);

// stream
void s1()
{
auto result = unpack(data1).as!(typeof(test1));
}

// direct conversion
void d1()
{
typeof(test1) result;
unpack(data1, result);
}

// array
auto test2 = new int[](1000);
auto data2 = pack(test2);

// stream
void s2()
{
auto result = unpack(data2).as!(typeof(test2));
}

// direct conversion
void d2()
{
typeof(test2) result;
unpack(data2, result);
}

auto times = benchmark!(s1, d1, s2, d2)(1000);
writeln("Stream(Tuple):", times[0].msecs);
writeln("Direct(Tuple):", times[1].msecs);
writeln("Stream(Array):", times[2].msecs);
writeln("Direct(Array):", times[3].msecs);
}
Loading

0 comments on commit 61a1736

Please sign in to comment.