Skip to content

Commit

Permalink
fix conversion of bitmasks to strings
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed Sep 21, 2023
1 parent 4ff9532 commit 67aee16
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 12 deletions.
57 changes: 45 additions & 12 deletions pkg/conversion/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ const (
{{- else }}
import (
{{- if .Enum.Bitmask }}
"strings"
{{- else }}
"strconv"
{{- end }}
"fmt"
)
Expand All @@ -105,43 +109,70 @@ var labels_{{ .Enum.Name }} = map[{{ .Enum.Name }}]string{
{{- end }}
}
var values_{{ .Enum.Name }} = map[string]{{ .Enum.Name }}{
{{- range .Enum.Values }}
"{{ .Name }}": {{ .Name }},
{{- end }}
}
// MarshalText implements the encoding.TextMarshaler interface.
func (e {{ .Enum.Name }}) MarshalText() ([]byte, error) {
{{- if .Enum.Bitmask }}
var names []string
for mask, label := range labels_{{ .Enum.Name }} {
for i := 0; i < {{ len .Enum.Values }}; i++ {
mask := {{ .Enum.Name }}(1 << i)
if e&mask == mask {
names = append(names, label)
names = append(names, labels_{{ .Enum.Name }}[mask])
}
}
return []byte(strings.Join(names, " | ")), nil
{{- else }}
if e == 0 {
return nil, nil
}
name, ok := labels_{{ .Enum.Name }}[e]
if !ok {
return nil, fmt.Errorf("invalid value %d", e)
}
return []byte(name), nil
{{- end }}
}
// UnmarshalText implements the encoding.TextUnmarshaler interface.
func (e *{{ .Enum.Name }}) UnmarshalText(text []byte) error {
{{- if .Enum.Bitmask }}
labels := strings.Split(string(text), " | ")
var mask {{ .Enum.Name }}
for _, label := range labels {
found := false
for value, l := range labels_{{ .Enum.Name }} {
if l == label {
mask |= value
found = true
break
}
}
if !found {
if value, ok := values_{{ .Enum.Name }}[label]; ok {
mask |= value
} else {
return fmt.Errorf("invalid label '%s'", label)
}
}
*e = mask
{{- else }}
value, ok := values_{{ .Enum.Name }}[string(text)]
if !ok {
return fmt.Errorf("invalid label '%s'", text)
}
*e = value
{{- end }}
return nil
}
// String implements the fmt.Stringer interface.
func (e {{ .Enum.Name }}) String() string {
{{- if .Enum.Bitmask }}
val, _ := e.MarshalText()
return string(val)
{{- else }}
name, ok := labels_{{ .Enum.Name }}[e]
if !ok {
return strconv.Itoa(int(e))
}
return name
{{- end }}
}
{{- end }}
`))
Expand Down Expand Up @@ -250,6 +281,7 @@ type outEnum struct {
Name string
Description []string
Values []*outEnumValue
Bitmask bool
}

type outField struct {
Expand Down Expand Up @@ -328,6 +360,7 @@ func processDefinition(
DefName: outDef.Name,
Name: enum.Name,
Description: parseDescription(enum.Description),
Bitmask: enum.Bitmask,
}

for _, val := range enum.Values {
Expand Down
1 change: 1 addition & 0 deletions pkg/conversion/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type definitionEnum struct {
Name string `xml:"name,attr"`
Description string `xml:"description"`
Values []*definitionEnumValue `xml:"entry"`
Bitmask bool `xml:"bitmask,attr"`
}

type dialectField struct {
Expand Down

0 comments on commit 67aee16

Please sign in to comment.