{"id":18736880,"url":"https://github.com/bitwizeshift/datatranslator","last_synced_at":"2025-11-17T04:30:15.247Z","repository":{"id":81485371,"uuid":"64365507","full_name":"bitwizeshift/DataTranslator","owner":"bitwizeshift","description":"A C++ class for translating serialized data","archived":false,"fork":false,"pushed_at":"2016-08-06T06:40:57.000Z","size":246,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-12-28T17:14:08.211Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"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/bitwizeshift.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2016-07-28T04:55:18.000Z","updated_at":"2023-05-15T03:25:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"678ec73b-7b46-4092-8695-be927f7edb2c","html_url":"https://github.com/bitwizeshift/DataTranslator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwizeshift%2FDataTranslator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwizeshift%2FDataTranslator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwizeshift%2FDataTranslator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwizeshift%2FDataTranslator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitwizeshift","download_url":"https://codeload.github.com/bitwizeshift/DataTranslator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239611993,"owners_count":19668274,"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-07T15:22:51.869Z","updated_at":"2025-11-17T04:30:15.215Z","avatar_url":"https://github.com/bitwizeshift.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"#Data Translator\n[![Build Status](https://travis-ci.org/bitwizeshift/DataTranslator.svg?branch=master)](https://travis-ci.org/bitwizeshift/DataTranslator)\n[![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](http://bitwizeshift.github.io/DataTranslator)\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/bitwizeshift/DataTranslator/master/LICENSE)\n[![Compiler Support](https://img.shields.io/badge/compilers-gcc%20%7C%20clang-blue.svg)](#tested-compilers)\n\n##What is Data Translator?\n\n`DataTranslator` is a simple way of translating serialized data into C++ structures. \nNormally, translating data from nodes retrieved from deserializing libraries requires \na lot of boiler-plate code, and can become even more cumbersome to translate into each\nindividual member of a given `struct` or `class`. \n\n`DataTranslator` relieves the burden by abstracting away the concept of a data node, \nand allowing for seamless translation of multiple objects at a time!\n\n**Note**: This is a standalone implementation of the original DataTranslator found in the [Serial](https://github.com/bitwizeshift/Serial) repository. \n\n##Features\n\n- Written in modern C++11 code \n- Compatible with most major compilers\n- Compatible with most major deserializing libraries, such as **YamlCpp**, **RapidXML**, **RapidJSON**, - Implementation is fast and lightweight to allow for quick translation of types\n- Highly configurable, enabling support for almost any fundamental member type\n- Supports translation of both scalar members and vector members of a given type\netc. (Requires a \"Translation Scheme\" described later)\n- Can translate single entries, uniform copying of multiple entries, and groups of entries at a single time\n\n##Use\n\n###Getting Started\n\nThe single header file, `DataTranslator.hpp` is in the `include` directory. \nSimply include this file with \n\n```c++\n#include \u003cDataTranslator.hpp\u003e\n```\n\nto begin working with this library. See below for constructing `DataTranslator` classes\n\n**Note** Make sure that the compiler is using c++11 or greater in order for this to work \n(the library will fail with a message stating as such otherwise).\n\n###Constructing a `DataTranslator`\n\n`serial::DataTranslator` is a templated class that requires at least one argument _T_ for the \n`struct` or `class` that will be populated.\n\nI recommend using type aliasing to simplify the name (or `typedef` if you're old-school):\n\n```c++\n// Translates the struct/class 'ExampleClass'\nusing ExampleDataTranslator = serial::DataTranslator\u003cExampleClass\u003e; \n\nauto translator = ExampleDataTranslator();\n ```\n\nTo specify the data members that are to be translated within the specified class, make \ncalls to `add_member` supplying the name of the configuration node from the serialized library,\nand the pointer-to-members of that object to be translated. Calls to `add_member` can be chained\nin order to create a single `const` instance of a `DataTranslator.\n\n\nThe configuration node name can be any arbitrary type (normally a string) to retrieve a configuration value from a given deserialized node. For example, this could be an XPath string for an XML node type, or a configuration string for a `YAML::Node` from YamlCpp. How this string is managed is determined\nby the Translation Scheme (explained below) and the underlying node type.\n\n####Example\n\n```c++\nstruct ExampleClass \n{\n  bool        my_bool;\n  int         my_int;\n  float       my_float;\n  std::string my_string;\n};\n\ntypedef DataTranslator\u003cExampleClass\u003e ExampleTranslator;\n\nconst ExampleTranslator translator = ExampleTranslator()\n  .add_member(\"my.bool\", \u0026ExampleClass::my_bool)\n  .add_member(\"my.int\", \u0026ExampleClass::my_int)\n  .add_member(\"my.float\", \u0026ExampleClass::my_float)\n  .add_member(\"my.string\", \u0026ExampleClass::my_string);\n```\n\n###Using custom types (Advanced)\n\nIf the default types of `bool`, `int`, `float`, `std::string` don't work for the translated types,\nthis is all configurable by further template arguments\n\nThe template arguments are, in order:\n\n| Type      | Description                                                         |\n|-----------|---------------------------------------------------------------------|\n| `T`       | The type to translate. This is a required template                  |\n| `BoolT`   | The type to translate as a boolean (default: `bool`)                |\n| `IntT`    | The type to translate as an integer (default: `int`)                |\n| `FloatT`  | The type to translate as a floating point number (default: `float`) |\n| `StringT` | The type to translate as a string (default: `std::string`)          |\n| `KeyT`    | The type to use for keys (default: `std::string`)                   |\n\nThis allows for customization when using different frameworks, or dealing with integral/floating point sizes outside of the defaults.\n\nFor example, if working with the windows API, the following can be done for translations:\n\n####Example\n\n```c++\nstruct Win32Struct\n{\n  BOOL         my_bool;\n  DWORD        my_int\n  double       my_float;\n  std::wstring my_string;\n};\n\nusing Win32StructTranslator = DataTranslator\u003cWin32Struct,\n                                             BOOL,\n\t\t\t\t\t\t\t\t\t\t\t                       DWORD,\n\t\t\t\t\t\t\t\t\t\t\t                       double,\n\t\t\t\t\t\t\t\t\t\t\t                       std::wstring,\n\t\t\t\t\t\t\t\t\t\t\t                       std::wstring\u003e;\n```\n\nIf a situation occurs where two types are the same (in the previous example, `BOOL` is normally implemented as `int`), then the calls can be disambiguated by using the _verbose_ loader functions\nin order to be explicit.\n\nThe verbose loaders are identical to the `add_member` call, except that it is not overloaded.\n\n####Example\n\n```c++\nWin32StructTranslator translator = Win32StructTranslator()\n  .add_bool_member(L\"my.bool\", \u0026Win32Struct::my_bool)\n  .add_int_member(L\"my.int\", \u0026Win32Struct::my_int)\n  .add_float_member(L\"my.int\", \u0026Win32Struct::my_int)\n  .add_string_member(L\"my.string\", \u0026Win32Struct::my_string);\n  // first params are wide string because KeyT is std::wstring\n```\n\n###Creating a Translation Scheme class\n\nA translation scheme class needs to satisfy a very simple set of functionalities. \n\nThere are two types of translation schemes:\n - `ScalarTranslationScheme` used for translating single entries at a time\n - `SequenceTranslationScheme` used for translating sequences of entries.\n \n**Note**: It is up to the implementation of Translation Scheme as to how to handle error \ncases, such as a value being requested by an incorrect type. This is to allow for native\nexceptions to be caught/thrown depending on the type wrapped by the translation scheme.\n\n####ScalarTranslationScheme Concept\n\n#####Requirements\n\n- **T** Translator Type;\n- **t** object of type **const T**.\n\n#####Functions\n\n| expression                           | return                       | semantics                                                                                                                                               |\n|--------------------------------------|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `t.size( name )`                     | convertible to `std::size_t` | Determines the size of a non-scalar node with the given `name`. This is undefined for scalar types.                                                     |\n| `t.has( name )`                  | convertible to `bool`        | Returns `true` if `t` contains a node with the given name                                                                                         |\n| `t.as_bool( name )`                  | convertible to `BoolT`       | Returns the result of the node with identifier `name` if it exists. Behavior is undefined otherwise.                                                    |\n| `t.as_int( name )`                   | convertible to `IntT`        | Returns the result of the node with identifier `name` if it exists. Behavior is undefined otherwise.                                                    |\n| `t.as_float( name )`                 | convertible to `FloatT`      | Returns the result of the node with identifier `name` if it exists. Behavior is undefined otherwise.                                                    |\n| `t.as_string( name )`                | convertible to `StringT`     | Returns the result of the node with identifier `name` if it exists. Behavior is undefined otherwise.                                                    |\n| `t.as_bool_sequence( name, func )`   | void                         | Iterates all entries in the node with identifier `name` if it exists, calling `func` on each entry. Argument to `func` must be convertible to `BoolT`   |\n| `t.as_int_sequence( name, func )`    | void                         | Iterates all entries in the node with identifier `name` if it exists, calling `func` on each entry. Argument to `func` must be convertible to `IntT`    |\n| `t.as_float_sequence( name, func )`  | void                         | Iterates all entries in the node with identifier `name` if it exists, calling `func` on each entry. Argument to `func` must be convertible to `FloatT`  |\n| `t.as_string_sequence( name, func )` | void                         | Iterates all entries in the node with identifier `name` if it exists, calling `func` on each entry. Argument to `func` must be convertible to `StringT` |\n\n* A `Translator` must have all functions marked as `const`.\n\nAs long as a translator supports these functions, it can be used with the `DataTranslator` to translate data to a `struct` or `class`. This would normally\nbe done in the form of a wrapper around the node returned by the deserialization library of your choice.\n\n#####Example\n\nAn example dummy translator class that can only convert boolean with identifier \"b\" to `true`,\ninteger \"i\" to `42`, float \"f\" to `3.14`, and `std::string` \"s\" to \"hello world\".\n\n```c++\nclass DummyTranslator {\npublic:\n  std::size_t size(std::string) const{ return 0; }\n\n  bool has(std::string x) const{ return true; }\n\n  bool        as_bool(std::string) const{ return true; }\n  int         as_int(std::string) const{ return 42; }\n  float       as_float(std::string) const{ return 3.14; }\n  std::string as_string(std::string) const{ return \"hello world\"; }\n\n  template\u003ctypename Func\u003e\n  void as_bool_sequence(std::string, Func) const{}\n\n  template\u003ctypename Func\u003e\n  void as_int_sequence(std::string, Func) const{}\n\n  template\u003ctypename Func\u003e\n  void as_float_sequence(std::string, Func) const{}\n\n  template\u003ctypename Func\u003e\n  void as_string_sequence(std::string, Func) const{}\n};\n```\n\nTo create a more complicated translator, you can write a wrapper around the desired node\ntype, such as mapping `YAML::Node`'s `as\u003cint\u003e()` to `as_int()`.\n\n####SequenceTranslationScheme\n\n#####Requirements\n\n- **T** Translator Type;\n- **t** object of type **T**.\n\n#####Relationship\n\n- `SequenceTranslationScheme` is also a `ScalarTranslationScheme`.\n\n#####Functions\n\n| expression                           | return                       | semantics                                                                                                                                               |\n|--------------------------------------|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `t.next()`                     | convertible to `bool` | Iterates to the next entry in the sequence, if one exists. returns `true` if there is an entry, `false` otherwise.                                                     |\n\n### Complete Example\n\nUsing the `DummyTranslator` class above, mixed with parts from the first example example:\n\n```c++\n#include \u003ciostream\u003e\nstruct ExampleClass \n{\n  bool        my_bool;\n  int         my_int;\n  float       my_float;\n  std::string my_string;\n};\n\ntypedef DataTranslator\u003cExampleClass\u003e ExampleTranslator;\n\nconst ExampleTranslator translator = ExampleTranslator()\n  .add_member(\"b\", \u0026ExampleClass::my_bool)    // translate \"b\" -\u003e true\n  .add_member(\"i\", \u0026ExampleClass::my_int)     // translate \"i\" -\u003e 42\n  .add_member(\"f\", \u0026ExampleClass::my_float)   // translate \"f\" -\u003e 3.14\n  .add_member(\"s\", \u0026ExampleClass::my_string); // translate \"s\" -\u003e \"hello world\"\n  \nint main()\n{\n  ExampleClass example; // construct a class, no initialization\n\n  translator.translate(\u0026example, DummyTranslator());\n\n  std::cout \u003c\u003c example.my_bool \u003c\u003c \"\\n\"\n            \u003c\u003c example.my_int  \u003c\u003c \"\\n\"\n            \u003c\u003c example.my_float \u003c\u003c \"\\n\"\n            \u003c\u003c example.my_string \u003c\u003c \"\\n\";\n\n  return 0;  \n}\n```\n\nThe above example, when compiled with `gcc 5.3.0` is the following:\n\n```\n1\n42\n3.14\nhello world\n```\n\n### Further Examples\n\nBelow are some fully implemented translation scheme examples wrapper around \nexisting deserialization libraries:\n\n```todo: upload examples```\n\n##\u003ca name=\"tested-compilers\"\u003e\u003c/a\u003e Tested Compilers\n\nThe following compilers are currently being tested through continuous integration with [Travis](https://travis-ci.org/bitwizeshift/DataTranslator).\n\n| Compiler        | Operating System                   |\n|-----------------|------------------------------------|\n| g++ 4.8.5       | Ubuntu 14.04.1 TLS                 |\n| g++ 4.9.3       | Ubuntu 14.04.4 TLS                 |\n| g++ 5.3.0       | Ubuntu 14.04.4 TLS                 |\n| g++ 6.1.1       | Ubuntu 14.04.1 TLS                 |\n| clang 3.5.0     | Ubuntu 14.04.1 TLS                 |\n| clang 3.6.2     | Ubuntu 14.04.1 TLS                 |\n| clang xcode 6.0 | Darwin Kernel 13.4.0 (OSX 10.9.5)  |\n| clang xcode 6.1 | Darwin Kernel 14.3.0 (OSX 10.9.5)  |\n| clang xcode 7.0 | Darwin Kernel 14.5.0 (OSX 10.10.5) |\n| clang xcode 7.3 | Darwin Kernel 15.5.0 (OSX 10.11.5) |\n| clang xcode 8.0 | Darwin Kernel 15.6.0 (OSX 10.11.5) |\n\n## License\n\n\u003cimg align=\"right\" src=\"http://opensource.org/trademarks/opensource/OSI-Approved-License-100x137.png\"\u003e\n\nThe class is licensed under the [MIT License](http://opensource.org/licenses/MIT):\n\nCopyright \u0026copy; 2016 [Matthew Rodusek](http://rodusek.me/)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitwizeshift%2Fdatatranslator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitwizeshift%2Fdatatranslator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitwizeshift%2Fdatatranslator/lists"}