github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/conv/p2j/conv.go (about) 1 package p2j 2 3 import ( 4 "context" 5 6 "github.com/cloudwego/dynamicgo/conv" 7 "github.com/cloudwego/dynamicgo/http" 8 "github.com/cloudwego/dynamicgo/meta" 9 "github.com/cloudwego/dynamicgo/proto" 10 ) 11 12 type BinaryConv struct { 13 opts conv.Options 14 } 15 16 // NewBinaryConv returns a new BinaryConv 17 func NewBinaryConv(opts conv.Options) BinaryConv { 18 return BinaryConv{opts: opts} 19 } 20 21 // SetOptions sets options 22 func (self *BinaryConv) SetOptions(opts conv.Options) { 23 self.opts = opts 24 } 25 26 // Do converts protobuf binary (pbytes) to json bytes (jbytes) 27 // desc is the protobuf type descriptor of the protobuf binary, usually it is a response Message type 28 func (self *BinaryConv) Do(ctx context.Context, desc *proto.TypeDescriptor, pbytes []byte) (json []byte, err error) { 29 buf := conv.NewBytes() 30 31 // resp alloc but not use 32 var resp http.ResponseSetter 33 if self.opts.EnableHttpMapping { 34 respi := ctx.Value(conv.CtxKeyHTTPResponse) 35 if respi != nil { 36 respi, ok := respi.(http.ResponseSetter) 37 if !ok { 38 return nil, wrapError(meta.ErrInvalidParam, "invalid http.Response", nil) 39 } 40 resp = respi 41 } else { 42 return nil, wrapError(meta.ErrInvalidParam, "no http response in context", nil) 43 } 44 } 45 46 err = self.do(ctx, pbytes, desc, buf, resp) 47 if err == nil && len(*buf) > 0 { 48 json = make([]byte, len(*buf)) 49 copy(json, *buf) 50 } 51 52 conv.FreeBytes(buf) 53 return 54 } 55 56 // DoInto behaves like Do, but it writes the result to buffer directly instead of returning a new buffer 57 func (self *BinaryConv) DoInto(ctx context.Context, desc *proto.TypeDescriptor, pbytes []byte, buf *[]byte) (err error) { 58 // resp alloc but not use 59 var resp http.ResponseSetter 60 if self.opts.EnableHttpMapping { 61 respi := ctx.Value(conv.CtxKeyHTTPResponse) 62 if respi != nil { 63 respi, ok := respi.(http.ResponseSetter) 64 if !ok { 65 return wrapError(meta.ErrInvalidParam, "invalid http.Response", nil) 66 } 67 resp = respi 68 } else { 69 return wrapError(meta.ErrInvalidParam, "no http response in context", nil) 70 } 71 } 72 73 return self.do(ctx, pbytes, desc, buf, resp) 74 }