Skip to content

extremeheat/protodef-cpp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

61 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

protodef-cpp

NPM version Build Status Try it on gitpod Official Discord

C++ compiler in Node.js for ProtoDef schemas, a lighter and more versatile alternative to Protocol Buffers or FlatBuffers that can support any binary format.

See the ProtoDef specification at https://github.com/ProtoDef-io/ProtoDef.

Features

  • Header-only : No dependencies other than the C or C++ standard libraries
  • Arrays, enums, nested structures, optional fields, variable-length integers/strings, custom types, etc. See ProtoDef spec for more details
  • Built-in support for dumping JSON for utility/debugging on top of binary encode/decode

Install

npm install protodef-cpp

Usage

via npx / command line

Feed the CLI tool a .json or .yaml file, and optionally specify a directory to write the generated files to. Two header files will be written: a "streams.h", containing a binary stream implementation used by the encoder/decoder (if you don't already have one), and a "protocol.h" header file (name will vary depending on your input name), containing the generated encoder/decoder code.

$ npx protodef-cpp --help
protodef-cpp - v1.0.0
protodef-cpp - A C++ compiler for ProtoDef schemas

Options:
  --input, -i   Path to ProtoDef JSON/YAML file with protocol data
  --lang, -l    What language use compile to. Currently only C++.  (default: cpp)
  --output      Output folder  (default: ./)
  --config, -t  Path to JS file whose exports will be merged into the current options, which allows you to define custom types and variables.
  --namespace   What namespace to use, useful if you have multiple protocols.  (default: proto)

If you have multiple protocols specified inside one JSON file, please use the programmatic API instead (example).

via code / programmatic API

const protodefCpp = require('protodef-cpp')
protodefCpp.compile({
  inputFile: 'protocol.json',
  outputFolder: './',
  lang: 'cpp',
  namespace: 'proto',
})

Example

protocol.yml:

string: ["pstring", { countType: "varint" }]
packet_video_stream_connect:
  server_uri: string
  frame_send_frequency: lf32
  action: u8 =>
     1: none
     2: close
  resolution_x: li32
  resolution_y: li32

Command line:

npx protodef-cpp -i protocol.yml --lang cpp

Done! You should now have a "protocol.h" file in your current directory. Here's how you would encode a structure:

#include "protocol.h"

int main () {
  pdef::proto::packet_video_stream_connect packet {
    .server_uri = "wss://example.com",
    .frame_send_frequency = 60.0f,
    .action = pdef::proto::packet_video_stream_connect::Action::None,
    .resolution_x = 1920,
    .resolution_y = 1080,
  };
  pdef::Stream stream(0);
  pdef::proto::encode::packet_video_stream_connect(stream, packet);
  stream.dumpToStdout();
  return 0;
}

See examples/ for more examples.

Deviations from ProtoDef spec

protodef-cpp does not support root level switches, or $ variables. Some preprocessing is done to inline root level switches, but for $ variables, some complex use-cases may not work. Please update the schema to not use $ variables if you encounter any issues.