From f320faf4bc91458bb6a80233ed3c581b5999cd05 Mon Sep 17 00:00:00 2001 From: John Beisley Date: Wed, 18 Aug 2021 17:03:52 +0100 Subject: [PATCH] Consolidate V1 SOAP type data into the SOAP package. --- cmd/goupnpdcpgen/dcp.go | 23 +++++++++-------- cmd/goupnpdcpgen/typemap.go | 35 -------------------------- dcps/dcps.gotemplate | 4 +-- soap/types.go | 50 +++++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 48 deletions(-) delete mode 100644 cmd/goupnpdcpgen/typemap.go diff --git a/cmd/goupnpdcpgen/dcp.go b/cmd/goupnpdcpgen/dcp.go index c1e8045..40abe38 100644 --- a/cmd/goupnpdcpgen/dcp.go +++ b/cmd/goupnpdcpgen/dcp.go @@ -11,6 +11,7 @@ import ( "github.com/huin/goupnp" "github.com/huin/goupnp/scpd" + "github.com/huin/goupnp/soap" ) // 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 { 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 { return nil, fmt.Errorf("unknown data type: %q, for state variable %q, for argument %q", relVar.DataType.Type, arg.RelatedStateVariable, arg.Name) } return &argumentWrapper{ - Argument: *arg, - relVar: relVar, - conv: cnv, + Argument: *arg, + relVar: relVar, + typeDataV1: cnv, }, nil } type argumentWrapper struct { scpd.Argument - relVar *scpd.StateVariable - conv conv + relVar *scpd.StateVariable + typeDataV1 soap.TypeData } 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 { @@ -213,12 +214,12 @@ func (arg *argumentWrapper) Document() string { return "" } -func (arg *argumentWrapper) Marshal() string { - return fmt.Sprintf("soap.Marshal%s(%s)", arg.conv.FuncSuffix, arg.Name) +func (arg *argumentWrapper) MarshalV1() string { + return fmt.Sprintf("soap.%s(%s)", arg.typeDataV1.MarshalFunc(), arg.Name) } -func (arg *argumentWrapper) Unmarshal(objVar string) string { - return fmt.Sprintf("soap.Unmarshal%s(%s.%s)", arg.conv.FuncSuffix, objVar, arg.Name) +func (arg *argumentWrapper) UnmarshalV1(objVar string) string { + return fmt.Sprintf("soap.%s(%s.%s)", arg.typeDataV1.UnmarshalFunc(), objVar, arg.Name) } type argumentWrapperList []*argumentWrapper diff --git a/cmd/goupnpdcpgen/typemap.go b/cmd/goupnpdcpgen/typemap.go deleted file mode 100644 index 50b02c7..0000000 --- a/cmd/goupnpdcpgen/typemap.go +++ /dev/null @@ -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"}, -} diff --git a/dcps/dcps.gotemplate b/dcps/dcps.gotemplate index 45d3efa..68a36af 100644 --- a/dcps/dcps.gotemplate +++ b/dcps/dcps.gotemplate @@ -121,7 +121,7 @@ func (client *{{$srvIdent}}) {{.Name}}Ctx( request := {{if $winargs}}&{{template "argstruct" $winargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}} // BEGIN Marshal arguments into request. {{range $winargs}} - if request.{{.Name}}, err = {{.Marshal}}; err != nil { + if request.{{.Name}}, err = {{.MarshalV1}}; err != nil { return }{{end}} // END Marshal arguments into request. @@ -136,7 +136,7 @@ func (client *{{$srvIdent}}) {{.Name}}Ctx( // BEGIN Unmarshal arguments from response. {{range $woutargs}} - if {{.Name}}, err = {{.Unmarshal "response"}}; err != nil { + if {{.Name}}, err = {{.UnmarshalV1 "response"}}; err != nil { return }{{end}} // END Unmarshal arguments from response. diff --git a/soap/types.go b/soap/types.go index 3e73d99..b54b216 100644 --- a/soap/types.go +++ b/soap/types.go @@ -526,3 +526,53 @@ func MarshalURI(v *url.URL) (string, error) { func UnmarshalURI(s string) (*url.URL, error) { 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"}, +}