in MavLinkCom/MavLinkComGenerator/MavLinkGenerator.cs [255:454]
private void GenerateMessages()
{
foreach (var m in definitions.messages)
{
int id = int.Parse(m.id);
if (id > 255)
{
// these require mavlink 2...
continue;
}
string name = CamelCase(m.name);
Console.WriteLine("generating message {0}", name);
if (!string.IsNullOrWhiteSpace(m.description))
{
WriteComment("", m.description);
}
header.WriteLine("class MavLink{0} : public MavLinkMessageBase {{", name);
header.WriteLine("public:");
header.WriteLine(" const static uint8_t kMessageId = {0};", m.id);
header.WriteLine(" MavLink{0}() {{ msgid = kMessageId; }}", name);
// find array types and split the type string "int[16]" into element type "int" and isArray=true and array_length=16.
foreach (var field in m.fields)
{
string type = field.type;
if (type.Contains('['))
{
var tuple = ParseArrayType(type);
field.type = tuple.Item1;
field.isArray = true;
field.array_length = tuple.Item2;
}
}
int length = m.fields.Count;
for (int i = 0; i < length; i++)
{
var field = m.fields[i];
if (!string.IsNullOrWhiteSpace(field.description))
{
WriteComment(" ", field.description);
}
var type = field.type;
if (type == "uint8_t_mavlink_version")
{
type = "uint8_t";
}
if (field.isArray)
{
header.WriteLine(" {0} {1}[{2}] = {{ 0 }};", type, field.name, field.array_length);
}
else
{
header.WriteLine(" {0} {1} = 0;", type, field.name);
}
}
// mavlink packs the fields in order of descending size (but not including the extension fields.
var sortedFields = m.fields;
int extensionPos = m.ExtensionPos;
if (extensionPos == 0)
{
extensionPos = m.fields.Count;
}
sortedFields = new List<MavField>(m.fields.Take(extensionPos));
sortedFields = sortedFields.OrderByDescending(x => typeSize[x.type]).ToList();
sortedFields.AddRange(m.fields.Skip(extensionPos));
m.fields = sortedFields;
header.WriteLine(" virtual std::string toJSon();");
header.WriteLine("protected:");
header.WriteLine(" virtual int pack(char* buffer) const;");
impl.WriteLine("int MavLink{0}::pack(char* buffer) const {{", name);
int offset = 0;
for (int i = 0; i < length; i++)
{
var field = m.fields[i];
var type = field.type;
if (type == "uint8_t_mavlink_version")
{
type = "uint8_t";
}
int size = typeSize[type];
if (field.isArray)
{
// it is an array.
impl.WriteLine(" pack_{0}_array({1}, buffer, reinterpret_cast<const {0}*>(&this->{2}[0]), {3});", type, field.array_length, field.name, offset);
size *= field.array_length;
}
else
{
impl.WriteLine(" pack_{0}(buffer, reinterpret_cast<const {0}*>(&this->{1}), {2});", type, field.name, offset);
}
offset += size;
}
impl.WriteLine(" return {0};", offset);
impl.WriteLine("}");
impl.WriteLine("");
header.WriteLine(" virtual int unpack(const char* buffer);");
impl.WriteLine("int MavLink{0}::unpack(const char* buffer) {{", name);
offset = 0;
for (int i = 0; i < length; i++)
{
var field = m.fields[i];
var type = field.type;
if (type == "uint8_t_mavlink_version")
{
type = "uint8_t";
}
int size = typeSize[type];
if (field.isArray)
{
// it is an array.
impl.WriteLine(" unpack_{0}_array({1}, buffer, reinterpret_cast<{0}*>(&this->{2}[0]), {3});", type, field.array_length, field.name, offset);
size *= field.array_length;
}
else
{
impl.WriteLine(" unpack_{0}(buffer, reinterpret_cast<{0}*>(&this->{1}), {2});", type, field.name, offset);
}
offset += size;
}
impl.WriteLine(" return {0};", offset);
impl.WriteLine("}");
impl.WriteLine("");
impl.WriteLine("std::string MavLink{0}::toJSon() {{", name);
impl.WriteLine(" std::ostringstream ss;");
impl.WriteLine(" ss << \"{{ \\\"name\\\": \\\"{0}\\\", \\\"id\\\": {1}, \\\"timestamp\\\":\" << timestamp << \", \\\"msg\\\": {{\";", m.name, id);
for (int i = 0; i < length; i++)
{
var field = m.fields[i];
var type = field.type;
if (type == "uint8_t_mavlink_version")
{
type = "uint8_t";
}
if (i == 0)
{
impl.Write(" ss << \"\\\"{0}\\\":\" ", field.name);
}
else
{
impl.Write(" ss << \", \\\"{0}\\\":\" ", field.name);
}
if (field.isArray)
{
if (type == "char")
{
impl.Write(" << \"\\\"\" << ");
impl.Write("char_array_tostring({1}, reinterpret_cast<{0}*>(&this->{2}[0]))", type, field.array_length, field.name);
impl.Write(" << \"\\\"\"");
}
else
{
impl.Write(" << \"[\" << ");
impl.Write("{0}_array_tostring({1}, reinterpret_cast<{0}*>(&this->{2}[0]))", type, field.array_length, field.name);
impl.Write(" << \"]\"");
}
}
else if (type == "int8_t")
{
// so that stream doesn't try and treat this as a char.
impl.Write(" << static_cast<int>(this->{0})", field.name);
}
else if (type == "uint8_t")
{
// so that stream doesn't try and treat this as a char.
impl.Write(" << static_cast<unsigned int>(this->{0})", field.name);
}
else if (type == "float")
{
impl.Write(" << float_tostring(this->{0})", field.name);
}
else
{
impl.Write(" << this->{0}", field.name);
}
impl.WriteLine(";");
}
impl.WriteLine(" ss << \"} },\";");
impl.WriteLine(" return ss.str();");
impl.WriteLine("}");
impl.WriteLine("");
header.WriteLine("};");
header.WriteLine("");
}
}