Hermes is a YAML based protocol definition language.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src
.gitignore
README.md
pom.xml

README.md

Hermes

Overview

Hermes is a YAML based protocol definition language. The library is beeing developed in Scala with full Java interoperability in mind.

Language Structure

The Hermes language uses a small subset of YAML's features. A protocol definition consists of 4 sections divided by hyphens (---). The first two sections consists of simple key value pairs. While the final two sections contain the actual protocol unit definitions.

Section 1: Protocol Configuration

Name Description Type Default Optional
messageIdSize the size in bytes of the message id unsigned int 1

**Section 2: Header definition**
Name Description Type Optional
protocolId the id of the protocol unsigned int
version protocol version unsigned int

**Section 3: Complex Type Definitions**
Complex type definitions are used to specify data that is contained in multiple of the protocol's units. A complex type definition consist of a name followed by some fields.
<string>: # complex datatype name                           
  - field1 
      ...
  - ...

...

**Section 4: Unit Definitions**
The unit definition's syntax is similar to the syntax of the complex type definitions. The only difference is that a complex data type is defined by its name (string) and a unit is defined by its id (unsigned integer). Each unit definition represents one protocol unit.
<unsigned int>: # complex datatype name                           
  - field1 
      ...
  - ...

...

Fields Each field has a datatype. There are three types of data types.

Basic datatypes need to specify their length with either length_f for a fixed length field or length_v for a variable sized field. Optionally the field repetitions can be defined using either reps_f or reps_v. Basic datatypes should be named according to the follwing syntax: BasicTypeName<optionalEncoding> e.g.: BigInteger, String or MyOwnClass.

Complex datatypes defined beforehand can also be used as the fields datatype. Such a field must not specify a length but can set the repetitions.

Protocol data type must not specify a length but can specify the number of repetitions. A protocol data type should be named according to the follwing syntax: Protocol<protocolName> e.g.: Protocol<Chat>.

Name Description Type
type the type of the field, may be the name of a basic data type, a previously defined complex data type or another protocol string
length_f the fixed length of the field in bytes unsigned int
length_v the number of bytes used to define the length of the field during runtime unsigned int
reps_f the fixed number of field repetitions in bytes unsigned int
reps_v the number of bytes used to define the number of repetitions during runtime unsigned int

Example Protocol Definition

With the following simple chat protocol messages and files can be exchanged. Note that the the possible file units are defined in a different protocol. Therefore each file unit contains a user's metadata as well as a field containing a unit defined in the file protocol.

# chat.yaml or chat.hermes.yaml

# Protocol Configuration #
messageIdSize:    1

---

# Header Definition #
protocolId:       0420
version:          01

---

# Complex Type Definitions #
User:
  - userName:
      type: String<utf8>
      length_f: 1
  - tags:
      type: String<ascii>
      length_f: 1
      reps_v: 1

Metadata:
  - user:
      type: User
  - date:
      type: java.util.Date
      length_f: 2


---

# Unit Definitions #
00: # message(s)
  - metadata:
      type: Metadata
  - messages:
      type: String<utf8>
      length_v: 2
      reps_v: 1

01: # file
  - metadata:
      type: Metadata
  - file:
      type: Protocol<file>

Lets analyse a unit's bytecode generated by the protocol library.

Library Usage

val source = scala.io.Source.fromFile("src/main/resources/messenger.yaml")
val pi = Protocol(source.getLines mkString "\n")
val source = scala.io.Source.fromFile("src/main/resources/messenger.yaml")
val pi = Protocol(source.getLines mkString "\n")

chat.yaml or chat.hermes.yaml

---
# Complex Type Definitions #

Person:
  - firstName:
      type: String
      length_f: 7
  - lastName:
      type: String
      length_v: 2
  - initial:
      type: String
      length_v: 2

Family:
  - dad:
      type: Person
      reps_f: 1

License

MIT License

Copyright (c) 2016 Florian Gauger

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.