Consolidate V1 SOAP type data into the SOAP package.

This commit is contained in:
John Beisley 2021-08-18 17:03:52 +01:00 committed by Huin
parent a37fadc3ba
commit f320faf4bc
4 changed files with 64 additions and 48 deletions

View File

@ -11,6 +11,7 @@ import (
"github.com/huin/goupnp" "github.com/huin/goupnp"
"github.com/huin/goupnp/scpd" "github.com/huin/goupnp/scpd"
"github.com/huin/goupnp/soap"
) )
// DCP collects together information about a UPnP Device Control Protocol. // DCP collects together information about a UPnP Device Control Protocol.
@ -165,25 +166,25 @@ func (s *SCPDWithURN) wrapArgument(arg *scpd.Argument) (*argumentWrapper, error)
if relVar == nil { if relVar == nil {
return nil, fmt.Errorf("no such state variable: %q, for argument %q", arg.RelatedStateVariable, arg.Name) return nil, fmt.Errorf("no such state variable: %q, for argument %q", arg.RelatedStateVariable, arg.Name)
} }
cnv, ok := typeConvs[relVar.DataType.Name] cnv, ok := soap.TypeDataMap[relVar.DataType.Name]
if !ok { if !ok {
return nil, fmt.Errorf("unknown data type: %q, for state variable %q, for argument %q", relVar.DataType.Type, arg.RelatedStateVariable, arg.Name) return nil, fmt.Errorf("unknown data type: %q, for state variable %q, for argument %q", relVar.DataType.Type, arg.RelatedStateVariable, arg.Name)
} }
return &argumentWrapper{ return &argumentWrapper{
Argument: *arg, Argument: *arg,
relVar: relVar, relVar: relVar,
conv: cnv, typeDataV1: cnv,
}, nil }, nil
} }
type argumentWrapper struct { type argumentWrapper struct {
scpd.Argument scpd.Argument
relVar *scpd.StateVariable relVar *scpd.StateVariable
conv conv typeDataV1 soap.TypeData
} }
func (arg *argumentWrapper) AsParameter() string { func (arg *argumentWrapper) AsParameter() string {
return fmt.Sprintf("%s %s", arg.Name, arg.conv.ExtType) return fmt.Sprintf("%s %s", arg.Name, arg.typeDataV1.GoTypeName())
} }
func (arg *argumentWrapper) HasDoc() bool { func (arg *argumentWrapper) HasDoc() bool {
@ -213,12 +214,12 @@ func (arg *argumentWrapper) Document() string {
return "" return ""
} }
func (arg *argumentWrapper) Marshal() string { func (arg *argumentWrapper) MarshalV1() string {
return fmt.Sprintf("soap.Marshal%s(%s)", arg.conv.FuncSuffix, arg.Name) return fmt.Sprintf("soap.%s(%s)", arg.typeDataV1.MarshalFunc(), arg.Name)
} }
func (arg *argumentWrapper) Unmarshal(objVar string) string { func (arg *argumentWrapper) UnmarshalV1(objVar string) string {
return fmt.Sprintf("soap.Unmarshal%s(%s.%s)", arg.conv.FuncSuffix, objVar, arg.Name) return fmt.Sprintf("soap.%s(%s.%s)", arg.typeDataV1.UnmarshalFunc(), objVar, arg.Name)
} }
type argumentWrapperList []*argumentWrapper type argumentWrapperList []*argumentWrapper

View File

@ -1,35 +0,0 @@
package main
type conv struct {
FuncSuffix string
ExtType string
}
// typeConvs maps from a SOAP type (e.g "fixed.14.4") to the function name
// suffix inside the soap module (e.g "Fixed14_4") and the Go type.
var typeConvs = map[string]conv{
"ui1": {"Ui1", "uint8"},
"ui2": {"Ui2", "uint16"},
"ui4": {"Ui4", "uint32"},
"ui8": {"Ui8", "uint64"},
"i1": {"I1", "int8"},
"i2": {"I2", "int16"},
"i4": {"I4", "int32"},
"int": {"Int", "int64"},
"r4": {"R4", "float32"},
"r8": {"R8", "float64"},
"number": {"R8", "float64"}, // Alias for r8.
"fixed.14.4": {"Fixed14_4", "float64"},
"float": {"R8", "float64"},
"char": {"Char", "rune"},
"string": {"String", "string"},
"date": {"Date", "time.Time"},
"dateTime": {"DateTime", "time.Time"},
"dateTime.tz": {"DateTimeTz", "time.Time"},
"time": {"TimeOfDay", "soap.TimeOfDay"},
"time.tz": {"TimeOfDayTz", "soap.TimeOfDay"},
"boolean": {"Boolean", "bool"},
"bin.base64": {"BinBase64", "[]byte"},
"bin.hex": {"BinHex", "[]byte"},
"uri": {"URI", "*url.URL"},
}

View File

@ -121,7 +121,7 @@ func (client *{{$srvIdent}}) {{.Name}}Ctx(
request := {{if $winargs}}&{{template "argstruct" $winargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}} request := {{if $winargs}}&{{template "argstruct" $winargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}}
// BEGIN Marshal arguments into request. // BEGIN Marshal arguments into request.
{{range $winargs}} {{range $winargs}}
if request.{{.Name}}, err = {{.Marshal}}; err != nil { if request.{{.Name}}, err = {{.MarshalV1}}; err != nil {
return return
}{{end}} }{{end}}
// END Marshal arguments into request. // END Marshal arguments into request.
@ -136,7 +136,7 @@ func (client *{{$srvIdent}}) {{.Name}}Ctx(
// BEGIN Unmarshal arguments from response. // BEGIN Unmarshal arguments from response.
{{range $woutargs}} {{range $woutargs}}
if {{.Name}}, err = {{.Unmarshal "response"}}; err != nil { if {{.Name}}, err = {{.UnmarshalV1 "response"}}; err != nil {
return return
}{{end}} }{{end}}
// END Unmarshal arguments from response. // END Unmarshal arguments from response.

View File

@ -526,3 +526,53 @@ func MarshalURI(v *url.URL) (string, error) {
func UnmarshalURI(s string) (*url.URL, error) { func UnmarshalURI(s string) (*url.URL, error) {
return url.Parse(s) return url.Parse(s)
} }
// TypeData provides metadata about for marshalling and unmarshalling a SOAP
// type.
type TypeData struct {
funcSuffix string
goType string
}
// GoTypeName returns the name of the Go type.
func (td TypeData) GoTypeName() string {
return td.goType
}
// MarshalFunc returns the name of the function that marshals the type.
func (td TypeData) MarshalFunc() string {
return fmt.Sprintf("Marshal%s", td.funcSuffix)
}
// UnmarshalFunc returns the name of the function that unmarshals the type.
func (td TypeData) UnmarshalFunc() string {
return fmt.Sprintf("Unmarshal%s", td.funcSuffix)
}
// TypeDataMap maps from a SOAP type (e.g "fixed.14.4") to its type data.
var TypeDataMap = map[string]TypeData{
"ui1": {"Ui1", "uint8"},
"ui2": {"Ui2", "uint16"},
"ui4": {"Ui4", "uint32"},
"ui8": {"Ui8", "uint64"},
"i1": {"I1", "int8"},
"i2": {"I2", "int16"},
"i4": {"I4", "int32"},
"int": {"Int", "int64"},
"r4": {"R4", "float32"},
"r8": {"R8", "float64"},
"number": {"R8", "float64"}, // Alias for r8.
"fixed.14.4": {"Fixed14_4", "float64"},
"float": {"R8", "float64"},
"char": {"Char", "rune"},
"string": {"String", "string"},
"date": {"Date", "time.Time"},
"dateTime": {"DateTime", "time.Time"},
"dateTime.tz": {"DateTimeTz", "time.Time"},
"time": {"TimeOfDay", "soap.TimeOfDay"},
"time.tz": {"TimeOfDayTz", "soap.TimeOfDay"},
"boolean": {"Boolean", "bool"},
"bin.base64": {"BinBase64", "[]byte"},
"bin.hex": {"BinHex", "[]byte"},
"uri": {"URI", "*url.URL"},
}