You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
3.4 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package codec
import (
ctxpkg "github.com/noahlann/nnet/pkg/context"
protocolpkg "github.com/noahlann/nnet/pkg/protocol"
)
// Resolver Codec解析器接口
// 每个Resolver负责一种Codec选择策略支持双向解析解码和编码
type Resolver interface {
// ResolveForDecode 解析用于解码的Codec数据流入
// registry: 编解码器注册表可以动态注册codec
// ctx: 请求上下文
// raw: 原始数据
// header: 协议帧头(如果有)
// 返回: 解析到的Codec如果无法解析返回nil和nil错误继续下一个resolver
// 注意resolver可以将解析到的codec注册到registry中供后续使用
ResolveForDecode(registry Registry, ctx ctxpkg.Context, raw []byte, header protocolpkg.FrameHeader) (Codec, error)
// ResolveForEncode 解析用于编码的Codec数据流出
// registry: 编解码器注册表可以动态注册codec
// ctx: 请求上下文
// data: 要编码的数据Go对象
// header: 协议帧头(如果有)
// 返回: 解析到的Codec如果无法解析返回nil和nil错误继续下一个resolver
// 注意通常流入时已经将codec注册到registry这里可以直接获取
ResolveForEncode(registry Registry, ctx ctxpkg.Context, data interface{}, header protocolpkg.FrameHeader) (Codec, error)
}
// ResolverChain Codec解析器链
// 按顺序尝试每个Resolver直到找到可用的Codec
type ResolverChain struct {
resolvers []Resolver
registry Registry
defaultName string
}
// NewResolverChain 创建解析器链
func NewResolverChain(registry Registry, defaultName string) *ResolverChain {
return &ResolverChain{
resolvers: make([]Resolver, 0),
registry: registry,
defaultName: defaultName,
}
}
// Add 添加解析器到链中
func (c *ResolverChain) Add(resolver Resolver) *ResolverChain {
c.resolvers = append(c.resolvers, resolver)
return c
}
// ResolveForDecode 执行解析器链用于解码返回第一个成功解析的Codec
// 如果所有resolver都无法解析返回默认Codec
func (c *ResolverChain) ResolveForDecode(ctx ctxpkg.Context, raw []byte, header protocolpkg.FrameHeader) (Codec, error) {
// 按顺序尝试每个resolver
for _, resolver := range c.resolvers {
codec, err := resolver.ResolveForDecode(c.registry, ctx, raw, header)
if err != nil {
// 如果resolver返回错误继续下一个
continue
}
if codec != nil {
return codec, nil
}
}
// 所有resolver都无法解析使用默认
if c.defaultName != "" {
if codec, err := c.registry.Get(c.defaultName); err == nil {
return codec, nil
}
}
return c.registry.Default(), nil
}
// ResolveForEncode 执行解析器链用于编码返回第一个成功解析的Codec
// 如果所有resolver都无法解析返回默认Codec
func (c *ResolverChain) ResolveForEncode(ctx ctxpkg.Context, data interface{}, header protocolpkg.FrameHeader) (Codec, error) {
// 按顺序尝试每个resolver
for _, resolver := range c.resolvers {
codec, err := resolver.ResolveForEncode(c.registry, ctx, data, header)
if err != nil {
// 如果resolver返回错误继续下一个
continue
}
if codec != nil {
return codec, nil
}
}
// 所有resolver都无法解析使用默认
if c.defaultName != "" {
if codec, err := c.registry.Get(c.defaultName); err == nil {
return codec, nil
}
}
return c.registry.Default(), nil
}