private void GenerateMessages()

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("");
            }
        }