本站源代码
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

156 lines
3.8KB

  1. // Copyright 2015 go-swagger maintainers
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package runtime
  15. import (
  16. "bytes"
  17. "encoding"
  18. "errors"
  19. "fmt"
  20. "io"
  21. "reflect"
  22. "github.com/go-openapi/swag"
  23. )
  24. func defaultCloser() error { return nil }
  25. type byteStreamOpt func(opts *byteStreamOpts)
  26. // ClosesStream when the bytestream consumer or producer is finished
  27. func ClosesStream(opts *byteStreamOpts) {
  28. opts.Close = true
  29. }
  30. type byteStreamOpts struct {
  31. Close bool
  32. }
  33. // ByteStreamConsumer creates a consmer for byte streams,
  34. // takes a Writer/BinaryUnmarshaler interface or binary slice by reference,
  35. // and reads from the provided reader
  36. func ByteStreamConsumer(opts ...byteStreamOpt) Consumer {
  37. var vals byteStreamOpts
  38. for _, opt := range opts {
  39. opt(&vals)
  40. }
  41. return ConsumerFunc(func(reader io.Reader, data interface{}) error {
  42. if reader == nil {
  43. return errors.New("ByteStreamConsumer requires a reader") // early exit
  44. }
  45. close := defaultCloser
  46. if vals.Close {
  47. if cl, ok := reader.(io.Closer); ok {
  48. close = cl.Close
  49. }
  50. }
  51. defer close()
  52. if wrtr, ok := data.(io.Writer); ok {
  53. _, err := io.Copy(wrtr, reader)
  54. return err
  55. }
  56. buf := new(bytes.Buffer)
  57. _, err := buf.ReadFrom(reader)
  58. if err != nil {
  59. return err
  60. }
  61. b := buf.Bytes()
  62. if bu, ok := data.(encoding.BinaryUnmarshaler); ok {
  63. return bu.UnmarshalBinary(b)
  64. }
  65. if t := reflect.TypeOf(data); data != nil && t.Kind() == reflect.Ptr {
  66. v := reflect.Indirect(reflect.ValueOf(data))
  67. if t = v.Type(); t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8 {
  68. v.SetBytes(b)
  69. return nil
  70. }
  71. }
  72. return fmt.Errorf("%v (%T) is not supported by the ByteStreamConsumer, %s",
  73. data, data, "can be resolved by supporting Writer/BinaryUnmarshaler interface")
  74. })
  75. }
  76. // ByteStreamProducer creates a producer for byte streams,
  77. // takes a Reader/BinaryMarshaler interface or binary slice,
  78. // and writes to a writer (essentially a pipe)
  79. func ByteStreamProducer(opts ...byteStreamOpt) Producer {
  80. var vals byteStreamOpts
  81. for _, opt := range opts {
  82. opt(&vals)
  83. }
  84. return ProducerFunc(func(writer io.Writer, data interface{}) error {
  85. if writer == nil {
  86. return errors.New("ByteStreamProducer requires a writer") // early exit
  87. }
  88. close := defaultCloser
  89. if vals.Close {
  90. if cl, ok := writer.(io.Closer); ok {
  91. close = cl.Close
  92. }
  93. }
  94. defer close()
  95. if rc, ok := data.(io.ReadCloser); ok {
  96. defer rc.Close()
  97. }
  98. if rdr, ok := data.(io.Reader); ok {
  99. _, err := io.Copy(writer, rdr)
  100. return err
  101. }
  102. if bm, ok := data.(encoding.BinaryMarshaler); ok {
  103. bytes, err := bm.MarshalBinary()
  104. if err != nil {
  105. return err
  106. }
  107. _, err = writer.Write(bytes)
  108. return err
  109. }
  110. if data != nil {
  111. if e, ok := data.(error); ok {
  112. _, err := writer.Write([]byte(e.Error()))
  113. return err
  114. }
  115. v := reflect.Indirect(reflect.ValueOf(data))
  116. if t := v.Type(); t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8 {
  117. _, err := writer.Write(v.Bytes())
  118. return err
  119. }
  120. if t := v.Type(); t.Kind() == reflect.Struct || t.Kind() == reflect.Slice {
  121. b, err := swag.WriteJSON(data)
  122. if err != nil {
  123. return err
  124. }
  125. _, err = writer.Write(b)
  126. return err
  127. }
  128. }
  129. return fmt.Errorf("%v (%T) is not supported by the ByteStreamProducer, %s",
  130. data, data, "can be resolved by supporting Reader/BinaryMarshaler interface")
  131. })
  132. }
上海开阖软件有限公司 沪ICP备12045867号-1