{"id":20649493,"url":"https://github.com/leapmotion/leapserial","last_synced_at":"2025-04-17T01:02:28.727Z","repository":{"id":35152409,"uuid":"39382591","full_name":"leapmotion/leapserial","owner":"leapmotion","description":"The Leap Motion cross-format, cross-platform declarative serialization library","archived":false,"fork":false,"pushed_at":"2018-04-12T19:33:36.000Z","size":1031,"stargazers_count":18,"open_issues_count":3,"forks_count":7,"subscribers_count":45,"default_branch":"master","last_synced_at":"2025-03-29T05:51:14.890Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"menushka/personal-website","license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leapmotion.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-20T12:33:36.000Z","updated_at":"2025-03-16T15:41:12.000Z","dependencies_parsed_at":"2022-07-25T19:17:55.923Z","dependency_job_id":null,"html_url":"https://github.com/leapmotion/leapserial","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leapmotion%2Fleapserial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leapmotion%2Fleapserial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leapmotion%2Fleapserial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leapmotion%2Fleapserial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leapmotion","download_url":"https://codeload.github.com/leapmotion/leapserial/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249296202,"owners_count":21246271,"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":[],"created_at":"2024-11-16T17:14:32.030Z","updated_at":"2025-04-17T01:02:28.700Z","avatar_url":"https://github.com/leapmotion.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"Introduction to LeapSerial\n===\n\nLeapSerial is a cross-format, declarative, serialization and deserialization library written and maintained by Leap Motion.  This library is built with CMake, and makes heavy use of C++11.\n\nLeapSerial is mainly intended to provide users with a way to describe how their types should be serialized without being too concerned about the wire format serialization should take.  Users should be able to directly annotate and serialize/deserialize their business objects rather than having to convert to and from DTOs generated by tools like `protoc`.\n\nThe following four output formats are currently supported:\n\n* JSON\n* Protobuf\n* Flatbuffers\n* LeapSerial Proprietary\n\nLeapSerial also provides a simple stream concept, some wrapper classes, and a few standard implementations.  These streams may be composed with one another similarly to how it's done with Protobuf streams.\n\n* Wrapper for `std::istream` and `std::ostream`\n* AES-256 encryption\n* Zlib compression\n* BZip2 compression\n* Memory stream\n\nUsers may also write their own.\n\nQuick Start\n===\n\nHere's how you mark the fields to be serialized:\n\n```C++\n#include \u003cLeapSerial/LeapSerial.h\u003e\n\nclass MyClass {\n  int my_member;\n\n  static leap::descriptor GetDescriptor() {\n    return {\n      \u0026MyClass::my_member\n    };\n  }\n};\n```\n\nSerialization one-liner:\n\n```C++\nMyClass myClass;\nstd::stringstream os;\nleap::Serialize(os, myClass);\n```\n\nDeserialization is also a one-liner:\n\n```C++\nstd::shared_ptr\u003cMyClass\u003e a = leap::Deserialize\u003cMyClass\u003e(ss, myClass);\n```\n\nIf your type doesn't use native pointers (either directly or transitively), you can also deserialize in-place.\n\n```C++\nMyClass b;\nleap::Deserialize(ss, b);\n```\n\nAlternative Archivers\n---\nLeapSerial has a few output formats that are well supported.  The `leap::Serialize` call, by default, will use the internal LeapSerial archiver, which formats data in a custom bitstream format.  You can use other formats, though, such as Protobuf, but this requires that your fields are numbered or named.  The following sections all use the following numbered and named data structure:\n\n```C++\nclass MyProtobufObject {\npublic:\n  int a = 949;\n  std::string b = \"Hello world!\";\n  std::vector\u003cint\u003e c {4, 5, 6};\n\n  static leap::descriptor GetDescriptor(void) {\n    return{\n      \"MyProtobufObject\",\n      {\n        { 424, \"a\", \u0026MyProtobufObject::a },\n        { 425, \"b\", \u0026MyProtobufObject::b },\n        { 426, \"c\", \u0026MyProtobufObject::c }\n      }\n    };\n  }\n};\n```\n\nProtobuf\n===\nProtobuf serialization can be done with `OArchiveProtobuf`:\n\n```C++\n#include \u003cLeapSerial/IArchiveProtobuf.h\u003e\n#include \u003cLeapSerial/OArchiveProtobuf.h\u003e\n\nvoid Foo() {\n  MyProtobufObject myobj;\n  std::stringstream ss;\n\n  leap::Serialize\u003cleap::OArchiveProtobuf\u003e(ss, defaultPerson);\n}\n```\n\nThe resulting object can be parsed by Protobuf, if you have a schema for `MyProtobufObject`.  You can also create the corresponding `proto` file by serializing the descriptor, like this:\n\n```C++\nstd::stringstream ss;\nleap::Serialize\u003cleap::protobuf_v1\u003e(\n  ss,\n  MyProtobufObject::GetDescriptor()\n);\n``` \n\nThis is what you get:\n\n```Protobuf\nmessage MyProtobufObject {\n  required sint32 a = 424;\n  optional string b = 425;\n  repeated sint32 c = 426;\n}\n```\n\nRight now, `leap::protobuf_v1` and `leap::protobuf_v2` are supported to ensure the generated `proto` file can be parsed by your chosen version of `protoc`.\n\nJSON\n===\n\nJSON serialization is also supported.  The protov3 specification's JSON mapping is used wherever possible.  Currently, deserialization is not supported, but there is a `leap::IArchiveJSON` type which will provide deserialization once it's implemented.\n\n```C++\n#include \u003cLeapSerial/ArchiveJSON.h\u003e\n\nvoid Foo() {\n  MyProtobufObject obj;\n  std::stringstream ss;\n  leap::Serialize\u003cleap::OArchiveJSON\u003e(ss, obj);\n}\n```\n\nHere's the resulting JSON:\n\n```Json\n{\n  \"a\": 949,\n  \"b\": \"Hello world!\",\n  \"c\": [ 4, 5, 6 ]\n}\n```\n\nAlternative Streams\n===\n\nYou can also serialize to a memory buffer, if you don't like `std::stringstream`:\n\n```C++\nleap::MemoryStream ms;\nMyClass b;\nleap::Serialize(ms, b);\n\n// In case you want to do something with the data\nstd::vector\u003cuint8_t\u003e\u0026 data = ms.GetDatadata();\n\n// Or you can just round trip right from here\nstd::shared_ptr\u003cMyClass\u003e c = leap::Deserialize(ms);\n```\n\nMaybe you have a buffer already that you want to deserialize\n\n```C++\nchar buf[1024];\nFillMyBuffer(buf, 1024);\n\nleap::BufferedStream bs{buf, sizeof(buf), sizeof(buf)};\nstd::shared_ptr\u003cMyClass\u003e mc = leap::Deserialize\u003cMyClass\u003e(bs);\n```\n\nEncryption and compression are supported, too.  Encrypting and compressing streams are declared as a filter.  Protobuf's zero copy streams are similarly implemented.  Here's how you might encrypt a file directly to disk with an `std::ofstream`.  Make sure you fill `key` with a cryptographic function or you might be vulnerable to a related key attack.\n\n```C++\nstd::array\u003cuint8_t, 32\u003e myKey;\n\nstd::ofstream of(\"myfile.dat\");\nleap::OutputStreamAdapter osa(of);\nleap::CompressionStream\u003cZlib\u003e cs { osa };\nleap::AESEncryptionStream ecs { cs, myKey };\nMyObject obj;\nleap::Serialize(ecs, obj);\n```\n\nIf you use encryption and compression, make sure the compression step happens before the encryption step, otherwise you will wind up making the file size larger.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleapmotion%2Fleapserial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleapmotion%2Fleapserial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleapmotion%2Fleapserial/lists"}