github.com/bluenviron/gomavlib/v2@v2.2.1-0.20240308101627-2c07e3da629c/pkg/conversion/definition.go (about)

     1  package conversion
     2  
     3  import (
     4  	"encoding/xml"
     5  	"strconv"
     6  )
     7  
     8  type definitionEnumEntry struct {
     9  	Value       string `xml:"value,attr"`
    10  	Name        string `xml:"name,attr"`
    11  	Description string `xml:"description"`
    12  }
    13  
    14  type definitionEnum struct {
    15  	Name        string                 `xml:"name,attr"`
    16  	Description string                 `xml:"description"`
    17  	Entries     []*definitionEnumEntry `xml:"entry"`
    18  	Bitmask     bool                   `xml:"bitmask,attr"`
    19  }
    20  
    21  type dialectField struct {
    22  	Extension   bool   `xml:"-"`
    23  	Type        string `xml:"type,attr"`
    24  	Name        string `xml:"name,attr"`
    25  	Enum        string `xml:"enum,attr"`
    26  	Description string `xml:",innerxml"`
    27  }
    28  
    29  type definitionMessage struct {
    30  	ID          int
    31  	Name        string
    32  	Description string
    33  	Fields      []*dialectField
    34  }
    35  
    36  // UnmarshalXML implements xml.Unmarshaler
    37  // we must unmarshal manually due to extension fields
    38  func (m *definitionMessage) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    39  	// unmarshal attributes
    40  	for _, a := range start.Attr {
    41  		switch a.Name.Local {
    42  		case "id":
    43  			v, _ := strconv.Atoi(a.Value)
    44  			m.ID = v
    45  		case "name":
    46  			m.Name = a.Value
    47  		}
    48  	}
    49  
    50  	inExtensions := false
    51  	for {
    52  		t, _ := d.Token()
    53  		if t == nil {
    54  			break
    55  		}
    56  
    57  		if se, ok := t.(xml.StartElement); ok {
    58  			switch se.Name.Local {
    59  			case "description":
    60  				err := d.DecodeElement(&m.Description, &se)
    61  				if err != nil {
    62  					return err
    63  				}
    64  
    65  			case "extensions":
    66  				inExtensions = true
    67  
    68  			case "field":
    69  				field := &dialectField{Extension: inExtensions}
    70  				err := d.DecodeElement(&field, &se)
    71  				if err != nil {
    72  					return err
    73  				}
    74  				m.Fields = append(m.Fields, field)
    75  			}
    76  		}
    77  	}
    78  	return nil
    79  }
    80  
    81  type definition struct {
    82  	Version  string               `xml:"version"`
    83  	Dialect  int                  `xml:"dialect"`
    84  	Includes []string             `xml:"include"`
    85  	Enums    []*definitionEnum    `xml:"enums>enum"`
    86  	Messages []*definitionMessage `xml:"messages>message"`
    87  }
    88  
    89  func definitionDecode(buf []byte) (*definition, error) {
    90  	def := &definition{}
    91  	err := xml.Unmarshal(buf, def)
    92  	return def, err
    93  }