From a8a89879803afd7ae888af98fb832546bf3a1e60 Mon Sep 17 00:00:00 2001 From: John Beisley Date: Mon, 6 Jan 2014 19:47:57 +0000 Subject: [PATCH] Use nil interface{} instead of struct{} for empty requests/responses. The XML encoder doesn't like receiving struct{}. --- cmd/specgen/pkgtmpl.go | 12 +++++---- cmd/specgen/specgen.go | 59 ++++++++++++++++++++++++++++++++---------- soap/soap.go | 14 ++++++---- 3 files changed, 62 insertions(+), 23 deletions(-) diff --git a/cmd/specgen/pkgtmpl.go b/cmd/specgen/pkgtmpl.go index 0855e96..2c57e76 100644 --- a/cmd/specgen/pkgtmpl.go +++ b/cmd/specgen/pkgtmpl.go @@ -70,8 +70,7 @@ func (client *{{$srvIdent}}) {{.Name}}({{range $inargs}}{{/* */}}) ({{range $outargs}}{{/* */}}{{$argWrap := $srv.WrapArgument .}}{{$argWrap.AsParameter}}, {{end}} err error) { // Request structure. - var request struct {{"{"}}{{range .Arguments}}{{if .IsInput}}{{.Name}} string -{{end}}{{end}}} + request := {{if $inargs}}&{{template "argstruct" $inargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}} // BEGIN Marshal arguments into request. {{range $inargs}}{{$argWrap := $srv.WrapArgument .}} if request.{{.Name}}, err = {{$argWrap.Marshal}}; err != nil { @@ -80,11 +79,10 @@ func (client *{{$srvIdent}}) {{.Name}}({{range $inargs}}{{/* // END Marshal arguments into request. // Response structure. - var response struct {{"{"}}{{range $outargs}}{{.Name}} string -{{end}}} + response := {{if $outargs}}&{{template "argstruct" $outargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}} // Perform the SOAP call. - if err = client.SOAPClient.PerformAction({{$srv.URNParts.Const}}, "{{.Name}}", &request, &response); err != nil { + if err = client.SOAPClient.PerformAction({{$srv.URNParts.Const}}, "{{.Name}}", request, response); err != nil { return } @@ -98,4 +96,8 @@ func (client *{{$srvIdent}}) {{.Name}}({{range $inargs}}{{/* } {{end}}{{/* range .SCPD.Actions */}} {{end}}{{/* range .Services */}} + +{{define "argstruct"}}struct {{"{"}}{{range .}} +{{.Name}} string +{{end}}{{"}"}}{{end}} `)) diff --git a/cmd/specgen/specgen.go b/cmd/specgen/specgen.go index 1383fdd..790610e 100644 --- a/cmd/specgen/specgen.go +++ b/cmd/specgen/specgen.go @@ -28,6 +28,8 @@ import ( var ( specFilename = flag.String("spec", "", "Path to the specification file.") outDir = flag.String("out-dir", "", "Path to the output directory.") + enableGofmt = flag.Bool("gofmt", true, "Pass the output through gofmt. "+ + "Disable if debugging code output problems.") ) var ( @@ -173,24 +175,55 @@ func (dcp *DCP) writePackage(outDir string) error { if err != nil { return err } - defer packageFile.Close() - gofmt := exec.Command("gofmt") - gofmt.Stdout = packageFile - gofmt.Stderr = os.Stderr - gofmtWriter, err := gofmt.StdinPipe() - if err != nil { + var output io.WriteCloser = packageFile + if *enableGofmt { + if output, err = NewGofmtWriteCloser(output); err != nil { + packageFile.Close() + return err + } + } + if err = packageTmpl.Execute(output, dcp); err != nil { + output.Close() return err } + return output.Close() +} + +type GofmtWriteCloser struct { + output io.WriteCloser + stdin io.WriteCloser + gofmt *exec.Cmd +} + +func NewGofmtWriteCloser(output io.WriteCloser) (*GofmtWriteCloser, error) { + gofmt := exec.Command("gofmt") + gofmt.Stdout = output + gofmt.Stderr = os.Stderr + stdin, err := gofmt.StdinPipe() + if err != nil { + return nil, err + } if err = gofmt.Start(); err != nil { + return nil, err + } + return &GofmtWriteCloser{ + output: output, + stdin: stdin, + gofmt: gofmt, + }, nil +} + +func (gwc *GofmtWriteCloser) Write(p []byte) (int, error) { + return gwc.stdin.Write(p) +} + +func (gwc *GofmtWriteCloser) Close() error { + gwc.stdin.Close() + if err := gwc.output.Close(); err != nil { + gwc.gofmt.Wait() return err } - if err = packageTmpl.Execute(gofmtWriter, dcp); err != nil { - gofmtWriter.Close() - gofmt.Wait() - return err - } - gofmtWriter.Close() - return gofmt.Wait() + return gwc.gofmt.Wait() } func (dcp *DCP) processSCPDFile(file *zip.File) { diff --git a/soap/soap.go b/soap/soap.go index 9c56e02..b8a2f49 100644 --- a/soap/soap.go +++ b/soap/soap.go @@ -64,8 +64,10 @@ func (client *SOAPClient) PerformAction(actionNamespace, actionName string, inAc return responseEnv.Body.Fault } - if err := xml.Unmarshal(responseEnv.Body.RawAction, outAction); err != nil { - return err + if outAction != nil { + if err := xml.Unmarshal(responseEnv.Body.RawAction, outAction); err != nil { + return err + } } return nil @@ -86,9 +88,11 @@ func newSOAPEnvelope() *soapEnvelope { func encodeRequestAction(inAction interface{}) ([]byte, error) { requestBuf := new(bytes.Buffer) requestBuf.WriteString(soapPrefix) - requestEnc := xml.NewEncoder(requestBuf) - if err := requestEnc.Encode(inAction); err != nil { - return nil, err + if inAction != nil { + requestEnc := xml.NewEncoder(requestBuf) + if err := requestEnc.Encode(inAction); err != nil { + return nil, err + } } requestBuf.WriteString(soapSuffix) return requestBuf.Bytes(), nil