@(__context: Context, __messages: Set[Message])@org.mavlink.txt._header(__context)
package org.mavlink.messages
import java.nio.ByteBuffer
import java.nio.charset.Charset
@__scalaMessageType(message: Message) = {@StringUtils.Camelify(message.name)}
@__scalaFieldName(field: Field) = {@StringUtils.camelify(field.name)}
@__scalaFieldType(tpe: Type) = {@tpe match {
case IntType(1, _) => {Byte}
case IntType(2, _) => {Short}
case IntType(4, _) => {Int}
case IntType(8, _) => {Long}
case FloatType(4) => {Float}
case FloatType(8) => {Double}
case StringType(_) => {String}
case ArrayType(underlying, _) => {Seq[@__scalaFieldType(underlying)]}
}}
@__scalaFieldFormal(field: Field) = {@__scalaFieldName(field): @__scalaFieldType(field.tpe)}
@__bufferReadMethod(buffer: String, tpe: Type) = {@tpe match {
case IntType(1, _) => {@{buffer}.get()}
case IntType(2, _) => {@{buffer}.getShort()}
case IntType(4, _) => {@{buffer}.getInt()}
case IntType(8, _) => {@{buffer}.getLong()}
case FloatType(4) => {@{buffer}.getFloat()}
case FloatType(8) => {@{buffer}.getDouble()}
case StringType(maxLength) =>{{
val bytes = new Array[Byte](@maxLength)
@{buffer}.get(bytes, 0, @maxLength)
val length = bytes.indexOf(0) match {
case -1 => @maxLength
case i => i
}
new String(bytes, 0, length, Charset.forName("UTF-8"))
}}
case ArrayType(underlying, length) => {for (i <- 0 until @length) yield {@__bufferReadMethod(buffer, underlying)}}
}}
@__bufferWriteMethod(buffer: String, data: String, tpe: Type) = {@tpe match {
case IntType(1, _) => {@{buffer}.put(@data)}
case IntType(2, _) => {@{buffer}.putShort(@data)}
case IntType(4, _) => {@{buffer}.putInt(@data)}
case IntType(8, _) => {@{buffer}.putLong(@data)}
case FloatType(4) => {@{buffer}.putFloat(@data)}
case FloatType(8) => {@{buffer}.putDouble(@data)}
case StringType(maxLength) => {
{
val bytes = @{data}.getBytes(Charset.forName("UTF-8"))
val endPosition = @{buffer}.position + @maxLength
@{buffer}.put(bytes, 0, math.min(bytes.length, @maxLength))
while (@{buffer}.position < endPosition) {
@{buffer}.put(0: Byte)
}
}}
case ArrayType(underlying, length) => {for (i <- 0 until @length) {@__bufferWriteMethod(buffer, data + "(i)", underlying)}}
}}
@__commentParagraphs(paragraphs: Seq[String]) = {@paragraphs.mkString("/**\n * ", "\n * ", "\n */")}
@__comment(message: Message) = {@__commentParagraphs(message.description.grouped(100).toList ++ message.fields.map(field => "@param " + field.name + " " + field.description))}
/** Marker trait for MAVLink messages. All supported messages extend this trait. */
sealed trait Message
@for(__msg <- __messages) {
@__comment(__msg)
case class @{__scalaMessageType(__msg)}(@__msg.fields.map(__scalaFieldFormal).mkString(", ")) extends Message
}
/**
* Wraps an unknown message.
* @@param id the ID of the message
* @@param payload the message's contents
*/
case class Unknown(id: Byte, payload: Array[Byte]) extends Message
/**
* Provides utility methods for converting data to and from MAVLink messages.
*/
object Message {
/**
* Interprets an ID and payload as a message. The contents must be ordered
* according to the MAVLink specification.
* @@param id ID of the message
* @@param payload contents of the message
* @@return payload interpreted as a message or 'Unknown' in case of an unknown ID
*/
def unpack(id: Byte, payload: Array[Byte]): Message = {
val buffer = ByteBuffer.wrap(payload)
id match {
@for(__msg <- __messages) {
case @__msg.id =>
@for(__field <- __msg.orderedFields) {val @__scalaFieldFormal(__field) = @__bufferReadMethod("buffer", __field.tpe)
}
@{__scalaMessageType(__msg)}(@__msg.fields.map(__scalaFieldName(_)).mkString(", "))
}
case u => Unknown(u, payload)
}
}
/**
* Encodes a message according to the MAVLink specification.
* @@param message the message to write
* @@return (id, payload) id and payload of the encoded message
*/
def pack(message: Message): (Byte, Array[Byte]) = message match {
@for(__msg <- __messages) {
case m: @__scalaMessageType(__msg) =>
val arr = new Array[Byte](@__msg.length)
val buffer = ByteBuffer.wrap(arr)
@for(__field <- __msg.orderedFields) {@__bufferWriteMethod("buffer", "m." + __scalaFieldName(__field), __field.tpe)
}
(@__msg.id, arr)
}
case u: Unknown =>
(u.id, u.payload)
}
}