github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/core/protocol/message/analysis/analysis.go (about)

     1  package analysis
     2  
     3  import (
     4  	"encoding/json"
     5  	container2 "github.com/nyan233/littlerpc/core/container"
     6  	message2 "github.com/nyan233/littlerpc/core/protocol/message"
     7  	"github.com/nyan233/littlerpc/core/protocol/message/mux"
     8  	"github.com/nyan233/littlerpc/core/utils/convert"
     9  	"unsafe"
    10  )
    11  
    12  type messageCopyDefined struct {
    13  	Scope         [2]uint8
    14  	MsgId         uint64
    15  	PayloadLength uint32
    16  	ServiceName   string
    17  	MetaData      *container2.SliceMap[string, string]
    18  	PayloadLayout container2.Slice[uint32]
    19  	Payloads      container2.Slice[byte]
    20  }
    21  
    22  type Graph struct {
    23  	First         string
    24  	MsgType       string
    25  	Codec         string
    26  	Encoder       string
    27  	MsgId         uint64
    28  	DataLength    uint32
    29  	ServiceName   string
    30  	MetaData      map[string]string
    31  	PayloadLayout []uint32
    32  	Payloads      []uint8
    33  }
    34  
    35  func (g *Graph) String() string {
    36  	bytes, err := json.Marshal(g)
    37  	if err != nil {
    38  		panic(err)
    39  	}
    40  	return convert.BytesToString(bytes)
    41  }
    42  
    43  type MuxGraph struct {
    44  	MuxType       string
    45  	StreamId      uint32
    46  	MsgId         uint64
    47  	PayloadLength uint16
    48  	*Graph
    49  }
    50  
    51  func (g *MuxGraph) String() string {
    52  	bytes, err := json.Marshal(g)
    53  	if err != nil {
    54  		panic(err)
    55  	}
    56  	return convert.BytesToString(bytes)
    57  }
    58  
    59  func NoMux(data []byte) *Graph {
    60  	g := &Graph{
    61  		MetaData: make(map[string]string),
    62  	}
    63  	rawMsg := message2.New()
    64  	msg := (*messageCopyDefined)(unsafe.Pointer(rawMsg))
    65  	_ = message2.Unmarshal(data, rawMsg)
    66  	switch msg.Scope[0] {
    67  	case message2.MagicNumber:
    68  		g.First = "no_mux"
    69  	case mux.Enabled:
    70  		g.First = "mux"
    71  	default:
    72  		g.First = "unknown"
    73  	}
    74  	switch rawMsg.GetMsgType() {
    75  	case message2.Call:
    76  		g.MsgType = "call"
    77  	case message2.Return:
    78  		g.MsgType = "return"
    79  	case message2.Ping:
    80  		g.MsgType = "ping"
    81  	case message2.Pong:
    82  		g.MsgType = "pong"
    83  	case message2.ContextCancel:
    84  		g.MsgType = "context_cancel"
    85  	default:
    86  		g.MsgType = "unknown"
    87  	}
    88  	if codecScheme := rawMsg.MetaData.Load(message2.CodecScheme); codecScheme != "" {
    89  		g.Codec = codecScheme
    90  	} else {
    91  		g.Codec = message2.DefaultCodec
    92  	}
    93  	if encoderScheme := rawMsg.MetaData.Load(message2.CodecScheme); encoderScheme != "" {
    94  		g.Encoder = encoderScheme
    95  	} else {
    96  		g.Encoder = message2.DefaultPacker
    97  	}
    98  	g.MsgId = msg.MsgId
    99  	g.DataLength = msg.PayloadLength
   100  	g.ServiceName = msg.ServiceName
   101  	if msg.MetaData != nil {
   102  		msg.MetaData.Range(func(k, v string) bool {
   103  			g.MetaData[k] = v
   104  			return true
   105  		})
   106  	}
   107  	if msg.PayloadLayout != nil {
   108  		for _, v := range msg.PayloadLayout {
   109  			g.PayloadLayout = append(g.PayloadLayout, v)
   110  		}
   111  	}
   112  	if msg.Payloads != nil {
   113  		for _, v := range msg.Payloads {
   114  			g.Payloads = append(g.Payloads, v)
   115  		}
   116  	}
   117  	return g
   118  }
   119  
   120  func Mux(data []byte) *MuxGraph {
   121  	var muxBlock mux.Block
   122  	_ = mux.Unmarshal(data, &muxBlock)
   123  	g := &MuxGraph{}
   124  	switch muxBlock.Flags {
   125  	case mux.Enabled:
   126  		g.MuxType = "mux_enabled"
   127  	default:
   128  		g.MuxType = "unknown"
   129  	}
   130  	g.StreamId = muxBlock.StreamId
   131  	g.MsgId = muxBlock.MsgId
   132  	g.PayloadLength = muxBlock.PayloadLength
   133  	if muxBlock.Payloads == nil {
   134  		return g
   135  	}
   136  	g.Graph = NoMux(muxBlock.Payloads)
   137  	return g
   138  }