github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/kit/httptransport/transformer/tsfm_octet_stream.go (about) 1 package transformer 2 3 import ( 4 "bytes" 5 "context" 6 "io" 7 "mime/multipart" 8 "net/textproto" 9 "reflect" 10 11 "github.com/machinefi/w3bstream/pkg/depends/kit/httptransport/httpx" 12 "github.com/machinefi/w3bstream/pkg/depends/x/typesx" 13 ) 14 15 func init() { DefaultFactory.Register(&OctetStream{}) } 16 17 type OctetStream struct{} 18 19 func (t *OctetStream) String() string { return httpx.MIME_OCTET_STREAM } 20 21 func (OctetStream) Names() []string { 22 return []string{httpx.MIME_OCTET_STREAM, "stream", "octet-stream"} 23 } 24 25 func (OctetStream) New(context.Context, typesx.Type) (Transformer, error) { return &OctetStream{}, nil } 26 27 func (t *OctetStream) EncodeTo(ctx context.Context, w io.Writer, v interface{}) error { 28 rv, ok := v.(reflect.Value) 29 if ok { 30 v = rv.Interface() 31 } 32 33 switch x := v.(type) { 34 case io.Reader: 35 httpx.MaybeWriteHeader(ctx, w, t.Names()[0], nil) 36 if _, err := io.Copy(w, x); err != nil { 37 return err 38 } 39 case bytes.Buffer: 40 // TODO draft for fix bytes.Buffer 41 httpx.MaybeWriteHeader(ctx, w, t.Names()[0], nil) 42 if _, err := io.Copy(w, &x); err != nil { 43 return err 44 } 45 case *multipart.FileHeader: 46 file, err := x.Open() 47 if err != nil { 48 return err 49 } 50 defer file.Close() 51 52 if rw, ok := w.(httpx.WithHeader); ok { 53 for k := range x.Header { 54 rw.Header()[k] = x.Header[k] 55 } 56 } 57 58 if _, err := io.Copy(w, file); err != nil { 59 return err 60 } 61 } 62 63 return nil 64 } 65 66 func (OctetStream) DecodeFrom(_ context.Context, r io.Reader, v interface{}, _ ...textproto.MIMEHeader) error { 67 rv, ok := v.(reflect.Value) 68 if ok { 69 v = rv.Interface() 70 } 71 72 switch x := v.(type) { 73 case io.Writer: 74 if _, err := io.Copy(x, r); err != nil { 75 return err 76 } 77 case *multipart.FileHeader: 78 if with, ok := r.(CanInterface); ok { 79 if fh, ok := with.Interface().(*multipart.FileHeader); ok { 80 *x = *fh 81 } 82 } 83 case **multipart.FileHeader: 84 if with, ok := r.(CanInterface); ok { 85 if fh, ok := with.Interface().(*multipart.FileHeader); ok { 86 *x = fh 87 } 88 } 89 } 90 91 return nil 92 }