github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/conv/j2p/conv.go (about)

     1  package j2p
     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  // BinaryConv is a converter from json to protobuf binary
    13  type BinaryConv struct {
    14  	opts conv.Options
    15  }
    16  
    17  // NewBinaryConv returns a new BinaryConv
    18  func NewBinaryConv(opts conv.Options) BinaryConv {
    19  	return BinaryConv{
    20  		opts: opts,
    21  	}
    22  }
    23  
    24  // Do converts json bytes (jbytes) to protobuf binary (tbytes)
    25  // desc is the protobuf type descriptor of the protobuf binary, usually it the request Message type
    26  func (self *BinaryConv) Do(ctx context.Context, desc *proto.TypeDescriptor, jbytes []byte) (tbytes []byte, err error) {
    27  	buf := conv.NewBytes()
    28  
    29  	// req alloc but not use
    30  	var req http.RequestGetter
    31  	if self.opts.EnableHttpMapping {
    32  		reqi := ctx.Value(conv.CtxKeyHTTPRequest)
    33  		if reqi != nil {
    34  			reqi, ok := reqi.(http.RequestGetter)
    35  			if !ok {
    36  				return nil, newError(meta.ErrInvalidParam, "invalid http.RequestGetter", nil)
    37  			}
    38  			req = reqi
    39  		} else {
    40  			return nil, newError(meta.ErrInvalidParam, "EnableHttpMapping but no http response in context", nil)
    41  		}
    42  	}
    43  
    44  	err = self.do(ctx, jbytes, desc, buf, req)
    45  	if err == nil && len(*buf) > 0 {
    46  		tbytes = make([]byte, len(*buf))
    47  		copy(tbytes, *buf)
    48  	}
    49  
    50  	conv.FreeBytes(buf)
    51  	return
    52  }
    53  
    54  // DoInto behaves like Do, but it writes the result to buffer directly instead of returning a new buffer
    55  func (self *BinaryConv) DoInto(ctx context.Context, desc *proto.TypeDescriptor, jbytes []byte, buf *[]byte) error {
    56  	// req alloc but not use
    57  	var req http.RequestGetter
    58  	if self.opts.EnableHttpMapping {
    59  		reqi := ctx.Value(conv.CtxKeyHTTPRequest)
    60  		if reqi != nil {
    61  			reqi, ok := reqi.(http.RequestGetter)
    62  			if !ok {
    63  				return newError(meta.ErrInvalidParam, "invalid http.RequestGetter", nil)
    64  			}
    65  			req = reqi
    66  		} else {
    67  			return newError(meta.ErrInvalidParam, "EnableHttpMapping but no http response in context", nil)
    68  		}
    69  	}
    70  	return self.do(ctx, jbytes, desc, buf, req)
    71  }