Merge branch 'dev' of http://git.legu.cc/liwei_3d/go_dreamfactory into dev
This commit is contained in:
commit
0b7f26bab3
@ -203,6 +203,9 @@ func (r *Robot) onUserLoaded() {
|
|||||||
|
|
||||||
//task
|
//task
|
||||||
r.RunTask()
|
r.RunTask()
|
||||||
|
|
||||||
|
// story
|
||||||
|
r.RunStory()
|
||||||
}
|
}
|
||||||
|
|
||||||
//注册账号
|
//注册账号
|
||||||
|
45
cmd/robot/story.go
Normal file
45
cmd/robot/story.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package robot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"go_dreamfactory/comm"
|
||||||
|
"go_dreamfactory/modules/story"
|
||||||
|
"go_dreamfactory/pb"
|
||||||
|
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
storyBuilders = []*TestCase{
|
||||||
|
{
|
||||||
|
desc: "主线数据",
|
||||||
|
mainType: string(comm.ModuleStory),
|
||||||
|
subType: story.StoryGetListResp,
|
||||||
|
req: &pb.StoryGetListReq{},
|
||||||
|
rsp: &pb.StoryGetListResp{},
|
||||||
|
print: func(rsp proto.Message) {
|
||||||
|
out := rsp.(*pb.StoryGetListResp)
|
||||||
|
for i, v := range out.Data {
|
||||||
|
fmt.Printf("%d- %v\n", (i + 1), v)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//enabled: true,
|
||||||
|
}, {
|
||||||
|
desc: "主线详情",
|
||||||
|
mainType: string(comm.ModuleStory),
|
||||||
|
subType: story.StoryChallengeResp,
|
||||||
|
req: &pb.StoryChallengeReq{
|
||||||
|
ChapterId: 1,
|
||||||
|
StoryId: 1,
|
||||||
|
},
|
||||||
|
rsp: &pb.StoryChallengeResp{},
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
//声明加入到构建器并发起请求
|
||||||
|
func (r *Robot) RunStory() {
|
||||||
|
r.addBuilders(storyBuilders)
|
||||||
|
r.batchHandleReq()
|
||||||
|
}
|
@ -29,12 +29,12 @@ const (
|
|||||||
//模块名定义处
|
//模块名定义处
|
||||||
const (
|
const (
|
||||||
ModuleGate core.M_Modules = "gateway" //gate模块 网关服务模块
|
ModuleGate core.M_Modules = "gateway" //gate模块 网关服务模块
|
||||||
ModuleWeb core.M_Modules = "web" //web模块
|
ModuleGM core.M_Modules = "gm" //gm模块
|
||||||
ModuleUser core.M_Modules = "user" //用户模块
|
ModuleUser core.M_Modules = "user" //用户模块
|
||||||
ModulePack core.M_Modules = "pack" //背包模块
|
ModulePack core.M_Modules = "pack" //背包模块
|
||||||
ModuleMail core.M_Modules = "mail" //邮件模块
|
ModuleMail core.M_Modules = "mail" //邮件模块
|
||||||
ModuleFriend core.M_Modules = "friend" //好友模块
|
ModuleFriend core.M_Modules = "friend" //好友模块
|
||||||
ModuleLogModel core.M_Modules = "model" //日志模块
|
ModuleMgoLog core.M_Modules = "mgolog" //日志模块
|
||||||
ModuleEquipment core.M_Modules = "equipment" //装备模块
|
ModuleEquipment core.M_Modules = "equipment" //装备模块
|
||||||
ModuleHero core.M_Modules = "hero" //英雄模块
|
ModuleHero core.M_Modules = "hero" //英雄模块
|
||||||
ModuleForum core.M_Modules = "forum" //论坛模块
|
ModuleForum core.M_Modules = "forum" //论坛模块
|
||||||
@ -42,6 +42,7 @@ const (
|
|||||||
ModuleShop core.M_Modules = "shop" //商店模块
|
ModuleShop core.M_Modules = "shop" //商店模块
|
||||||
ModuleTask core.M_Modules = "task" //任务模块
|
ModuleTask core.M_Modules = "task" //任务模块
|
||||||
ModuleStory core.M_Modules = "story" //主线模块
|
ModuleStory core.M_Modules = "story" //主线模块
|
||||||
|
ModuleNotify core.M_Modules = "notify" //公告模块
|
||||||
)
|
)
|
||||||
|
|
||||||
//RPC服务接口定义处
|
//RPC服务接口定义处
|
||||||
|
@ -118,7 +118,7 @@ func (this *UserSession) UnBind() (err error) {
|
|||||||
|
|
||||||
//向用户发送消息
|
//向用户发送消息
|
||||||
func (this *UserSession) SendMsg(mainType, subType string, msg proto.Message) (err error) {
|
func (this *UserSession) SendMsg(mainType, subType string, msg proto.Message) (err error) {
|
||||||
log.Debugf("SendMsg to UserId:[%s] Data: %v", this.UserId, msg)
|
// log.Debugf("SendMsg to UserId:[%s] Data: %v", this.UserId, msg)
|
||||||
data, _ := anypb.New(msg)
|
data, _ := anypb.New(msg)
|
||||||
this.msgqueue = append(this.msgqueue, &pb.UserMessage{
|
this.msgqueue = append(this.msgqueue, &pb.UserMessage{
|
||||||
MainType: mainType,
|
MainType: mainType,
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"go_dreamfactory/lego/base"
|
"go_dreamfactory/lego/base"
|
||||||
"go_dreamfactory/lego/core"
|
"go_dreamfactory/lego/core"
|
||||||
"go_dreamfactory/lego/core/cbase"
|
"go_dreamfactory/lego/core/cbase"
|
||||||
|
"go_dreamfactory/lego/sys/codec"
|
||||||
"go_dreamfactory/lego/sys/event"
|
"go_dreamfactory/lego/sys/event"
|
||||||
"go_dreamfactory/lego/sys/log"
|
"go_dreamfactory/lego/sys/log"
|
||||||
"go_dreamfactory/lego/sys/rpcx"
|
"go_dreamfactory/lego/sys/rpcx"
|
||||||
@ -83,6 +84,12 @@ func (this *RPCXService) InitSys() {
|
|||||||
} else {
|
} else {
|
||||||
log.Infof("Sys event Init success !")
|
log.Infof("Sys event Init success !")
|
||||||
}
|
}
|
||||||
|
//初始化编码Codec
|
||||||
|
if err := codec.OnInit(this.opts.Setting.Sys["codec"]); err != nil {
|
||||||
|
log.Panicf(fmt.Sprintf("Sys codec Init err:%v", err))
|
||||||
|
} else {
|
||||||
|
log.Infof("Sys codec Init success !")
|
||||||
|
}
|
||||||
//初始化rpcx系统
|
//初始化rpcx系统
|
||||||
if err := rpcx.OnInit(this.opts.Setting.Sys["rpcx"], rpcx.SetServiceTag(this.GetTag()), rpcx.SetServiceId(this.GetId()), rpcx.SetServiceType(this.GetType()), rpcx.SetServiceVersion(this.GetVersion()), rpcx.SetServiceAddr(fmt.Sprintf("%s:%d", this.GetIp(), this.GetPort()))); err != nil {
|
if err := rpcx.OnInit(this.opts.Setting.Sys["rpcx"], rpcx.SetServiceTag(this.GetTag()), rpcx.SetServiceId(this.GetId()), rpcx.SetServiceType(this.GetType()), rpcx.SetServiceVersion(this.GetVersion()), rpcx.SetServiceAddr(fmt.Sprintf("%s:%d", this.GetIp(), this.GetPort()))); err != nil {
|
||||||
log.Panicf(fmt.Sprintf("Sys rpcx Init err:%v", err))
|
log.Panicf(fmt.Sprintf("Sys rpcx Init err:%v", err))
|
||||||
|
@ -105,8 +105,8 @@ func (this *ServiceBase) Run(mod ...core.IModule) {
|
|||||||
mi: v,
|
mi: v,
|
||||||
closeSig: make(chan bool, 1),
|
closeSig: make(chan bool, 1),
|
||||||
}
|
}
|
||||||
log.Warnf("注册模块【%s】 没有对应的配置信息", v.GetType())
|
|
||||||
}
|
}
|
||||||
|
log.Infof("注册模块【%s】", v.GetType())
|
||||||
}
|
}
|
||||||
for _, v := range this.modules { //序列化每一个模块的参数对象 完成模块的初始化 过程
|
for _, v := range this.modules { //序列化每一个模块的参数对象 完成模块的初始化 过程
|
||||||
options := v.mi.NewOptions()
|
options := v.mi.NewOptions()
|
||||||
|
273
lego/sys/codec/codec.go
Normal file
273
lego/sys/codec/codec.go
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
package codec
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"go_dreamfactory/lego/sys/codec/core"
|
||||||
|
"go_dreamfactory/lego/sys/codec/factory"
|
||||||
|
"go_dreamfactory/lego/sys/codec/render"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newSys(options core.Options) (sys *Codec, err error) {
|
||||||
|
sys = &Codec{
|
||||||
|
options: &options,
|
||||||
|
decoderCache: new(sync.Map),
|
||||||
|
encoderCache: new(sync.Map),
|
||||||
|
streamPool: &sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return render.NewStream(sys, 512)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extraPool: &sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return render.NewExtractor(sys)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type Codec struct {
|
||||||
|
options *core.Options
|
||||||
|
decoderCache *sync.Map
|
||||||
|
encoderCache *sync.Map
|
||||||
|
streamPool *sync.Pool
|
||||||
|
extraPool *sync.Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Codec) Options() *core.Options {
|
||||||
|
return this.options
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Codec) addDecoderToCache(cacheKey uintptr, decoder core.IDecoder) {
|
||||||
|
this.decoderCache.Store(cacheKey, decoder)
|
||||||
|
}
|
||||||
|
func (this *Codec) addEncoderToCache(cacheKey uintptr, encoder core.IEncoder) {
|
||||||
|
this.encoderCache.Store(cacheKey, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Codec) GetEncoderFromCache(cacheKey uintptr) core.IEncoder {
|
||||||
|
encoder, found := this.encoderCache.Load(cacheKey)
|
||||||
|
if found {
|
||||||
|
return encoder.(core.IEncoder)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Codec) GetDecoderFromCache(cacheKey uintptr) core.IDecoder {
|
||||||
|
decoder, found := this.decoderCache.Load(cacheKey)
|
||||||
|
if found {
|
||||||
|
return decoder.(core.IDecoder)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Codec) EncoderOf(typ reflect2.Type) core.IEncoder {
|
||||||
|
cacheKey := typ.RType()
|
||||||
|
encoder := this.GetEncoderFromCache(cacheKey)
|
||||||
|
if encoder != nil {
|
||||||
|
return encoder
|
||||||
|
}
|
||||||
|
ctx := &core.Ctx{
|
||||||
|
ICodec: this,
|
||||||
|
Prefix: "",
|
||||||
|
Decoders: map[reflect2.Type]core.IDecoder{},
|
||||||
|
Encoders: map[reflect2.Type]core.IEncoder{},
|
||||||
|
}
|
||||||
|
encoder = factory.EncoderOfType(ctx, typ)
|
||||||
|
if typ.LikePtr() {
|
||||||
|
encoder = factory.NewonePtrEncoder(encoder)
|
||||||
|
}
|
||||||
|
this.addEncoderToCache(cacheKey, encoder)
|
||||||
|
return encoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Codec) DecoderOf(typ reflect2.Type) core.IDecoder {
|
||||||
|
cacheKey := typ.RType()
|
||||||
|
decoder := this.GetDecoderFromCache(cacheKey)
|
||||||
|
if decoder != nil {
|
||||||
|
return decoder
|
||||||
|
}
|
||||||
|
ctx := &core.Ctx{
|
||||||
|
ICodec: this,
|
||||||
|
Prefix: "",
|
||||||
|
Decoders: map[reflect2.Type]core.IDecoder{},
|
||||||
|
Encoders: map[reflect2.Type]core.IEncoder{},
|
||||||
|
}
|
||||||
|
ptrType := typ.(*reflect2.UnsafePtrType)
|
||||||
|
decoder = factory.DecoderOfType(ctx, ptrType.Elem())
|
||||||
|
this.addDecoderToCache(cacheKey, decoder)
|
||||||
|
return decoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Codec) BorrowStream() core.IStream {
|
||||||
|
stream := this.streamPool.Get().(core.IStream)
|
||||||
|
return stream
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Codec) ReturnStream(stream core.IStream) {
|
||||||
|
this.streamPool.Put(stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Codec) BorrowExtractor(buf []byte) core.IExtractor {
|
||||||
|
extra := this.extraPool.Get().(core.IExtractor)
|
||||||
|
extra.ResetBytes(buf)
|
||||||
|
return extra
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Codec) ReturnExtractor(extra core.IExtractor) {
|
||||||
|
this.extraPool.Put(extra)
|
||||||
|
}
|
||||||
|
|
||||||
|
//编码对象到json
|
||||||
|
func (this *Codec) MarshalJson(val interface{}, option ...core.ExecuteOption) (buf []byte, err error) {
|
||||||
|
stream := this.BorrowStream()
|
||||||
|
defer this.ReturnStream(stream)
|
||||||
|
stream.WriteVal(val)
|
||||||
|
if stream.Error() != nil {
|
||||||
|
return nil, stream.Error()
|
||||||
|
}
|
||||||
|
result := stream.Buffer()
|
||||||
|
copied := make([]byte, len(result))
|
||||||
|
copy(copied, result)
|
||||||
|
return copied, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//解码json到对象
|
||||||
|
func (this *Codec) UnmarshalJson(data []byte, v interface{}, option ...core.ExecuteOption) error {
|
||||||
|
extra := this.BorrowExtractor(data)
|
||||||
|
defer this.ReturnExtractor(extra)
|
||||||
|
extra.ReadVal(v)
|
||||||
|
return extra.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
//编码对象到mapjson
|
||||||
|
func (this *Codec) MarshalMapJson(val interface{}, option ...core.ExecuteOption) (ret map[string]string, err error) {
|
||||||
|
if nil == val {
|
||||||
|
err = errors.New("val is null")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cacheKey := reflect2.RTypeOf(val)
|
||||||
|
encoder := this.GetEncoderFromCache(cacheKey)
|
||||||
|
if encoder == nil {
|
||||||
|
typ := reflect2.TypeOf(val)
|
||||||
|
encoder = this.EncoderOf(typ)
|
||||||
|
}
|
||||||
|
if encoderMapJson, ok := encoder.(core.IEncoderMapJson); !ok {
|
||||||
|
err = fmt.Errorf("val type:%T not support MarshalMapJson", val)
|
||||||
|
} else {
|
||||||
|
ret, err = encoderMapJson.EncodeToMapJson(reflect2.PtrOf(val))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//解码mapjson到对象
|
||||||
|
func (this *Codec) UnmarshalMapJson(data map[string]string, val interface{}, option ...core.ExecuteOption) (err error) {
|
||||||
|
cacheKey := reflect2.RTypeOf(val)
|
||||||
|
decoder := this.GetDecoderFromCache(cacheKey)
|
||||||
|
if decoder == nil {
|
||||||
|
typ := reflect2.TypeOf(val)
|
||||||
|
if typ == nil || typ.Kind() != reflect.Ptr {
|
||||||
|
err = errors.New("can only unmarshal into pointer")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
decoder = this.DecoderOf(typ)
|
||||||
|
}
|
||||||
|
ptr := reflect2.PtrOf(val)
|
||||||
|
if ptr == nil {
|
||||||
|
err = errors.New("can not read into nil pointer")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if decoderMapJson, ok := decoder.(core.IDecoderMapJson); !ok {
|
||||||
|
err = fmt.Errorf("val type:%T not support MarshalMapJson", val)
|
||||||
|
} else {
|
||||||
|
err = decoderMapJson.DecodeForMapJson(ptr, data)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//编码对象到sliceJson
|
||||||
|
func (this *Codec) MarshalSliceJson(val interface{}, option ...core.ExecuteOption) (ret []string, err error) {
|
||||||
|
if nil == val {
|
||||||
|
err = errors.New("val is null")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cacheKey := reflect2.RTypeOf(val)
|
||||||
|
encoder := this.GetEncoderFromCache(cacheKey)
|
||||||
|
if encoder == nil {
|
||||||
|
typ := reflect2.TypeOf(val)
|
||||||
|
encoder = this.EncoderOf(typ)
|
||||||
|
}
|
||||||
|
if encoderMapJson, ok := encoder.(core.IEncoderSliceJson); !ok {
|
||||||
|
err = fmt.Errorf("val type:%T not support MarshalMapJson", val)
|
||||||
|
} else {
|
||||||
|
ret, err = encoderMapJson.EncodeToSliceJson(reflect2.PtrOf(val))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//解码sliceJson到对象
|
||||||
|
func (this *Codec) UnmarshalSliceJson(data []string, val interface{}, option ...core.ExecuteOption) (err error) {
|
||||||
|
cacheKey := reflect2.RTypeOf(val)
|
||||||
|
decoder := this.GetDecoderFromCache(cacheKey)
|
||||||
|
if decoder == nil {
|
||||||
|
typ := reflect2.TypeOf(val)
|
||||||
|
if typ == nil || typ.Kind() != reflect.Ptr {
|
||||||
|
err = errors.New("can only unmarshal into pointer")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
decoder = this.DecoderOf(typ)
|
||||||
|
}
|
||||||
|
ptr := reflect2.PtrOf(val)
|
||||||
|
if ptr == nil {
|
||||||
|
err = errors.New("can not read into nil pointer")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if decoderMapJson, ok := decoder.(core.IDecoderSliceJson); !ok {
|
||||||
|
err = fmt.Errorf("val type:%T not support UnmarshalSliceJson", val)
|
||||||
|
} else {
|
||||||
|
err = decoderMapJson.DecodeForSliceJson(ptr, data)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
///日志***********************************************************************
|
||||||
|
func (this *Codec) Debug() bool {
|
||||||
|
return this.options.Debug
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Codec) Debugf(format string, a ...interface{}) {
|
||||||
|
if this.options.Debug {
|
||||||
|
this.options.Log.Debugf("[SYS Codec] "+format, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *Codec) Infof(format string, a ...interface{}) {
|
||||||
|
if this.options.Debug {
|
||||||
|
this.options.Log.Infof("[SYS Codec] "+format, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *Codec) Warnf(format string, a ...interface{}) {
|
||||||
|
if this.options.Debug {
|
||||||
|
this.options.Log.Warnf("[SYS Codec] "+format, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *Codec) Errorf(format string, a ...interface{}) {
|
||||||
|
if this.options.Debug {
|
||||||
|
this.options.Log.Errorf("[SYS Codec] "+format, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *Codec) Panicf(format string, a ...interface{}) {
|
||||||
|
if this.options.Debug {
|
||||||
|
this.options.Log.Panicf("[SYS Codec] "+format, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *Codec) Fatalf(format string, a ...interface{}) {
|
||||||
|
if this.options.Debug {
|
||||||
|
this.options.Log.Fatalf("[SYS Codec] "+format, a...)
|
||||||
|
}
|
||||||
|
}
|
56
lego/sys/codec/core.go
Normal file
56
lego/sys/codec/core.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package codec
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go_dreamfactory/lego/sys/codec/core"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
ISys interface {
|
||||||
|
DecoderOf(typ reflect2.Type) core.IDecoder
|
||||||
|
EncoderOf(typ reflect2.Type) core.IEncoder
|
||||||
|
MarshalJson(v interface{}, option ...core.ExecuteOption) ([]byte, error)
|
||||||
|
UnmarshalJson(data []byte, v interface{}, option ...core.ExecuteOption) error
|
||||||
|
MarshalMapJson(val interface{}, option ...core.ExecuteOption) (ret map[string]string, err error)
|
||||||
|
UnmarshalMapJson(data map[string]string, val interface{}, option ...core.ExecuteOption) (err error)
|
||||||
|
MarshalSliceJson(val interface{}, option ...core.ExecuteOption) (ret []string, err error)
|
||||||
|
UnmarshalSliceJson(data []string, val interface{}, option ...core.ExecuteOption) (err error)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var defsys ISys
|
||||||
|
|
||||||
|
func OnInit(config map[string]interface{}, option ...core.Option) (err error) {
|
||||||
|
defsys, err = newSys(newOptions(config, option...))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSys(option ...core.Option) (sys ISys, err error) {
|
||||||
|
sys, err = newSys(newOptionsByOption(option...))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func DecoderOf(typ reflect2.Type) core.IDecoder {
|
||||||
|
return defsys.DecoderOf(typ)
|
||||||
|
}
|
||||||
|
func EncoderOf(typ reflect2.Type) core.IEncoder {
|
||||||
|
return defsys.EncoderOf(typ)
|
||||||
|
}
|
||||||
|
func MarshalJson(v interface{}, option ...core.ExecuteOption) ([]byte, error) {
|
||||||
|
return defsys.MarshalJson(v, option...)
|
||||||
|
}
|
||||||
|
func UnmarshalJson(data []byte, v interface{}, option ...core.ExecuteOption) error {
|
||||||
|
return defsys.UnmarshalJson(data, v, option...)
|
||||||
|
}
|
||||||
|
func MarshalMapJson(val interface{}, option ...core.ExecuteOption) (ret map[string]string, err error) {
|
||||||
|
return defsys.MarshalMapJson(val, option...)
|
||||||
|
}
|
||||||
|
func UnmarshalMapJson(data map[string]string, val interface{}, option ...core.ExecuteOption) (err error) {
|
||||||
|
return defsys.UnmarshalMapJson(data, val, option...)
|
||||||
|
}
|
||||||
|
func MarshalSliceJson(val interface{}, option ...core.ExecuteOption) (ret []string, err error) {
|
||||||
|
return defsys.MarshalSliceJson(val, option...)
|
||||||
|
}
|
||||||
|
func UnmarshalSliceJson(data []string, val interface{}, option ...core.ExecuteOption) (err error) {
|
||||||
|
return defsys.UnmarshalSliceJson(data, val)
|
||||||
|
}
|
167
lego/sys/codec/core/core.go
Normal file
167
lego/sys/codec/core/core.go
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
//数据类型
|
||||||
|
type CodecType int8
|
||||||
|
|
||||||
|
const (
|
||||||
|
Json CodecType = iota //json 格式数据
|
||||||
|
Bytes //byte 字节流数据
|
||||||
|
Proto //proto google protobuff 数据
|
||||||
|
)
|
||||||
|
|
||||||
|
//结构值类型
|
||||||
|
type ValueType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// InvalidValue invalid JSON element
|
||||||
|
InvalidValue ValueType = iota
|
||||||
|
// StringValue JSON element "string"
|
||||||
|
StringValue
|
||||||
|
// NumberValue JSON element 100 or 0.10
|
||||||
|
NumberValue
|
||||||
|
// NilValue JSON element null
|
||||||
|
NilValue
|
||||||
|
// BoolValue JSON element true or false
|
||||||
|
BoolValue
|
||||||
|
// ArrayValue JSON element []
|
||||||
|
ArrayValue
|
||||||
|
// ObjectValue JSON element {}
|
||||||
|
ObjectValue
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
ICodec interface {
|
||||||
|
Options() *Options
|
||||||
|
GetEncoderFromCache(cacheKey uintptr) IEncoder
|
||||||
|
GetDecoderFromCache(cacheKey uintptr) IDecoder
|
||||||
|
EncoderOf(typ reflect2.Type) IEncoder
|
||||||
|
DecoderOf(typ reflect2.Type) IDecoder
|
||||||
|
BorrowExtractor(buf []byte) IExtractor //借 提取器
|
||||||
|
ReturnExtractor(extra IExtractor) //还 提取器
|
||||||
|
BorrowStream() IStream //借 输出对象
|
||||||
|
ReturnStream(stream IStream) //换 输出对象
|
||||||
|
}
|
||||||
|
IExtractor interface {
|
||||||
|
ReadVal(obj interface{}) //读取指定类型对象
|
||||||
|
WhatIsNext() ValueType
|
||||||
|
Read() interface{}
|
||||||
|
ReadNil() (ret bool) //读取空 null
|
||||||
|
ReadArrayStart() (ret bool) //读数组开始 [
|
||||||
|
CheckNextIsArrayEnd() (ret bool) //下一个是否是数组结束符 不影响数据游标位置
|
||||||
|
ReadArrayEnd() (ret bool) //读数组结束 ]
|
||||||
|
ReadObjectStart() (ret bool) //读对象或Map开始 {
|
||||||
|
CheckNextIsObjectEnd() (ret bool) //下一个是否是数对象结束符 不影响数据游标位置
|
||||||
|
ReadObjectEnd() (ret bool) //读对象或Map结束 }
|
||||||
|
ReadMemberSplit() (ret bool) //读成员分割符 ,
|
||||||
|
ReadKVSplit() (ret bool) //读取key value 分割符 :
|
||||||
|
ReadKeyStart() (ret bool) //读取字段名 开始
|
||||||
|
ReadKeyEnd() (ret bool) //读取字段名 结束
|
||||||
|
Skip() //跳过一个数据单元 容错处理
|
||||||
|
ReadBool() (ret bool)
|
||||||
|
ReadInt8() (ret int8)
|
||||||
|
ReadInt16() (ret int16)
|
||||||
|
ReadInt32() (ret int32)
|
||||||
|
ReadInt64() (ret int64)
|
||||||
|
ReadUint8() (ret uint8)
|
||||||
|
ReadUint16() (ret uint16)
|
||||||
|
ReadUint32() (ret uint32)
|
||||||
|
ReadUint64() (ret uint64)
|
||||||
|
ReadFloat32() (ret float32)
|
||||||
|
ReadFloat64() (ret float64)
|
||||||
|
ReadString() (ret string)
|
||||||
|
ResetBytes(d []byte)
|
||||||
|
Error() error
|
||||||
|
SetErr(err error)
|
||||||
|
}
|
||||||
|
IStream interface {
|
||||||
|
WriteVal(val interface{}) //写入一个对象
|
||||||
|
WriteNil() //写空 null
|
||||||
|
WriteEmptyArray() //写空数组 []
|
||||||
|
WriteArrayStart() //写数组开始 [
|
||||||
|
WriteArrayEnd() //写数组结束 ]
|
||||||
|
WriteEmptyObject() //写空对象 {}
|
||||||
|
WriteObjectStart() //写对象或Map开始 {
|
||||||
|
WriteObjectEnd() //写对象或Map结束 }
|
||||||
|
WriteMemberSplit() //写成员分割符 ,
|
||||||
|
WriteKVSplit() //写key value 分割符 :
|
||||||
|
WriteKeyStart() //写入字段名 开始
|
||||||
|
WriteKeyEnd() //写入字段名 结束
|
||||||
|
WriteObjectFieldName(val string) //写入对象字段名
|
||||||
|
WriteBool(val bool)
|
||||||
|
WriteInt8(val int8)
|
||||||
|
WriteInt16(val int16)
|
||||||
|
WriteInt32(val int32)
|
||||||
|
WriteInt64(val int64)
|
||||||
|
WriteUint8(val uint8)
|
||||||
|
WriteUint16(val uint16)
|
||||||
|
WriteUint32(val uint32)
|
||||||
|
WriteUint64(val uint64)
|
||||||
|
WriteFloat32(val float32)
|
||||||
|
WriteFloat64(val float64)
|
||||||
|
WriteString(val string)
|
||||||
|
WriteBytes(val []byte)
|
||||||
|
Reset(bufSize int)
|
||||||
|
Buffer() []byte //返回缓存区数据
|
||||||
|
Error() error
|
||||||
|
SetErr(err error)
|
||||||
|
}
|
||||||
|
//Json 编码器
|
||||||
|
IEncoder interface {
|
||||||
|
GetType() reflect.Kind
|
||||||
|
IsEmpty(ptr unsafe.Pointer) bool
|
||||||
|
Encode(ptr unsafe.Pointer, stream IStream)
|
||||||
|
}
|
||||||
|
//MapJson 编码器
|
||||||
|
IEncoderMapJson interface {
|
||||||
|
EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error)
|
||||||
|
}
|
||||||
|
//SliceJson 编码器
|
||||||
|
IEncoderSliceJson interface {
|
||||||
|
EncodeToSliceJson(ptr unsafe.Pointer) (ret []string, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Json 解码器
|
||||||
|
IDecoder interface {
|
||||||
|
GetType() reflect.Kind
|
||||||
|
Decode(ptr unsafe.Pointer, extra IExtractor)
|
||||||
|
}
|
||||||
|
//MapJson 解码器
|
||||||
|
IDecoderMapJson interface {
|
||||||
|
DecodeForMapJson(ptr unsafe.Pointer, extra map[string]string) (err error)
|
||||||
|
}
|
||||||
|
//MapJson 解码器
|
||||||
|
IDecoderSliceJson interface {
|
||||||
|
DecodeForSliceJson(ptr unsafe.Pointer, extra []string) (err error)
|
||||||
|
}
|
||||||
|
//空校验
|
||||||
|
CheckIsEmpty interface {
|
||||||
|
IsEmpty(ptr unsafe.Pointer) bool
|
||||||
|
}
|
||||||
|
//内嵌指针是否是空
|
||||||
|
IsEmbeddedPtrNil interface {
|
||||||
|
IsEmbeddedPtrNil(ptr unsafe.Pointer) bool
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type Ctx struct {
|
||||||
|
ICodec
|
||||||
|
Prefix string
|
||||||
|
Encoders map[reflect2.Type]IEncoder
|
||||||
|
Decoders map[reflect2.Type]IDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Ctx) Append(prefix string) *Ctx {
|
||||||
|
return &Ctx{
|
||||||
|
ICodec: this.ICodec,
|
||||||
|
Prefix: this.Prefix + " " + prefix,
|
||||||
|
Encoders: this.Encoders,
|
||||||
|
Decoders: this.Decoders,
|
||||||
|
}
|
||||||
|
}
|
30
lego/sys/codec/core/options.go
Normal file
30
lego/sys/codec/core/options.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go_dreamfactory/lego/sys/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Option func(*Options)
|
||||||
|
type Options struct {
|
||||||
|
IndentionStep int //缩进步骤
|
||||||
|
ObjectFieldMustBeSimpleString bool //对象字段必须是简单字符串
|
||||||
|
OnlyTaggedField bool //仅仅处理标签字段
|
||||||
|
DisallowUnknownFields bool //禁止未知字段
|
||||||
|
CaseSensitive bool //是否区分大小写
|
||||||
|
TagKey string //标签
|
||||||
|
Debug bool //日志是否开启
|
||||||
|
Log log.ILog
|
||||||
|
}
|
||||||
|
|
||||||
|
//执行选项
|
||||||
|
type ExecuteOption func(*ExecuteOptions)
|
||||||
|
type ExecuteOptions struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewExecuteOptions(opts ...ExecuteOption) ExecuteOptions {
|
||||||
|
options := ExecuteOptions{}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
219
lego/sys/codec/factory/factory.go
Normal file
219
lego/sys/codec/factory/factory.go
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
package factory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"go_dreamfactory/lego/sys/codec/core"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type sortableBindings []*Binding
|
||||||
|
|
||||||
|
func (this sortableBindings) Len() int {
|
||||||
|
return len(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this sortableBindings) Less(i, j int) bool {
|
||||||
|
left := this[i].levels
|
||||||
|
right := this[j].levels
|
||||||
|
k := 0
|
||||||
|
for {
|
||||||
|
if left[k] < right[k] {
|
||||||
|
return true
|
||||||
|
} else if left[k] > right[k] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
k++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this sortableBindings) Swap(i, j int) {
|
||||||
|
this[i], this[j] = this[j], this[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
func EncoderOfType(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
|
||||||
|
encoder := ctx.Encoders[typ]
|
||||||
|
if encoder != nil {
|
||||||
|
return encoder
|
||||||
|
}
|
||||||
|
root := &rootEncoder{}
|
||||||
|
ctx.Encoders[typ] = root
|
||||||
|
encoder = _createEncoderOfType(ctx, typ)
|
||||||
|
root.encoder = encoder
|
||||||
|
return encoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func _createEncoderOfType(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
|
||||||
|
var encoder core.IEncoder
|
||||||
|
encoder = createEncoderOfNative(ctx, typ)
|
||||||
|
if encoder != nil {
|
||||||
|
return encoder
|
||||||
|
}
|
||||||
|
kind := typ.Kind()
|
||||||
|
switch kind {
|
||||||
|
case reflect.Interface:
|
||||||
|
return &dynamicEncoder{typ}
|
||||||
|
case reflect.Struct:
|
||||||
|
return encoderOfStruct(ctx, typ)
|
||||||
|
case reflect.Array:
|
||||||
|
return encoderOfArray(ctx, typ)
|
||||||
|
case reflect.Slice:
|
||||||
|
return encoderOfSlice(ctx, typ)
|
||||||
|
case reflect.Map:
|
||||||
|
return encoderOfMap(ctx, typ)
|
||||||
|
case reflect.Ptr:
|
||||||
|
return encoderOfOptional(ctx, typ)
|
||||||
|
default:
|
||||||
|
return &lazyErrorEncoder{err: fmt.Errorf("%s %s is unsupported type", ctx.Prefix, typ.String())}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecoderOfType(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
|
||||||
|
decoder := ctx.Decoders[typ]
|
||||||
|
if decoder != nil {
|
||||||
|
return decoder
|
||||||
|
}
|
||||||
|
root := &rootDecoder{}
|
||||||
|
ctx.Decoders[typ] = root
|
||||||
|
decoder = _createDecoderOfType(ctx, typ)
|
||||||
|
root.decoder = decoder
|
||||||
|
return decoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func _createDecoderOfType(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
|
||||||
|
var decoder core.IDecoder
|
||||||
|
|
||||||
|
decoder = createDecoderOfNative(ctx, typ)
|
||||||
|
if decoder != nil {
|
||||||
|
return decoder
|
||||||
|
}
|
||||||
|
switch typ.Kind() {
|
||||||
|
case reflect.Interface:
|
||||||
|
ifaceType, isIFace := typ.(*reflect2.UnsafeIFaceType)
|
||||||
|
if isIFace {
|
||||||
|
return &ifaceDecoder{valType: ifaceType}
|
||||||
|
}
|
||||||
|
return &efaceDecoder{}
|
||||||
|
case reflect.Struct:
|
||||||
|
return decoderOfStruct(ctx, typ)
|
||||||
|
case reflect.Array:
|
||||||
|
return decoderOfArray(ctx, typ)
|
||||||
|
case reflect.Slice:
|
||||||
|
return decoderOfSlice(ctx, typ)
|
||||||
|
case reflect.Map:
|
||||||
|
return decoderOfMap(ctx, typ)
|
||||||
|
case reflect.Ptr:
|
||||||
|
return decoderOfOptional(ctx, typ)
|
||||||
|
default:
|
||||||
|
return &lazyErrorDecoder{err: fmt.Errorf("%s %s is unsupported type", ctx.Prefix, typ.String())}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// string
|
||||||
|
func BytesToString(b []byte) string {
|
||||||
|
return *(*string)(unsafe.Pointer(&b))
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringToBytes(s string) []byte {
|
||||||
|
return *(*[]byte)(unsafe.Pointer(
|
||||||
|
&struct {
|
||||||
|
string
|
||||||
|
Cap int
|
||||||
|
}{s, len(s)},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
//根节点 -------------------------------------------------------------------
|
||||||
|
type rootDecoder struct {
|
||||||
|
decoder core.IDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *rootDecoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Ptr
|
||||||
|
}
|
||||||
|
func (this *rootDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
this.decoder.Decode(ptr, extra)
|
||||||
|
}
|
||||||
|
|
||||||
|
type rootEncoder struct {
|
||||||
|
encoder core.IEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *rootEncoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Ptr
|
||||||
|
}
|
||||||
|
func (this *rootEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
this.encoder.Encode(ptr, stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *rootEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return this.encoder.IsEmpty(ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
//onePtrEncoder---------------------------------------------------------------
|
||||||
|
func NewonePtrEncoder(encoder core.IEncoder) core.IEncoder {
|
||||||
|
return &onePtrEncoder{encoder}
|
||||||
|
}
|
||||||
|
|
||||||
|
type onePtrEncoder struct {
|
||||||
|
encoder core.IEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *onePtrEncoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Ptr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return this.encoder.IsEmpty(unsafe.Pointer(&ptr))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *onePtrEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
this.encoder.Encode(unsafe.Pointer(&ptr), stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *onePtrEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error) {
|
||||||
|
if encoderMapJson, ok := this.encoder.(core.IEncoderMapJson); !ok {
|
||||||
|
err = fmt.Errorf("encoder %T not support EncodeToMapJson", this.encoder)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
return encoderMapJson.EncodeToMapJson(unsafe.Pointer(&ptr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//错误节点 ------------------------------------------------------------------
|
||||||
|
type lazyErrorDecoder struct {
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *lazyErrorDecoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Ptr
|
||||||
|
}
|
||||||
|
func (this *lazyErrorDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if extra.Error() == nil {
|
||||||
|
extra.SetErr(this.err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type lazyErrorEncoder struct {
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *lazyErrorEncoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Ptr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
if ptr == nil {
|
||||||
|
stream.WriteNil()
|
||||||
|
} else if stream.Error() == nil {
|
||||||
|
stream.SetErr(this.err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *lazyErrorEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return false
|
||||||
|
}
|
145
lego/sys/codec/factory/factory_array.go
Normal file
145
lego/sys/codec/factory/factory_array.go
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
package factory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"go_dreamfactory/lego/sys/codec/core"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func decoderOfArray(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
|
||||||
|
arrayType := typ.(*reflect2.UnsafeArrayType)
|
||||||
|
decoder := DecoderOfType(ctx.Append("[arrayElem]"), arrayType.Elem())
|
||||||
|
return &arrayDecoder{ctx.ICodec, arrayType, decoder}
|
||||||
|
}
|
||||||
|
|
||||||
|
func encoderOfArray(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
|
||||||
|
arrayType := typ.(*reflect2.UnsafeArrayType)
|
||||||
|
if arrayType.Len() == 0 {
|
||||||
|
return &emptyArrayEncoder{}
|
||||||
|
}
|
||||||
|
encoder := EncoderOfType(ctx.Append("[arrayElem]"), arrayType.Elem())
|
||||||
|
return &arrayEncoder{ctx.ICodec, arrayType, encoder}
|
||||||
|
}
|
||||||
|
|
||||||
|
//array-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
type arrayEncoder struct {
|
||||||
|
codec core.ICodec
|
||||||
|
arrayType *reflect2.UnsafeArrayType
|
||||||
|
elemEncoder core.IEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *arrayEncoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Array
|
||||||
|
}
|
||||||
|
func (this *arrayEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteArrayStart()
|
||||||
|
elemPtr := unsafe.Pointer(ptr)
|
||||||
|
this.elemEncoder.Encode(elemPtr, stream)
|
||||||
|
for i := 1; i < this.arrayType.Len(); i++ {
|
||||||
|
stream.WriteMemberSplit()
|
||||||
|
elemPtr = this.arrayType.UnsafeGetIndex(ptr, i)
|
||||||
|
this.elemEncoder.Encode(elemPtr, stream)
|
||||||
|
}
|
||||||
|
stream.WriteArrayEnd()
|
||||||
|
if stream.Error() != nil && stream.Error() != io.EOF {
|
||||||
|
stream.SetErr(fmt.Errorf("%v: %s", this.arrayType, stream.Error().Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
//编码对象到json数组
|
||||||
|
func (this *arrayEncoder) EncodeToSliceJson(ptr unsafe.Pointer) (ret []string, err error) {
|
||||||
|
ret = make([]string, this.arrayType.Len())
|
||||||
|
stream := this.codec.BorrowStream()
|
||||||
|
for i := 1; i < this.arrayType.Len(); i++ {
|
||||||
|
elemPtr := this.arrayType.UnsafeGetIndex(ptr, i)
|
||||||
|
this.elemEncoder.Encode(elemPtr, stream)
|
||||||
|
if stream.Error() != nil && stream.Error() != io.EOF {
|
||||||
|
err = stream.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret[i] = BytesToString(stream.Buffer())
|
||||||
|
stream.Reset(512)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type arrayDecoder struct {
|
||||||
|
codec core.ICodec
|
||||||
|
arrayType *reflect2.UnsafeArrayType
|
||||||
|
elemDecoder core.IDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *arrayDecoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Array
|
||||||
|
}
|
||||||
|
func (this *arrayDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
arrayType := this.arrayType
|
||||||
|
if extra.ReadNil() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if extra.ReadArrayStart() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if extra.CheckNextIsArrayEnd() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
elemPtr := arrayType.UnsafeGetIndex(ptr, 0)
|
||||||
|
this.elemDecoder.Decode(elemPtr, extra)
|
||||||
|
length := 1
|
||||||
|
for extra.ReadMemberSplit() {
|
||||||
|
idx := length
|
||||||
|
length += 1
|
||||||
|
elemPtr = arrayType.UnsafeGetIndex(ptr, idx)
|
||||||
|
this.elemDecoder.Decode(elemPtr, extra)
|
||||||
|
}
|
||||||
|
if extra.ReadArrayEnd() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if extra.Error() != nil && extra.Error() != io.EOF {
|
||||||
|
extra.SetErr(fmt.Errorf("%v: %s", this.arrayType, extra.Error().Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *arrayDecoder) DecodeForSliceJson(ptr unsafe.Pointer, data []string) (err error) {
|
||||||
|
arrayType := this.arrayType
|
||||||
|
if data == nil {
|
||||||
|
err = errors.New("extra is nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
extra := this.codec.BorrowExtractor([]byte{})
|
||||||
|
arrayType.UnsafeGetIndex(ptr, len(data))
|
||||||
|
for i, v := range data {
|
||||||
|
elemPtr := arrayType.UnsafeGetIndex(ptr, i)
|
||||||
|
extra.ResetBytes(StringToBytes(v))
|
||||||
|
this.elemDecoder.Decode(elemPtr, extra)
|
||||||
|
if extra.Error() != nil && extra.Error() != io.EOF {
|
||||||
|
err = extra.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type emptyArrayEncoder struct{}
|
||||||
|
|
||||||
|
func (this *emptyArrayEncoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Array
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteEmptyArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return true
|
||||||
|
}
|
83
lego/sys/codec/factory/factory_interface.go
Normal file
83
lego/sys/codec/factory/factory_interface.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package factory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"go_dreamfactory/lego/sys/codec/core"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type dynamicEncoder struct {
|
||||||
|
valType reflect2.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *dynamicEncoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Interface
|
||||||
|
}
|
||||||
|
func (encoder *dynamicEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
obj := encoder.valType.UnsafeIndirect(ptr)
|
||||||
|
stream.WriteVal(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return encoder.valType.UnsafeIndirect(ptr) == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type efaceDecoder struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *efaceDecoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Interface
|
||||||
|
}
|
||||||
|
func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
pObj := (*interface{})(ptr)
|
||||||
|
obj := *pObj
|
||||||
|
if obj == nil {
|
||||||
|
*pObj = extra.Read()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
typ := reflect2.TypeOf(obj)
|
||||||
|
if typ.Kind() != reflect.Ptr {
|
||||||
|
*pObj = extra.Read()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ptrType := typ.(*reflect2.UnsafePtrType)
|
||||||
|
ptrElemType := ptrType.Elem()
|
||||||
|
if extra.WhatIsNext() == core.NilValue {
|
||||||
|
if ptrElemType.Kind() != reflect.Ptr {
|
||||||
|
extra.ReadNil()
|
||||||
|
*pObj = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if reflect2.IsNil(obj) {
|
||||||
|
obj := ptrElemType.New()
|
||||||
|
extra.ReadVal(obj)
|
||||||
|
*pObj = obj
|
||||||
|
return
|
||||||
|
}
|
||||||
|
extra.ReadVal(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ifaceDecoder struct {
|
||||||
|
valType *reflect2.UnsafeIFaceType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *ifaceDecoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Interface
|
||||||
|
}
|
||||||
|
func (decoder *ifaceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if extra.ReadNil() {
|
||||||
|
decoder.valType.UnsafeSet(ptr, decoder.valType.UnsafeNew())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
obj := decoder.valType.UnsafeIndirect(ptr)
|
||||||
|
if reflect2.IsNil(obj) {
|
||||||
|
extra.SetErr(errors.New("decode non empty interface can not unmarshal into nil"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
extra.ReadVal(obj)
|
||||||
|
}
|
273
lego/sys/codec/factory/factory_map.go
Normal file
273
lego/sys/codec/factory/factory_map.go
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
package factory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"go_dreamfactory/lego/sys/codec/core"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func decoderOfMap(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
|
||||||
|
mapType := typ.(*reflect2.UnsafeMapType)
|
||||||
|
keyDecoder := decoderOfMapKey(ctx.Append("[mapKey]"), mapType.Key())
|
||||||
|
elemDecoder := DecoderOfType(ctx.Append("[mapElem]"), mapType.Elem())
|
||||||
|
return &mapDecoder{
|
||||||
|
codec: ctx.ICodec,
|
||||||
|
mapType: mapType,
|
||||||
|
keyType: mapType.Key(),
|
||||||
|
elemType: mapType.Elem(),
|
||||||
|
keyDecoder: keyDecoder,
|
||||||
|
elemDecoder: elemDecoder,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func encoderOfMap(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
|
||||||
|
mapType := typ.(*reflect2.UnsafeMapType)
|
||||||
|
return &mapEncoder{
|
||||||
|
codec: ctx.ICodec,
|
||||||
|
mapType: mapType,
|
||||||
|
keyEncoder: encoderOfMapKey(ctx.Append("[mapKey]"), mapType.Key()),
|
||||||
|
elemEncoder: EncoderOfType(ctx.Append("[mapElem]"), mapType.Elem()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func decoderOfMapKey(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
|
||||||
|
switch typ.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
return DecoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
|
||||||
|
case reflect.Bool,
|
||||||
|
reflect.Uint8, reflect.Int8,
|
||||||
|
reflect.Uint16, reflect.Int16,
|
||||||
|
reflect.Uint32, reflect.Int32,
|
||||||
|
reflect.Uint64, reflect.Int64,
|
||||||
|
reflect.Uint, reflect.Int,
|
||||||
|
reflect.Float32, reflect.Float64,
|
||||||
|
reflect.Uintptr:
|
||||||
|
typ = reflect2.DefaultTypeOfKind(typ.Kind())
|
||||||
|
return &numericMapKeyDecoder{DecoderOfType(ctx, typ)}
|
||||||
|
default:
|
||||||
|
return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func encoderOfMapKey(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
|
||||||
|
switch typ.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
return EncoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
|
||||||
|
case reflect.Bool,
|
||||||
|
reflect.Uint8, reflect.Int8,
|
||||||
|
reflect.Uint16, reflect.Int16,
|
||||||
|
reflect.Uint32, reflect.Int32,
|
||||||
|
reflect.Uint64, reflect.Int64,
|
||||||
|
reflect.Uint, reflect.Int,
|
||||||
|
reflect.Float32, reflect.Float64,
|
||||||
|
reflect.Uintptr:
|
||||||
|
typ = reflect2.DefaultTypeOfKind(typ.Kind())
|
||||||
|
return &numericMapKeyEncoder{EncoderOfType(ctx, typ)}
|
||||||
|
default:
|
||||||
|
if typ.Kind() == reflect.Interface {
|
||||||
|
return &dynamicMapKeyEncoder{ctx, typ}
|
||||||
|
}
|
||||||
|
return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Map--------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
type mapEncoder struct {
|
||||||
|
codec core.ICodec
|
||||||
|
mapType *reflect2.UnsafeMapType
|
||||||
|
keyEncoder core.IEncoder
|
||||||
|
elemEncoder core.IEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *mapEncoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Map
|
||||||
|
}
|
||||||
|
func (this *mapEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
if *(*unsafe.Pointer)(ptr) == nil {
|
||||||
|
stream.WriteNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
stream.WriteObjectStart()
|
||||||
|
iter := this.mapType.UnsafeIterate(ptr)
|
||||||
|
for i := 0; iter.HasNext(); i++ {
|
||||||
|
if i != 0 {
|
||||||
|
stream.WriteMemberSplit()
|
||||||
|
}
|
||||||
|
key, elem := iter.UnsafeNext()
|
||||||
|
this.keyEncoder.Encode(key, stream)
|
||||||
|
stream.WriteKVSplit()
|
||||||
|
this.elemEncoder.Encode(elem, stream)
|
||||||
|
}
|
||||||
|
stream.WriteObjectEnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *mapEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error) {
|
||||||
|
ret = make(map[string]string)
|
||||||
|
keystream := this.codec.BorrowStream()
|
||||||
|
elemstream := this.codec.BorrowStream()
|
||||||
|
iter := this.mapType.UnsafeIterate(ptr)
|
||||||
|
for i := 0; iter.HasNext(); i++ {
|
||||||
|
key, elem := iter.UnsafeNext()
|
||||||
|
this.keyEncoder.Encode(key, keystream)
|
||||||
|
if keystream.Error() != nil && keystream.Error() != io.EOF {
|
||||||
|
err = keystream.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.elemEncoder.Encode(elem, elemstream)
|
||||||
|
if elemstream.Error() != nil && elemstream.Error() != io.EOF {
|
||||||
|
err = elemstream.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret[BytesToString(keystream.Buffer())] = BytesToString(elemstream.Buffer())
|
||||||
|
keystream.Reset(512)
|
||||||
|
elemstream.Reset(512)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
iter := this.mapType.UnsafeIterate(ptr)
|
||||||
|
return !iter.HasNext()
|
||||||
|
}
|
||||||
|
|
||||||
|
type mapDecoder struct {
|
||||||
|
codec core.ICodec
|
||||||
|
mapType *reflect2.UnsafeMapType
|
||||||
|
keyType reflect2.Type
|
||||||
|
elemType reflect2.Type
|
||||||
|
keyDecoder core.IDecoder
|
||||||
|
elemDecoder core.IDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *mapDecoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Map
|
||||||
|
}
|
||||||
|
func (this *mapDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
mapType := this.mapType
|
||||||
|
if extra.ReadNil() {
|
||||||
|
*(*unsafe.Pointer)(ptr) = nil
|
||||||
|
mapType.UnsafeSet(ptr, mapType.UnsafeNew())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if mapType.UnsafeIsNil(ptr) {
|
||||||
|
mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0))
|
||||||
|
}
|
||||||
|
if !extra.ReadObjectStart() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if extra.CheckNextIsObjectEnd() {
|
||||||
|
extra.ReadObjectEnd()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
key := this.keyType.UnsafeNew()
|
||||||
|
this.keyDecoder.Decode(key, extra)
|
||||||
|
if !extra.ReadKVSplit() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
elem := this.elemType.UnsafeNew()
|
||||||
|
this.elemDecoder.Decode(elem, extra)
|
||||||
|
this.mapType.UnsafeSetIndex(ptr, key, elem)
|
||||||
|
for extra.ReadMemberSplit() {
|
||||||
|
key := this.keyType.UnsafeNew()
|
||||||
|
this.keyDecoder.Decode(key, extra)
|
||||||
|
if !extra.ReadKVSplit() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
elem := this.elemType.UnsafeNew()
|
||||||
|
this.elemDecoder.Decode(elem, extra)
|
||||||
|
this.mapType.UnsafeSetIndex(ptr, key, elem)
|
||||||
|
}
|
||||||
|
extra.ReadObjectEnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
//解码对象从MapJson 中
|
||||||
|
func (this *mapDecoder) DecodeForMapJson(ptr unsafe.Pointer, extra map[string]string) (err error) {
|
||||||
|
keyext := this.codec.BorrowExtractor([]byte{})
|
||||||
|
elemext := this.codec.BorrowExtractor([]byte{})
|
||||||
|
for k, v := range extra {
|
||||||
|
key := this.keyType.UnsafeNew()
|
||||||
|
if this.keyDecoder.GetType() != reflect.String {
|
||||||
|
keyext.ResetBytes(StringToBytes(k))
|
||||||
|
this.keyDecoder.Decode(key, keyext)
|
||||||
|
if keyext.Error() != nil && keyext.Error() != io.EOF {
|
||||||
|
err = keyext.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*((*string)(key)) = k
|
||||||
|
}
|
||||||
|
elem := this.elemType.UnsafeNew()
|
||||||
|
if this.elemDecoder.GetType() != reflect.String {
|
||||||
|
elemext.ResetBytes(StringToBytes(v))
|
||||||
|
this.elemDecoder.Decode(elem, elemext)
|
||||||
|
this.mapType.UnsafeSetIndex(ptr, key, elem)
|
||||||
|
if elemext.Error() != nil && elemext.Error() != io.EOF {
|
||||||
|
err = elemext.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*((*string)(elem)) = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//NumericMap-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
type numericMapKeyDecoder struct {
|
||||||
|
decoder core.IDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *numericMapKeyDecoder) GetType() reflect.Kind {
|
||||||
|
return this.decoder.GetType()
|
||||||
|
}
|
||||||
|
func (this *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if extra.ReadKeyStart() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.decoder.Decode(ptr, extra)
|
||||||
|
if extra.ReadKeyEnd() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type numericMapKeyEncoder struct {
|
||||||
|
encoder core.IEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *numericMapKeyEncoder) GetType() reflect.Kind {
|
||||||
|
return this.encoder.GetType()
|
||||||
|
}
|
||||||
|
func (this *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteKeyStart()
|
||||||
|
this.encoder.Encode(ptr, stream)
|
||||||
|
stream.WriteKeyEnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------------------------
|
||||||
|
type dynamicMapKeyEncoder struct {
|
||||||
|
ctx *core.Ctx
|
||||||
|
valType reflect2.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *dynamicMapKeyEncoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Interface
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
obj := this.valType.UnsafeIndirect(ptr)
|
||||||
|
encoderOfMapKey(this.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
obj := this.valType.UnsafeIndirect(ptr)
|
||||||
|
return encoderOfMapKey(this.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj))
|
||||||
|
}
|
434
lego/sys/codec/factory/factory_native.go
Normal file
434
lego/sys/codec/factory/factory_native.go
Normal file
@ -0,0 +1,434 @@
|
|||||||
|
package factory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"go_dreamfactory/lego/sys/codec/core"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ptrSize = 32 << uintptr(^uintptr(0)>>63) //计算int的大小 是32 还是64
|
||||||
|
|
||||||
|
func createDecoderOfNative(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
|
||||||
|
typeName := typ.String()
|
||||||
|
switch typ.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
if typeName != "string" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &stringCodec{}
|
||||||
|
case reflect.Int:
|
||||||
|
if typeName != "int" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
|
||||||
|
}
|
||||||
|
if strconv.IntSize == 32 {
|
||||||
|
return &int32Codec{}
|
||||||
|
}
|
||||||
|
return &int64Codec{}
|
||||||
|
case reflect.Int8:
|
||||||
|
if typeName != "int8" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &int8Codec{}
|
||||||
|
case reflect.Int16:
|
||||||
|
if typeName != "int16" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &int16Codec{}
|
||||||
|
case reflect.Int32:
|
||||||
|
if typeName != "int32" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &int32Codec{}
|
||||||
|
case reflect.Int64:
|
||||||
|
if typeName != "int64" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &int64Codec{}
|
||||||
|
case reflect.Uint:
|
||||||
|
if typeName != "uint" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
|
||||||
|
}
|
||||||
|
if strconv.IntSize == 32 {
|
||||||
|
return &uint32Codec{}
|
||||||
|
}
|
||||||
|
return &uint64Codec{}
|
||||||
|
case reflect.Uint8:
|
||||||
|
if typeName != "uint8" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &uint8Codec{}
|
||||||
|
case reflect.Uint16:
|
||||||
|
if typeName != "uint16" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &uint16Codec{}
|
||||||
|
case reflect.Uint32:
|
||||||
|
if typeName != "uint32" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &uint32Codec{}
|
||||||
|
case reflect.Uintptr:
|
||||||
|
if typeName != "uintptr" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
|
||||||
|
}
|
||||||
|
if ptrSize == 32 {
|
||||||
|
return &uint32Codec{}
|
||||||
|
}
|
||||||
|
return &uint64Codec{}
|
||||||
|
case reflect.Uint64:
|
||||||
|
if typeName != "uint64" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &uint64Codec{}
|
||||||
|
case reflect.Float32:
|
||||||
|
if typeName != "float32" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &float32Codec{}
|
||||||
|
case reflect.Float64:
|
||||||
|
if typeName != "float64" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &float64Codec{}
|
||||||
|
case reflect.Bool:
|
||||||
|
if typeName != "bool" {
|
||||||
|
return DecoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &boolCodec{}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createEncoderOfNative(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
|
||||||
|
typeName := typ.String()
|
||||||
|
kind := typ.Kind()
|
||||||
|
switch kind {
|
||||||
|
case reflect.String:
|
||||||
|
if typeName != "string" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &stringCodec{}
|
||||||
|
case reflect.Int:
|
||||||
|
if typeName != "int" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
|
||||||
|
}
|
||||||
|
if strconv.IntSize == 32 {
|
||||||
|
return &int32Codec{}
|
||||||
|
}
|
||||||
|
return &int64Codec{}
|
||||||
|
case reflect.Int8:
|
||||||
|
if typeName != "int8" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &int8Codec{}
|
||||||
|
case reflect.Int16:
|
||||||
|
if typeName != "int16" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &int16Codec{}
|
||||||
|
case reflect.Int32:
|
||||||
|
if typeName != "int32" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &int32Codec{}
|
||||||
|
case reflect.Int64:
|
||||||
|
if typeName != "int64" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &int64Codec{}
|
||||||
|
case reflect.Uint:
|
||||||
|
if typeName != "uint" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
|
||||||
|
}
|
||||||
|
if strconv.IntSize == 32 {
|
||||||
|
return &uint32Codec{}
|
||||||
|
}
|
||||||
|
return &uint64Codec{}
|
||||||
|
case reflect.Uint8:
|
||||||
|
if typeName != "uint8" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &uint8Codec{}
|
||||||
|
case reflect.Uint16:
|
||||||
|
if typeName != "uint16" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &uint16Codec{}
|
||||||
|
case reflect.Uint32:
|
||||||
|
if typeName != "uint32" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &uint32Codec{}
|
||||||
|
case reflect.Uintptr:
|
||||||
|
if typeName != "uintptr" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
|
||||||
|
}
|
||||||
|
if ptrSize == 32 {
|
||||||
|
return &uint32Codec{}
|
||||||
|
}
|
||||||
|
return &uint64Codec{}
|
||||||
|
case reflect.Uint64:
|
||||||
|
if typeName != "uint64" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &uint64Codec{}
|
||||||
|
case reflect.Float32:
|
||||||
|
if typeName != "float32" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &float32Codec{}
|
||||||
|
case reflect.Float64:
|
||||||
|
if typeName != "float64" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &float64Codec{}
|
||||||
|
case reflect.Bool:
|
||||||
|
if typeName != "bool" {
|
||||||
|
return EncoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem())
|
||||||
|
}
|
||||||
|
return &boolCodec{}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type stringCodec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *stringCodec) GetType() reflect.Kind {
|
||||||
|
return reflect.String
|
||||||
|
}
|
||||||
|
func (codec *stringCodec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
*((*string)(ptr)) = extra.ReadString()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
str := *((*string)(ptr))
|
||||||
|
stream.WriteString(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*string)(ptr)) == ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type int8Codec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *int8Codec) GetType() reflect.Kind {
|
||||||
|
return reflect.Int8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *int8Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if !extra.ReadNil() {
|
||||||
|
*((*int8)(ptr)) = extra.ReadInt8()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteInt8(*((*int8)(ptr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*int8)(ptr)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type int16Codec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *int16Codec) GetType() reflect.Kind {
|
||||||
|
return reflect.Int16
|
||||||
|
}
|
||||||
|
func (codec *int16Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if !extra.ReadNil() {
|
||||||
|
*((*int16)(ptr)) = extra.ReadInt16()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteInt16(*((*int16)(ptr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*int16)(ptr)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type int32Codec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *int32Codec) GetType() reflect.Kind {
|
||||||
|
return reflect.Int32
|
||||||
|
}
|
||||||
|
func (codec *int32Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if !extra.ReadNil() {
|
||||||
|
*((*int32)(ptr)) = extra.ReadInt32()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteInt32(*((*int32)(ptr)))
|
||||||
|
}
|
||||||
|
func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*int32)(ptr)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type int64Codec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *int64Codec) GetType() reflect.Kind {
|
||||||
|
return reflect.Int64
|
||||||
|
}
|
||||||
|
func (codec *int64Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if !extra.ReadNil() {
|
||||||
|
*((*int64)(ptr)) = extra.ReadInt64()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteInt64(*((*int64)(ptr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*int64)(ptr)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type uint8Codec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *uint8Codec) GetType() reflect.Kind {
|
||||||
|
return reflect.Uint8
|
||||||
|
}
|
||||||
|
func (codec *uint8Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if !extra.ReadNil() {
|
||||||
|
*((*uint8)(ptr)) = extra.ReadUint8()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteUint8(*((*uint8)(ptr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*uint8)(ptr)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type uint16Codec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *uint16Codec) GetType() reflect.Kind {
|
||||||
|
return reflect.Uint16
|
||||||
|
}
|
||||||
|
func (codec *uint16Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if !extra.ReadNil() {
|
||||||
|
*((*uint16)(ptr)) = extra.ReadUint16()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteUint16(*((*uint16)(ptr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*uint16)(ptr)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type uint32Codec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *uint32Codec) GetType() reflect.Kind {
|
||||||
|
return reflect.Uint32
|
||||||
|
}
|
||||||
|
func (codec *uint32Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if !extra.ReadNil() {
|
||||||
|
*((*uint32)(ptr)) = extra.ReadUint32()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteUint32(*((*uint32)(ptr)))
|
||||||
|
}
|
||||||
|
func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*uint32)(ptr)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type uint64Codec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *uint64Codec) GetType() reflect.Kind {
|
||||||
|
return reflect.Uint64
|
||||||
|
}
|
||||||
|
func (codec *uint64Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if !extra.ReadNil() {
|
||||||
|
*((*uint64)(ptr)) = extra.ReadUint64()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteUint64(*((*uint64)(ptr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*uint64)(ptr)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type float32Codec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *float32Codec) GetType() reflect.Kind {
|
||||||
|
return reflect.Float32
|
||||||
|
}
|
||||||
|
func (codec *float32Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if !extra.ReadNil() {
|
||||||
|
*((*float32)(ptr)) = extra.ReadFloat32()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteFloat32(*((*float32)(ptr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*float32)(ptr)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type float64Codec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *float64Codec) GetType() reflect.Kind {
|
||||||
|
return reflect.Float64
|
||||||
|
}
|
||||||
|
func (codec *float64Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if !extra.ReadNil() {
|
||||||
|
*((*float64)(ptr)) = extra.ReadFloat64()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteFloat64(*((*float64)(ptr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*float64)(ptr)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type boolCodec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *boolCodec) GetType() reflect.Kind {
|
||||||
|
return reflect.Bool
|
||||||
|
}
|
||||||
|
func (codec *boolCodec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if !extra.ReadNil() {
|
||||||
|
*((*bool)(ptr)) = extra.ReadBool()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteBool(*((*bool)(ptr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return !(*((*bool)(ptr)))
|
||||||
|
}
|
167
lego/sys/codec/factory/factory_optional.go
Normal file
167
lego/sys/codec/factory/factory_optional.go
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
package factory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"go_dreamfactory/lego/sys/codec/core"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func decoderOfOptional(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
|
||||||
|
ptrType := typ.(*reflect2.UnsafePtrType)
|
||||||
|
elemType := ptrType.Elem()
|
||||||
|
decoder := DecoderOfType(ctx, elemType)
|
||||||
|
return &OptionalDecoder{elemType, decoder}
|
||||||
|
}
|
||||||
|
|
||||||
|
func encoderOfOptional(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
|
||||||
|
ptrType := typ.(*reflect2.UnsafePtrType)
|
||||||
|
elemType := ptrType.Elem()
|
||||||
|
elemEncoder := EncoderOfType(ctx, elemType)
|
||||||
|
encoder := &OptionalEncoder{elemEncoder}
|
||||||
|
return encoder
|
||||||
|
}
|
||||||
|
|
||||||
|
//Optional--------------------------------------------------------------------------------------------------------------------
|
||||||
|
type OptionalDecoder struct {
|
||||||
|
ValueType reflect2.Type
|
||||||
|
ValueDecoder core.IDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *OptionalDecoder) GetType() reflect.Kind {
|
||||||
|
return this.ValueDecoder.GetType()
|
||||||
|
}
|
||||||
|
func (this *OptionalDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if extra.ReadNil() {
|
||||||
|
*((*unsafe.Pointer)(ptr)) = nil
|
||||||
|
} else {
|
||||||
|
if *((*unsafe.Pointer)(ptr)) == nil {
|
||||||
|
newPtr := this.ValueType.UnsafeNew()
|
||||||
|
this.ValueDecoder.Decode(newPtr, extra)
|
||||||
|
*((*unsafe.Pointer)(ptr)) = newPtr
|
||||||
|
} else {
|
||||||
|
this.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), extra)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *OptionalDecoder) DecodeForMapJson(ptr unsafe.Pointer, extra map[string]string) (err error) {
|
||||||
|
if decoderMapJson, ok := this.ValueDecoder.(core.IDecoderMapJson); !ok {
|
||||||
|
err = fmt.Errorf("encoder %T not support EncodeToMapJson", this.ValueDecoder)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
return decoderMapJson.DecodeForMapJson(ptr, extra)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type OptionalEncoder struct {
|
||||||
|
ValueEncoder core.IEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *OptionalEncoder) GetType() reflect.Kind {
|
||||||
|
return this.ValueEncoder.GetType()
|
||||||
|
}
|
||||||
|
func (this *OptionalEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
if *((*unsafe.Pointer)(ptr)) == nil {
|
||||||
|
stream.WriteNil()
|
||||||
|
} else {
|
||||||
|
this.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*unsafe.Pointer)(ptr)) == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *OptionalEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error) {
|
||||||
|
if encoderMapJson, ok := this.ValueEncoder.(core.IEncoderMapJson); !ok {
|
||||||
|
err = fmt.Errorf("encoder %T not support EncodeToMapJson", this.ValueEncoder)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
if *((*unsafe.Pointer)(ptr)) == nil {
|
||||||
|
err = fmt.Errorf("encoder ptr is nil")
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
return encoderMapJson.EncodeToMapJson(*((*unsafe.Pointer)(ptr)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//reference--------------------------------------------------------------------------------------------------------------------
|
||||||
|
type referenceEncoder struct {
|
||||||
|
encoder core.IEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *referenceEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
this.encoder.Encode(unsafe.Pointer(&ptr), stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return this.encoder.IsEmpty(unsafe.Pointer(&ptr))
|
||||||
|
}
|
||||||
|
|
||||||
|
type referenceDecoder struct {
|
||||||
|
decoder core.IDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *referenceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
this.decoder.Decode(unsafe.Pointer(&ptr), extra)
|
||||||
|
}
|
||||||
|
|
||||||
|
//dereference--------------------------------------------------------------------------------------------------------------------
|
||||||
|
type dereferenceDecoder struct {
|
||||||
|
valueType reflect2.Type
|
||||||
|
valueDecoder core.IDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *dereferenceDecoder) GetType() reflect.Kind {
|
||||||
|
return this.valueDecoder.GetType()
|
||||||
|
}
|
||||||
|
func (this *dereferenceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if *((*unsafe.Pointer)(ptr)) == nil {
|
||||||
|
newPtr := this.valueType.UnsafeNew()
|
||||||
|
this.valueDecoder.Decode(newPtr, extra)
|
||||||
|
*((*unsafe.Pointer)(ptr)) = newPtr
|
||||||
|
} else {
|
||||||
|
this.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), extra)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type dereferenceEncoder struct {
|
||||||
|
ValueEncoder core.IEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *dereferenceEncoder) GetType() reflect.Kind {
|
||||||
|
return this.ValueEncoder.GetType()
|
||||||
|
}
|
||||||
|
func (this *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
if *((*unsafe.Pointer)(ptr)) == nil {
|
||||||
|
stream.WriteNil()
|
||||||
|
} else {
|
||||||
|
this.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
dePtr := *((*unsafe.Pointer)(ptr))
|
||||||
|
if dePtr == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return this.ValueEncoder.IsEmpty(dePtr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
|
||||||
|
deReferenced := *((*unsafe.Pointer)(ptr))
|
||||||
|
if deReferenced == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
isEmbeddedPtrNil, converted := this.ValueEncoder.(core.IsEmbeddedPtrNil)
|
||||||
|
if !converted {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
fieldPtr := unsafe.Pointer(deReferenced)
|
||||||
|
return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
|
||||||
|
}
|
146
lego/sys/codec/factory/factory_slice.go
Normal file
146
lego/sys/codec/factory/factory_slice.go
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
package factory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"go_dreamfactory/lego/sys/codec/core"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func decoderOfSlice(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
|
||||||
|
sliceType := typ.(*reflect2.UnsafeSliceType)
|
||||||
|
decoder := DecoderOfType(ctx.Append("[sliceElem]"), sliceType.Elem())
|
||||||
|
return &sliceDecoder{ctx.ICodec, sliceType, decoder}
|
||||||
|
}
|
||||||
|
func encoderOfSlice(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
|
||||||
|
sliceType := typ.(*reflect2.UnsafeSliceType)
|
||||||
|
encoder := EncoderOfType(ctx.Append("[sliceElem]"), sliceType.Elem())
|
||||||
|
return &sliceEncoder{ctx.ICodec, sliceType, encoder}
|
||||||
|
}
|
||||||
|
|
||||||
|
type sliceEncoder struct {
|
||||||
|
codec core.ICodec
|
||||||
|
sliceType *reflect2.UnsafeSliceType
|
||||||
|
elemEncoder core.IEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *sliceEncoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Slice
|
||||||
|
}
|
||||||
|
func (this *sliceEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
if this.sliceType.UnsafeIsNil(ptr) {
|
||||||
|
stream.WriteNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
length := this.sliceType.UnsafeLengthOf(ptr)
|
||||||
|
if length == 0 {
|
||||||
|
stream.WriteEmptyArray()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
stream.WriteArrayStart()
|
||||||
|
this.elemEncoder.Encode(this.sliceType.UnsafeGetIndex(ptr, 0), stream)
|
||||||
|
for i := 1; i < length; i++ {
|
||||||
|
stream.WriteMemberSplit()
|
||||||
|
elemPtr := this.sliceType.UnsafeGetIndex(ptr, i)
|
||||||
|
this.elemEncoder.Encode(elemPtr, stream)
|
||||||
|
}
|
||||||
|
stream.WriteArrayEnd()
|
||||||
|
if stream.Error() != nil && stream.Error() != io.EOF {
|
||||||
|
stream.SetErr(fmt.Errorf("%v: %s", this.sliceType, stream.Error().Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return this.sliceType.UnsafeLengthOf(ptr) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
//编码对象到json数组
|
||||||
|
func (this *sliceEncoder) EncodeToSliceJson(ptr unsafe.Pointer) (ret []string, err error) {
|
||||||
|
if this.sliceType.UnsafeIsNil(ptr) {
|
||||||
|
err = errors.New("val is nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
length := this.sliceType.UnsafeLengthOf(ptr)
|
||||||
|
ret = make([]string, length)
|
||||||
|
if length == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
stream := this.codec.BorrowStream()
|
||||||
|
for i := 1; i < length; i++ {
|
||||||
|
elemPtr := this.sliceType.UnsafeGetIndex(ptr, i)
|
||||||
|
this.elemEncoder.Encode(elemPtr, stream)
|
||||||
|
if stream.Error() != nil && stream.Error() != io.EOF {
|
||||||
|
err = stream.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret[i] = BytesToString(stream.Buffer())
|
||||||
|
stream.Reset(512)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type sliceDecoder struct {
|
||||||
|
codec core.ICodec
|
||||||
|
sliceType *reflect2.UnsafeSliceType
|
||||||
|
elemDecoder core.IDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *sliceDecoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Slice
|
||||||
|
}
|
||||||
|
func (this *sliceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
sliceType := this.sliceType
|
||||||
|
if extra.ReadNil() {
|
||||||
|
sliceType.UnsafeSetNil(ptr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !extra.ReadArrayStart() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if extra.CheckNextIsArrayEnd() {
|
||||||
|
sliceType.UnsafeSet(ptr, sliceType.UnsafeMakeSlice(0, 0))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sliceType.UnsafeGrow(ptr, 1)
|
||||||
|
elemPtr := sliceType.UnsafeGetIndex(ptr, 0)
|
||||||
|
this.elemDecoder.Decode(elemPtr, extra)
|
||||||
|
length := 1
|
||||||
|
for extra.ReadMemberSplit() {
|
||||||
|
idx := length
|
||||||
|
length += 1
|
||||||
|
sliceType.UnsafeGrow(ptr, length)
|
||||||
|
elemPtr = sliceType.UnsafeGetIndex(ptr, idx)
|
||||||
|
this.elemDecoder.Decode(elemPtr, extra)
|
||||||
|
}
|
||||||
|
if extra.ReadArrayEnd() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if extra.Error() != nil && extra.Error() != io.EOF {
|
||||||
|
extra.SetErr(fmt.Errorf("%v: %s", this.sliceType, extra.Error().Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *sliceDecoder) DecodeForSliceJson(ptr unsafe.Pointer, data []string) (err error) {
|
||||||
|
sliceType := this.sliceType
|
||||||
|
if data == nil {
|
||||||
|
err = errors.New("extra is nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
extra := this.codec.BorrowExtractor([]byte{})
|
||||||
|
sliceType.UnsafeGrow(ptr, len(data))
|
||||||
|
for i, v := range data {
|
||||||
|
elemPtr := sliceType.UnsafeGetIndex(ptr, i)
|
||||||
|
extra.ResetBytes(StringToBytes(v))
|
||||||
|
this.elemDecoder.Decode(elemPtr, extra)
|
||||||
|
if extra.Error() != nil && extra.Error() != io.EOF {
|
||||||
|
err = extra.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
447
lego/sys/codec/factory/factory_struct.go
Normal file
447
lego/sys/codec/factory/factory_struct.go
Normal file
@ -0,0 +1,447 @@
|
|||||||
|
package factory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"go_dreamfactory/lego/sys/codec/core"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StructDescriptor struct {
|
||||||
|
Type reflect2.Type
|
||||||
|
Fields []*Binding
|
||||||
|
}
|
||||||
|
|
||||||
|
type Binding struct {
|
||||||
|
levels []int
|
||||||
|
Field reflect2.StructField
|
||||||
|
FromNames []string
|
||||||
|
ToNames []string
|
||||||
|
Encoder core.IEncoder
|
||||||
|
Decoder core.IDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func encoderOfStruct(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
|
||||||
|
type bindingTo struct {
|
||||||
|
binding *Binding
|
||||||
|
toName string
|
||||||
|
ignored bool
|
||||||
|
}
|
||||||
|
orderedBindings := []*bindingTo{}
|
||||||
|
structDescriptor := describeStruct(ctx, typ)
|
||||||
|
for _, binding := range structDescriptor.Fields {
|
||||||
|
for _, toName := range binding.ToNames {
|
||||||
|
new := &bindingTo{
|
||||||
|
binding: binding,
|
||||||
|
toName: toName,
|
||||||
|
}
|
||||||
|
for _, old := range orderedBindings {
|
||||||
|
if old.toName != toName {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
old.ignored, new.ignored = resolveConflictBinding(ctx.Options(), old.binding, new.binding)
|
||||||
|
}
|
||||||
|
orderedBindings = append(orderedBindings, new)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(orderedBindings) == 0 {
|
||||||
|
return &emptyStructEncoder{}
|
||||||
|
}
|
||||||
|
finalOrderedFields := []structFieldTo{}
|
||||||
|
for _, bindingTo := range orderedBindings {
|
||||||
|
if !bindingTo.ignored {
|
||||||
|
finalOrderedFields = append(finalOrderedFields, structFieldTo{
|
||||||
|
encoder: bindingTo.binding.Encoder.(*structFieldEncoder),
|
||||||
|
toName: bindingTo.toName,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &structEncoder{ctx.ICodec, typ, finalOrderedFields}
|
||||||
|
}
|
||||||
|
|
||||||
|
func decoderOfStruct(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
|
||||||
|
bindings := map[string]*Binding{}
|
||||||
|
structDescriptor := describeStruct(ctx, typ)
|
||||||
|
for _, binding := range structDescriptor.Fields {
|
||||||
|
for _, fromName := range binding.FromNames {
|
||||||
|
old := bindings[fromName]
|
||||||
|
if old == nil {
|
||||||
|
bindings[fromName] = binding
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ignoreOld, ignoreNew := resolveConflictBinding(ctx.Options(), old, binding)
|
||||||
|
if ignoreOld {
|
||||||
|
delete(bindings, fromName)
|
||||||
|
}
|
||||||
|
if !ignoreNew {
|
||||||
|
bindings[fromName] = binding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fields := map[string]*structFieldDecoder{}
|
||||||
|
for k, binding := range bindings {
|
||||||
|
fields[k] = binding.Decoder.(*structFieldDecoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ctx.Options().CaseSensitive {
|
||||||
|
for k, binding := range bindings {
|
||||||
|
if _, found := fields[strings.ToLower(k)]; !found {
|
||||||
|
fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return createStructDecoder(ctx.ICodec, typ, fields)
|
||||||
|
}
|
||||||
|
|
||||||
|
//结构第编辑码构建
|
||||||
|
func describeStruct(ctx *core.Ctx, typ reflect2.Type) *StructDescriptor {
|
||||||
|
structType := typ.(*reflect2.UnsafeStructType)
|
||||||
|
embeddedBindings := []*Binding{}
|
||||||
|
bindings := []*Binding{}
|
||||||
|
for i := 0; i < structType.NumField(); i++ {
|
||||||
|
field := structType.Field(i)
|
||||||
|
tag, hastag := field.Tag().Lookup(ctx.Options().TagKey)
|
||||||
|
if ctx.Options().OnlyTaggedField && !hastag && !field.Anonymous() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if tag == "-" || field.Name() == "_" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tagParts := strings.Split(tag, ",")
|
||||||
|
if field.Anonymous() && (tag == "" || tagParts[0] == "") {
|
||||||
|
if field.Type().Kind() == reflect.Struct {
|
||||||
|
structDescriptor := describeStruct(ctx, field.Type())
|
||||||
|
for _, binding := range structDescriptor.Fields {
|
||||||
|
binding.levels = append([]int{i}, binding.levels...)
|
||||||
|
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
|
||||||
|
binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty}
|
||||||
|
binding.Decoder = &structFieldDecoder{field, binding.Decoder}
|
||||||
|
embeddedBindings = append(embeddedBindings, binding)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
} else if field.Type().Kind() == reflect.Ptr {
|
||||||
|
ptrType := field.Type().(*reflect2.UnsafePtrType)
|
||||||
|
if ptrType.Elem().Kind() == reflect.Struct {
|
||||||
|
structDescriptor := describeStruct(ctx, ptrType.Elem())
|
||||||
|
for _, binding := range structDescriptor.Fields {
|
||||||
|
binding.levels = append([]int{i}, binding.levels...)
|
||||||
|
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
|
||||||
|
binding.Encoder = &dereferenceEncoder{binding.Encoder}
|
||||||
|
binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty}
|
||||||
|
binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder}
|
||||||
|
binding.Decoder = &structFieldDecoder{field, binding.Decoder}
|
||||||
|
embeddedBindings = append(embeddedBindings, binding)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fieldNames := calcFieldNames(field.Name(), tagParts[0], tag)
|
||||||
|
decoder := DecoderOfType(ctx.Append(field.Name()), field.Type())
|
||||||
|
encoder := EncoderOfType(ctx.Append(field.Name()), field.Type())
|
||||||
|
binding := &Binding{
|
||||||
|
Field: field,
|
||||||
|
FromNames: fieldNames,
|
||||||
|
ToNames: fieldNames,
|
||||||
|
Decoder: decoder,
|
||||||
|
Encoder: encoder,
|
||||||
|
}
|
||||||
|
binding.levels = []int{i}
|
||||||
|
bindings = append(bindings, binding)
|
||||||
|
}
|
||||||
|
return createStructDescriptor(ctx, typ, bindings, embeddedBindings)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createStructDescriptor(ctx *core.Ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
|
||||||
|
structDescriptor := &StructDescriptor{
|
||||||
|
Type: typ,
|
||||||
|
Fields: bindings,
|
||||||
|
}
|
||||||
|
processTags(structDescriptor, ctx.ICodec)
|
||||||
|
allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...))
|
||||||
|
sort.Sort(allBindings)
|
||||||
|
structDescriptor.Fields = allBindings
|
||||||
|
return structDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
func processTags(structDescriptor *StructDescriptor, codec core.ICodec) {
|
||||||
|
for _, binding := range structDescriptor.Fields {
|
||||||
|
shouldOmitEmpty := false
|
||||||
|
tagParts := strings.Split(binding.Field.Tag().Get(codec.Options().TagKey), ",")
|
||||||
|
for _, tagPart := range tagParts[1:] {
|
||||||
|
if tagPart == "omitempty" {
|
||||||
|
shouldOmitEmpty = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder}
|
||||||
|
binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string {
|
||||||
|
// ignore?
|
||||||
|
if wholeTag == "-" {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
// rename?
|
||||||
|
var fieldNames []string
|
||||||
|
if tagProvidedFieldName == "" {
|
||||||
|
fieldNames = []string{originalFieldName}
|
||||||
|
} else {
|
||||||
|
fieldNames = []string{tagProvidedFieldName}
|
||||||
|
}
|
||||||
|
// private?
|
||||||
|
isNotExported := unicode.IsLower(rune(originalFieldName[0])) || originalFieldName[0] == '_'
|
||||||
|
if isNotExported {
|
||||||
|
fieldNames = []string{}
|
||||||
|
}
|
||||||
|
return fieldNames
|
||||||
|
}
|
||||||
|
|
||||||
|
func createStructDecoder(codec core.ICodec, typ reflect2.Type, fields map[string]*structFieldDecoder) core.IDecoder {
|
||||||
|
if codec.Options().DisallowUnknownFields {
|
||||||
|
return &structDecoder{typ: typ, fields: fields, disallowUnknownFields: true}
|
||||||
|
} else {
|
||||||
|
return &structDecoder{codec, typ, fields, false}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveConflictBinding(opt *core.Options, old, new *Binding) (ignoreOld, ignoreNew bool) {
|
||||||
|
newTagged := new.Field.Tag().Get(opt.TagKey) != ""
|
||||||
|
oldTagged := old.Field.Tag().Get(opt.TagKey) != ""
|
||||||
|
if newTagged {
|
||||||
|
if oldTagged {
|
||||||
|
if len(old.levels) > len(new.levels) {
|
||||||
|
return true, false
|
||||||
|
} else if len(new.levels) > len(old.levels) {
|
||||||
|
return false, true
|
||||||
|
} else {
|
||||||
|
return true, true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true, false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if oldTagged {
|
||||||
|
return true, false
|
||||||
|
}
|
||||||
|
if len(old.levels) > len(new.levels) {
|
||||||
|
return true, false
|
||||||
|
} else if len(new.levels) > len(old.levels) {
|
||||||
|
return false, true
|
||||||
|
} else {
|
||||||
|
return true, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//结构对象 编解码-----------------------------------------------------------------------------------------------------------------------
|
||||||
|
type structEncoder struct {
|
||||||
|
codec core.ICodec
|
||||||
|
typ reflect2.Type
|
||||||
|
fields []structFieldTo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *structEncoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Struct
|
||||||
|
}
|
||||||
|
func (this *structEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteObjectStart()
|
||||||
|
isNotFirst := false
|
||||||
|
for _, field := range this.fields {
|
||||||
|
if field.encoder.omitempty && field.encoder.IsEmpty(ptr) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if field.encoder.IsEmbeddedPtrNil(ptr) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if isNotFirst {
|
||||||
|
stream.WriteMemberSplit()
|
||||||
|
}
|
||||||
|
stream.WriteObjectFieldName(field.toName)
|
||||||
|
field.encoder.Encode(ptr, stream)
|
||||||
|
isNotFirst = true
|
||||||
|
}
|
||||||
|
stream.WriteObjectEnd()
|
||||||
|
if stream.Error() != nil && stream.Error() != io.EOF {
|
||||||
|
stream.SetErr(fmt.Errorf("%v.%s", this.typ, stream.Error().Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *structEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error) {
|
||||||
|
ret = make(map[string]string)
|
||||||
|
stream := this.codec.BorrowStream()
|
||||||
|
for _, field := range this.fields {
|
||||||
|
if field.encoder.omitempty && field.encoder.IsEmpty(ptr) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if field.encoder.IsEmbeddedPtrNil(ptr) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
stream.Reset(512)
|
||||||
|
field.encoder.Encode(ptr, stream)
|
||||||
|
if stream.Error() != nil && stream.Error() != io.EOF {
|
||||||
|
err = stream.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret[field.toName] = BytesToString(stream.Buffer())
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *structEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
type structDecoder struct {
|
||||||
|
codec core.ICodec
|
||||||
|
typ reflect2.Type
|
||||||
|
fields map[string]*structFieldDecoder
|
||||||
|
disallowUnknownFields bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *structDecoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Struct
|
||||||
|
}
|
||||||
|
func (this *structDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
if !extra.ReadObjectStart() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.decodeField(ptr, extra)
|
||||||
|
for extra.ReadMemberSplit() {
|
||||||
|
this.decodeField(ptr, extra)
|
||||||
|
}
|
||||||
|
if extra.Error() != nil && extra.Error() != io.EOF && len(this.typ.Type1().Name()) != 0 {
|
||||||
|
extra.SetErr(fmt.Errorf("%v.%s", this.typ, extra.Error().Error()))
|
||||||
|
}
|
||||||
|
extra.ReadObjectEnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *structDecoder) decodeField(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
var field string
|
||||||
|
var fieldDecoder *structFieldDecoder
|
||||||
|
|
||||||
|
field = extra.ReadString()
|
||||||
|
fieldDecoder = this.fields[field]
|
||||||
|
if fieldDecoder == nil && !this.codec.Options().CaseSensitive {
|
||||||
|
fieldDecoder = this.fields[strings.ToLower(field)]
|
||||||
|
}
|
||||||
|
|
||||||
|
if fieldDecoder == nil {
|
||||||
|
if this.disallowUnknownFields {
|
||||||
|
msg := "found unknown field: " + field
|
||||||
|
extra.SetErr(fmt.Errorf("decodeField %s", msg))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !extra.ReadKVSplit() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
extra.Skip() //跳过一个数据单元
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !extra.ReadKVSplit() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fieldDecoder.Decode(ptr, extra)
|
||||||
|
}
|
||||||
|
|
||||||
|
//解码对象从MapJson 中
|
||||||
|
func (this *structDecoder) DecodeForMapJson(ptr unsafe.Pointer, extra map[string]string) (err error) {
|
||||||
|
var fieldDecoder *structFieldDecoder
|
||||||
|
ext := this.codec.BorrowExtractor([]byte{})
|
||||||
|
for k, v := range extra {
|
||||||
|
fieldDecoder = this.fields[k]
|
||||||
|
if fieldDecoder == nil && !this.codec.Options().CaseSensitive {
|
||||||
|
fieldDecoder = this.fields[strings.ToLower(k)]
|
||||||
|
}
|
||||||
|
if fieldDecoder == nil {
|
||||||
|
if this.disallowUnknownFields {
|
||||||
|
err = errors.New("found unknown field: " + k)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ext.ResetBytes(StringToBytes(v))
|
||||||
|
fieldDecoder.Decode(ptr, ext)
|
||||||
|
if ext.Error() != nil && ext.Error() != io.EOF {
|
||||||
|
err = ext.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//结构对象字段 编解码-----------------------------------------------------------------------------------------------------------------------
|
||||||
|
type structFieldTo struct {
|
||||||
|
encoder *structFieldEncoder
|
||||||
|
toName string
|
||||||
|
}
|
||||||
|
type structFieldEncoder struct {
|
||||||
|
field reflect2.StructField
|
||||||
|
fieldEncoder core.IEncoder
|
||||||
|
omitempty bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *structFieldEncoder) GetType() reflect.Kind {
|
||||||
|
return this.fieldEncoder.GetType()
|
||||||
|
}
|
||||||
|
func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
fieldPtr := encoder.field.UnsafeGet(ptr)
|
||||||
|
encoder.fieldEncoder.Encode(fieldPtr, stream)
|
||||||
|
if stream.Error() != nil && stream.Error() != io.EOF {
|
||||||
|
stream.SetErr(fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error().Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
fieldPtr := encoder.field.UnsafeGet(ptr)
|
||||||
|
return encoder.fieldEncoder.IsEmpty(fieldPtr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
|
||||||
|
isEmbeddedPtrNil, converted := encoder.fieldEncoder.(core.IsEmbeddedPtrNil)
|
||||||
|
if !converted {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
fieldPtr := encoder.field.UnsafeGet(ptr)
|
||||||
|
return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
|
||||||
|
}
|
||||||
|
|
||||||
|
type structFieldDecoder struct {
|
||||||
|
field reflect2.StructField
|
||||||
|
fieldDecoder core.IDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *structFieldDecoder) GetType() reflect.Kind {
|
||||||
|
return this.fieldDecoder.GetType()
|
||||||
|
}
|
||||||
|
func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
|
||||||
|
fieldPtr := decoder.field.UnsafeGet(ptr)
|
||||||
|
decoder.fieldDecoder.Decode(fieldPtr, extra)
|
||||||
|
if extra.Error() != nil && extra.Error() != io.EOF {
|
||||||
|
extra.SetErr(fmt.Errorf("%s: %s", decoder.field.Name(), extra.Error().Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Empty-----------------------------------------------------------------------------------------------------------------------
|
||||||
|
type emptyStructEncoder struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *emptyStructEncoder) GetType() reflect.Kind {
|
||||||
|
return reflect.Struct
|
||||||
|
}
|
||||||
|
func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
|
||||||
|
stream.WriteEmptyObject()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return false
|
||||||
|
}
|
36
lego/sys/codec/options.go
Normal file
36
lego/sys/codec/options.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package codec
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go_dreamfactory/lego/sys/codec/core"
|
||||||
|
"go_dreamfactory/lego/sys/log"
|
||||||
|
"go_dreamfactory/lego/utils/mapstructure"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newOptions(config map[string]interface{}, opts ...core.Option) core.Options {
|
||||||
|
options := core.Options{
|
||||||
|
IndentionStep: 2,
|
||||||
|
}
|
||||||
|
if config != nil {
|
||||||
|
mapstructure.Decode(config, &options)
|
||||||
|
}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
if options.Debug && options.Log == nil {
|
||||||
|
options.Log = log.Clone()
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
func newOptionsByOption(opts ...core.Option) core.Options {
|
||||||
|
options := core.Options{
|
||||||
|
IndentionStep: 2,
|
||||||
|
}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
if options.Debug && options.Log == nil {
|
||||||
|
options.Log = log.Clone()
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
45
lego/sys/codec/render/core.go
Normal file
45
lego/sys/codec/render/core.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package render
|
||||||
|
|
||||||
|
import "go_dreamfactory/lego/sys/codec/core"
|
||||||
|
|
||||||
|
const maxDepth = 10000
|
||||||
|
|
||||||
|
var hexDigits []byte
|
||||||
|
var valueTypes []core.ValueType
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
hexDigits = make([]byte, 256)
|
||||||
|
for i := 0; i < len(hexDigits); i++ {
|
||||||
|
hexDigits[i] = 255
|
||||||
|
}
|
||||||
|
for i := '0'; i <= '9'; i++ {
|
||||||
|
hexDigits[i] = byte(i - '0')
|
||||||
|
}
|
||||||
|
for i := 'a'; i <= 'f'; i++ {
|
||||||
|
hexDigits[i] = byte((i - 'a') + 10)
|
||||||
|
}
|
||||||
|
for i := 'A'; i <= 'F'; i++ {
|
||||||
|
hexDigits[i] = byte((i - 'A') + 10)
|
||||||
|
}
|
||||||
|
valueTypes = make([]core.ValueType, 256)
|
||||||
|
for i := 0; i < len(valueTypes); i++ {
|
||||||
|
valueTypes[i] = core.InvalidValue
|
||||||
|
}
|
||||||
|
valueTypes['"'] = core.StringValue
|
||||||
|
valueTypes['-'] = core.NumberValue
|
||||||
|
valueTypes['0'] = core.NumberValue
|
||||||
|
valueTypes['1'] = core.NumberValue
|
||||||
|
valueTypes['2'] = core.NumberValue
|
||||||
|
valueTypes['3'] = core.NumberValue
|
||||||
|
valueTypes['4'] = core.NumberValue
|
||||||
|
valueTypes['5'] = core.NumberValue
|
||||||
|
valueTypes['6'] = core.NumberValue
|
||||||
|
valueTypes['7'] = core.NumberValue
|
||||||
|
valueTypes['8'] = core.NumberValue
|
||||||
|
valueTypes['9'] = core.NumberValue
|
||||||
|
valueTypes['t'] = core.BoolValue
|
||||||
|
valueTypes['f'] = core.BoolValue
|
||||||
|
valueTypes['n'] = core.NilValue
|
||||||
|
valueTypes['['] = core.ArrayValue
|
||||||
|
valueTypes['{'] = core.ObjectValue
|
||||||
|
}
|
823
lego/sys/codec/render/json_extractor.go
Normal file
823
lego/sys/codec/render/json_extractor.go
Normal file
@ -0,0 +1,823 @@
|
|||||||
|
package render
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"go_dreamfactory/lego/sys/codec/core"
|
||||||
|
"go_dreamfactory/lego/sys/codec/utils"
|
||||||
|
"io"
|
||||||
|
"math/big"
|
||||||
|
"reflect"
|
||||||
|
"unicode/utf16"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewExtractor(codec core.ICodec) *JsonExtractor {
|
||||||
|
return &JsonExtractor{
|
||||||
|
codec: codec,
|
||||||
|
buf: nil,
|
||||||
|
head: 0,
|
||||||
|
tail: 0,
|
||||||
|
depth: 0,
|
||||||
|
err: nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type JsonExtractor struct {
|
||||||
|
codec core.ICodec
|
||||||
|
buf []byte
|
||||||
|
head int
|
||||||
|
tail int
|
||||||
|
depth int
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *JsonExtractor) ReadVal(obj interface{}) {
|
||||||
|
depth := this.depth
|
||||||
|
cacheKey := reflect2.RTypeOf(obj)
|
||||||
|
decoder := this.codec.GetDecoderFromCache(cacheKey)
|
||||||
|
if decoder == nil {
|
||||||
|
typ := reflect2.TypeOf(obj)
|
||||||
|
if typ == nil || typ.Kind() != reflect.Ptr {
|
||||||
|
this.reportError("ReadVal", "can only unmarshal into pointer")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
decoder = this.codec.DecoderOf(typ)
|
||||||
|
}
|
||||||
|
ptr := reflect2.PtrOf(obj)
|
||||||
|
if ptr == nil {
|
||||||
|
this.reportError("ReadVal", "can not read into nil pointer")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
decoder.Decode(ptr, this)
|
||||||
|
if this.depth != depth {
|
||||||
|
this.reportError("ReadVal", "unexpected mismatched nesting")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) WhatIsNext() core.ValueType {
|
||||||
|
valueType := valueTypes[this.nextToken()]
|
||||||
|
this.unreadByte()
|
||||||
|
return valueType
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) Read() interface{} {
|
||||||
|
valueType := this.WhatIsNext()
|
||||||
|
switch valueType {
|
||||||
|
case core.StringValue:
|
||||||
|
return this.ReadString()
|
||||||
|
case core.NumberValue:
|
||||||
|
return this.ReadFloat64()
|
||||||
|
case core.NilValue:
|
||||||
|
this.skipFourBytes('n', 'u', 'l', 'l')
|
||||||
|
return nil
|
||||||
|
case core.BoolValue:
|
||||||
|
return this.ReadBool()
|
||||||
|
case core.ArrayValue:
|
||||||
|
arr := []interface{}{}
|
||||||
|
this.ReadArrayCB(func(extra core.IExtractor) bool {
|
||||||
|
var elem interface{}
|
||||||
|
extra.ReadVal(&elem)
|
||||||
|
arr = append(arr, elem)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return arr
|
||||||
|
case core.ObjectValue:
|
||||||
|
obj := map[string]interface{}{}
|
||||||
|
this.ReadMapCB(func(extra core.IExtractor, field string) bool {
|
||||||
|
var elem interface{}
|
||||||
|
this.ReadVal(&elem)
|
||||||
|
obj[field] = elem
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return obj
|
||||||
|
default:
|
||||||
|
this.reportError("Read", fmt.Sprintf("unexpected value type: %v", valueType))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadNil() (ret bool) {
|
||||||
|
c := this.nextToken()
|
||||||
|
if c == 'n' {
|
||||||
|
this.skipThreeBytes('u', 'l', 'l') // null
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
this.unreadByte()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadArrayStart() (ret bool) {
|
||||||
|
c := this.nextToken()
|
||||||
|
if c == '[' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
this.reportError("ReadArrayStart", `expect [ but found `+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) CheckNextIsArrayEnd() (ret bool) {
|
||||||
|
c := this.nextToken()
|
||||||
|
this.unreadByte()
|
||||||
|
if c == ']' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadArrayEnd() (ret bool) {
|
||||||
|
c := this.nextToken()
|
||||||
|
if c == ']' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
this.reportError("ReadArrayEnd", `expect ] but found `+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadObjectStart() (ret bool) {
|
||||||
|
c := this.nextToken()
|
||||||
|
if c == '{' {
|
||||||
|
return this.incrementDepth()
|
||||||
|
}
|
||||||
|
this.reportError("ReadObjectStart", `expect { but found `+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) CheckNextIsObjectEnd() (ret bool) {
|
||||||
|
c := this.nextToken()
|
||||||
|
this.unreadByte()
|
||||||
|
if c == '}' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadObjectEnd() (ret bool) {
|
||||||
|
c := this.nextToken()
|
||||||
|
if c == '}' {
|
||||||
|
return this.decrementDepth()
|
||||||
|
}
|
||||||
|
this.reportError("ReadObjectEnd", `expect } but found `+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadMemberSplit() (ret bool) {
|
||||||
|
c := this.nextToken()
|
||||||
|
if c == ',' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
this.unreadByte()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadKVSplit() (ret bool) {
|
||||||
|
c := this.nextToken()
|
||||||
|
if c == ':' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
this.reportError("ReadKVSplit", `expect : but found `+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadKeyStart() (ret bool) {
|
||||||
|
c := this.nextToken()
|
||||||
|
if c == '"' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
this.reportError("ReadKeyStart", `expect " but found `+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadKeyEnd() (ret bool) {
|
||||||
|
c := this.nextToken()
|
||||||
|
if c == '"' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
this.reportError("ReadKeyEnd", `expect " but found `+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) Skip() {
|
||||||
|
c := this.nextToken()
|
||||||
|
switch c {
|
||||||
|
case '"':
|
||||||
|
this.skipString()
|
||||||
|
case 'n':
|
||||||
|
this.skipThreeBytes('u', 'l', 'l') // null
|
||||||
|
case 't':
|
||||||
|
this.skipThreeBytes('r', 'u', 'e') // true
|
||||||
|
case 'f':
|
||||||
|
this.skipFourBytes('a', 'l', 's', 'e') // false
|
||||||
|
case '0':
|
||||||
|
this.unreadByte()
|
||||||
|
this.ReadFloat32()
|
||||||
|
case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
|
this.skipNumber()
|
||||||
|
case '[':
|
||||||
|
this.skipArray()
|
||||||
|
case '{':
|
||||||
|
this.skipObject()
|
||||||
|
default:
|
||||||
|
this.reportError("Skip", fmt.Sprintf("do not know how to skip: %v", c))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadBool() (ret bool) {
|
||||||
|
c := this.nextToken()
|
||||||
|
if c == 't' {
|
||||||
|
this.skipThreeBytes('r', 'u', 'e')
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if c == 'f' {
|
||||||
|
this.skipFourBytes('a', 'l', 's', 'e')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
this.reportError("ReadBool", "expect t or f, but found "+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadInt8() (ret int8) {
|
||||||
|
var (
|
||||||
|
n int
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if ret, n, err = utils.ReadInt8ForString(this.buf[this.head:]); err != nil {
|
||||||
|
this.reportError("ReadInt8", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.head += n
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadInt16() (ret int16) {
|
||||||
|
var (
|
||||||
|
n int
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if ret, n, err = utils.ReadInt16ForString(this.buf[this.head:]); err != nil {
|
||||||
|
this.reportError("ReadInt32", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.head += n
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadInt32() (ret int32) {
|
||||||
|
var (
|
||||||
|
n int
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if ret, n, err = utils.ReadInt32ForString(this.buf[this.head:]); err != nil {
|
||||||
|
this.reportError("ReadInt32", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.head += n
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadInt64() (ret int64) {
|
||||||
|
var (
|
||||||
|
n int
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if ret, n, err = utils.ReadInt64ForString(this.buf[this.head:]); err != nil {
|
||||||
|
this.reportError("ReadInt64", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.head += n
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadUint8() (ret uint8) {
|
||||||
|
var (
|
||||||
|
n int
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if ret, n, err = utils.ReadUint8ForString(this.buf[this.head:]); err != nil {
|
||||||
|
this.reportError("ReadUint8", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.head += n
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadUint16() (ret uint16) {
|
||||||
|
var (
|
||||||
|
n int
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if ret, n, err = utils.ReadUint16ForString(this.buf[this.head:]); err != nil {
|
||||||
|
this.reportError("ReadUint16", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.head += n
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadUint32() (ret uint32) {
|
||||||
|
var (
|
||||||
|
n int
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if ret, n, err = utils.ReadUint32ForString(this.buf[this.head:]); err != nil {
|
||||||
|
this.reportError("ReadUint32", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.head += n
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadUint64() (ret uint64) {
|
||||||
|
var (
|
||||||
|
n int
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if ret, n, err = utils.ReadUint64ForString(this.buf[this.head:]); err != nil {
|
||||||
|
this.reportError("ReadUint64", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.head += n
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadFloat32() (ret float32) {
|
||||||
|
var (
|
||||||
|
n int
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if ret, n, err = utils.ReadFloat32ForString(this.buf[this.head:]); err != nil {
|
||||||
|
this.reportError("ReadFloat32", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.head += n
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadFloat64() (ret float64) {
|
||||||
|
var (
|
||||||
|
n int
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if ret, n, err = utils.ReadFloat64ForString(this.buf[this.head:]); err != nil {
|
||||||
|
this.reportError("ReadFloat64", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.head += n
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadString() (ret string) {
|
||||||
|
c := this.nextToken()
|
||||||
|
if c == '"' {
|
||||||
|
for i := this.head; i < this.tail; i++ {
|
||||||
|
c := this.buf[i]
|
||||||
|
if c == '"' {
|
||||||
|
ret = string(this.buf[this.head:i])
|
||||||
|
this.head = i + 1
|
||||||
|
return ret
|
||||||
|
} else if c == '\\' {
|
||||||
|
break
|
||||||
|
} else if c < ' ' {
|
||||||
|
this.reportError("ReadString",
|
||||||
|
fmt.Sprintf(`invalid control character found: %d`, c))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.readStringSlowPath()
|
||||||
|
} else if c == 'n' {
|
||||||
|
this.skipThreeBytes('u', 'l', 'l')
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
this.reportError("ReadString", `expects " or n, but found `+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ResetBytes(d []byte) {
|
||||||
|
this.buf = d
|
||||||
|
this.head = 0
|
||||||
|
this.tail = len(d)
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) Error() error {
|
||||||
|
return this.err
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) SetErr(err error) {
|
||||||
|
this.err = err
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
func (this *JsonExtractor) readByte() (ret byte) {
|
||||||
|
if this.head == this.tail {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
ret = this.buf[this.head]
|
||||||
|
this.head++
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) readStringSlowPath() (ret string) {
|
||||||
|
var str []byte
|
||||||
|
var c byte
|
||||||
|
for this.err == nil {
|
||||||
|
c = this.readByte()
|
||||||
|
if c == '"' {
|
||||||
|
return string(str)
|
||||||
|
}
|
||||||
|
if c == '\\' {
|
||||||
|
c = this.readByte()
|
||||||
|
str = this.readEscapedChar(c, str)
|
||||||
|
} else {
|
||||||
|
str = append(str, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.reportError("readStringSlowPath", "unexpected end of input")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) readEscapedChar(c byte, str []byte) []byte {
|
||||||
|
switch c {
|
||||||
|
case 'u':
|
||||||
|
r := this.readU4()
|
||||||
|
if utf16.IsSurrogate(r) {
|
||||||
|
c = this.readByte()
|
||||||
|
if this.err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if c != '\\' {
|
||||||
|
this.unreadByte()
|
||||||
|
str = utils.AppendRune(str, r)
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
c = this.readByte()
|
||||||
|
if this.err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if c != 'u' {
|
||||||
|
str = utils.AppendRune(str, r)
|
||||||
|
return this.readEscapedChar(c, str)
|
||||||
|
}
|
||||||
|
r2 := this.readU4()
|
||||||
|
if this.err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
combined := utf16.DecodeRune(r, r2)
|
||||||
|
if combined == '\uFFFD' {
|
||||||
|
str = utils.AppendRune(str, r)
|
||||||
|
str = utils.AppendRune(str, r2)
|
||||||
|
} else {
|
||||||
|
str = utils.AppendRune(str, combined)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
str = utils.AppendRune(str, r)
|
||||||
|
}
|
||||||
|
case '"':
|
||||||
|
str = append(str, '"')
|
||||||
|
case '\\':
|
||||||
|
str = append(str, '\\')
|
||||||
|
case '/':
|
||||||
|
str = append(str, '/')
|
||||||
|
case 'b':
|
||||||
|
str = append(str, '\b')
|
||||||
|
case 'f':
|
||||||
|
str = append(str, '\f')
|
||||||
|
case 'n':
|
||||||
|
str = append(str, '\n')
|
||||||
|
case 'r':
|
||||||
|
str = append(str, '\r')
|
||||||
|
case 't':
|
||||||
|
str = append(str, '\t')
|
||||||
|
default:
|
||||||
|
this.reportError("readEscapedChar",
|
||||||
|
`invalid escape char after \`)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) readU4() (ret rune) {
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
c := this.readByte()
|
||||||
|
if this.err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if c >= '0' && c <= '9' {
|
||||||
|
ret = ret*16 + rune(c-'0')
|
||||||
|
} else if c >= 'a' && c <= 'f' {
|
||||||
|
ret = ret*16 + rune(c-'a'+10)
|
||||||
|
} else if c >= 'A' && c <= 'F' {
|
||||||
|
ret = ret*16 + rune(c-'A'+10)
|
||||||
|
} else {
|
||||||
|
this.reportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) nextToken() byte {
|
||||||
|
for i := this.head; i < this.tail; i++ {
|
||||||
|
c := this.buf[i]
|
||||||
|
switch c {
|
||||||
|
case ' ', '\n', '\t', '\r':
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
this.head = i + 1
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) unreadByte() {
|
||||||
|
if this.err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.head--
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) skipNumber() {
|
||||||
|
if !this.trySkipNumber() {
|
||||||
|
this.unreadByte()
|
||||||
|
if this.err != nil && this.err != io.EOF {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.ReadFloat64()
|
||||||
|
if this.err != nil && this.err != io.EOF {
|
||||||
|
this.err = nil
|
||||||
|
this.ReadBigFloat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) ReadBigFloat() (ret *big.Float) {
|
||||||
|
var (
|
||||||
|
n int
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if ret, n, err = utils.ReadBigFloatForString(this.buf[this.head:]); err != nil {
|
||||||
|
this.reportError("ReadBigFloat", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.head += n
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (iter *JsonExtractor) trySkipNumber() bool {
|
||||||
|
dotFound := false
|
||||||
|
for i := iter.head; i < iter.tail; i++ {
|
||||||
|
c := iter.buf[i]
|
||||||
|
switch c {
|
||||||
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
|
case '.':
|
||||||
|
if dotFound {
|
||||||
|
iter.reportError("validateNumber", `more than one dot found in number`)
|
||||||
|
return true // already failed
|
||||||
|
}
|
||||||
|
if i+1 == iter.tail {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c = iter.buf[i+1]
|
||||||
|
switch c {
|
||||||
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
|
default:
|
||||||
|
iter.reportError("validateNumber", `missing digit after dot`)
|
||||||
|
return true // already failed
|
||||||
|
}
|
||||||
|
dotFound = true
|
||||||
|
default:
|
||||||
|
switch c {
|
||||||
|
case ',', ']', '}', ' ', '\t', '\n', '\r':
|
||||||
|
if iter.head == i {
|
||||||
|
return false // if - without following digits
|
||||||
|
}
|
||||||
|
iter.head = i
|
||||||
|
return true // must be valid
|
||||||
|
}
|
||||||
|
return false // may be invalid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) skipString() {
|
||||||
|
if !this.trySkipString() {
|
||||||
|
this.unreadByte()
|
||||||
|
this.ReadString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) trySkipString() bool {
|
||||||
|
for i := this.head; i < this.tail; i++ {
|
||||||
|
c := this.buf[i]
|
||||||
|
if c == '"' {
|
||||||
|
this.head = i + 1
|
||||||
|
return true // valid
|
||||||
|
} else if c == '\\' {
|
||||||
|
return false
|
||||||
|
} else if c < ' ' {
|
||||||
|
this.reportError("trySkipString",
|
||||||
|
fmt.Sprintf(`invalid control character found: %d`, c))
|
||||||
|
return true // already failed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) skipObject() {
|
||||||
|
this.unreadByte()
|
||||||
|
this.ReadObjectCB(func(extra core.IExtractor, field string) bool {
|
||||||
|
extra.Skip()
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) skipArray() {
|
||||||
|
this.unreadByte()
|
||||||
|
this.ReadArrayCB(func(extra core.IExtractor) bool {
|
||||||
|
extra.Skip()
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) skipThreeBytes(b1, b2, b3 byte) {
|
||||||
|
if this.readByte() != b1 {
|
||||||
|
this.reportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if this.readByte() != b2 {
|
||||||
|
this.reportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if this.readByte() != b3 {
|
||||||
|
this.reportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) skipFourBytes(b1, b2, b3, b4 byte) {
|
||||||
|
if this.readByte() != b1 {
|
||||||
|
this.reportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if this.readByte() != b2 {
|
||||||
|
this.reportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if this.readByte() != b3 {
|
||||||
|
this.reportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if this.readByte() != b4 {
|
||||||
|
this.reportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) reportError(operation string, msg string) {
|
||||||
|
if this.err != nil {
|
||||||
|
if this.err != io.EOF {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
peekStart := this.head - 10
|
||||||
|
if peekStart < 0 {
|
||||||
|
peekStart = 0
|
||||||
|
}
|
||||||
|
peekEnd := this.head + 10
|
||||||
|
if peekEnd > this.tail {
|
||||||
|
peekEnd = this.tail
|
||||||
|
}
|
||||||
|
parsing := string(this.buf[peekStart:peekEnd])
|
||||||
|
contextStart := this.head - 50
|
||||||
|
if contextStart < 0 {
|
||||||
|
contextStart = 0
|
||||||
|
}
|
||||||
|
contextEnd := this.head + 50
|
||||||
|
if contextEnd > this.tail {
|
||||||
|
contextEnd = this.tail
|
||||||
|
}
|
||||||
|
context := string(this.buf[contextStart:contextEnd])
|
||||||
|
this.err = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...",
|
||||||
|
operation, msg, this.head-peekStart, parsing, context)
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) incrementDepth() (success bool) {
|
||||||
|
this.depth++
|
||||||
|
if this.depth <= maxDepth {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
this.reportError("incrementDepth", "exceeded max depth")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func (this *JsonExtractor) decrementDepth() (success bool) {
|
||||||
|
this.depth--
|
||||||
|
if this.depth >= 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
this.reportError("decrementDepth", "unexpected negative nesting")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func (iter *JsonExtractor) ReadObjectCB(callback func(core.IExtractor, string) bool) bool {
|
||||||
|
c := iter.nextToken()
|
||||||
|
var field string
|
||||||
|
if c == '{' {
|
||||||
|
if !iter.incrementDepth() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c = iter.nextToken()
|
||||||
|
if c == '"' {
|
||||||
|
iter.unreadByte()
|
||||||
|
field = iter.ReadString()
|
||||||
|
c = iter.nextToken()
|
||||||
|
if c != ':' {
|
||||||
|
iter.reportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
|
||||||
|
}
|
||||||
|
if !callback(iter, field) {
|
||||||
|
iter.decrementDepth()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c = iter.nextToken()
|
||||||
|
for c == ',' {
|
||||||
|
field = iter.ReadString()
|
||||||
|
c = iter.nextToken()
|
||||||
|
if c != ':' {
|
||||||
|
iter.reportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
|
||||||
|
}
|
||||||
|
if !callback(iter, field) {
|
||||||
|
iter.decrementDepth()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c = iter.nextToken()
|
||||||
|
}
|
||||||
|
if c != '}' {
|
||||||
|
iter.reportError("ReadObjectCB", `object not ended with }`)
|
||||||
|
iter.decrementDepth()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return iter.decrementDepth()
|
||||||
|
}
|
||||||
|
if c == '}' {
|
||||||
|
return iter.decrementDepth()
|
||||||
|
}
|
||||||
|
iter.reportError("ReadObjectCB", `expect " after {, but found `+string([]byte{c}))
|
||||||
|
iter.decrementDepth()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if c == 'n' {
|
||||||
|
iter.skipThreeBytes('u', 'l', 'l')
|
||||||
|
return true // null
|
||||||
|
}
|
||||||
|
iter.reportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c}))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *JsonExtractor) ReadMapCB(callback func(core.IExtractor, string) bool) bool {
|
||||||
|
c := iter.nextToken()
|
||||||
|
if c == '{' {
|
||||||
|
if !iter.incrementDepth() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c = iter.nextToken()
|
||||||
|
if c == '"' {
|
||||||
|
iter.unreadByte()
|
||||||
|
field := iter.ReadString()
|
||||||
|
if iter.nextToken() != ':' {
|
||||||
|
iter.reportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
|
||||||
|
iter.decrementDepth()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !callback(iter, field) {
|
||||||
|
iter.decrementDepth()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c = iter.nextToken()
|
||||||
|
for c == ',' {
|
||||||
|
field = iter.ReadString()
|
||||||
|
if iter.nextToken() != ':' {
|
||||||
|
iter.reportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
|
||||||
|
iter.decrementDepth()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !callback(iter, field) {
|
||||||
|
iter.decrementDepth()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c = iter.nextToken()
|
||||||
|
}
|
||||||
|
if c != '}' {
|
||||||
|
iter.reportError("ReadMapCB", `object not ended with }`)
|
||||||
|
iter.decrementDepth()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return iter.decrementDepth()
|
||||||
|
}
|
||||||
|
if c == '}' {
|
||||||
|
return iter.decrementDepth()
|
||||||
|
}
|
||||||
|
iter.reportError("ReadMapCB", `expect " after {, but found `+string([]byte{c}))
|
||||||
|
iter.decrementDepth()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if c == 'n' {
|
||||||
|
iter.skipThreeBytes('u', 'l', 'l')
|
||||||
|
return true // null
|
||||||
|
}
|
||||||
|
iter.reportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *JsonExtractor) ReadArrayCB(callback func(core.IExtractor) bool) (ret bool) {
|
||||||
|
c := iter.nextToken()
|
||||||
|
if c == '[' {
|
||||||
|
if !iter.incrementDepth() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c = iter.nextToken()
|
||||||
|
if c != ']' {
|
||||||
|
iter.unreadByte()
|
||||||
|
if !callback(iter) {
|
||||||
|
iter.decrementDepth()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c = iter.nextToken()
|
||||||
|
for c == ',' {
|
||||||
|
if !callback(iter) {
|
||||||
|
iter.decrementDepth()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c = iter.nextToken()
|
||||||
|
}
|
||||||
|
if c != ']' {
|
||||||
|
iter.reportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c}))
|
||||||
|
iter.decrementDepth()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return iter.decrementDepth()
|
||||||
|
}
|
||||||
|
return iter.decrementDepth()
|
||||||
|
}
|
||||||
|
if c == 'n' {
|
||||||
|
iter.skipThreeBytes('u', 'l', 'l')
|
||||||
|
return true // null
|
||||||
|
}
|
||||||
|
iter.reportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c}))
|
||||||
|
return false
|
||||||
|
}
|
206
lego/sys/codec/render/json_stream.go
Normal file
206
lego/sys/codec/render/json_stream.go
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
package render
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go_dreamfactory/lego/sys/codec/core"
|
||||||
|
"go_dreamfactory/lego/sys/codec/utils"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewStream(codec core.ICodec, bufSize int) *JsonStream {
|
||||||
|
return &JsonStream{
|
||||||
|
codec: codec,
|
||||||
|
buf: make([]byte, 0, bufSize),
|
||||||
|
err: nil,
|
||||||
|
indention: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type JsonStream struct {
|
||||||
|
codec core.ICodec
|
||||||
|
err error
|
||||||
|
buf []byte
|
||||||
|
indention int
|
||||||
|
}
|
||||||
|
|
||||||
|
//写入对象
|
||||||
|
func (this *JsonStream) WriteVal(val interface{}) {
|
||||||
|
if nil == val {
|
||||||
|
this.WriteNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cacheKey := reflect2.RTypeOf(val)
|
||||||
|
encoder := this.codec.GetEncoderFromCache(cacheKey)
|
||||||
|
if encoder == nil {
|
||||||
|
typ := reflect2.TypeOf(val)
|
||||||
|
encoder = this.codec.EncoderOf(typ)
|
||||||
|
}
|
||||||
|
encoder.Encode(reflect2.PtrOf(val), this)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *JsonStream) WriteNil() {
|
||||||
|
this.writeFourBytes('n', 'u', 'l', 'l')
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteEmptyArray() {
|
||||||
|
this.writeTwoBytes('[', ']')
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteArrayStart() {
|
||||||
|
this.indention += this.codec.Options().IndentionStep
|
||||||
|
this.writeByte('[')
|
||||||
|
this.writeIndention(0)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteArrayEnd() {
|
||||||
|
this.writeIndention(this.codec.Options().IndentionStep)
|
||||||
|
this.indention -= this.codec.Options().IndentionStep
|
||||||
|
this.writeByte(']')
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteEmptyObject() {
|
||||||
|
this.writeTwoBytes('{', '}')
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteObjectStart() {
|
||||||
|
this.indention += this.codec.Options().IndentionStep
|
||||||
|
this.writeByte('{')
|
||||||
|
this.writeIndention(0)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteObjectEnd() {
|
||||||
|
this.writeIndention(this.codec.Options().IndentionStep)
|
||||||
|
this.indention -= this.codec.Options().IndentionStep
|
||||||
|
this.writeByte('}')
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteMemberSplit() {
|
||||||
|
this.writeByte(',')
|
||||||
|
this.writeIndention(0)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteKVSplit() {
|
||||||
|
this.writeByte(':')
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteKeyStart() {
|
||||||
|
this.writeByte('"')
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteKeyEnd() {
|
||||||
|
this.writeByte('"')
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteObjectFieldName(val string) {
|
||||||
|
this.WriteString(val)
|
||||||
|
if this.indention > 0 {
|
||||||
|
this.writeTwoBytes(':', ' ')
|
||||||
|
} else {
|
||||||
|
this.writeByte(':')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteBool(val bool) {
|
||||||
|
if val {
|
||||||
|
this.writeTrue()
|
||||||
|
} else {
|
||||||
|
this.writeFalse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteInt8(val int8) {
|
||||||
|
utils.WriteInt8ToString(&this.buf, val)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteInt16(val int16) {
|
||||||
|
utils.WriteInt16ToString(&this.buf, val)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteInt32(val int32) {
|
||||||
|
utils.WriteInt32ToString(&this.buf, val)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteInt64(val int64) {
|
||||||
|
utils.WriteInt64ToString(&this.buf, val)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteUint8(val uint8) {
|
||||||
|
utils.WriteUint8ToString(&this.buf, val)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteUint16(val uint16) {
|
||||||
|
utils.WriteUint16ToString(&this.buf, val)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteUint32(val uint32) {
|
||||||
|
utils.WriteUint32ToString(&this.buf, val)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteUint64(val uint64) {
|
||||||
|
utils.WriteUint64ToString(&this.buf, val)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteFloat32(val float32) {
|
||||||
|
utils.WriteFloat32ToString(&this.buf, val)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteFloat64(val float64) {
|
||||||
|
utils.WriteFloat64ToString(&this.buf, val)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteString(val string) {
|
||||||
|
valLen := len(val)
|
||||||
|
this.buf = append(this.buf, '"')
|
||||||
|
i := 0
|
||||||
|
for ; i < valLen; i++ {
|
||||||
|
c := val[i]
|
||||||
|
if c > 31 && c != '"' && c != '\\' {
|
||||||
|
this.buf = append(this.buf, c)
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i == valLen {
|
||||||
|
this.buf = append(this.buf, '"')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
utils.WriteStringSlowPath(&this.buf, i, val, valLen)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) WriteBytes(val []byte) {
|
||||||
|
this.buf = append(this.buf, val...)
|
||||||
|
}
|
||||||
|
func (this *JsonStream) Reset(bufSize int) {
|
||||||
|
this.buf = make([]byte, 0, bufSize)
|
||||||
|
this.err = nil
|
||||||
|
this.indention = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *JsonStream) Buffer() []byte {
|
||||||
|
return this.buf
|
||||||
|
}
|
||||||
|
func (this *JsonStream) Error() error {
|
||||||
|
return this.err
|
||||||
|
}
|
||||||
|
func (this *JsonStream) SetErr(err error) {
|
||||||
|
this.err = err
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// WriteTrue write true to stream
|
||||||
|
func (stream *JsonStream) writeTrue() {
|
||||||
|
stream.writeFourBytes('t', 'r', 'u', 'e')
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteFalse write false to stream
|
||||||
|
func (stream *JsonStream) writeFalse() {
|
||||||
|
stream.writeFiveBytes('f', 'a', 'l', 's', 'e')
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *JsonStream) writeByte(c byte) {
|
||||||
|
this.buf = append(this.buf, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *JsonStream) writeTwoBytes(c1 byte, c2 byte) {
|
||||||
|
this.buf = append(this.buf, c1, c2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *JsonStream) writeThreeBytes(c1 byte, c2 byte, c3 byte) {
|
||||||
|
this.buf = append(this.buf, c1, c2, c3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *JsonStream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) {
|
||||||
|
this.buf = append(this.buf, c1, c2, c3, c4)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *JsonStream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) {
|
||||||
|
this.buf = append(this.buf, c1, c2, c3, c4, c5)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (stream *JsonStream) writeIndention(delta int) {
|
||||||
|
if stream.indention == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
stream.writeByte('\n')
|
||||||
|
toWrite := stream.indention - delta
|
||||||
|
for i := 0; i < toWrite; i++ {
|
||||||
|
stream.buf = append(stream.buf, ' ')
|
||||||
|
}
|
||||||
|
}
|
106
lego/sys/codec/sys_test.go
Normal file
106
lego/sys/codec/sys_test.go
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
package codec_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"go_dreamfactory/lego/sys/codec"
|
||||||
|
"go_dreamfactory/lego/sys/log"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestData struct {
|
||||||
|
Name string
|
||||||
|
Value int
|
||||||
|
Array []interface{}
|
||||||
|
Data map[string]interface{}
|
||||||
|
}
|
||||||
|
type Test1Data struct {
|
||||||
|
Name string
|
||||||
|
Value int
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_sys_slice(t *testing.T) {
|
||||||
|
if err := log.OnInit(nil); err != nil {
|
||||||
|
fmt.Printf("log init err:%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if sys, err := codec.NewSys(); err != nil {
|
||||||
|
fmt.Printf("gin init err:%v", err)
|
||||||
|
} else {
|
||||||
|
data := []*Test1Data{{"liwe", 1}, {"liwe2", 2}}
|
||||||
|
d, err := sys.MarshalJson(data)
|
||||||
|
fmt.Printf("codec Marshal d:%s err:%v", d, err)
|
||||||
|
data = []*Test1Data{}
|
||||||
|
err = sys.UnmarshalJson(d, &data)
|
||||||
|
fmt.Printf("codec UnmarshalJson data:%v err:%v", data, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func Test_sys_json(t *testing.T) {
|
||||||
|
if err := log.OnInit(nil); err != nil {
|
||||||
|
fmt.Printf("log init err:%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if sys, err := codec.NewSys(); err != nil {
|
||||||
|
fmt.Printf("gin init err:%v", err)
|
||||||
|
} else {
|
||||||
|
d, err := sys.MarshalJson(&TestData{Name: "http://liwei1dao.com?asd=1&dd=1", Value: 10, Array: []interface{}{1, "dajiahao", &Test1Data{Name: "liwe1dao", Value: 123}}, Data: map[string]interface{}{"hah": 1, "asd": 999}})
|
||||||
|
fmt.Printf("codec Marshal d:%s err:%v", d, err)
|
||||||
|
data := &TestData{}
|
||||||
|
err = sys.UnmarshalJson(d, data)
|
||||||
|
fmt.Printf("codec UnmarshalJson data:%v err:%v", data, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_sys_mapjson(t *testing.T) {
|
||||||
|
if err := log.OnInit(nil); err != nil {
|
||||||
|
fmt.Printf("log init err:%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if sys, err := codec.NewSys(); err != nil {
|
||||||
|
fmt.Printf("gin init err:%v", err)
|
||||||
|
} else {
|
||||||
|
m := map[string]interface{}{"liwe": 123, "aasd": "123"}
|
||||||
|
fmt.Printf("codec Marshal m:%s err:%v", m, err)
|
||||||
|
d, err := sys.MarshalMapJson(&TestData{Name: "http://liwei1dao.com?asd=1&dd=1", Value: 10, Array: []interface{}{1, "dajiahao", &Test1Data{Name: "liwe1dao", Value: 123}}, Data: map[string]interface{}{"hah": 1, "asd": 999}})
|
||||||
|
fmt.Printf("codec Marshal d:%s err:%v", d, err)
|
||||||
|
data := &TestData{}
|
||||||
|
err = sys.UnmarshalMapJson(d, data)
|
||||||
|
fmt.Printf("codec UnmarshalJson data:%v err:%v", data, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_sys_reflect2(t *testing.T) {
|
||||||
|
data := []*Test1Data{}
|
||||||
|
ptr := reflect2.TypeOf(&data)
|
||||||
|
kind := ptr.Kind()
|
||||||
|
switch kind {
|
||||||
|
case reflect.Interface:
|
||||||
|
return
|
||||||
|
case reflect.Struct:
|
||||||
|
return
|
||||||
|
case reflect.Array:
|
||||||
|
return
|
||||||
|
case reflect.Slice:
|
||||||
|
return
|
||||||
|
case reflect.Map:
|
||||||
|
return
|
||||||
|
case reflect.Ptr:
|
||||||
|
ptrType := ptr.(*reflect2.UnsafePtrType)
|
||||||
|
elemType := ptrType.Elem()
|
||||||
|
kind = elemType.Kind()
|
||||||
|
if kind == reflect.Slice {
|
||||||
|
sliceelem := elemType.(*reflect2.UnsafeSliceType).Elem()
|
||||||
|
sliceelemkind := sliceelem.Kind()
|
||||||
|
if sliceelemkind == reflect.Ptr {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
416
lego/sys/codec/utils/float.go
Normal file
416
lego/sys/codec/utils/float.go
Normal file
@ -0,0 +1,416 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"math/big"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
var pow10 []uint64
|
||||||
|
var floatDigits []int8
|
||||||
|
|
||||||
|
const invalidCharForNumber = int8(-1)
|
||||||
|
const endOfNumber = int8(-2)
|
||||||
|
const dotInNumber = int8(-3)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
pow10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000}
|
||||||
|
floatDigits = make([]int8, 256)
|
||||||
|
for i := 0; i < len(floatDigits); i++ {
|
||||||
|
floatDigits[i] = invalidCharForNumber
|
||||||
|
}
|
||||||
|
for i := int8('0'); i <= int8('9'); i++ {
|
||||||
|
floatDigits[i] = i - int8('0')
|
||||||
|
}
|
||||||
|
floatDigits[','] = endOfNumber
|
||||||
|
floatDigits[']'] = endOfNumber
|
||||||
|
floatDigits['}'] = endOfNumber
|
||||||
|
floatDigits[' '] = endOfNumber
|
||||||
|
floatDigits['\t'] = endOfNumber
|
||||||
|
floatDigits['\n'] = endOfNumber
|
||||||
|
floatDigits['.'] = dotInNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
//Read Float For String-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
//从字符串中读取float 对象
|
||||||
|
func ReadBigFloatForString(buf []byte) (ret *big.Float, n int, err error) {
|
||||||
|
var str string
|
||||||
|
if str, n, err = readNumberAsString(buf); err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
prec := 64
|
||||||
|
if len(str) > prec {
|
||||||
|
prec = len(str)
|
||||||
|
}
|
||||||
|
ret, _, err = big.ParseFloat(str, 10, uint(prec), big.ToZero)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func ReadFloat32ForString(buf []byte) (ret float32, n int, err error) {
|
||||||
|
if buf[0] == '-' {
|
||||||
|
ret, n, err = readPositiveFloat32(buf[1:])
|
||||||
|
ret = -ret
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return readPositiveFloat32(buf)
|
||||||
|
}
|
||||||
|
func ReadFloat64ForString(buf []byte) (ret float64, n int, err error) {
|
||||||
|
if buf[0] == '-' {
|
||||||
|
ret, n, err = readPositiveFloat64(buf[1:])
|
||||||
|
ret = -ret
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return readPositiveFloat64(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
//读取float32
|
||||||
|
func readPositiveFloat32(buf []byte) (ret float32, n int, err error) {
|
||||||
|
i := 0
|
||||||
|
// first char
|
||||||
|
if len(buf) == 0 {
|
||||||
|
return readFloat32SlowPath(buf)
|
||||||
|
}
|
||||||
|
c := buf[i]
|
||||||
|
i++
|
||||||
|
ind := floatDigits[c]
|
||||||
|
switch ind {
|
||||||
|
case invalidCharForNumber:
|
||||||
|
return readFloat32SlowPath(buf)
|
||||||
|
case endOfNumber:
|
||||||
|
err = errors.New("readFloat32 empty number")
|
||||||
|
return
|
||||||
|
case dotInNumber:
|
||||||
|
err = errors.New("readFloat32 leading dot is invalid")
|
||||||
|
return
|
||||||
|
case 0:
|
||||||
|
if i == len(buf) {
|
||||||
|
return readFloat32SlowPath(buf)
|
||||||
|
}
|
||||||
|
c = buf[i]
|
||||||
|
switch c {
|
||||||
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
|
err = errors.New("readFloat32 leading zero is invalid")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value := uint64(ind)
|
||||||
|
// chars before dot
|
||||||
|
non_decimal_loop:
|
||||||
|
for ; i < len(buf); i++ {
|
||||||
|
c = buf[i]
|
||||||
|
ind := floatDigits[c]
|
||||||
|
switch ind {
|
||||||
|
case invalidCharForNumber:
|
||||||
|
return readFloat32SlowPath(buf)
|
||||||
|
case endOfNumber:
|
||||||
|
n = i
|
||||||
|
ret = float32(value)
|
||||||
|
return
|
||||||
|
case dotInNumber:
|
||||||
|
break non_decimal_loop
|
||||||
|
}
|
||||||
|
if value > uint64SafeToMultiple10 {
|
||||||
|
return readFloat32SlowPath(buf)
|
||||||
|
}
|
||||||
|
value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind;
|
||||||
|
}
|
||||||
|
// chars after dot
|
||||||
|
if c == '.' {
|
||||||
|
i++
|
||||||
|
decimalPlaces := 0
|
||||||
|
if i == len(buf) {
|
||||||
|
return readFloat32SlowPath(buf)
|
||||||
|
}
|
||||||
|
for ; i < len(buf); i++ {
|
||||||
|
c = buf[i]
|
||||||
|
ind := floatDigits[c]
|
||||||
|
switch ind {
|
||||||
|
case endOfNumber:
|
||||||
|
if decimalPlaces > 0 && decimalPlaces < len(pow10) {
|
||||||
|
n = i
|
||||||
|
ret = float32(float64(value) / float64(pow10[decimalPlaces]))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// too many decimal places
|
||||||
|
return readFloat32SlowPath(buf)
|
||||||
|
case invalidCharForNumber, dotInNumber:
|
||||||
|
return readFloat32SlowPath(buf)
|
||||||
|
}
|
||||||
|
decimalPlaces++
|
||||||
|
if value > uint64SafeToMultiple10 {
|
||||||
|
return readFloat32SlowPath(buf)
|
||||||
|
}
|
||||||
|
value = (value << 3) + (value << 1) + uint64(ind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return readFloat32SlowPath(buf)
|
||||||
|
}
|
||||||
|
func readFloat32SlowPath(buf []byte) (ret float32, n int, err error) {
|
||||||
|
var str string
|
||||||
|
if str, n, err = readNumberAsString(buf); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
errMsg := validateFloat(str)
|
||||||
|
if errMsg != "" {
|
||||||
|
err = errors.New(errMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var val float64
|
||||||
|
if val, err = strconv.ParseFloat(str, 32); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = float32(val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//读取float64
|
||||||
|
func readPositiveFloat64(buf []byte) (ret float64, n int, err error) {
|
||||||
|
i := 0
|
||||||
|
// first char
|
||||||
|
if i == len(buf) {
|
||||||
|
return readFloat64SlowPath(buf)
|
||||||
|
}
|
||||||
|
c := buf[i]
|
||||||
|
i++
|
||||||
|
ind := floatDigits[c]
|
||||||
|
switch ind {
|
||||||
|
case invalidCharForNumber:
|
||||||
|
return readFloat64SlowPath(buf)
|
||||||
|
case endOfNumber:
|
||||||
|
err = errors.New("readFloat64 empty number")
|
||||||
|
return
|
||||||
|
case dotInNumber:
|
||||||
|
err = errors.New("readFloat64 leading dot is invalid")
|
||||||
|
return
|
||||||
|
case 0:
|
||||||
|
if i == len(buf) {
|
||||||
|
return readFloat64SlowPath(buf)
|
||||||
|
}
|
||||||
|
c = buf[i]
|
||||||
|
switch c {
|
||||||
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
|
err = errors.New("readFloat64 leading zero is invalid")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value := uint64(ind)
|
||||||
|
// chars before dot
|
||||||
|
non_decimal_loop:
|
||||||
|
for ; i < len(buf); i++ {
|
||||||
|
c = buf[i]
|
||||||
|
ind := floatDigits[c]
|
||||||
|
switch ind {
|
||||||
|
case invalidCharForNumber:
|
||||||
|
return readFloat64SlowPath(buf)
|
||||||
|
case endOfNumber:
|
||||||
|
n = i
|
||||||
|
ret = float64(value)
|
||||||
|
return
|
||||||
|
case dotInNumber:
|
||||||
|
break non_decimal_loop
|
||||||
|
}
|
||||||
|
if value > uint64SafeToMultiple10 {
|
||||||
|
return readFloat64SlowPath(buf)
|
||||||
|
}
|
||||||
|
value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind;
|
||||||
|
}
|
||||||
|
// chars after dot
|
||||||
|
if c == '.' {
|
||||||
|
i++
|
||||||
|
decimalPlaces := 0
|
||||||
|
if i == len(buf) {
|
||||||
|
return readFloat64SlowPath(buf)
|
||||||
|
}
|
||||||
|
for ; i < len(buf); i++ {
|
||||||
|
c = buf[i]
|
||||||
|
ind := floatDigits[c]
|
||||||
|
switch ind {
|
||||||
|
case endOfNumber:
|
||||||
|
if decimalPlaces > 0 && decimalPlaces < len(pow10) {
|
||||||
|
n = i
|
||||||
|
ret = float64(value) / float64(pow10[decimalPlaces])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// too many decimal places
|
||||||
|
return readFloat64SlowPath(buf)
|
||||||
|
case invalidCharForNumber, dotInNumber:
|
||||||
|
return readFloat64SlowPath(buf)
|
||||||
|
}
|
||||||
|
decimalPlaces++
|
||||||
|
if value > uint64SafeToMultiple10 {
|
||||||
|
return readFloat64SlowPath(buf)
|
||||||
|
}
|
||||||
|
value = (value << 3) + (value << 1) + uint64(ind)
|
||||||
|
if value > maxFloat64 {
|
||||||
|
return readFloat64SlowPath(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return readFloat64SlowPath(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func readFloat64SlowPath(buf []byte) (ret float64, n int, err error) {
|
||||||
|
var str string
|
||||||
|
if str, n, err = readNumberAsString(buf); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
errMsg := validateFloat(str)
|
||||||
|
if errMsg != "" {
|
||||||
|
err = fmt.Errorf("readFloat64SlowPath:%v", errMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret, err = strconv.ParseFloat(str, 64)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//读取字符串数字
|
||||||
|
func readNumberAsString(buf []byte) (ret string, n int, err error) {
|
||||||
|
strBuf := [16]byte{}
|
||||||
|
str := strBuf[0:0]
|
||||||
|
load_loop:
|
||||||
|
for i := 0; i < len(buf); i++ {
|
||||||
|
c := buf[i]
|
||||||
|
switch c {
|
||||||
|
case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
|
str = append(str, c)
|
||||||
|
continue
|
||||||
|
default:
|
||||||
|
n = i
|
||||||
|
break load_loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(str) == 0 {
|
||||||
|
err = errors.New("readNumberAsString invalid number")
|
||||||
|
}
|
||||||
|
ret = *(*string)(unsafe.Pointer(&str))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//字符串float 错误检验
|
||||||
|
func validateFloat(str string) string {
|
||||||
|
if len(str) == 0 {
|
||||||
|
return "empty number"
|
||||||
|
}
|
||||||
|
if str[0] == '-' {
|
||||||
|
return "-- is not valid"
|
||||||
|
}
|
||||||
|
dotPos := strings.IndexByte(str, '.')
|
||||||
|
if dotPos != -1 {
|
||||||
|
if dotPos == len(str)-1 {
|
||||||
|
return "dot can not be last character"
|
||||||
|
}
|
||||||
|
switch str[dotPos+1] {
|
||||||
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
|
default:
|
||||||
|
return "missing digit after dot"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
//Write Float To String-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
func WriteFloat32ToString(buff *[]byte, val float32) (err error) {
|
||||||
|
if math.IsInf(float64(val), 0) || math.IsNaN(float64(val)) {
|
||||||
|
err = fmt.Errorf("unsupported value: %f", val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
abs := math.Abs(float64(val))
|
||||||
|
fmt := byte('f')
|
||||||
|
if abs != 0 {
|
||||||
|
if float32(abs) < 1e-6 || float32(abs) >= 1e21 {
|
||||||
|
fmt = 'e'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*buff = strconv.AppendFloat(*buff, float64(val), fmt, -1, 32)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//float32 写入只有 6 位精度的流,但速度要快得多
|
||||||
|
func WriteFloat32LossyToString(buf *[]byte, val float32) (err error) {
|
||||||
|
if math.IsInf(float64(val), 0) || math.IsNaN(float64(val)) {
|
||||||
|
err = fmt.Errorf("unsupported value: %f", val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if val < 0 {
|
||||||
|
WriteChar(buf, '-')
|
||||||
|
val = -val
|
||||||
|
}
|
||||||
|
if val > 0x4ffffff {
|
||||||
|
WriteFloat32ToString(buf, val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
precision := 6
|
||||||
|
exp := uint64(1000000) // 6
|
||||||
|
lval := uint64(float64(val)*float64(exp) + 0.5)
|
||||||
|
WriteUint64ToString(buf, lval/exp)
|
||||||
|
fval := lval % exp
|
||||||
|
if fval == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
WriteChar(buf, '.')
|
||||||
|
for p := precision - 1; p > 0 && fval < pow10[p]; p-- {
|
||||||
|
WriteChar(buf, '0')
|
||||||
|
}
|
||||||
|
WriteUint64ToString(buf, fval)
|
||||||
|
temp := *buf
|
||||||
|
for temp[len(temp)-1] == '0' {
|
||||||
|
temp = temp[:len(temp)-1]
|
||||||
|
}
|
||||||
|
buf = &temp
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteFloat64ToString(buf *[]byte, val float64) (err error) {
|
||||||
|
if math.IsInf(val, 0) || math.IsNaN(val) {
|
||||||
|
err = fmt.Errorf("unsupported value: %f", val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
abs := math.Abs(val)
|
||||||
|
fmt := byte('f')
|
||||||
|
// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
|
||||||
|
if abs != 0 {
|
||||||
|
if abs < 1e-6 || abs >= 1e21 {
|
||||||
|
fmt = 'e'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*buf = strconv.AppendFloat(*buf, float64(val), fmt, -1, 64)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//将 float64 写入只有 6 位精度的流,但速度要快得多
|
||||||
|
func WriteFloat64LossyToString(buf *[]byte, val float64) (err error) {
|
||||||
|
if math.IsInf(val, 0) || math.IsNaN(val) {
|
||||||
|
err = fmt.Errorf("unsupported value: %f", val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if val < 0 {
|
||||||
|
WriteChar(buf, '-')
|
||||||
|
val = -val
|
||||||
|
}
|
||||||
|
if val > 0x4ffffff {
|
||||||
|
WriteFloat64ToString(buf, val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
precision := 6
|
||||||
|
exp := uint64(1000000) // 6
|
||||||
|
lval := uint64(val*float64(exp) + 0.5)
|
||||||
|
WriteUint64ToString(buf, lval/exp)
|
||||||
|
fval := lval % exp
|
||||||
|
if fval == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
WriteChar(buf, '.')
|
||||||
|
for p := precision - 1; p > 0 && fval < pow10[p]; p-- {
|
||||||
|
WriteChar(buf, '0')
|
||||||
|
}
|
||||||
|
WriteUint64ToString(buf, fval)
|
||||||
|
temp := *buf
|
||||||
|
for temp[len(temp)-1] == '0' {
|
||||||
|
temp = temp[:len(temp)-1]
|
||||||
|
}
|
||||||
|
buf = &temp
|
||||||
|
return
|
||||||
|
}
|
543
lego/sys/codec/utils/int.go
Normal file
543
lego/sys/codec/utils/int.go
Normal file
@ -0,0 +1,543 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
var digits []uint32
|
||||||
|
var intDigits []int8
|
||||||
|
|
||||||
|
const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1
|
||||||
|
const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1
|
||||||
|
const maxFloat64 = 1<<53 - 1
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
digits = make([]uint32, 1000)
|
||||||
|
for i := uint32(0); i < 1000; i++ {
|
||||||
|
digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0'
|
||||||
|
if i < 10 {
|
||||||
|
digits[i] += 2 << 24
|
||||||
|
} else if i < 100 {
|
||||||
|
digits[i] += 1 << 24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
intDigits = make([]int8, 256)
|
||||||
|
for i := 0; i < len(intDigits); i++ {
|
||||||
|
intDigits[i] = invalidCharForNumber
|
||||||
|
}
|
||||||
|
for i := int8('0'); i <= int8('9'); i++ {
|
||||||
|
intDigits[i] = i - int8('0')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Read Int For String--------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
func ReadInt8ForString(buf []byte) (ret int8, n int, err error) {
|
||||||
|
var (
|
||||||
|
val uint32
|
||||||
|
)
|
||||||
|
c := buf[0]
|
||||||
|
if c == '-' {
|
||||||
|
val, n, err = ReadUint32ForString(buf[1:])
|
||||||
|
if val > math.MaxInt8+1 {
|
||||||
|
err = errors.New("ReadInt8ForString overflow: " + strconv.FormatInt(int64(val), 10))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = -int8(val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val, n, err = ReadUint32ForString(buf)
|
||||||
|
if val > math.MaxInt8 {
|
||||||
|
err = errors.New("ReadInt8ForString overflow: " + strconv.FormatInt(int64(val), 10))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = int8(val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadInt16ForString(buf []byte) (ret int16, n int, err error) {
|
||||||
|
var (
|
||||||
|
val uint32
|
||||||
|
)
|
||||||
|
c := buf[0]
|
||||||
|
if c == '-' {
|
||||||
|
val, n, err = ReadUint32ForString(buf[1:])
|
||||||
|
if val > math.MaxInt16+1 {
|
||||||
|
err = errors.New("ReadInt16ForString overflow: " + strconv.FormatInt(int64(val), 10))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = -int16(val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val, n, err = ReadUint32ForString(buf)
|
||||||
|
if val > math.MaxInt16 {
|
||||||
|
err = errors.New("ReadInt16ForString overflow: " + strconv.FormatInt(int64(val), 10))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = int16(val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadInt32ForString(buf []byte) (ret int32, n int, err error) {
|
||||||
|
var (
|
||||||
|
val uint32
|
||||||
|
)
|
||||||
|
c := buf[0]
|
||||||
|
if c == '-' {
|
||||||
|
val, n, err = ReadUint32ForString(buf[1:])
|
||||||
|
if val > math.MaxInt32+1 {
|
||||||
|
err = errors.New("ReadInt32ForString overflow: " + strconv.FormatInt(int64(val), 10))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = -int32(val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val, n, err = ReadUint32ForString(buf)
|
||||||
|
if val > math.MaxInt32 {
|
||||||
|
err = errors.New("ReadInt32ForString overflow: " + strconv.FormatInt(int64(val), 10))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = int32(val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadInt64ForString(buf []byte) (ret int64, n int, err error) {
|
||||||
|
var (
|
||||||
|
val uint64
|
||||||
|
)
|
||||||
|
c := buf[0]
|
||||||
|
if c == '-' {
|
||||||
|
val, n, err = ReadUint64ForString(buf[1:])
|
||||||
|
if val > math.MaxInt64+1 {
|
||||||
|
err = errors.New("ReadInt64ForString overflow: " + strconv.FormatInt(int64(val), 10))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = -int64(val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val, n, err = ReadUint64ForString(buf)
|
||||||
|
if val > math.MaxInt64 {
|
||||||
|
err = errors.New("ReadInt64ForString overflow: " + strconv.FormatInt(int64(val), 10))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = int64(val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadUint8ForString(buf []byte) (ret uint8, n int, err error) {
|
||||||
|
var (
|
||||||
|
val uint32
|
||||||
|
)
|
||||||
|
val, n, err = ReadUint32ForString(buf)
|
||||||
|
if val > math.MaxUint8 {
|
||||||
|
err = errors.New("ReadUInt8ForString overflow: " + strconv.FormatInt(int64(val), 10))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = uint8(val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadUint16ForString(buf []byte) (ret uint16, n int, err error) {
|
||||||
|
var (
|
||||||
|
val uint32
|
||||||
|
)
|
||||||
|
val, n, err = ReadUint32ForString(buf)
|
||||||
|
if val > math.MaxUint16 {
|
||||||
|
err = errors.New("ReadUInt16ForString overflow: " + strconv.FormatInt(int64(val), 10))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = uint16(val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadUint32ForString(buf []byte) (ret uint32, n int, err error) {
|
||||||
|
ind := intDigits[buf[0]]
|
||||||
|
if ind == 0 {
|
||||||
|
err = assertInteger(buf[1:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ind == invalidCharForNumber {
|
||||||
|
err = errors.New("ReadUint32ForString unexpected character: " + string([]byte{byte(ind)}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = uint32(ind)
|
||||||
|
if len(buf) > 10 {
|
||||||
|
i := 0
|
||||||
|
ind2 := intDigits[buf[i]]
|
||||||
|
if ind2 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind3 := intDigits[buf[i]]
|
||||||
|
if ind3 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
ret = ret*10 + uint32(ind2)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind4 := intDigits[buf[i]]
|
||||||
|
if ind4 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
ret = ret*100 + uint32(ind2)*10 + uint32(ind3)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind5 := intDigits[buf[i]]
|
||||||
|
if ind5 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
ret = ret*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind6 := intDigits[buf[i]]
|
||||||
|
if ind6 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
ret = ret*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind7 := intDigits[buf[i]]
|
||||||
|
if ind7 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
ret = ret*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind8 := intDigits[buf[i]]
|
||||||
|
if ind8 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
ret = ret*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind9 := intDigits[buf[i]]
|
||||||
|
ret = ret*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8)
|
||||||
|
n = i
|
||||||
|
if ind9 == invalidCharForNumber {
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 1; i < len(buf); i++ {
|
||||||
|
ind = intDigits[buf[i]]
|
||||||
|
if ind == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ret > uint32SafeToMultiply10 {
|
||||||
|
value2 := (ret << 3) + (ret << 1) + uint32(ind)
|
||||||
|
if value2 < ret {
|
||||||
|
err = errors.New("ReadUint32ForString overflow")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = value2
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ret = (ret << 3) + (ret << 1) + uint32(ind)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadUint64ForString(buf []byte) (ret uint64, n int, err error) {
|
||||||
|
ind := intDigits[buf[0]]
|
||||||
|
if ind == 0 {
|
||||||
|
err = assertInteger(buf[1:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ind == invalidCharForNumber {
|
||||||
|
err = errors.New("ReadUint64ForString unexpected character: " + string([]byte{byte(ind)}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = uint64(ind)
|
||||||
|
if len(buf) > 10 {
|
||||||
|
i := 0
|
||||||
|
ind2 := intDigits[buf[i]]
|
||||||
|
if ind2 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind3 := intDigits[buf[i]]
|
||||||
|
if ind3 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
ret = ret*10 + uint64(ind2)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind4 := intDigits[buf[i]]
|
||||||
|
if ind4 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
ret = ret*100 + uint64(ind2)*10 + uint64(ind3)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind5 := intDigits[buf[i]]
|
||||||
|
if ind5 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
ret = ret*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind6 := intDigits[buf[i]]
|
||||||
|
if ind6 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
ret = ret*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind7 := intDigits[buf[i]]
|
||||||
|
if ind7 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
ret = ret*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind8 := intDigits[buf[i]]
|
||||||
|
if ind8 == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
ret = ret*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
ind9 := intDigits[buf[i]]
|
||||||
|
ret = ret*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8)
|
||||||
|
n = i
|
||||||
|
if ind9 == invalidCharForNumber {
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 1; i < len(buf); i++ {
|
||||||
|
ind = intDigits[buf[i]]
|
||||||
|
if ind == invalidCharForNumber {
|
||||||
|
n = i
|
||||||
|
err = assertInteger(buf[i:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ret > uint64SafeToMultiple10 {
|
||||||
|
value2 := (ret << 3) + (ret << 1) + uint64(ind)
|
||||||
|
if value2 < ret {
|
||||||
|
err = errors.New("ReadUint64ForString overflow")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = value2
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ret = (ret << 3) + (ret << 1) + uint64(ind)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertInteger(buf []byte) (err error) {
|
||||||
|
if len(buf) > 0 && buf[0] == '.' {
|
||||||
|
err = errors.New("assertInteger can not decode float as int")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//Write Int To String--------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
func WriteChar(buff *[]byte, c byte) {
|
||||||
|
*buff = append(*buff, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteUint8 write uint8 to stream
|
||||||
|
func WriteUint8ToString(buf *[]byte, val uint8) {
|
||||||
|
*buf = writeFirstBuf(*buf, digits[val])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteInt8 write int8 to stream
|
||||||
|
func WriteInt8ToString(buf *[]byte, nval int8) {
|
||||||
|
var val uint8
|
||||||
|
if nval < 0 {
|
||||||
|
val = uint8(-nval)
|
||||||
|
*buf = append(*buf, '-')
|
||||||
|
} else {
|
||||||
|
val = uint8(nval)
|
||||||
|
}
|
||||||
|
*buf = writeFirstBuf(*buf, digits[val])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteUint16 write uint16 to stream
|
||||||
|
func WriteUint16ToString(buf *[]byte, val uint16) {
|
||||||
|
q1 := val / 1000
|
||||||
|
if q1 == 0 {
|
||||||
|
*buf = writeFirstBuf(*buf, digits[val])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r1 := val - q1*1000
|
||||||
|
*buf = writeFirstBuf(*buf, digits[q1])
|
||||||
|
*buf = writeBuf(*buf, digits[r1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteInt16 write int16 to stream
|
||||||
|
func WriteInt16ToString(buf *[]byte, nval int16) {
|
||||||
|
var val uint16
|
||||||
|
if nval < 0 {
|
||||||
|
val = uint16(-nval)
|
||||||
|
*buf = append(*buf, '-')
|
||||||
|
} else {
|
||||||
|
val = uint16(nval)
|
||||||
|
}
|
||||||
|
WriteUint16ToString(buf, val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteUint32 write uint32 to stream
|
||||||
|
func WriteUint32ToString(buf *[]byte, val uint32) {
|
||||||
|
q1 := val / 1000
|
||||||
|
if q1 == 0 {
|
||||||
|
*buf = writeFirstBuf(*buf, digits[val])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r1 := val - q1*1000
|
||||||
|
q2 := q1 / 1000
|
||||||
|
if q2 == 0 {
|
||||||
|
*buf = writeFirstBuf(*buf, digits[q1])
|
||||||
|
*buf = writeBuf(*buf, digits[r1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r2 := q1 - q2*1000
|
||||||
|
q3 := q2 / 1000
|
||||||
|
if q3 == 0 {
|
||||||
|
*buf = writeFirstBuf(*buf, digits[q2])
|
||||||
|
} else {
|
||||||
|
r3 := q2 - q3*1000
|
||||||
|
*buf = append(*buf, byte(q3+'0'))
|
||||||
|
*buf = writeBuf(*buf, digits[r3])
|
||||||
|
}
|
||||||
|
*buf = writeBuf(*buf, digits[r2])
|
||||||
|
*buf = writeBuf(*buf, digits[r1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteInt32 write int32 to stream
|
||||||
|
func WriteInt32ToString(buf *[]byte, nval int32) {
|
||||||
|
var val uint32
|
||||||
|
if nval < 0 {
|
||||||
|
val = uint32(-nval)
|
||||||
|
*buf = append(*buf, '-')
|
||||||
|
} else {
|
||||||
|
val = uint32(nval)
|
||||||
|
}
|
||||||
|
WriteUint32ToString(buf, val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteUint64 write uint64 to stream
|
||||||
|
func WriteUint64ToString(buf *[]byte, val uint64) {
|
||||||
|
q1 := val / 1000
|
||||||
|
if q1 == 0 {
|
||||||
|
*buf = writeFirstBuf(*buf, digits[val])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r1 := val - q1*1000
|
||||||
|
q2 := q1 / 1000
|
||||||
|
if q2 == 0 {
|
||||||
|
*buf = writeFirstBuf(*buf, digits[q1])
|
||||||
|
*buf = writeBuf(*buf, digits[r1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r2 := q1 - q2*1000
|
||||||
|
q3 := q2 / 1000
|
||||||
|
if q3 == 0 {
|
||||||
|
*buf = writeFirstBuf(*buf, digits[q2])
|
||||||
|
*buf = writeBuf(*buf, digits[r2])
|
||||||
|
*buf = writeBuf(*buf, digits[r1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r3 := q2 - q3*1000
|
||||||
|
q4 := q3 / 1000
|
||||||
|
if q4 == 0 {
|
||||||
|
*buf = writeFirstBuf(*buf, digits[q3])
|
||||||
|
*buf = writeBuf(*buf, digits[r3])
|
||||||
|
*buf = writeBuf(*buf, digits[r2])
|
||||||
|
*buf = writeBuf(*buf, digits[r1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r4 := q3 - q4*1000
|
||||||
|
q5 := q4 / 1000
|
||||||
|
if q5 == 0 {
|
||||||
|
*buf = writeFirstBuf(*buf, digits[q4])
|
||||||
|
*buf = writeBuf(*buf, digits[r4])
|
||||||
|
*buf = writeBuf(*buf, digits[r3])
|
||||||
|
*buf = writeBuf(*buf, digits[r2])
|
||||||
|
*buf = writeBuf(*buf, digits[r1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r5 := q4 - q5*1000
|
||||||
|
q6 := q5 / 1000
|
||||||
|
if q6 == 0 {
|
||||||
|
*buf = writeFirstBuf(*buf, digits[q5])
|
||||||
|
} else {
|
||||||
|
*buf = writeFirstBuf(*buf, digits[q6])
|
||||||
|
r6 := q5 - q6*1000
|
||||||
|
*buf = writeBuf(*buf, digits[r6])
|
||||||
|
}
|
||||||
|
*buf = writeBuf(*buf, digits[r5])
|
||||||
|
*buf = writeBuf(*buf, digits[r4])
|
||||||
|
*buf = writeBuf(*buf, digits[r3])
|
||||||
|
*buf = writeBuf(*buf, digits[r2])
|
||||||
|
*buf = writeBuf(*buf, digits[r1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteInt64 write int64 to stream
|
||||||
|
func WriteInt64ToString(buf *[]byte, nval int64) {
|
||||||
|
var val uint64
|
||||||
|
if nval < 0 {
|
||||||
|
val = uint64(-nval)
|
||||||
|
*buf = append(*buf, '-')
|
||||||
|
} else {
|
||||||
|
val = uint64(nval)
|
||||||
|
}
|
||||||
|
WriteUint64ToString(buf, val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteInt write int to stream
|
||||||
|
func WriteIntToString(buf *[]byte, val int) {
|
||||||
|
WriteInt64ToString(buf, int64(val))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteUint write uint to stream
|
||||||
|
func WriteUint(buf *[]byte, val uint) {
|
||||||
|
WriteUint64ToString(buf, uint64(val))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeFirstBuf(space []byte, v uint32) []byte {
|
||||||
|
start := v >> 24
|
||||||
|
if start == 0 {
|
||||||
|
space = append(space, byte(v>>16), byte(v>>8))
|
||||||
|
} else if start == 1 {
|
||||||
|
space = append(space, byte(v>>8))
|
||||||
|
}
|
||||||
|
space = append(space, byte(v))
|
||||||
|
return space
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeBuf(buf []byte, v uint32) []byte {
|
||||||
|
return append(buf, byte(v>>16), byte(v>>8), byte(v))
|
||||||
|
}
|
349
lego/sys/codec/utils/string.go
Normal file
349
lego/sys/codec/utils/string.go
Normal file
@ -0,0 +1,349 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import "unicode/utf8"
|
||||||
|
|
||||||
|
var htmlSafeSet = [utf8.RuneSelf]bool{
|
||||||
|
' ': true,
|
||||||
|
'!': true,
|
||||||
|
'"': false,
|
||||||
|
'#': true,
|
||||||
|
'$': true,
|
||||||
|
'%': true,
|
||||||
|
'&': false,
|
||||||
|
'\'': true,
|
||||||
|
'(': true,
|
||||||
|
')': true,
|
||||||
|
'*': true,
|
||||||
|
'+': true,
|
||||||
|
',': true,
|
||||||
|
'-': true,
|
||||||
|
'.': true,
|
||||||
|
'/': true,
|
||||||
|
'0': true,
|
||||||
|
'1': true,
|
||||||
|
'2': true,
|
||||||
|
'3': true,
|
||||||
|
'4': true,
|
||||||
|
'5': true,
|
||||||
|
'6': true,
|
||||||
|
'7': true,
|
||||||
|
'8': true,
|
||||||
|
'9': true,
|
||||||
|
':': true,
|
||||||
|
';': true,
|
||||||
|
'<': false,
|
||||||
|
'=': true,
|
||||||
|
'>': false,
|
||||||
|
'?': true,
|
||||||
|
'@': true,
|
||||||
|
'A': true,
|
||||||
|
'B': true,
|
||||||
|
'C': true,
|
||||||
|
'D': true,
|
||||||
|
'E': true,
|
||||||
|
'F': true,
|
||||||
|
'G': true,
|
||||||
|
'H': true,
|
||||||
|
'I': true,
|
||||||
|
'J': true,
|
||||||
|
'K': true,
|
||||||
|
'L': true,
|
||||||
|
'M': true,
|
||||||
|
'N': true,
|
||||||
|
'O': true,
|
||||||
|
'P': true,
|
||||||
|
'Q': true,
|
||||||
|
'R': true,
|
||||||
|
'S': true,
|
||||||
|
'T': true,
|
||||||
|
'U': true,
|
||||||
|
'V': true,
|
||||||
|
'W': true,
|
||||||
|
'X': true,
|
||||||
|
'Y': true,
|
||||||
|
'Z': true,
|
||||||
|
'[': true,
|
||||||
|
'\\': false,
|
||||||
|
']': true,
|
||||||
|
'^': true,
|
||||||
|
'_': true,
|
||||||
|
'`': true,
|
||||||
|
'a': true,
|
||||||
|
'b': true,
|
||||||
|
'c': true,
|
||||||
|
'd': true,
|
||||||
|
'e': true,
|
||||||
|
'f': true,
|
||||||
|
'g': true,
|
||||||
|
'h': true,
|
||||||
|
'i': true,
|
||||||
|
'j': true,
|
||||||
|
'k': true,
|
||||||
|
'l': true,
|
||||||
|
'm': true,
|
||||||
|
'n': true,
|
||||||
|
'o': true,
|
||||||
|
'p': true,
|
||||||
|
'q': true,
|
||||||
|
'r': true,
|
||||||
|
's': true,
|
||||||
|
't': true,
|
||||||
|
'u': true,
|
||||||
|
'v': true,
|
||||||
|
'w': true,
|
||||||
|
'x': true,
|
||||||
|
'y': true,
|
||||||
|
'z': true,
|
||||||
|
'{': true,
|
||||||
|
'|': true,
|
||||||
|
'}': true,
|
||||||
|
'~': true,
|
||||||
|
'\u007f': true,
|
||||||
|
}
|
||||||
|
|
||||||
|
var safeSet = [utf8.RuneSelf]bool{
|
||||||
|
' ': true,
|
||||||
|
'!': true,
|
||||||
|
'"': false,
|
||||||
|
'#': true,
|
||||||
|
'$': true,
|
||||||
|
'%': true,
|
||||||
|
'&': true,
|
||||||
|
'\'': true,
|
||||||
|
'(': true,
|
||||||
|
')': true,
|
||||||
|
'*': true,
|
||||||
|
'+': true,
|
||||||
|
',': true,
|
||||||
|
'-': true,
|
||||||
|
'.': true,
|
||||||
|
'/': true,
|
||||||
|
'0': true,
|
||||||
|
'1': true,
|
||||||
|
'2': true,
|
||||||
|
'3': true,
|
||||||
|
'4': true,
|
||||||
|
'5': true,
|
||||||
|
'6': true,
|
||||||
|
'7': true,
|
||||||
|
'8': true,
|
||||||
|
'9': true,
|
||||||
|
':': true,
|
||||||
|
';': true,
|
||||||
|
'<': true,
|
||||||
|
'=': true,
|
||||||
|
'>': true,
|
||||||
|
'?': true,
|
||||||
|
'@': true,
|
||||||
|
'A': true,
|
||||||
|
'B': true,
|
||||||
|
'C': true,
|
||||||
|
'D': true,
|
||||||
|
'E': true,
|
||||||
|
'F': true,
|
||||||
|
'G': true,
|
||||||
|
'H': true,
|
||||||
|
'I': true,
|
||||||
|
'J': true,
|
||||||
|
'K': true,
|
||||||
|
'L': true,
|
||||||
|
'M': true,
|
||||||
|
'N': true,
|
||||||
|
'O': true,
|
||||||
|
'P': true,
|
||||||
|
'Q': true,
|
||||||
|
'R': true,
|
||||||
|
'S': true,
|
||||||
|
'T': true,
|
||||||
|
'U': true,
|
||||||
|
'V': true,
|
||||||
|
'W': true,
|
||||||
|
'X': true,
|
||||||
|
'Y': true,
|
||||||
|
'Z': true,
|
||||||
|
'[': true,
|
||||||
|
'\\': false,
|
||||||
|
']': true,
|
||||||
|
'^': true,
|
||||||
|
'_': true,
|
||||||
|
'`': true,
|
||||||
|
'a': true,
|
||||||
|
'b': true,
|
||||||
|
'c': true,
|
||||||
|
'd': true,
|
||||||
|
'e': true,
|
||||||
|
'f': true,
|
||||||
|
'g': true,
|
||||||
|
'h': true,
|
||||||
|
'i': true,
|
||||||
|
'j': true,
|
||||||
|
'k': true,
|
||||||
|
'l': true,
|
||||||
|
'm': true,
|
||||||
|
'n': true,
|
||||||
|
'o': true,
|
||||||
|
'p': true,
|
||||||
|
'q': true,
|
||||||
|
'r': true,
|
||||||
|
's': true,
|
||||||
|
't': true,
|
||||||
|
'u': true,
|
||||||
|
'v': true,
|
||||||
|
'w': true,
|
||||||
|
'x': true,
|
||||||
|
'y': true,
|
||||||
|
'z': true,
|
||||||
|
'{': true,
|
||||||
|
'|': true,
|
||||||
|
'}': true,
|
||||||
|
'~': true,
|
||||||
|
'\u007f': true,
|
||||||
|
}
|
||||||
|
|
||||||
|
var hex = "0123456789abcdef"
|
||||||
|
|
||||||
|
func WriteStringSlowPathWithHTMLEscaped(buf *[]byte, i int, s string, valLen int) {
|
||||||
|
start := i
|
||||||
|
// for the remaining parts, we process them char by char
|
||||||
|
for i < valLen {
|
||||||
|
if b := s[i]; b < utf8.RuneSelf {
|
||||||
|
if htmlSafeSet[b] {
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if start < i {
|
||||||
|
*buf = append(*buf, s[start:i]...)
|
||||||
|
}
|
||||||
|
switch b {
|
||||||
|
case '\\', '"':
|
||||||
|
*buf = append(*buf, '\\', b)
|
||||||
|
case '\n':
|
||||||
|
*buf = append(*buf, '\\', 'n')
|
||||||
|
case '\r':
|
||||||
|
*buf = append(*buf, '\\', 'r')
|
||||||
|
case '\t':
|
||||||
|
*buf = append(*buf, '\\', 't')
|
||||||
|
default:
|
||||||
|
*buf = append(*buf, `\u00`...)
|
||||||
|
*buf = append(*buf, hex[b>>4], hex[b&0xF])
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
start = i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
c, size := utf8.DecodeRuneInString(s[i:])
|
||||||
|
if c == utf8.RuneError && size == 1 {
|
||||||
|
if start < i {
|
||||||
|
*buf = append(*buf, s[start:i]...)
|
||||||
|
}
|
||||||
|
*buf = append(*buf, `\ufffd`...)
|
||||||
|
i++
|
||||||
|
start = i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if c == '\u2028' || c == '\u2029' {
|
||||||
|
if start < i {
|
||||||
|
*buf = append(*buf, s[start:i]...)
|
||||||
|
}
|
||||||
|
*buf = append(*buf, `\u202`...)
|
||||||
|
*buf = append(*buf, hex[c&0xF])
|
||||||
|
i += size
|
||||||
|
start = i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i += size
|
||||||
|
}
|
||||||
|
if start < len(s) {
|
||||||
|
*buf = append(*buf, s[start:]...)
|
||||||
|
}
|
||||||
|
*buf = append(*buf, '"')
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteStringSlowPath(buf *[]byte, i int, s string, valLen int) {
|
||||||
|
start := i
|
||||||
|
for i < valLen {
|
||||||
|
if b := s[i]; b < utf8.RuneSelf {
|
||||||
|
if safeSet[b] {
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if start < i {
|
||||||
|
*buf = append(*buf, s[start:i]...)
|
||||||
|
}
|
||||||
|
switch b {
|
||||||
|
case '\\', '"':
|
||||||
|
*buf = append(*buf, '\\', b)
|
||||||
|
case '\n':
|
||||||
|
*buf = append(*buf, '\\', 'n')
|
||||||
|
case '\r':
|
||||||
|
*buf = append(*buf, '\\', 'r')
|
||||||
|
case '\t':
|
||||||
|
*buf = append(*buf, '\\', 't')
|
||||||
|
default:
|
||||||
|
*buf = append(*buf, `\u00`...)
|
||||||
|
*buf = append(*buf, hex[b>>4], hex[b&0xF])
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
start = i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if start < len(s) {
|
||||||
|
*buf = append(*buf, s[start:]...)
|
||||||
|
}
|
||||||
|
*buf = append(*buf, '"')
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
t1 = 0x00 // 0000 0000
|
||||||
|
tx = 0x80 // 1000 0000
|
||||||
|
t2 = 0xC0 // 1100 0000
|
||||||
|
t3 = 0xE0 // 1110 0000
|
||||||
|
t4 = 0xF0 // 1111 0000
|
||||||
|
t5 = 0xF8 // 1111 1000
|
||||||
|
|
||||||
|
maskx = 0x3F // 0011 1111
|
||||||
|
mask2 = 0x1F // 0001 1111
|
||||||
|
mask3 = 0x0F // 0000 1111
|
||||||
|
mask4 = 0x07 // 0000 0111
|
||||||
|
|
||||||
|
rune1Max = 1<<7 - 1
|
||||||
|
rune2Max = 1<<11 - 1
|
||||||
|
rune3Max = 1<<16 - 1
|
||||||
|
|
||||||
|
surrogateMin = 0xD800
|
||||||
|
surrogateMax = 0xDFFF
|
||||||
|
|
||||||
|
maxRune = '\U0010FFFF' // Maximum valid Unicode code point.
|
||||||
|
runeError = '\uFFFD' // the "error" Rune or "Unicode replacement character"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AppendRune(p []byte, r rune) []byte {
|
||||||
|
// Negative values are erroneous. Making it unsigned addresses the problem.
|
||||||
|
switch i := uint32(r); {
|
||||||
|
case i <= rune1Max:
|
||||||
|
p = append(p, byte(r))
|
||||||
|
return p
|
||||||
|
case i <= rune2Max:
|
||||||
|
p = append(p, t2|byte(r>>6))
|
||||||
|
p = append(p, tx|byte(r)&maskx)
|
||||||
|
return p
|
||||||
|
case i > maxRune, surrogateMin <= i && i <= surrogateMax:
|
||||||
|
r = runeError
|
||||||
|
fallthrough
|
||||||
|
case i <= rune3Max:
|
||||||
|
p = append(p, t3|byte(r>>12))
|
||||||
|
p = append(p, tx|byte(r>>6)&maskx)
|
||||||
|
p = append(p, tx|byte(r)&maskx)
|
||||||
|
return p
|
||||||
|
default:
|
||||||
|
p = append(p, t4|byte(r>>18))
|
||||||
|
p = append(p, tx|byte(r>>12)&maskx)
|
||||||
|
p = append(p, tx|byte(r>>6)&maskx)
|
||||||
|
p = append(p, tx|byte(r)&maskx)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,14 @@
|
|||||||
package gin
|
package gin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"go_dreamfactory/lego/sys/gin/engine"
|
"go_dreamfactory/lego/sys/gin/engine"
|
||||||
|
"go_dreamfactory/lego/utils/crypto/md5"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ISys interface {
|
type ISys interface {
|
||||||
@ -71,3 +76,41 @@ func Static(relativePath string, root string) engine.IRoutes {
|
|||||||
func StaticFS(relativePath string, fs http.FileSystem) engine.IRoutes {
|
func StaticFS(relativePath string, fs http.FileSystem) engine.IRoutes {
|
||||||
return defsys.StaticFS(relativePath, fs)
|
return defsys.StaticFS(relativePath, fs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//签名接口
|
||||||
|
func ParamSign(key string, param map[string]interface{}) (sign string) {
|
||||||
|
var keys []string
|
||||||
|
for k, _ := range param {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
builder := strings.Builder{}
|
||||||
|
for _, v := range keys {
|
||||||
|
builder.WriteString(v)
|
||||||
|
builder.WriteString("=")
|
||||||
|
switch reflect.TypeOf(param[v]).Kind() {
|
||||||
|
case reflect.Int,
|
||||||
|
reflect.Int8,
|
||||||
|
reflect.Int16,
|
||||||
|
reflect.Int32,
|
||||||
|
reflect.Int64,
|
||||||
|
reflect.Uint,
|
||||||
|
reflect.Uint8,
|
||||||
|
reflect.Uint16,
|
||||||
|
reflect.Uint32,
|
||||||
|
reflect.Uint64,
|
||||||
|
reflect.Uintptr,
|
||||||
|
reflect.Float32,
|
||||||
|
reflect.Float64:
|
||||||
|
builder.WriteString(fmt.Sprintf("%d", param[v]))
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
builder.WriteString(fmt.Sprintf("%s", param[v]))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
builder.WriteString("&")
|
||||||
|
}
|
||||||
|
builder.WriteString("key=" + key)
|
||||||
|
sign = md5.MD5EncToLower(builder.String())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -50,7 +50,10 @@ func NewSys(option ...Option) (sys ILog, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Clone(option ...Option) ILog {
|
func Clone(option ...Option) ILog {
|
||||||
return defsys.Clone(option...)
|
if defsys != nil {
|
||||||
|
return defsys.Clone(option...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Debug(msg string, fields ...Field) { defsys.Debug(msg, fields...) }
|
func Debug(msg string, fields ...Field) { defsys.Debug(msg, fields...) }
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
"go.mongodb.org/mongo-driver/mongo/readconcern"
|
|
||||||
"go.mongodb.org/mongo-driver/mongo/readpref"
|
"go.mongodb.org/mongo-driver/mongo/readpref"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,12 +30,12 @@ func (this *Mongodb) init() (err error) {
|
|||||||
// return fmt.Errorf("数据库设置辅助节点 err=%s", err.Error())
|
// return fmt.Errorf("数据库设置辅助节点 err=%s", err.Error())
|
||||||
// }
|
// }
|
||||||
// wc := writeconcern.New(writeconcern.W(1))
|
// wc := writeconcern.New(writeconcern.W(1))
|
||||||
readconcern.Majority()
|
// readconcern.Majority()
|
||||||
//链接mongo服务
|
//链接mongo服务
|
||||||
opt := options.Client().ApplyURI(this.options.MongodbUrl)
|
opt := options.Client().ApplyURI(this.options.MongodbUrl)
|
||||||
// opt.SetLocalThreshold(3 * time.Second) //只使用与mongo操作耗时小于3秒的
|
// opt.SetLocalThreshold(3 * time.Second) //只使用与mongo操作耗时小于3秒的
|
||||||
// opt.SetMaxConnIdleTime(5 * time.Second) //指定连接可以保持空闲的最大毫秒数
|
// opt.SetMaxConnIdleTime(5 * time.Second) //指定连接可以保持空闲的最大毫秒数
|
||||||
opt.SetMaxPoolSize(this.options.MaxPoolSize) //使用最大的连接数
|
// opt.SetMaxPoolSize(this.options.MaxPoolSize) //使用最大的连接数
|
||||||
// opt.SetReadPreference(want) //表示只使用辅助节点
|
// opt.SetReadPreference(want) //表示只使用辅助节点
|
||||||
// opt.SetReadConcern(readconcern.Majority()) //指定查询应返回实例的最新数据确认为,已写入副本集中的大多数成员
|
// opt.SetReadConcern(readconcern.Majority()) //指定查询应返回实例的最新数据确认为,已写入副本集中的大多数成员
|
||||||
// opt.SetWriteConcern(wc) //请求确认写操作传播到大多数mongod实例
|
// opt.SetWriteConcern(wc) //请求确认写操作传播到大多数mongod实例
|
||||||
@ -48,7 +47,6 @@ func (this *Mongodb) init() (err error) {
|
|||||||
return fmt.Errorf("数据库不可用 err=%s", err.Error())
|
return fmt.Errorf("数据库不可用 err=%s", err.Error())
|
||||||
}
|
}
|
||||||
this.Database = client.Database(this.options.MongodbDatabase)
|
this.Database = client.Database(this.options.MongodbDatabase)
|
||||||
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,14 @@ package cluster
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"go_dreamfactory/lego/utils/codec"
|
"go_dreamfactory/lego/sys/redis/core"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-redis/redis/v8"
|
"github.com/go-redis/redis/v8"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewSys(RedisUrl []string, RedisPassword string, timeOut time.Duration,
|
func NewSys(RedisUrl []string, RedisPassword string, timeOut time.Duration,
|
||||||
encode codec.IEncoder,
|
codec core.ICodec,
|
||||||
decode codec.IDecoder,
|
|
||||||
) (sys *Redis, err error) {
|
) (sys *Redis, err error) {
|
||||||
var (
|
var (
|
||||||
client *redis.ClusterClient
|
client *redis.ClusterClient
|
||||||
@ -22,8 +21,7 @@ func NewSys(RedisUrl []string, RedisPassword string, timeOut time.Duration,
|
|||||||
sys = &Redis{
|
sys = &Redis{
|
||||||
client: client,
|
client: client,
|
||||||
timeOut: timeOut,
|
timeOut: timeOut,
|
||||||
encode: encode,
|
codec: codec,
|
||||||
decode: decode,
|
|
||||||
}
|
}
|
||||||
_, err = sys.Ping()
|
_, err = sys.Ping()
|
||||||
return
|
return
|
||||||
@ -32,8 +30,7 @@ func NewSys(RedisUrl []string, RedisPassword string, timeOut time.Duration,
|
|||||||
type Redis struct {
|
type Redis struct {
|
||||||
client *redis.ClusterClient
|
client *redis.ClusterClient
|
||||||
timeOut time.Duration
|
timeOut time.Duration
|
||||||
encode codec.IEncoder
|
codec core.ICodec
|
||||||
decode codec.IDecoder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Redis) getContext() (ctx context.Context) {
|
func (this *Redis) getContext() (ctx context.Context) {
|
||||||
|
@ -36,7 +36,7 @@ func (this *Redis) HMSet(key string, v interface{}) (err error) {
|
|||||||
agrs = append(agrs, "HMSET")
|
agrs = append(agrs, "HMSET")
|
||||||
agrs = append(agrs, key)
|
agrs = append(agrs, key)
|
||||||
var data map[string]string
|
var data map[string]string
|
||||||
if data, err = this.encode.EncoderToMapString(v); err != nil {
|
if data, err = this.codec.MarshalMap(v); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for k, v := range data {
|
for k, v := range data {
|
||||||
@ -46,19 +46,30 @@ func (this *Redis) HMSet(key string, v interface{}) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *Redis) HMSetForMap(key string, v map[string]string) (err error) {
|
||||||
|
agrs := make([]interface{}, 0)
|
||||||
|
agrs = append(agrs, "HMSET")
|
||||||
|
agrs = append(agrs, key)
|
||||||
|
for k, v := range v {
|
||||||
|
agrs = append(agrs, k, v)
|
||||||
|
}
|
||||||
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Redis Hget 命令用于返回哈希表中指定字段的值
|
Redis Hget 命令用于返回哈希表中指定字段的值
|
||||||
*/
|
*/
|
||||||
func (this *Redis) HGet(key string, field string, v interface{}) (err error) {
|
func (this *Redis) HGet(key string, field string, v interface{}) (err error) {
|
||||||
cmd := redis.NewStringCmd(this.getContext(), "HGET", key, field)
|
cmd := redis.NewStringCmd(this.getContext(), "HGET", key, field)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
var _result string
|
var _result []byte
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Bytes(); err == nil {
|
||||||
if len(_result) == 0 {
|
if len(_result) == 0 {
|
||||||
err = redis.Nil
|
err = redis.Nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.decode.DecoderString(_result, v)
|
err = this.codec.Unmarshal(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -76,7 +87,22 @@ func (this *Redis) HGetAll(key string, v interface{}) (err error) {
|
|||||||
err = redis.Nil
|
err = redis.Nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.decode.DecoderMapString(_result, v)
|
err = this.codec.UnmarshalMap(_result, v)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
读取全部hash集合数据到map中
|
||||||
|
*/
|
||||||
|
func (this *Redis) HGetAllToMapString(key string) (result map[string]string, err error) {
|
||||||
|
cmd := redis.NewStringStringMapCmd(this.getContext(), "HGETALL", key)
|
||||||
|
this.client.Process(this.getContext(), cmd)
|
||||||
|
if result, err = cmd.Result(); err == nil {
|
||||||
|
if len(result) == 0 {
|
||||||
|
err = redis.Nil
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -140,7 +166,7 @@ func (this *Redis) HMGet(key string, v interface{}, fields ...string) (err error
|
|||||||
err = redis.Nil
|
err = redis.Nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.decode.DecoderMapString(_result, v)
|
err = this.codec.UnmarshalMap(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -152,7 +178,7 @@ Redis Hset 命令用于为哈希表中的字段赋值
|
|||||||
*/
|
*/
|
||||||
func (this *Redis) HSet(key string, field string, value interface{}) (err error) {
|
func (this *Redis) HSet(key string, field string, value interface{}) (err error) {
|
||||||
var resultvalue []byte
|
var resultvalue []byte
|
||||||
if resultvalue, err = this.encode.Encoder(value); err == nil {
|
if resultvalue, err = this.codec.Marshal(value); err == nil {
|
||||||
err = this.client.Do(this.getContext(), "HSET", key, field, resultvalue).Err()
|
err = this.client.Do(this.getContext(), "HSET", key, field, resultvalue).Err()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -166,7 +192,7 @@ Redis Hsetnx 命令用于为哈希表中不存在的的字段赋值
|
|||||||
*/
|
*/
|
||||||
func (this *Redis) HSetNX(key string, field string, value interface{}) (err error) {
|
func (this *Redis) HSetNX(key string, field string, value interface{}) (err error) {
|
||||||
var resultvalue []byte
|
var resultvalue []byte
|
||||||
if resultvalue, err = this.encode.Encoder(value); err == nil {
|
if resultvalue, err = this.codec.Marshal(value); err == nil {
|
||||||
err = this.client.Do(this.getContext(), "HSETNX", key, field, resultvalue).Err()
|
err = this.client.Do(this.getContext(), "HSETNX", key, field, resultvalue).Err()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -10,13 +10,13 @@ Redis Lindex 命令用于通过索引获取列表中的元素。你也可以使
|
|||||||
func (this *Redis) Lindex(key string, v interface{}) (err error) {
|
func (this *Redis) Lindex(key string, v interface{}) (err error) {
|
||||||
cmd := redis.NewStringCmd(this.getContext(), "LINDEX", key)
|
cmd := redis.NewStringCmd(this.getContext(), "LINDEX", key)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
var _result string
|
var _result []byte
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Bytes(); err == nil {
|
||||||
if len(_result) == 0 {
|
if len(_result) == 0 {
|
||||||
err = redis.Nil
|
err = redis.Nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.decode.DecoderString(_result, v)
|
err = this.codec.Unmarshal(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -28,13 +28,13 @@ Redis Linsert 命令用于在列表的元素前或者后插入元素。当指定
|
|||||||
*/
|
*/
|
||||||
func (this *Redis) Linsert(key string, isbefore bool, tager interface{}, value interface{}) (err error) {
|
func (this *Redis) Linsert(key string, isbefore bool, tager interface{}, value interface{}) (err error) {
|
||||||
var (
|
var (
|
||||||
tagervalue string
|
tagervalue []byte
|
||||||
resultvalue string
|
resultvalue []byte
|
||||||
)
|
)
|
||||||
if tagervalue, err = this.encode.EncoderString(tager); err != nil {
|
if tagervalue, err = this.codec.Marshal(tager); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if resultvalue, err = this.encode.EncoderString(value); err != nil {
|
if resultvalue, err = this.codec.Marshal(value); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if isbefore {
|
if isbefore {
|
||||||
@ -59,9 +59,9 @@ Redis Lpop 命令用于移除并返回列表的第一个元素
|
|||||||
func (this *Redis) LPop(key string, v interface{}) (err error) {
|
func (this *Redis) LPop(key string, v interface{}) (err error) {
|
||||||
cmd := redis.NewStringCmd(this.getContext(), "LPOP", key)
|
cmd := redis.NewStringCmd(this.getContext(), "LPOP", key)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
var _result string
|
var _result []byte
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Bytes(); err == nil {
|
||||||
err = this.decode.DecoderString(_result, v)
|
err = this.codec.Unmarshal(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ func (this *Redis) LPush(key string, values ...interface{}) (err error) {
|
|||||||
agrs := make([]interface{}, 0)
|
agrs := make([]interface{}, 0)
|
||||||
agrs = append(agrs, "LPUSH")
|
agrs = append(agrs, "LPUSH")
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, result)
|
agrs = append(agrs, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
@ -87,7 +87,7 @@ func (this *Redis) LPushX(key string, values ...interface{}) (err error) {
|
|||||||
agrs := make([]interface{}, 0)
|
agrs := make([]interface{}, 0)
|
||||||
agrs = append(agrs, "LPUSHX")
|
agrs = append(agrs, "LPUSHX")
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, result)
|
agrs = append(agrs, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
@ -103,7 +103,7 @@ func (this *Redis) LRange(key string, start, end int, v interface{}) (err error)
|
|||||||
cmd := redis.NewStringSliceCmd(this.getContext(), "LRANGE", key, start, end)
|
cmd := redis.NewStringSliceCmd(this.getContext(), "LRANGE", key, start, end)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -116,8 +116,8 @@ count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,
|
|||||||
count = 0 : 移除表中所有与 VALUE 相等的值
|
count = 0 : 移除表中所有与 VALUE 相等的值
|
||||||
*/
|
*/
|
||||||
func (this *Redis) LRem(key string, count int, target interface{}) (err error) {
|
func (this *Redis) LRem(key string, count int, target interface{}) (err error) {
|
||||||
var resultvalue string
|
var resultvalue []byte
|
||||||
if resultvalue, err = this.encode.EncoderString(target); err != nil {
|
if resultvalue, err = this.codec.Marshal(target); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), "LREM", key, count, resultvalue).Err()
|
err = this.client.Do(this.getContext(), "LREM", key, count, resultvalue).Err()
|
||||||
@ -129,8 +129,8 @@ Redis Lset 通过索引来设置元素的值。
|
|||||||
当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误
|
当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误
|
||||||
*/
|
*/
|
||||||
func (this *Redis) LSet(key string, index int, value interface{}) (err error) {
|
func (this *Redis) LSet(key string, index int, value interface{}) (err error) {
|
||||||
var resultvalue string
|
var resultvalue []byte
|
||||||
if resultvalue, err = this.encode.EncoderString(value); err == nil {
|
if resultvalue, err = this.codec.Marshal(value); err == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), "LSET", key, index, resultvalue).Err()
|
err = this.client.Do(this.getContext(), "LSET", key, index, resultvalue).Err()
|
||||||
@ -153,9 +153,9 @@ Redis Rpop 命令用于移除列表的最后一个元素,返回值为移除的
|
|||||||
func (this *Redis) Rpop(key string, v interface{}) (err error) {
|
func (this *Redis) Rpop(key string, v interface{}) (err error) {
|
||||||
cmd := redis.NewStringCmd(this.getContext(), "RPOP", key)
|
cmd := redis.NewStringCmd(this.getContext(), "RPOP", key)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
var _result string
|
var _result []byte
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Bytes(); err == nil {
|
||||||
err = this.decode.DecoderString(_result, v)
|
err = this.codec.Unmarshal(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -166,9 +166,9 @@ Redis Rpoplpush 命令用于移除列表的最后一个元素,并将该元素
|
|||||||
func (this *Redis) RPopLPush(oldkey string, newkey string, v interface{}) (err error) {
|
func (this *Redis) RPopLPush(oldkey string, newkey string, v interface{}) (err error) {
|
||||||
cmd := redis.NewStringCmd(this.getContext(), "RPOPLPUSH", oldkey, newkey)
|
cmd := redis.NewStringCmd(this.getContext(), "RPOPLPUSH", oldkey, newkey)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
var _result string
|
var _result []byte
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Bytes(); err == nil {
|
||||||
err = this.decode.DecoderString(_result, v)
|
err = this.codec.Unmarshal(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ func (this *Redis) RPush(key string, values ...interface{}) (err error) {
|
|||||||
agrs := make([]interface{}, 0)
|
agrs := make([]interface{}, 0)
|
||||||
agrs = append(agrs, "RPUSH")
|
agrs = append(agrs, "RPUSH")
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, result)
|
agrs = append(agrs, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
@ -196,7 +196,7 @@ func (this *Redis) RPushX(key string, values ...interface{}) (err error) {
|
|||||||
agrs := make([]interface{}, 0)
|
agrs := make([]interface{}, 0)
|
||||||
agrs = append(agrs, "RPUSHX")
|
agrs = append(agrs, "RPUSHX")
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, result)
|
agrs = append(agrs, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
|
@ -10,7 +10,7 @@ func (this *Redis) SAdd(key string, values ...interface{}) (err error) {
|
|||||||
agrs = append(agrs, "SADD")
|
agrs = append(agrs, "SADD")
|
||||||
agrs = append(agrs, key)
|
agrs = append(agrs, key)
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, result)
|
agrs = append(agrs, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
@ -34,7 +34,7 @@ func (this *Redis) SDiff(v interface{}, keys ...string) (err error) {
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.SDiff(this.getContext(), keys...)
|
cmd := this.client.SDiff(this.getContext(), keys...)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ func (this *Redis) SInter(v interface{}, keys ...string) (err error) {
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.SInter(this.getContext(), keys...)
|
cmd := this.client.SInter(this.getContext(), keys...)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ func (this *Redis) SMembers(v interface{}, key string) (err error) {
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.SMembers(this.getContext(), key)
|
cmd := this.client.SMembers(this.getContext(), key)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ func (this *Redis) SUnion(v interface{}, keys ...string) (err error) {
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.SUnion(this.getContext(), keys...)
|
cmd := this.client.SUnion(this.getContext(), keys...)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ import (
|
|||||||
命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型。
|
命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型。
|
||||||
*/
|
*/
|
||||||
func (this *Redis) Set(key string, value interface{}, expiration time.Duration) (err error) {
|
func (this *Redis) Set(key string, value interface{}, expiration time.Duration) (err error) {
|
||||||
var result string
|
var result []byte
|
||||||
if result, err = this.encode.EncoderString(value); err != nil {
|
if result, err = this.codec.Marshal(value); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.client.Set(this.getContext(), key, result, expiration).Err()
|
err = this.client.Set(this.getContext(), key, result, expiration).Err()
|
||||||
@ -37,7 +37,7 @@ func (this *Redis) MSet(v map[string]interface{}) (err error) {
|
|||||||
agrs := make([]interface{}, 0)
|
agrs := make([]interface{}, 0)
|
||||||
agrs = append(agrs, "MSET")
|
agrs = append(agrs, "MSET")
|
||||||
for k, v := range v {
|
for k, v := range v {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, k, result)
|
agrs = append(agrs, k, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
@ -51,7 +51,7 @@ func (this *Redis) MSetNX(v map[string]interface{}) (err error) {
|
|||||||
agrs := make([]interface{}, 0)
|
agrs := make([]interface{}, 0)
|
||||||
agrs = append(agrs, "MSETNX")
|
agrs = append(agrs, "MSETNX")
|
||||||
for k, v := range v {
|
for k, v := range v {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, k, result)
|
agrs = append(agrs, k, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
@ -117,8 +117,8 @@ Redis Append 命令用于为指定的 key 追加值。
|
|||||||
如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
|
如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
|
||||||
*/
|
*/
|
||||||
func (this *Redis) Append(key string, value interface{}) (err error) {
|
func (this *Redis) Append(key string, value interface{}) (err error) {
|
||||||
var result string
|
var result []byte
|
||||||
if result, err = this.encode.EncoderString(value); err != nil {
|
if result, err = this.codec.Marshal(value); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), "APPEND", key, result).Err()
|
err = this.client.Do(this.getContext(), "APPEND", key, result).Err()
|
||||||
@ -129,9 +129,9 @@ func (this *Redis) Append(key string, value interface{}) (err error) {
|
|||||||
命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型
|
命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型
|
||||||
*/
|
*/
|
||||||
func (this *Redis) Get(key string, value interface{}) (err error) {
|
func (this *Redis) Get(key string, value interface{}) (err error) {
|
||||||
var result string
|
var result []byte
|
||||||
if result, err = this.client.Get(this.getContext(), key).Result(); err == nil {
|
if result, err = this.client.Get(this.getContext(), key).Bytes(); err == nil {
|
||||||
err = this.decode.DecoderString(result, value)
|
err = this.codec.Unmarshal(result, value)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -141,14 +141,14 @@ func (this *Redis) Get(key string, value interface{}) (err error) {
|
|||||||
*/
|
*/
|
||||||
func (this *Redis) GetSet(key string, value interface{}, result interface{}) (err error) {
|
func (this *Redis) GetSet(key string, value interface{}, result interface{}) (err error) {
|
||||||
var (
|
var (
|
||||||
_value string
|
_value []byte
|
||||||
)
|
)
|
||||||
if _value, err = this.encode.EncoderString(value); err == nil {
|
if _value, err = this.codec.Marshal(value); err == nil {
|
||||||
cmd := redis.NewStringCmd(this.getContext(), "GETSET", key, _value)
|
cmd := redis.NewStringCmd(this.getContext(), "GETSET", key, _value)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
var _result string
|
var _result []byte
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Bytes(); err == nil {
|
||||||
err = this.decode.DecoderString(_result, result)
|
err = this.codec.Unmarshal(_result, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -169,7 +169,7 @@ func (this *Redis) MGet(v interface{}, keys ...string) (err error) {
|
|||||||
if result, err = cmd.Result(); err != nil {
|
if result, err = cmd.Result(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.decode.DecoderSliceString(result, v)
|
err = this.codec.UnmarshalSlice(result, v)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ func (this *Redis) ZRange(key string, start int64, stop int64, v interface{}) (e
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.ZRange(this.getContext(), key, start, stop)
|
cmd := this.client.ZRange(this.getContext(), key, start, stop)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ func (this *Redis) ZRangeByLex(key string, opt *redis.ZRangeBy, v interface{}) (
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.ZRangeByLex(this.getContext(), key, opt)
|
cmd := this.client.ZRangeByLex(this.getContext(), key, opt)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ func (this *Redis) ZRangeByScore(key string, opt *redis.ZRangeBy, v interface{})
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.ZRangeByScore(this.getContext(), key, opt)
|
cmd := this.client.ZRangeByScore(this.getContext(), key, opt)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ func (this *Redis) ZRevRange(key string, start int64, stop int64, v interface{})
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.ZRevRange(this.getContext(), key, start, stop)
|
cmd := this.client.ZRevRange(this.getContext(), key, start, stop)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ func (this *Redis) ZRevRangeByScore(key string, opt *redis.ZRangeBy, v interface
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.ZRevRangeByScore(this.getContext(), key, opt)
|
cmd := this.client.ZRevRangeByScore(this.getContext(), key, opt)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -65,12 +65,14 @@ type (
|
|||||||
HExists(key string, field string) (result bool, err error)
|
HExists(key string, field string) (result bool, err error)
|
||||||
HGet(key string, field string, value interface{}) (err error)
|
HGet(key string, field string, value interface{}) (err error)
|
||||||
HGetAll(key string, v interface{}) (err error)
|
HGetAll(key string, v interface{}) (err error)
|
||||||
|
HGetAllToMapString(key string) (result map[string]string, err error)
|
||||||
HIncrBy(key string, field string, value int) (err error)
|
HIncrBy(key string, field string, value int) (err error)
|
||||||
HIncrByFloat(key string, field string, value float32) (err error)
|
HIncrByFloat(key string, field string, value float32) (err error)
|
||||||
Hkeys(key string) (result []string, err error)
|
Hkeys(key string) (result []string, err error)
|
||||||
Hlen(key string) (result int, err error)
|
Hlen(key string) (result int, err error)
|
||||||
HMGet(key string, v interface{}, fields ...string) (err error)
|
HMGet(key string, v interface{}, fields ...string) (err error)
|
||||||
HMSet(key string, v interface{}) (err error)
|
HMSet(key string, v interface{}) (err error)
|
||||||
|
HMSetForMap(key string, v map[string]string) (err error)
|
||||||
HSet(key string, field string, value interface{}) (err error)
|
HSet(key string, field string, value interface{}) (err error)
|
||||||
HSetNX(key string, field string, value interface{}) (err error)
|
HSetNX(key string, field string, value interface{}) (err error)
|
||||||
/*Set*/
|
/*Set*/
|
||||||
@ -325,6 +327,9 @@ func HMGet(key string, v interface{}, fields ...string) (err error) {
|
|||||||
func HMSet(key string, v interface{}) (err error) {
|
func HMSet(key string, v interface{}) (err error) {
|
||||||
return defsys.HMSet(key, v)
|
return defsys.HMSet(key, v)
|
||||||
}
|
}
|
||||||
|
func HMSetForMap(key string, v map[string]string) (err error) {
|
||||||
|
return defsys.HMSetForMap(key, v)
|
||||||
|
}
|
||||||
func HSet(key string, field string, value interface{}) (err error) {
|
func HSet(key string, field string, value interface{}) (err error) {
|
||||||
return defsys.HSet(key, field, value)
|
return defsys.HSet(key, field, value)
|
||||||
}
|
}
|
||||||
|
12
lego/sys/redis/core/core.go
Normal file
12
lego/sys/redis/core/core.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
type (
|
||||||
|
ICodec interface {
|
||||||
|
Marshal(v interface{}) ([]byte, error)
|
||||||
|
Unmarshal(data []byte, v interface{}) error
|
||||||
|
MarshalMap(val interface{}) (ret map[string]string, err error)
|
||||||
|
UnmarshalMap(data map[string]string, val interface{}) (err error)
|
||||||
|
MarshalSlice(val interface{}) (ret []string, err error)
|
||||||
|
UnmarshalSlice(data []string, val interface{}) (err error)
|
||||||
|
}
|
||||||
|
)
|
@ -3,6 +3,7 @@ package redis
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go_dreamfactory/lego/sys/redis/core"
|
||||||
"go_dreamfactory/lego/utils/mapstructure"
|
"go_dreamfactory/lego/utils/mapstructure"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,14 +14,6 @@ const (
|
|||||||
Redis_Cluster
|
Redis_Cluster
|
||||||
)
|
)
|
||||||
|
|
||||||
///redis 存储数据格式化类型
|
|
||||||
type RedisStorageTyoe int8
|
|
||||||
|
|
||||||
const (
|
|
||||||
JsonData RedisStorageTyoe = iota
|
|
||||||
ProtoData
|
|
||||||
)
|
|
||||||
|
|
||||||
type Option func(*Options)
|
type Option func(*Options)
|
||||||
type Options struct {
|
type Options struct {
|
||||||
RedisType RedisType
|
RedisType RedisType
|
||||||
@ -30,8 +23,8 @@ type Options struct {
|
|||||||
Redis_Single_PoolSize int
|
Redis_Single_PoolSize int
|
||||||
Redis_Cluster_Addr []string
|
Redis_Cluster_Addr []string
|
||||||
Redis_Cluster_Password string
|
Redis_Cluster_Password string
|
||||||
RedisStorageType RedisStorageTyoe
|
|
||||||
TimeOut time.Duration
|
TimeOut time.Duration
|
||||||
|
Codec core.ICodec
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetRedisType(v RedisType) Option {
|
func SetRedisType(v RedisType) Option {
|
||||||
@ -74,11 +67,6 @@ func SetRedis_Cluster_Password(v string) Option {
|
|||||||
o.Redis_Cluster_Password = v
|
o.Redis_Cluster_Password = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func SetRedisStorageType(v RedisStorageTyoe) Option {
|
|
||||||
return func(o *Options) {
|
|
||||||
o.RedisStorageType = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetTimeOut(v time.Duration) Option {
|
func SetTimeOut(v time.Duration) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
@ -86,6 +74,12 @@ func SetTimeOut(v time.Duration) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetCodec(v core.ICodec) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Codec = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newOptions(config map[string]interface{}, opts ...Option) Options {
|
func newOptions(config map[string]interface{}, opts ...Option) Options {
|
||||||
options := Options{
|
options := Options{
|
||||||
Redis_Single_Addr: "127.0.0.1:6379",
|
Redis_Single_Addr: "127.0.0.1:6379",
|
||||||
|
@ -5,25 +5,15 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
"go_dreamfactory/lego/sys/codec"
|
||||||
|
|
||||||
"go_dreamfactory/lego/sys/redis/cluster"
|
"go_dreamfactory/lego/sys/redis/cluster"
|
||||||
"go_dreamfactory/lego/sys/redis/single"
|
"go_dreamfactory/lego/sys/redis/single"
|
||||||
"go_dreamfactory/lego/utils/codec"
|
|
||||||
|
|
||||||
"github.com/go-redis/redis/v8"
|
"github.com/go-redis/redis/v8"
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func newSys(options Options) (sys *Redis, err error) {
|
func newSys(options Options) (sys *Redis, err error) {
|
||||||
sys = &Redis{options: options}
|
sys = &Redis{options: options}
|
||||||
if options.RedisStorageType == JsonData {
|
|
||||||
sys.decoder = &codec.Decoder{DefDecoder: jsoniter.Unmarshal}
|
|
||||||
sys.encoder = &codec.Encoder{DefEncoder: jsoniter.Marshal}
|
|
||||||
} else {
|
|
||||||
sys.decoder = &codec.Decoder{DefDecoder: func(buf []byte, v interface{}) error { return proto.Unmarshal(buf, v.(proto.Message)) }}
|
|
||||||
sys.encoder = &codec.Encoder{DefEncoder: func(v interface{}) (data []byte, err error) { return proto.Marshal(v.(proto.Message)) }}
|
|
||||||
}
|
|
||||||
err = sys.init()
|
err = sys.init()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -31,8 +21,6 @@ func newSys(options Options) (sys *Redis, err error) {
|
|||||||
type Redis struct {
|
type Redis struct {
|
||||||
options Options
|
options Options
|
||||||
client IRedis
|
client IRedis
|
||||||
decoder codec.IDecoder
|
|
||||||
encoder codec.IEncoder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Redis) init() (err error) {
|
func (this *Redis) init() (err error) {
|
||||||
@ -43,16 +31,14 @@ func (this *Redis) init() (err error) {
|
|||||||
this.options.Redis_Single_DB,
|
this.options.Redis_Single_DB,
|
||||||
this.options.Redis_Single_PoolSize,
|
this.options.Redis_Single_PoolSize,
|
||||||
this.options.TimeOut,
|
this.options.TimeOut,
|
||||||
this.encoder,
|
this,
|
||||||
this.decoder,
|
|
||||||
)
|
)
|
||||||
} else if this.options.RedisType == Redis_Cluster {
|
} else if this.options.RedisType == Redis_Cluster {
|
||||||
this.client, err = cluster.NewSys(
|
this.client, err = cluster.NewSys(
|
||||||
this.options.Redis_Cluster_Addr,
|
this.options.Redis_Cluster_Addr,
|
||||||
this.options.Redis_Cluster_Password,
|
this.options.Redis_Cluster_Password,
|
||||||
this.options.TimeOut,
|
this.options.TimeOut,
|
||||||
this.encoder,
|
this,
|
||||||
this.decoder,
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
err = fmt.Errorf("init Redis err:RedisType - %d", this.options.RedisType)
|
err = fmt.Errorf("init Redis err:RedisType - %d", this.options.RedisType)
|
||||||
@ -227,6 +213,9 @@ func (this *Redis) HGet(key string, field string, value interface{}) (err error)
|
|||||||
func (this *Redis) HGetAll(key string, v interface{}) (err error) {
|
func (this *Redis) HGetAll(key string, v interface{}) (err error) {
|
||||||
return this.client.HGetAll(key, v)
|
return this.client.HGetAll(key, v)
|
||||||
}
|
}
|
||||||
|
func (this *Redis) HGetAllToMapString(key string) (result map[string]string, err error) {
|
||||||
|
return this.client.HGetAllToMapString(key)
|
||||||
|
}
|
||||||
func (this *Redis) HIncrBy(key string, field string, value int) (err error) {
|
func (this *Redis) HIncrBy(key string, field string, value int) (err error) {
|
||||||
return this.client.HIncrBy(key, field, value)
|
return this.client.HIncrBy(key, field, value)
|
||||||
}
|
}
|
||||||
@ -245,6 +234,11 @@ func (this *Redis) HMGet(key string, v interface{}, fields ...string) (err error
|
|||||||
func (this *Redis) HMSet(key string, v interface{}) (err error) {
|
func (this *Redis) HMSet(key string, v interface{}) (err error) {
|
||||||
return this.client.HMSet(key, v)
|
return this.client.HMSet(key, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *Redis) HMSetForMap(key string, v map[string]string) (err error) {
|
||||||
|
return this.client.HMSetForMap(key, v)
|
||||||
|
}
|
||||||
|
|
||||||
func (this *Redis) HSet(key string, field string, value interface{}) (err error) {
|
func (this *Redis) HSet(key string, field string, value interface{}) (err error) {
|
||||||
return this.client.HSet(key, field, value)
|
return this.client.HSet(key, field, value)
|
||||||
}
|
}
|
||||||
@ -360,3 +354,47 @@ func (this *Redis) ZUnionStore(dest string, store *redis.ZStore) (result int64,
|
|||||||
func (this *Redis) ZScan(key string, _cursor uint64, match string, count int64) (keys []string, cursor uint64, err error) {
|
func (this *Redis) ZScan(key string, _cursor uint64, match string, count int64) (keys []string, cursor uint64, err error) {
|
||||||
return this.client.ZScan(key, _cursor, match, count)
|
return this.client.ZScan(key, _cursor, match, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Codec---------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
func (this *Redis) Marshal(v interface{}) ([]byte, error) {
|
||||||
|
if this.options.Codec != nil {
|
||||||
|
return this.options.Codec.Marshal(v)
|
||||||
|
} else {
|
||||||
|
return codec.MarshalJson(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *Redis) Unmarshal(data []byte, v interface{}) error {
|
||||||
|
if this.options.Codec != nil {
|
||||||
|
return this.options.Codec.Unmarshal(data, v)
|
||||||
|
} else {
|
||||||
|
return codec.UnmarshalJson(data, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *Redis) MarshalMap(val interface{}) (ret map[string]string, err error) {
|
||||||
|
if this.options.Codec != nil {
|
||||||
|
return this.options.Codec.MarshalMap(val)
|
||||||
|
} else {
|
||||||
|
return codec.MarshalMapJson(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *Redis) UnmarshalMap(data map[string]string, val interface{}) (err error) {
|
||||||
|
if this.options.Codec != nil {
|
||||||
|
return this.options.Codec.UnmarshalMap(data, val)
|
||||||
|
} else {
|
||||||
|
return codec.UnmarshalMapJson(data, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *Redis) MarshalSlice(val interface{}) (ret []string, err error) {
|
||||||
|
if this.options.Codec != nil {
|
||||||
|
return this.options.Codec.MarshalSlice(val)
|
||||||
|
} else {
|
||||||
|
return codec.MarshalSliceJson(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *Redis) UnmarshalSlice(data []string, val interface{}) (err error) {
|
||||||
|
if this.options.Codec != nil {
|
||||||
|
return this.options.Codec.UnmarshalSlice(data, val)
|
||||||
|
} else {
|
||||||
|
return codec.UnmarshalSliceJson(data, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,15 +2,14 @@ package single
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"go_dreamfactory/lego/utils/codec"
|
"go_dreamfactory/lego/sys/redis/core"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-redis/redis/v8"
|
"github.com/go-redis/redis/v8"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewSys(RedisUrl, RedisPassword string, RedisDB, PoolSize int, timeOut time.Duration,
|
func NewSys(RedisUrl, RedisPassword string, RedisDB, PoolSize int, timeOut time.Duration,
|
||||||
encode codec.IEncoder,
|
codec core.ICodec,
|
||||||
decode codec.IDecoder,
|
|
||||||
) (sys *Redis, err error) {
|
) (sys *Redis, err error) {
|
||||||
var (
|
var (
|
||||||
client *redis.Client
|
client *redis.Client
|
||||||
@ -24,8 +23,7 @@ func NewSys(RedisUrl, RedisPassword string, RedisDB, PoolSize int, timeOut time.
|
|||||||
sys = &Redis{
|
sys = &Redis{
|
||||||
client: client,
|
client: client,
|
||||||
timeOut: timeOut,
|
timeOut: timeOut,
|
||||||
encode: encode,
|
codec: codec,
|
||||||
decode: decode,
|
|
||||||
}
|
}
|
||||||
_, err = sys.Ping()
|
_, err = sys.Ping()
|
||||||
return
|
return
|
||||||
@ -34,8 +32,7 @@ func NewSys(RedisUrl, RedisPassword string, RedisDB, PoolSize int, timeOut time.
|
|||||||
type Redis struct {
|
type Redis struct {
|
||||||
client *redis.Client
|
client *redis.Client
|
||||||
timeOut time.Duration
|
timeOut time.Duration
|
||||||
encode codec.IEncoder
|
codec core.ICodec
|
||||||
decode codec.IDecoder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Redis) getContext() (ctx context.Context) {
|
func (this *Redis) getContext() (ctx context.Context) {
|
||||||
|
@ -36,7 +36,7 @@ func (this *Redis) HMSet(key string, v interface{}) (err error) {
|
|||||||
agrs = append(agrs, "HMSET")
|
agrs = append(agrs, "HMSET")
|
||||||
agrs = append(agrs, key)
|
agrs = append(agrs, key)
|
||||||
var data map[string]string
|
var data map[string]string
|
||||||
if data, err = this.encode.EncoderToMapString(v); err != nil {
|
if data, err = this.codec.MarshalMap(v); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for k, v := range data {
|
for k, v := range data {
|
||||||
@ -45,6 +45,16 @@ func (this *Redis) HMSet(key string, v interface{}) (err error) {
|
|||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
func (this *Redis) HMSetForMap(key string, v map[string]string) (err error) {
|
||||||
|
agrs := make([]interface{}, 0)
|
||||||
|
agrs = append(agrs, "HMSET")
|
||||||
|
agrs = append(agrs, key)
|
||||||
|
for k, v := range v {
|
||||||
|
agrs = append(agrs, k, v)
|
||||||
|
}
|
||||||
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Redis Hget 命令用于返回哈希表中指定字段的值
|
Redis Hget 命令用于返回哈希表中指定字段的值
|
||||||
@ -52,9 +62,9 @@ Redis Hget 命令用于返回哈希表中指定字段的值
|
|||||||
func (this *Redis) HGet(key string, field string, v interface{}) (err error) {
|
func (this *Redis) HGet(key string, field string, v interface{}) (err error) {
|
||||||
cmd := redis.NewStringCmd(this.getContext(), "HGET", key, field)
|
cmd := redis.NewStringCmd(this.getContext(), "HGET", key, field)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
var _result string
|
var _result []byte
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Bytes(); err == nil {
|
||||||
err = this.decode.DecoderString(_result, v)
|
err = this.codec.Unmarshal(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -71,7 +81,22 @@ func (this *Redis) HGetAll(key string, v interface{}) (err error) {
|
|||||||
if len(_result) == 0 {
|
if len(_result) == 0 {
|
||||||
return redis.Nil
|
return redis.Nil
|
||||||
}
|
}
|
||||||
err = this.decode.DecoderMapString(_result, v)
|
err = this.codec.UnmarshalMap(_result, v)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
读取全部hash集合数据到map中
|
||||||
|
*/
|
||||||
|
func (this *Redis) HGetAllToMapString(key string) (result map[string]string, err error) {
|
||||||
|
cmd := redis.NewStringStringMapCmd(this.getContext(), "HGETALL", key)
|
||||||
|
this.client.Process(this.getContext(), cmd)
|
||||||
|
if result, err = cmd.Result(); err == nil {
|
||||||
|
if len(result) == 0 {
|
||||||
|
err = redis.Nil
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -131,7 +156,7 @@ func (this *Redis) HMGet(key string, v interface{}, fields ...string) (err error
|
|||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
var _result map[string]string
|
var _result map[string]string
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderMapString(_result, v)
|
err = this.codec.UnmarshalMap(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -143,7 +168,7 @@ Redis Hset 命令用于为哈希表中的字段赋值
|
|||||||
*/
|
*/
|
||||||
func (this *Redis) HSet(key string, field string, value interface{}) (err error) {
|
func (this *Redis) HSet(key string, field string, value interface{}) (err error) {
|
||||||
var resultvalue []byte
|
var resultvalue []byte
|
||||||
if resultvalue, err = this.encode.Encoder(value); err == nil {
|
if resultvalue, err = this.codec.Marshal(value); err == nil {
|
||||||
err = this.client.Do(this.getContext(), "HSET", key, field, resultvalue).Err()
|
err = this.client.Do(this.getContext(), "HSET", key, field, resultvalue).Err()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -157,7 +182,7 @@ Redis Hsetnx 命令用于为哈希表中不存在的的字段赋值
|
|||||||
*/
|
*/
|
||||||
func (this *Redis) HSetNX(key string, field string, value interface{}) (err error) {
|
func (this *Redis) HSetNX(key string, field string, value interface{}) (err error) {
|
||||||
var resultvalue []byte
|
var resultvalue []byte
|
||||||
if resultvalue, err = this.encode.Encoder(value); err == nil {
|
if resultvalue, err = this.codec.Marshal(value); err == nil {
|
||||||
err = this.client.Do(this.getContext(), "HSETNX", key, field, resultvalue).Err()
|
err = this.client.Do(this.getContext(), "HSETNX", key, field, resultvalue).Err()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -10,9 +10,9 @@ Redis Lindex 命令用于通过索引获取列表中的元素。你也可以使
|
|||||||
func (this *Redis) Lindex(key string, v interface{}) (err error) {
|
func (this *Redis) Lindex(key string, v interface{}) (err error) {
|
||||||
cmd := redis.NewStringCmd(this.getContext(), "LINDEX", key)
|
cmd := redis.NewStringCmd(this.getContext(), "LINDEX", key)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
var _result string
|
var _result []byte
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Bytes(); err == nil {
|
||||||
err = this.decode.DecoderString(_result, v)
|
err = this.codec.Unmarshal(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -24,13 +24,13 @@ Redis Linsert 命令用于在列表的元素前或者后插入元素。当指定
|
|||||||
*/
|
*/
|
||||||
func (this *Redis) Linsert(key string, isbefore bool, tager interface{}, value interface{}) (err error) {
|
func (this *Redis) Linsert(key string, isbefore bool, tager interface{}, value interface{}) (err error) {
|
||||||
var (
|
var (
|
||||||
tagervalue string
|
tagervalue []byte
|
||||||
resultvalue string
|
resultvalue []byte
|
||||||
)
|
)
|
||||||
if tagervalue, err = this.encode.EncoderString(tager); err != nil {
|
if tagervalue, err = this.codec.Marshal(tager); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if resultvalue, err = this.encode.EncoderString(value); err != nil {
|
if resultvalue, err = this.codec.Marshal(value); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if isbefore {
|
if isbefore {
|
||||||
@ -55,9 +55,9 @@ Redis Lpop 命令用于移除并返回列表的第一个元素
|
|||||||
func (this *Redis) LPop(key string, v interface{}) (err error) {
|
func (this *Redis) LPop(key string, v interface{}) (err error) {
|
||||||
cmd := redis.NewStringCmd(this.getContext(), "LPOP", key)
|
cmd := redis.NewStringCmd(this.getContext(), "LPOP", key)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
var _result string
|
var _result []byte
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Bytes(); err == nil {
|
||||||
err = this.decode.DecoderString(_result, v)
|
err = this.codec.Unmarshal(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ func (this *Redis) LPush(key string, values ...interface{}) (err error) {
|
|||||||
agrs := make([]interface{}, 0)
|
agrs := make([]interface{}, 0)
|
||||||
agrs = append(agrs, "LPUSH")
|
agrs = append(agrs, "LPUSH")
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, result)
|
agrs = append(agrs, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
@ -83,7 +83,7 @@ func (this *Redis) LPushX(key string, values ...interface{}) (err error) {
|
|||||||
agrs := make([]interface{}, 0)
|
agrs := make([]interface{}, 0)
|
||||||
agrs = append(agrs, "LPUSHX")
|
agrs = append(agrs, "LPUSHX")
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, result)
|
agrs = append(agrs, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
@ -99,7 +99,7 @@ func (this *Redis) LRange(key string, start, end int, v interface{}) (err error)
|
|||||||
cmd := redis.NewStringSliceCmd(this.getContext(), "LRANGE", key, start, end)
|
cmd := redis.NewStringSliceCmd(this.getContext(), "LRANGE", key, start, end)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -112,8 +112,8 @@ count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,
|
|||||||
count = 0 : 移除表中所有与 VALUE 相等的值
|
count = 0 : 移除表中所有与 VALUE 相等的值
|
||||||
*/
|
*/
|
||||||
func (this *Redis) LRem(key string, count int, target interface{}) (err error) {
|
func (this *Redis) LRem(key string, count int, target interface{}) (err error) {
|
||||||
var resultvalue string
|
var resultvalue []byte
|
||||||
if resultvalue, err = this.encode.EncoderString(target); err != nil {
|
if resultvalue, err = this.codec.Marshal(target); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), "LREM", key, count, resultvalue).Err()
|
err = this.client.Do(this.getContext(), "LREM", key, count, resultvalue).Err()
|
||||||
@ -125,8 +125,8 @@ Redis Lset 通过索引来设置元素的值。
|
|||||||
当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误
|
当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误
|
||||||
*/
|
*/
|
||||||
func (this *Redis) LSet(key string, index int, value interface{}) (err error) {
|
func (this *Redis) LSet(key string, index int, value interface{}) (err error) {
|
||||||
var resultvalue string
|
var resultvalue []byte
|
||||||
if resultvalue, err = this.encode.EncoderString(value); err == nil {
|
if resultvalue, err = this.codec.Marshal(value); err == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), "LSET", key, index, resultvalue).Err()
|
err = this.client.Do(this.getContext(), "LSET", key, index, resultvalue).Err()
|
||||||
@ -149,9 +149,9 @@ Redis Rpop 命令用于移除列表的最后一个元素,返回值为移除的
|
|||||||
func (this *Redis) Rpop(key string, v interface{}) (err error) {
|
func (this *Redis) Rpop(key string, v interface{}) (err error) {
|
||||||
cmd := redis.NewStringCmd(this.getContext(), "RPOP", key)
|
cmd := redis.NewStringCmd(this.getContext(), "RPOP", key)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
var _result string
|
var _result []byte
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Bytes(); err == nil {
|
||||||
err = this.decode.DecoderString(_result, v)
|
err = this.codec.Unmarshal(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -162,9 +162,9 @@ Redis Rpoplpush 命令用于移除列表的最后一个元素,并将该元素
|
|||||||
func (this *Redis) RPopLPush(oldkey string, newkey string, v interface{}) (err error) {
|
func (this *Redis) RPopLPush(oldkey string, newkey string, v interface{}) (err error) {
|
||||||
cmd := redis.NewStringCmd(this.getContext(), "RPOPLPUSH", oldkey, newkey)
|
cmd := redis.NewStringCmd(this.getContext(), "RPOPLPUSH", oldkey, newkey)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
var _result string
|
var _result []byte
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Bytes(); err == nil {
|
||||||
err = this.decode.DecoderString(_result, v)
|
err = this.codec.Unmarshal(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -178,7 +178,7 @@ func (this *Redis) RPush(key string, values ...interface{}) (err error) {
|
|||||||
agrs := make([]interface{}, 0)
|
agrs := make([]interface{}, 0)
|
||||||
agrs = append(agrs, "RPUSH")
|
agrs = append(agrs, "RPUSH")
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, result)
|
agrs = append(agrs, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
@ -192,7 +192,7 @@ func (this *Redis) RPushX(key string, values ...interface{}) (err error) {
|
|||||||
agrs := make([]interface{}, 0)
|
agrs := make([]interface{}, 0)
|
||||||
agrs = append(agrs, "RPUSHX")
|
agrs = append(agrs, "RPUSHX")
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, result)
|
agrs = append(agrs, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
|
@ -10,7 +10,7 @@ func (this *Redis) SAdd(key string, values ...interface{}) (err error) {
|
|||||||
agrs = append(agrs, "SADD")
|
agrs = append(agrs, "SADD")
|
||||||
agrs = append(agrs, key)
|
agrs = append(agrs, key)
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, result)
|
agrs = append(agrs, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
@ -34,7 +34,7 @@ func (this *Redis) SDiff(v interface{}, keys ...string) (err error) {
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.SDiff(this.getContext(), keys...)
|
cmd := this.client.SDiff(this.getContext(), keys...)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ func (this *Redis) SInter(v interface{}, keys ...string) (err error) {
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.SInter(this.getContext(), keys...)
|
cmd := this.client.SInter(this.getContext(), keys...)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ func (this *Redis) SMembers(v interface{}, key string) (err error) {
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.SMembers(this.getContext(), key)
|
cmd := this.client.SMembers(this.getContext(), key)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ func (this *Redis) SUnion(v interface{}, keys ...string) (err error) {
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.SUnion(this.getContext(), keys...)
|
cmd := this.client.SUnion(this.getContext(), keys...)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ import (
|
|||||||
命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型。
|
命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型。
|
||||||
*/
|
*/
|
||||||
func (this *Redis) Set(key string, value interface{}, expiration time.Duration) (err error) {
|
func (this *Redis) Set(key string, value interface{}, expiration time.Duration) (err error) {
|
||||||
var result string
|
var result []byte
|
||||||
if result, err = this.encode.EncoderString(value); err != nil {
|
if result, err = this.codec.Marshal(value); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.client.Set(this.getContext(), key, result, expiration).Err()
|
err = this.client.Set(this.getContext(), key, result, expiration).Err()
|
||||||
@ -37,7 +37,7 @@ func (this *Redis) MSet(v map[string]interface{}) (err error) {
|
|||||||
agrs := make([]interface{}, 0)
|
agrs := make([]interface{}, 0)
|
||||||
agrs = append(agrs, "MSET")
|
agrs = append(agrs, "MSET")
|
||||||
for k, v := range v {
|
for k, v := range v {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, k, result)
|
agrs = append(agrs, k, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
@ -51,7 +51,7 @@ func (this *Redis) MSetNX(v map[string]interface{}) (err error) {
|
|||||||
agrs := make([]interface{}, 0)
|
agrs := make([]interface{}, 0)
|
||||||
agrs = append(agrs, "MSETNX")
|
agrs = append(agrs, "MSETNX")
|
||||||
for k, v := range v {
|
for k, v := range v {
|
||||||
result, _ := this.encode.EncoderString(v)
|
result, _ := this.codec.Marshal(v)
|
||||||
agrs = append(agrs, k, result)
|
agrs = append(agrs, k, result)
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||||
@ -117,8 +117,8 @@ Redis Append 命令用于为指定的 key 追加值。
|
|||||||
如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
|
如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
|
||||||
*/
|
*/
|
||||||
func (this *Redis) Append(key string, value interface{}) (err error) {
|
func (this *Redis) Append(key string, value interface{}) (err error) {
|
||||||
var result string
|
var result []byte
|
||||||
if result, err = this.encode.EncoderString(value); err != nil {
|
if result, err = this.codec.Marshal(value); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.client.Do(this.getContext(), "APPEND", key, result).Err()
|
err = this.client.Do(this.getContext(), "APPEND", key, result).Err()
|
||||||
@ -129,9 +129,9 @@ func (this *Redis) Append(key string, value interface{}) (err error) {
|
|||||||
命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型
|
命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型
|
||||||
*/
|
*/
|
||||||
func (this *Redis) Get(key string, value interface{}) (err error) {
|
func (this *Redis) Get(key string, value interface{}) (err error) {
|
||||||
var result string
|
var result []byte
|
||||||
if result, err = this.client.Get(this.getContext(), key).Result(); err == nil {
|
if result, err = this.client.Get(this.getContext(), key).Bytes(); err == nil {
|
||||||
err = this.decode.DecoderString(result, value)
|
err = this.codec.Unmarshal(result, value)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -141,14 +141,14 @@ func (this *Redis) Get(key string, value interface{}) (err error) {
|
|||||||
*/
|
*/
|
||||||
func (this *Redis) GetSet(key string, value interface{}, result interface{}) (err error) {
|
func (this *Redis) GetSet(key string, value interface{}, result interface{}) (err error) {
|
||||||
var (
|
var (
|
||||||
_value string
|
_value []byte
|
||||||
)
|
)
|
||||||
if _value, err = this.encode.EncoderString(value); err == nil {
|
if _value, err = this.codec.Marshal(value); err == nil {
|
||||||
cmd := redis.NewStringCmd(this.getContext(), "GETSET", key, _value)
|
cmd := redis.NewStringCmd(this.getContext(), "GETSET", key, _value)
|
||||||
this.client.Process(this.getContext(), cmd)
|
this.client.Process(this.getContext(), cmd)
|
||||||
var _result string
|
var _result []byte
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Bytes(); err == nil {
|
||||||
err = this.decode.DecoderString(_result, result)
|
err = this.codec.Unmarshal(_result, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -169,7 +169,7 @@ func (this *Redis) MGet(v interface{}, keys ...string) (err error) {
|
|||||||
if result, err = cmd.Result(); err != nil {
|
if result, err = cmd.Result(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.decode.DecoderSliceString(result, v)
|
err = this.codec.UnmarshalSlice(result, v)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ func (this *Redis) ZRange(key string, start int64, stop int64, v interface{}) (e
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.ZRange(this.getContext(), key, start, stop)
|
cmd := this.client.ZRange(this.getContext(), key, start, stop)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ func (this *Redis) ZRangeByLex(key string, opt *redis.ZRangeBy, v interface{}) (
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.ZRangeByLex(this.getContext(), key, opt)
|
cmd := this.client.ZRangeByLex(this.getContext(), key, opt)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ func (this *Redis) ZRangeByScore(key string, opt *redis.ZRangeBy, v interface{})
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.ZRangeByScore(this.getContext(), key, opt)
|
cmd := this.client.ZRangeByScore(this.getContext(), key, opt)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ func (this *Redis) ZRevRange(key string, start int64, stop int64, v interface{})
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.ZRevRange(this.getContext(), key, start, stop)
|
cmd := this.client.ZRevRange(this.getContext(), key, start, stop)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ func (this *Redis) ZRevRangeByScore(key string, opt *redis.ZRangeBy, v interface
|
|||||||
var _result []string
|
var _result []string
|
||||||
cmd := this.client.ZRevRangeByScore(this.getContext(), key, opt)
|
cmd := this.client.ZRevRangeByScore(this.getContext(), key, opt)
|
||||||
if _result, err = cmd.Result(); err == nil {
|
if _result, err = cmd.Result(); err == nil {
|
||||||
err = this.decode.DecoderSliceString(_result, v)
|
err = this.codec.UnmarshalSlice(_result, v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ func TestMain(m *testing.M) {
|
|||||||
redis.SetRedisType(redis.Redis_Cluster),
|
redis.SetRedisType(redis.Redis_Cluster),
|
||||||
redis.SetRedis_Cluster_Addr([]string{"10.0.0.9:9001", "10.0.0.9:9002", "10.0.0.9:9003", "10.0.1.45:9004", "10.0.1.45:9005", "10.0.1.45:9006"}),
|
redis.SetRedis_Cluster_Addr([]string{"10.0.0.9:9001", "10.0.0.9:9002", "10.0.0.9:9003", "10.0.1.45:9004", "10.0.1.45:9005", "10.0.1.45:9006"}),
|
||||||
redis.SetRedis_Cluster_Password(""),
|
redis.SetRedis_Cluster_Password(""),
|
||||||
redis.SetRedisStorageType(redis.JsonData),
|
|
||||||
); err != nil {
|
); err != nil {
|
||||||
fmt.Println("err:", err)
|
fmt.Println("err:", err)
|
||||||
return
|
return
|
||||||
|
13
lego/utils/crypto/base64/base64.go
Normal file
13
lego/utils/crypto/base64/base64.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package base64
|
||||||
|
|
||||||
|
import "encoding/base64"
|
||||||
|
|
||||||
|
///编码
|
||||||
|
func EncodeToString(src []byte) string {
|
||||||
|
return base64.StdEncoding.EncodeToString(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
///解码
|
||||||
|
func DecodeString(s string) ([]byte, error) {
|
||||||
|
return base64.StdEncoding.DecodeString(s)
|
||||||
|
}
|
47
lego/utils/crypto/md5/md5.go
Normal file
47
lego/utils/crypto/md5/md5.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package md5
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
MD5加密
|
||||||
|
*/
|
||||||
|
|
||||||
|
//MD5加密 大写
|
||||||
|
func MD5EncToUpper(str string) string {
|
||||||
|
h := md5.New()
|
||||||
|
h.Write([]byte(str))
|
||||||
|
return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
|
||||||
|
}
|
||||||
|
|
||||||
|
//MD5加密 小写
|
||||||
|
func MD5EncToLower(str string) string {
|
||||||
|
h := md5.New()
|
||||||
|
h.Write([]byte(str))
|
||||||
|
return strings.ToLower(hex.EncodeToString(h.Sum(nil)))
|
||||||
|
}
|
||||||
|
|
||||||
|
//参数签名
|
||||||
|
func ParamSign(param map[string]interface{}, key string) (orsign, sign string) {
|
||||||
|
a := sort.StringSlice{}
|
||||||
|
for k, _ := range param {
|
||||||
|
a = append(a, k)
|
||||||
|
}
|
||||||
|
sort.Sort(a)
|
||||||
|
orsign = ""
|
||||||
|
for _, k := range a {
|
||||||
|
switch param[k].(type) { //只签名基础数据
|
||||||
|
case bool, byte, int8, int16, uint16, int32, uint32, int, int64, uint64, float64, float32, string:
|
||||||
|
orsign = orsign + fmt.Sprintf("%s=%v&", k, param[k])
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
orsign = orsign + fmt.Sprintf("key=%s", key)
|
||||||
|
sign = MD5EncToLower(orsign)
|
||||||
|
return
|
||||||
|
}
|
@ -6,14 +6,19 @@ import (
|
|||||||
"go_dreamfactory/comm"
|
"go_dreamfactory/comm"
|
||||||
"go_dreamfactory/lego/core"
|
"go_dreamfactory/lego/core"
|
||||||
"go_dreamfactory/lego/core/cbase"
|
"go_dreamfactory/lego/core/cbase"
|
||||||
|
"go_dreamfactory/lego/sys/codec"
|
||||||
|
ccore "go_dreamfactory/lego/sys/codec/core"
|
||||||
"go_dreamfactory/lego/sys/log"
|
"go_dreamfactory/lego/sys/log"
|
||||||
"go_dreamfactory/lego/sys/mgo"
|
"go_dreamfactory/lego/sys/mgo"
|
||||||
"go_dreamfactory/lego/sys/redis"
|
"go_dreamfactory/lego/sys/redis"
|
||||||
|
"go_dreamfactory/pb"
|
||||||
"go_dreamfactory/sys/cache"
|
"go_dreamfactory/sys/cache"
|
||||||
"go_dreamfactory/sys/db"
|
"go_dreamfactory/sys/db"
|
||||||
"reflect"
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
@ -70,6 +75,7 @@ func (this *MCompModel) InsertModelLogs(table string, uID string, target interfa
|
|||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *MCompModel) DeleteModelLogs(table string, uID string, where interface{}) (err error) {
|
func (this *MCompModel) DeleteModelLogs(table string, uID string, where interface{}) (err error) {
|
||||||
|
|
||||||
data := &comm.Autogenerated{
|
data := &comm.Autogenerated{
|
||||||
@ -88,6 +94,7 @@ func (this *MCompModel) DeleteModelLogs(table string, uID string, where interfac
|
|||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *MCompModel) UpdateModelLogs(table string, uID string, where bson.M, target interface{}) (err error) {
|
func (this *MCompModel) UpdateModelLogs(table string, uID string, where bson.M, target interface{}) (err error) {
|
||||||
|
|
||||||
data := &comm.Autogenerated{
|
data := &comm.Autogenerated{
|
||||||
@ -221,8 +228,8 @@ func (this *MCompModel) Get(uid string, data interface{}) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取列表数据 注意 data 必须啊转 切片的指针 *[]type
|
//获取列表数据 注意 data 必须是 切片的指针 *[]type 暂时废弃
|
||||||
func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
|
func (this *MCompModel) mGetList(uid string, data interface{}) (err error) {
|
||||||
var keys map[string]string = make(map[string]string)
|
var keys map[string]string = make(map[string]string)
|
||||||
var c *mongo.Cursor
|
var c *mongo.Cursor
|
||||||
t := reflect.TypeOf(data)
|
t := reflect.TypeOf(data)
|
||||||
@ -312,6 +319,110 @@ func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取列表数据 注意 data 必须是 切片的指针 *[]type
|
||||||
|
func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
|
||||||
|
var (
|
||||||
|
dtype reflect2.Type
|
||||||
|
dkind reflect.Kind
|
||||||
|
sType reflect2.Type
|
||||||
|
sliceType *reflect2.UnsafeSliceType
|
||||||
|
sliceelemType reflect2.Type
|
||||||
|
decoder ccore.IDecoderMapJson
|
||||||
|
encoder ccore.IEncoderMapJson
|
||||||
|
dptr unsafe.Pointer
|
||||||
|
elemPtr unsafe.Pointer
|
||||||
|
n int
|
||||||
|
ok bool
|
||||||
|
keys map[string]string
|
||||||
|
cdata map[string]string
|
||||||
|
c *mongo.Cursor
|
||||||
|
)
|
||||||
|
keys = make(map[string]string)
|
||||||
|
dptr = reflect2.PtrOf(data)
|
||||||
|
dtype = reflect2.TypeOf(data)
|
||||||
|
dkind = dtype.Kind()
|
||||||
|
if dkind != reflect.Ptr {
|
||||||
|
err = fmt.Errorf("MCompModel: GetList(non-pointer %T)", data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sType = dtype.(*reflect2.UnsafePtrType).Elem()
|
||||||
|
if sType.Kind() != reflect.Slice {
|
||||||
|
err = fmt.Errorf("MCompModel: GetList(data no slice %T)", data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sliceType = sType.(*reflect2.UnsafeSliceType)
|
||||||
|
sliceelemType = sliceType.Elem()
|
||||||
|
if sliceelemType.Kind() != reflect.Ptr {
|
||||||
|
err = fmt.Errorf("MCompModel: GetList(sliceelemType non-pointer %T)", data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if decoder, ok = codec.DecoderOf(sliceelemType).(ccore.IDecoderMapJson); !ok {
|
||||||
|
err = fmt.Errorf("MCompModel: GetList(data not support MarshalMapJson %T)", data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sliceelemType = sliceelemType.(*reflect2.UnsafePtrType).Elem()
|
||||||
|
keys, err = this.Redis.HGetAllToMapString(this.ukey(uid))
|
||||||
|
if err == nil {
|
||||||
|
n = 0
|
||||||
|
for _, v := range keys {
|
||||||
|
if cdata, err = this.Redis.HGetAllToMapString(v); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sliceType.UnsafeGrow(dptr, n+1)
|
||||||
|
elemPtr = sliceType.UnsafeGetIndex(dptr, n)
|
||||||
|
if *((*unsafe.Pointer)(elemPtr)) == nil {
|
||||||
|
newPtr := sliceelemType.UnsafeNew()
|
||||||
|
decoder.DecodeForMapJson(newPtr, cdata)
|
||||||
|
*((*unsafe.Pointer)(elemPtr)) = newPtr
|
||||||
|
} else {
|
||||||
|
decoder.DecodeForMapJson(*((*unsafe.Pointer)(elemPtr)), cdata)
|
||||||
|
}
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == redis.RedisNil {
|
||||||
|
//query from mgo
|
||||||
|
if c, err = this.DB.Find(core.SqlTable(this.TableName), bson.M{"uid": uid}); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
if encoder, ok = codec.EncoderOf(sliceelemType).(ccore.IEncoderMapJson); !ok {
|
||||||
|
err = fmt.Errorf("MCompModel: GetList(data not support UnMarshalMapJson %T)", data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n = 0
|
||||||
|
for c.Next(context.Background()) {
|
||||||
|
_id := c.Current.Lookup("_id").StringValue()
|
||||||
|
sliceType.UnsafeGrow(dptr, n+1)
|
||||||
|
elemPtr = sliceType.UnsafeGetIndex(dptr, n)
|
||||||
|
if *((*unsafe.Pointer)(elemPtr)) == nil {
|
||||||
|
newPtr := sliceelemType.UnsafeNew()
|
||||||
|
*((*unsafe.Pointer)(elemPtr)) = newPtr
|
||||||
|
}
|
||||||
|
elem := sliceType.GetIndex(data, n)
|
||||||
|
n++
|
||||||
|
if err = c.Decode(elem); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if cdata, err = encoder.EncodeToMapJson(*((*unsafe.Pointer)(elemPtr))); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
key := this.ukeylist(uid, _id)
|
||||||
|
if err = this.Redis.HMSetForMap(key, cdata); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
keys[_id] = key
|
||||||
|
}
|
||||||
|
if len(keys) > 0 {
|
||||||
|
if err = this.Redis.HMSet(this.ukey(uid), keys); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
//读取单个数据中 多个字段数据
|
//读取单个数据中 多个字段数据
|
||||||
func (this *MCompModel) GetFields(uid string, data interface{}, fields ...string) (err error) {
|
func (this *MCompModel) GetFields(uid string, data interface{}, fields ...string) (err error) {
|
||||||
this.Redis.HMGet(this.ukey(uid), data, fields...)
|
this.Redis.HMGet(this.ukey(uid), data, fields...)
|
||||||
@ -355,6 +466,21 @@ func (this *MCompModel) DelListlds(uid string, ids ...string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取用户通过扩展表
|
||||||
|
func (this *MCompModel) GetUserExpand(uid string) (result *pb.DBUserExpand, err error) {
|
||||||
|
result = &pb.DBUserExpand{}
|
||||||
|
if err = this.Redis.HGetAll(this.ukey(uid), result); err != nil && err != redis.RedisNil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err == redis.RedisNil {
|
||||||
|
if err = this.DB.FindOne(core.SqlTable("userexpand"), bson.M{"uid": uid}).Decode(result); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = this.Redis.HMSet(this.ukey(uid), result)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
//日志操作可选项
|
//日志操作可选项
|
||||||
func (this *MCompModel) logOpt(uid string, data interface{}, attrs ...*cache.OperationAttr) error {
|
func (this *MCompModel) logOpt(uid string, data interface{}, attrs ...*cache.OperationAttr) error {
|
||||||
ret := cache.OperationAttrs(attrs).Find(cache.ATTR_MGOLOG).Unwrap_Or(nil)
|
ret := cache.OperationAttrs(attrs).Find(cache.ATTR_MGOLOG).Unwrap_Or(nil)
|
||||||
|
@ -10,7 +10,9 @@ import (
|
|||||||
|
|
||||||
type (
|
type (
|
||||||
Options struct {
|
Options struct {
|
||||||
ListenPort int //websocket 监听端口
|
Debug bool //日志开关
|
||||||
|
GinDebug bool //web引擎日志开关
|
||||||
|
ListenPort int //websocket 监听端口
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,11 +25,9 @@ func (this *WSServiceComp) Init(service core.IService, module core.IModule, comp
|
|||||||
err = this.ModuleCompBase.Init(service, module, comp, options)
|
err = this.ModuleCompBase.Init(service, module, comp, options)
|
||||||
this.options = options.(*Options)
|
this.options = options.(*Options)
|
||||||
this.module = module.(IGateway)
|
this.module = module.(IGateway)
|
||||||
this.gin, err = gin.NewSys(gin.SetListenPort(this.options.ListenPort))
|
this.gin, err = gin.NewSys(gin.SetListenPort(this.options.ListenPort), gin.SetDebug(this.options.GinDebug))
|
||||||
|
|
||||||
// 游戏业务逻辑处理
|
// 游戏业务逻辑处理
|
||||||
this.gin.GET("/gateway", this.ws)
|
this.gin.GET("/gateway", this.ws)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package web
|
package gm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go_dreamfactory/lego/core"
|
"go_dreamfactory/lego/core"
|
||||||
@ -11,16 +11,16 @@ import (
|
|||||||
*/
|
*/
|
||||||
type Api_Comp struct {
|
type Api_Comp struct {
|
||||||
cbase.ModuleCompBase
|
cbase.ModuleCompBase
|
||||||
options *Options //模块参数
|
options *Options //模块参数
|
||||||
moduleWeb *Web //当前模块对象
|
module *GM //当前模块对象
|
||||||
gin gin.ISys //gin 框架 web的热门框架
|
gin gin.ISys //gin 框架 web的热门框架
|
||||||
}
|
}
|
||||||
|
|
||||||
//组件初始化接口 启动web服务 并注册api
|
//组件初始化接口 启动web服务 并注册api
|
||||||
func (this *Api_Comp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
|
func (this *Api_Comp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
|
||||||
err = this.ModuleCompBase.Init(service, module, comp, options)
|
err = this.ModuleCompBase.Init(service, module, comp, options)
|
||||||
this.options = options.(*Options)
|
this.options = options.(*Options)
|
||||||
this.moduleWeb = module.(*Web)
|
this.module = module.(*GM)
|
||||||
this.gin, err = gin.NewSys(gin.SetListenPort(this.options.Port))
|
this.gin, err = gin.NewSys(gin.SetListenPort(this.options.Port))
|
||||||
this.gin.POST("/register", this.Register)
|
this.gin.POST("/register", this.Register)
|
||||||
this.gin.GET("/serverlist", this.ServerList)
|
this.gin.GET("/serverlist", this.ServerList)
|
46
modules/gm/api_createnotify.go
Normal file
46
modules/gm/api_createnotify.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package gm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go_dreamfactory/lego/sys/gin"
|
||||||
|
"go_dreamfactory/lego/sys/gin/engine"
|
||||||
|
"go_dreamfactory/lego/sys/log"
|
||||||
|
"go_dreamfactory/pb"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateNotifyReq struct {
|
||||||
|
pb.DBSystemNotify
|
||||||
|
Sign string `json:"sign"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//服务列表
|
||||||
|
func (this *Api_Comp) CreateNotify(c *engine.Context) {
|
||||||
|
req := &CreateNotifyReq{}
|
||||||
|
c.BindJSON(&req)
|
||||||
|
defer log.Debugf("CreateNotify:%+v", req)
|
||||||
|
var (
|
||||||
|
code pb.ErrorCode
|
||||||
|
msg string
|
||||||
|
data interface{}
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
c.JSON(http.StatusOK, &Respond{Code: code, Message: msg, Data: data})
|
||||||
|
if sign := gin.ParamSign(this.options.Key, map[string]interface{}{"Title": req.Title, "Ctime": req.Ctime, "Rtime": req.Rtime}); sign != req.Sign {
|
||||||
|
log.Errorf("LoginByCaptchaReq SignError sgin:%s", sign)
|
||||||
|
code = pb.ErrorCode_SignError
|
||||||
|
msg = pb.GetErrorCodeMsg(code)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(req.Title) == 0 {
|
||||||
|
code = pb.ErrorCode_ReqParameterError
|
||||||
|
msg = pb.GetErrorCodeMsg(code)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = this.module.modelNotify.CreateSystemNotify(&req.DBSystemNotify); err != nil {
|
||||||
|
log.Errorf("LoginByCaptchaReq CreateSystemNotify err:%v", err)
|
||||||
|
code = pb.ErrorCode_DBError
|
||||||
|
msg = pb.GetErrorCodeMsg(code)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
msg = pb.GetErrorCodeMsg(code)
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package web
|
package gm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go_dreamfactory/lego/sys/gin/engine"
|
"go_dreamfactory/lego/sys/gin/engine"
|
||||||
@ -13,7 +13,7 @@ func (this *Api_Comp) Register(c *engine.Context) {
|
|||||||
rsp := &pb.UserRegisterResp{}
|
rsp := &pb.UserRegisterResp{}
|
||||||
err := c.BindJSON(&req)
|
err := c.BindJSON(&req)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err := this.moduleWeb.modelUser.User_Create(&pb.DBUser{
|
err := this.module.modelUser.User_Create(&pb.DBUser{
|
||||||
Binduid: req.Account,
|
Binduid: req.Account,
|
||||||
Sid: req.Sid,
|
Sid: req.Sid,
|
||||||
})
|
})
|
@ -1,4 +1,4 @@
|
|||||||
package web
|
package gm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go_dreamfactory/lego/sys/gin/engine"
|
"go_dreamfactory/lego/sys/gin/engine"
|
||||||
@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
//服务列表
|
//服务列表
|
||||||
func (this *Api_Comp) ServerList(c *engine.Context) {
|
func (this *Api_Comp) ServerList(c *engine.Context) {
|
||||||
conf := this.moduleWeb.configure.getServerListConf()
|
conf := this.module.configure.getServerListConf()
|
||||||
|
|
||||||
c.JSON(http.StatusOK, conf)
|
c.JSON(http.StatusOK, conf)
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package web
|
package gm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
9
modules/gm/core.go
Normal file
9
modules/gm/core.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package gm
|
||||||
|
|
||||||
|
import "go_dreamfactory/pb"
|
||||||
|
|
||||||
|
type Respond struct {
|
||||||
|
Code pb.ErrorCode `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Data interface{} `json:"data"`
|
||||||
|
}
|
42
modules/gm/modelNotify.go
Normal file
42
modules/gm/modelNotify.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package gm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go_dreamfactory/lego/core"
|
||||||
|
"go_dreamfactory/lego/sys/log"
|
||||||
|
"go_dreamfactory/modules"
|
||||||
|
"go_dreamfactory/pb"
|
||||||
|
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/x/bsonx"
|
||||||
|
)
|
||||||
|
|
||||||
|
///论坛 数据组件
|
||||||
|
type modelNotifyComp struct {
|
||||||
|
modules.MCompModel
|
||||||
|
module *GM
|
||||||
|
}
|
||||||
|
|
||||||
|
//组件初始化接口
|
||||||
|
func (this *modelNotifyComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
|
||||||
|
this.MCompModel.Init(service, module, comp, opt)
|
||||||
|
this.module = module.(*GM)
|
||||||
|
this.TableName = "notify"
|
||||||
|
//创建uid索引
|
||||||
|
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
|
||||||
|
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//创建系统公告
|
||||||
|
func (this *modelNotifyComp) CreateSystemNotify(notify *pb.DBSystemNotify) (err error) {
|
||||||
|
if _, err = this.DB.InsertOne(core.SqlTable(this.TableName), notify); err != nil {
|
||||||
|
log.Errorf("CreateSystemNotify err:%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = this.Redis.HSet(this.TableName, notify.Id, notify); err != nil {
|
||||||
|
log.Errorf("CreateSystemNotify err:%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package web
|
package gm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go_dreamfactory/comm"
|
"go_dreamfactory/comm"
|
||||||
@ -9,40 +9,41 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
模块名:web
|
模块名:gm
|
||||||
描述:为服务集群提供一些http服务接口 方便测试和后期运维实现
|
描述:提供管理员相关的http接口
|
||||||
开发:李伟
|
开发:李伟
|
||||||
*/
|
*/
|
||||||
func NewModule() core.IModule {
|
func NewModule() core.IModule {
|
||||||
m := new(Web)
|
m := new(GM)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
type Web struct {
|
type GM struct {
|
||||||
cbase.ModuleBase
|
cbase.ModuleBase
|
||||||
options *Options
|
options *Options
|
||||||
api_comp *Api_Comp //提供weba pi服务的组件
|
api_comp *Api_Comp //提供weba pi服务的组件
|
||||||
modelUser *user.ModelUser
|
modelUser *user.ModelUser
|
||||||
configure *configureComp
|
modelNotify *modelNotifyComp
|
||||||
|
configure *configureComp
|
||||||
}
|
}
|
||||||
|
|
||||||
//模块名
|
//模块名
|
||||||
func (this *Web) GetType() core.M_Modules {
|
func (this *GM) GetType() core.M_Modules {
|
||||||
return comm.ModuleWeb
|
return comm.ModuleGM
|
||||||
}
|
}
|
||||||
|
|
||||||
//模块自定义参数
|
//模块自定义参数
|
||||||
func (this *Web) NewOptions() (options core.IModuleOptions) {
|
func (this *GM) NewOptions() (options core.IModuleOptions) {
|
||||||
return new(Options)
|
return new(Options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Web) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
|
func (this *GM) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
|
||||||
err = this.ModuleBase.Init(service, module, options)
|
err = this.ModuleBase.Init(service, module, options)
|
||||||
this.options = options.(*Options)
|
this.options = options.(*Options)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Web) OnInstallComp() {
|
func (this *GM) OnInstallComp() {
|
||||||
this.ModuleBase.OnInstallComp()
|
this.ModuleBase.OnInstallComp()
|
||||||
this.api_comp = this.RegisterComp(new(Api_Comp)).(*Api_Comp)
|
this.api_comp = this.RegisterComp(new(Api_Comp)).(*Api_Comp)
|
||||||
this.modelUser = this.RegisterComp(new(user.ModelUser)).(*user.ModelUser)
|
this.modelUser = this.RegisterComp(new(user.ModelUser)).(*user.ModelUser)
|
@ -1,17 +1,23 @@
|
|||||||
package web
|
package gm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go_dreamfactory/lego/utils/mapstructure"
|
"go_dreamfactory/lego/utils/mapstructure"
|
||||||
|
"go_dreamfactory/modules"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
Options struct {
|
Options struct {
|
||||||
|
modules.Options
|
||||||
Port int
|
Port int
|
||||||
|
Key string
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Options) LoadConfig(settings map[string]interface{}) (err error) {
|
func (this *Options) LoadConfig(settings map[string]interface{}) (err error) {
|
||||||
if settings != nil {
|
if settings != nil {
|
||||||
|
if err = this.Options.LoadConfig(settings); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
err = mapstructure.Decode(settings, this)
|
err = mapstructure.Decode(settings, this)
|
||||||
}
|
}
|
||||||
return
|
return
|
@ -11,6 +11,8 @@ import (
|
|||||||
|
|
||||||
mengine "github.com/dengsgo/math-engine/engine"
|
mengine "github.com/dengsgo/math-engine/engine"
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/x/bsonx"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ModelHero struct {
|
type ModelHero struct {
|
||||||
@ -22,6 +24,10 @@ func (this *ModelHero) Init(service core.IService, module core.IModule, comp cor
|
|||||||
err = this.MCompModel.Init(service, module, comp, options)
|
err = this.MCompModel.Init(service, module, comp, options)
|
||||||
this.moduleHero = module.(*Hero)
|
this.moduleHero = module.(*Hero)
|
||||||
this.TableName = "hero"
|
this.TableName = "hero"
|
||||||
|
// 通过uid创建索引
|
||||||
|
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
|
||||||
|
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package items
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"go_dreamfactory/comm"
|
"go_dreamfactory/comm"
|
||||||
"go_dreamfactory/lego/sys/log"
|
|
||||||
"go_dreamfactory/pb"
|
"go_dreamfactory/pb"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -30,21 +29,25 @@ func (this *apiComp) Getlist(session comm.IUserSession, req *pb.ItemsGetlistReq)
|
|||||||
session.SendMsg(string(this.module.GetType()), "getlist", &pb.ItemsGetlistResp{Grids: grids})
|
session.SendMsg(string(this.module.GetType()), "getlist", &pb.ItemsGetlistResp{Grids: grids})
|
||||||
if code == pb.ErrorCode_Success {
|
if code == pb.ErrorCode_Success {
|
||||||
go func() { //异步处理修改数据
|
go func() { //异步处理修改数据
|
||||||
this.module.modelItems.Pack_UpdateUserPack(session.GetUserId(), modifys...)
|
if len(modifys) > 0 {
|
||||||
this.module.modelItems.Pack_DeleteUserPack(session.GetUserId(), dels...)
|
this.module.modelItems.Pack_UpdateUserPack(session.GetUserId(), modifys...)
|
||||||
|
}
|
||||||
|
if len(dels) > 0 {
|
||||||
|
this.module.modelItems.Pack_DeleteUserPack(session.GetUserId(), dels...)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if items, err = this.module.modelItems.Pack_QueryUserPack(session.GetUserId()); err != nil {
|
if items, err = this.module.modelItems.Pack_QueryUserPack(session.GetUserId()); err != nil {
|
||||||
log.Errorf("QueryUserPackReq err:%v", err)
|
this.module.Errorf("QueryUserPackReq err:%v", err)
|
||||||
code = pb.ErrorCode_CacheReadError
|
code = pb.ErrorCode_CacheReadError
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
tempgrids = this.module.configure.GetPackItemByType(items, req.IType)
|
tempgrids = this.module.configure.GetPackItemByType(items, req.IType)
|
||||||
modifys = make([]*pb.DB_UserItemData, 0, len(tempgrids))
|
modifys = make([]*pb.DB_UserItemData, 0, len(tempgrids))
|
||||||
dels = make([]string, 0, len(tempgrids))
|
dels = make([]string, 0, len(tempgrids))
|
||||||
grids = make([]*pb.DB_UserItemData, 0, len(grids))
|
grids = make([]*pb.DB_UserItemData, 0, len(items))
|
||||||
nt = time.Now().Unix()
|
nt = time.Now().Unix()
|
||||||
for _, v := range tempgrids {
|
for _, v := range tempgrids {
|
||||||
if v.ETime > 0 && v.ETime < nt { //已经过期
|
if v.ETime > 0 && v.ETime < nt { //已经过期
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
cfg "go_dreamfactory/sys/configure/structs"
|
cfg "go_dreamfactory/sys/configure/structs"
|
||||||
|
|
||||||
"go_dreamfactory/lego/core"
|
"go_dreamfactory/lego/core"
|
||||||
"go_dreamfactory/lego/sys/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -17,11 +16,13 @@ const (
|
|||||||
///背包配置管理组件
|
///背包配置管理组件
|
||||||
type ConfigureComp struct {
|
type ConfigureComp struct {
|
||||||
modules.MCompConfigure
|
modules.MCompConfigure
|
||||||
|
module *Items
|
||||||
}
|
}
|
||||||
|
|
||||||
//组件初始化接口
|
//组件初始化接口
|
||||||
func (this *ConfigureComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
|
func (this *ConfigureComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
|
||||||
this.MCompConfigure.Init(service, module, comp, options)
|
this.MCompConfigure.Init(service, module, comp, options)
|
||||||
|
this.module = module.(*Items)
|
||||||
err = this.LoadConfigure(game_item, cfg.NewGame_item)
|
err = this.LoadConfigure(game_item, cfg.NewGame_item)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -32,7 +33,7 @@ func (this *ConfigureComp) GetItemsConfigure() (items map[int32]*cfg.Game_itemDa
|
|||||||
v interface{}
|
v interface{}
|
||||||
)
|
)
|
||||||
if v, err = this.GetConfigure(game_item); err != nil {
|
if v, err = this.GetConfigure(game_item); err != nil {
|
||||||
log.Errorf("err:%v", err)
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
items = v.(*cfg.Game_item).GetDataMap()
|
items = v.(*cfg.Game_item).GetDataMap()
|
||||||
@ -47,12 +48,12 @@ func (this *ConfigureComp) GetItemConfigure(id int32) (item *cfg.Game_itemData,
|
|||||||
ok bool
|
ok bool
|
||||||
)
|
)
|
||||||
if v, err = this.GetConfigure(game_item); err != nil {
|
if v, err = this.GetConfigure(game_item); err != nil {
|
||||||
log.Errorf("err:%v", err)
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
if item, ok = v.(*cfg.Game_item).GetDataMap()[id]; !ok {
|
if item, ok = v.(*cfg.Game_item).GetDataMap()[id]; !ok {
|
||||||
err = fmt.Errorf("no found item:%d configure", id)
|
err = fmt.Errorf("no found item:%d configure", id)
|
||||||
log.Errorf("err:%v", err)
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,7 +71,7 @@ func (this *ConfigureComp) GetPackItemByType(itmes []*pb.DB_UserItemData, usetyp
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if v, err = this.GetConfigure(game_item); err != nil {
|
if v, err = this.GetConfigure(game_item); err != nil {
|
||||||
log.Errorf("err:%v", err)
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
table = v.(*cfg.Game_item)
|
table = v.(*cfg.Game_item)
|
||||||
@ -80,7 +81,7 @@ func (this *ConfigureComp) GetPackItemByType(itmes []*pb.DB_UserItemData, usetyp
|
|||||||
result = append(result, v)
|
result = append(result, v)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("no found itemConfigure:%d", v.ItemId)
|
this.module.Errorf("no found itemConfigure:%d", v.ItemId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,14 +34,18 @@ func (this *ModelItemsComp) Init(service core.IService, module core.IModule, com
|
|||||||
///查询用户背包数据
|
///查询用户背包数据
|
||||||
func (this *ModelItemsComp) Pack_QueryUserPack(uId string) (itmes []*pb.DB_UserItemData, err error) {
|
func (this *ModelItemsComp) Pack_QueryUserPack(uId string) (itmes []*pb.DB_UserItemData, err error) {
|
||||||
itmes = make([]*pb.DB_UserItemData, 0)
|
itmes = make([]*pb.DB_UserItemData, 0)
|
||||||
err = this.GetList(uId, &itmes)
|
if err = this.GetList(uId, &itmes); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
///查询用户指定格子的物品数据
|
///查询用户指定格子的物品数据
|
||||||
func (this *ModelItemsComp) Pack_QueryUserPackByGridId(uId string, grid string) (itme *pb.DB_UserItemData, err error) {
|
func (this *ModelItemsComp) Pack_QueryUserPackByGridId(uId string, grid string) (itme *pb.DB_UserItemData, err error) {
|
||||||
itme = &pb.DB_UserItemData{}
|
itme = &pb.DB_UserItemData{}
|
||||||
err = this.GetListObj(uId, grid, itme)
|
if err = this.GetListObj(uId, grid, itme); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +59,9 @@ func (this *ModelItemsComp) Pack_AddUserPack(uId string, itmes ...*pb.DB_UserIte
|
|||||||
|
|
||||||
//更新用户的背包信息
|
//更新用户的背包信息
|
||||||
func (this *ModelItemsComp) Pack_DelUserPack(uId string, ids ...string) (err error) {
|
func (this *ModelItemsComp) Pack_DelUserPack(uId string, ids ...string) (err error) {
|
||||||
err = this.DelListlds(uId, ids...)
|
if err = this.DelListlds(uId, ids...); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +77,10 @@ func (this *ModelItemsComp) Pack_UpdateUserPack(uId string, itmes ...*pb.DB_User
|
|||||||
|
|
||||||
//更新用户的背包信息
|
//更新用户的背包信息
|
||||||
func (this *ModelItemsComp) Pack_DeleteUserPack(uId string, gridIds ...string) (err error) {
|
func (this *ModelItemsComp) Pack_DeleteUserPack(uId string, gridIds ...string) (err error) {
|
||||||
err = this.DelListlds(uId, gridIds...)
|
if err = this.DelListlds(uId, gridIds...); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,6 +91,7 @@ func (this *ModelItemsComp) Pack_QueryUserPackItemsAmount(uId string, itemid ...
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if itmes, err = this.Pack_QueryUserPack(uId); err != nil {
|
if itmes, err = this.Pack_QueryUserPack(uId); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
result = map[int32]uint32{}
|
result = map[int32]uint32{}
|
||||||
@ -108,6 +118,7 @@ func (this *ModelItemsComp) Pack_AddItemToUserPack(uId string, itemId int32, add
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if itmes, err = this.Pack_QueryUserPack(uId); err != nil {
|
if itmes, err = this.Pack_QueryUserPack(uId); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
add, update, del, leftnum = this.pack_addItemToUserPack(itmes, itemId, addnum)
|
add, update, del, leftnum = this.pack_addItemToUserPack(itmes, itemId, addnum)
|
||||||
@ -120,16 +131,19 @@ func (this *ModelItemsComp) Pack_AddItemToUserPack(uId string, itemId int32, add
|
|||||||
}
|
}
|
||||||
if len(add) > 0 {
|
if len(add) > 0 {
|
||||||
if err = this.Pack_AddUserPack(uId, add...); err != nil {
|
if err = this.Pack_AddUserPack(uId, add...); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(del) > 0 {
|
if len(del) > 0 {
|
||||||
if err = this.Pack_DeleteUserPack(uId, del...); err != nil {
|
if err = this.Pack_DeleteUserPack(uId, del...); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(update) > 0 {
|
if len(update) > 0 {
|
||||||
if err = this.Pack_UpdateUserPack(uId, update...); err != nil {
|
if err = this.Pack_UpdateUserPack(uId, update...); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,6 +161,7 @@ func (this *ModelItemsComp) Pack_AddItemsToUserPack(uId string, items map[int32]
|
|||||||
leftnum int64
|
leftnum int64
|
||||||
)
|
)
|
||||||
if itmes, err = this.Pack_QueryUserPack(uId); err != nil {
|
if itmes, err = this.Pack_QueryUserPack(uId); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for k, v := range items {
|
for k, v := range items {
|
||||||
@ -160,16 +175,19 @@ func (this *ModelItemsComp) Pack_AddItemsToUserPack(uId string, items map[int32]
|
|||||||
}
|
}
|
||||||
if len(add) > 0 {
|
if len(add) > 0 {
|
||||||
if err = this.Pack_AddUserPack(uId, add...); err != nil {
|
if err = this.Pack_AddUserPack(uId, add...); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(del) > 0 {
|
if len(del) > 0 {
|
||||||
if err = this.Pack_DeleteUserPack(uId, del...); err != nil {
|
if err = this.Pack_DeleteUserPack(uId, del...); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(update) > 0 {
|
if len(update) > 0 {
|
||||||
if err = this.Pack_UpdateUserPack(uId, update...); err != nil {
|
if err = this.Pack_UpdateUserPack(uId, update...); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,10 +208,12 @@ func (this *ModelItemsComp) Pack_AddItemToUserPackByGrid(uId string, gridid stri
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if conf, err = this.module.configure.GetItemConfigure(itemId); err != nil {
|
if conf, err = this.module.configure.GetItemConfigure(itemId); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if itme, err = this.Pack_QueryUserPackByGridId(uId, gridid); err != nil {
|
if itme, err = this.Pack_QueryUserPackByGridId(uId, gridid); err != nil {
|
||||||
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
amount = int64(itme.Amount)
|
amount = int64(itme.Amount)
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"go_dreamfactory/pb"
|
"go_dreamfactory/pb"
|
||||||
|
|
||||||
"go_dreamfactory/lego/core"
|
"go_dreamfactory/lego/core"
|
||||||
"go_dreamfactory/lego/sys/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -48,7 +47,7 @@ func (this *Items) OnInstallComp() {
|
|||||||
//IItems-------------------------------------------------------------------------------------------------------------------------------
|
//IItems-------------------------------------------------------------------------------------------------------------------------------
|
||||||
///查询用户背包物品数量
|
///查询用户背包物品数量
|
||||||
func (this *Items) QueryItemAmount(source *comm.ModuleCallSource, uId string, itemid int32) (amount uint32) {
|
func (this *Items) QueryItemAmount(source *comm.ModuleCallSource, uId string, itemid int32) (amount uint32) {
|
||||||
defer log.Debugf("获取物品 uId:%s itemid:%d addnum:%d ", uId, itemid, amount)
|
defer this.Debugf("获取物品 uId:%s itemid:%d addnum:%d ", uId, itemid, amount)
|
||||||
amount = 0
|
amount = 0
|
||||||
if result := this.modelItems.Pack_QueryUserPackItemsAmount(uId, itemid); result != nil && len(result) > 0 {
|
if result := this.modelItems.Pack_QueryUserPackItemsAmount(uId, itemid); result != nil && len(result) > 0 {
|
||||||
return result[itemid]
|
return result[itemid]
|
||||||
@ -65,9 +64,9 @@ func (this *Items) QueryItemsAmount(source *comm.ModuleCallSource, uId string, i
|
|||||||
///添加单个物品到背包 (可以加物品和减物品)
|
///添加单个物品到背包 (可以加物品和减物品)
|
||||||
func (this *Items) AddItem(source *comm.ModuleCallSource, uId string, itemid, addnum int32) (code pb.ErrorCode) {
|
func (this *Items) AddItem(source *comm.ModuleCallSource, uId string, itemid, addnum int32) (code pb.ErrorCode) {
|
||||||
var err error
|
var err error
|
||||||
defer log.Debugf("给用户添加物品 uId:%s itemid:%d addnum:%d issucc:%v", uId, itemid, addnum, err == nil)
|
defer this.Debugf("给用户添加物品 uId:%s itemid:%d addnum:%d issucc:%v", uId, itemid, addnum, err == nil)
|
||||||
if err = this.modelItems.Pack_AddItemToUserPack(uId, itemid, addnum); err != nil {
|
if err = this.modelItems.Pack_AddItemToUserPack(uId, itemid, addnum); err != nil {
|
||||||
log.Errorf("给用户添加物品 uId:%s itemid:%d addnum:%d err:%v", uId, itemid, addnum, err)
|
this.Errorf("给用户添加物品 uId:%s itemid:%d addnum:%d err:%v", uId, itemid, addnum, err)
|
||||||
if err == ItemNotEnoughError {
|
if err == ItemNotEnoughError {
|
||||||
code = pb.ErrorCode_ItemsNoEnough
|
code = pb.ErrorCode_ItemsNoEnough
|
||||||
} else if err == PackGridNumUpper {
|
} else if err == PackGridNumUpper {
|
||||||
@ -82,9 +81,9 @@ func (this *Items) AddItem(source *comm.ModuleCallSource, uId string, itemid, ad
|
|||||||
///添加多个物品到背包 (可以加物品和减物品)
|
///添加多个物品到背包 (可以加物品和减物品)
|
||||||
func (this *Items) AddItems(source *comm.ModuleCallSource, uId string, items map[int32]int32) (code pb.ErrorCode) {
|
func (this *Items) AddItems(source *comm.ModuleCallSource, uId string, items map[int32]int32) (code pb.ErrorCode) {
|
||||||
var err error
|
var err error
|
||||||
defer log.Debugf("给用户添加物品 uId:%s items:%d items:%v", uId, items, err == nil)
|
defer this.Debugf("给用户添加物品 uId:%s items:%d items:%v", uId, items, err == nil)
|
||||||
if err = this.modelItems.Pack_AddItemsToUserPack(uId, items); err != nil {
|
if err = this.modelItems.Pack_AddItemsToUserPack(uId, items); err != nil {
|
||||||
log.Errorf("给用户添加物品 uId:%s items:%d err:%v", uId, items, err)
|
this.Errorf("给用户添加物品 uId:%s items:%d err:%v", uId, items, err)
|
||||||
if err == ItemNotEnoughError {
|
if err == ItemNotEnoughError {
|
||||||
code = pb.ErrorCode_ItemsNoEnough
|
code = pb.ErrorCode_ItemsNoEnough
|
||||||
} else if err == PackGridNumUpper {
|
} else if err == PackGridNumUpper {
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"go_dreamfactory/modules/equipment"
|
"go_dreamfactory/modules/equipment"
|
||||||
"go_dreamfactory/modules/hero"
|
"go_dreamfactory/modules/hero"
|
||||||
"go_dreamfactory/modules/items"
|
"go_dreamfactory/modules/items"
|
||||||
|
"go_dreamfactory/modules/task"
|
||||||
"go_dreamfactory/modules/user"
|
"go_dreamfactory/modules/user"
|
||||||
"go_dreamfactory/pb"
|
"go_dreamfactory/pb"
|
||||||
"go_dreamfactory/services"
|
"go_dreamfactory/services"
|
||||||
@ -74,6 +75,7 @@ func TestMain(m *testing.M) {
|
|||||||
hero.NewModule(),
|
hero.NewModule(),
|
||||||
user.NewModule(),
|
user.NewModule(),
|
||||||
equipment.NewModule(),
|
equipment.NewModule(),
|
||||||
|
task.NewModule(),
|
||||||
)
|
)
|
||||||
}()
|
}()
|
||||||
time.Sleep(time.Second * 3)
|
time.Sleep(time.Second * 3)
|
||||||
@ -81,10 +83,10 @@ func TestMain(m *testing.M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_Modules(t *testing.T) {
|
func Test_Modules(t *testing.T) {
|
||||||
data, _ := ptypes.MarshalAny(&pb.ItemsGetlistReq{})
|
data, _ := ptypes.MarshalAny(&pb.ItemsGetlistReq{IType: 9})
|
||||||
s_gateComp.ReceiveMsg(context.Background(), &pb.AgentMessage{MainType: "pack", SubType: "getlist", Message: data}, &pb.RPCMessageReply{})
|
reply := &pb.RPCMessageReply{}
|
||||||
// items, err := module.db_comp.Pack_QueryUserPack("liwei1dao")
|
s_gateComp.ReceiveMsg(context.Background(), &pb.AgentMessage{UserId: "0_62cd5952f72cc4bdc2d85f6b", MainType: "items", SubType: "getlist", Message: data}, reply)
|
||||||
// log.Debugf("item:%v err:%v", items, err)
|
log.Debugf("reply:%v", reply)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Modules_AddItems(t *testing.T) {
|
func Test_Modules_AddItems(t *testing.T) {
|
||||||
@ -93,5 +95,5 @@ func Test_Modules_AddItems(t *testing.T) {
|
|||||||
FuncName: "Test_Modules_AddItems",
|
FuncName: "Test_Modules_AddItems",
|
||||||
Describe: "测试模块接口",
|
Describe: "测试模块接口",
|
||||||
}, "0_62c259916d8cf3e4e06311a8", map[int32]int32{10001: 1000})
|
}, "0_62c259916d8cf3e4e06311a8", map[int32]int32{10001: 1000})
|
||||||
log.Debugf("Test_Modules_AddItems:%v code:%v", code)
|
log.Debugf("Test_Modules_AddItems code:%v", code)
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,6 @@ import (
|
|||||||
"go_dreamfactory/lego/core"
|
"go_dreamfactory/lego/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
QueryUserMailResp = "queryusermailresp"
|
|
||||||
ReadUserMailResp = "readusermailresp"
|
|
||||||
GetUserMailAttachmentResp = "getusermailattachmentresp"
|
|
||||||
DelUserMailResp = "delusermailresp"
|
|
||||||
GetNewEMailResp = "getnewEmailresp"
|
|
||||||
)
|
|
||||||
|
|
||||||
type apiComp struct {
|
type apiComp struct {
|
||||||
modules.MCompGate
|
modules.MCompGate
|
||||||
service core.IService
|
service core.IService
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
//参数校验
|
//参数校验
|
||||||
func (this *apiComp) DelMailCheck(session comm.IUserSession, req *pb.MailDelMailReq) (code pb.ErrorCode) {
|
func (this *apiComp) DelMailCheck(session comm.IUserSession, req *pb.MailDelMailReq) (code pb.ErrorCode) {
|
||||||
if session.GetUserId() == "" || req.ObjID == "" {
|
if session.GetUserId() == "" || req.ObjID == "" {
|
||||||
code = pb.ErrorCode_NoLogin
|
code = pb.ErrorCode_ReqParameterError
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -23,7 +23,7 @@ func (this *apiComp) DelMail(session comm.IUserSession, req *pb.MailDelMailReq)
|
|||||||
var err error
|
var err error
|
||||||
mailinfo := make([]*pb.DBMailData, 0)
|
mailinfo := make([]*pb.DBMailData, 0)
|
||||||
defer func() {
|
defer func() {
|
||||||
session.SendMsg(string(this.module.GetType()), DelUserMailResp, &pb.MailDelMailResp{Mail: mailinfo})
|
session.SendMsg(string(this.module.GetType()), "delmail", &pb.MailDelMailResp{Mail: mailinfo})
|
||||||
}()
|
}()
|
||||||
code = this.DelMailCheck(session, req) // check
|
code = this.DelMailCheck(session, req) // check
|
||||||
if code != pb.ErrorCode_Success {
|
if code != pb.ErrorCode_Success {
|
||||||
|
@ -22,7 +22,7 @@ func (this *apiComp) GetUserMailAttachment(session comm.IUserSession, req *pb.Ma
|
|||||||
mail *pb.DBMailData
|
mail *pb.DBMailData
|
||||||
)
|
)
|
||||||
defer func() {
|
defer func() {
|
||||||
session.SendMsg(string(this.module.GetType()), GetUserMailAttachmentResp, &pb.MailGetUserMailAttachmentResp{Mail: mail})
|
session.SendMsg(string(this.module.GetType()), "getusermailattachment", &pb.MailGetUserMailAttachmentResp{Mail: mail})
|
||||||
}()
|
}()
|
||||||
|
|
||||||
code = this.GetUserMailAttachmentCheck(session, req) // check
|
code = this.GetUserMailAttachmentCheck(session, req) // check
|
||||||
|
@ -18,7 +18,7 @@ func (this *apiComp) GetList(session comm.IUserSession, req *pb.MailGetListReq)
|
|||||||
var err error
|
var err error
|
||||||
mailinfo := make([]*pb.DBMailData, 0)
|
mailinfo := make([]*pb.DBMailData, 0)
|
||||||
defer func() {
|
defer func() {
|
||||||
session.SendMsg(string(this.module.GetType()), QueryUserMailResp, &pb.MailGetListResp{Mails: mailinfo})
|
session.SendMsg(string(this.module.GetType()), "getlist", &pb.MailGetListResp{Mails: mailinfo})
|
||||||
}()
|
}()
|
||||||
code = this.GetListCheck(session, req) // check
|
code = this.GetListCheck(session, req) // check
|
||||||
if code != pb.ErrorCode_Success {
|
if code != pb.ErrorCode_Success {
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
func (this *apiComp) ReadMailCheck(session comm.IUserSession, req *pb.MailReadMailReq) (code pb.ErrorCode) {
|
func (this *apiComp) ReadMailCheck(session comm.IUserSession, req *pb.MailReadMailReq) (code pb.ErrorCode) {
|
||||||
if session.GetUserId() == "" || req.ObjID == "" {
|
if session.GetUserId() == "" || req.ObjID == "" {
|
||||||
code = pb.ErrorCode_NoLogin
|
code = pb.ErrorCode_ReqParameterError
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -22,7 +22,7 @@ func (this *apiComp) ReadMail(session comm.IUserSession, req *pb.MailReadMailReq
|
|||||||
mail *pb.DBMailData
|
mail *pb.DBMailData
|
||||||
)
|
)
|
||||||
defer func() {
|
defer func() {
|
||||||
session.SendMsg(string(this.module.GetType()), ReadUserMailResp, &pb.MailReadMailResp{Mail: mail})
|
session.SendMsg(string(this.module.GetType()), "readmail", &pb.MailReadMailResp{Mail: mail})
|
||||||
}()
|
}()
|
||||||
code = this.ReadMailCheck(session, req) // check
|
code = this.ReadMailCheck(session, req) // check
|
||||||
if code != pb.ErrorCode_Success {
|
if code != pb.ErrorCode_Success {
|
||||||
|
@ -62,6 +62,6 @@ func (this *Mail) CreateNewMail(uId string, mail *pb.DBMailData) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
this.SendMsgToUser(string(this.GetType()), GetNewEMailResp, mail, _cache)
|
this.SendMsgToUser(string(this.GetType()), "newmail", mail, _cache)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package dbservice
|
package mgolog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go_dreamfactory/lego/core"
|
"go_dreamfactory/lego/core"
|
@ -1,4 +1,4 @@
|
|||||||
package dbservice
|
package mgolog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
@ -1,4 +1,4 @@
|
|||||||
package dbservice
|
package mgolog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go_dreamfactory/comm"
|
"go_dreamfactory/comm"
|
||||||
@ -7,26 +7,26 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewModule() core.IModule {
|
func NewModule() core.IModule {
|
||||||
m := new(DBService)
|
m := new(MgoLog)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
type DBService struct {
|
type MgoLog struct {
|
||||||
cbase.ModuleBase
|
cbase.ModuleBase
|
||||||
db_comp *DB_Comp
|
db_comp *DB_Comp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DBService) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
|
func (this *MgoLog) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
|
||||||
err = this.ModuleBase.Init(service, module, options)
|
err = this.ModuleBase.Init(service, module, options)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DBService) GetType() core.M_Modules {
|
func (this *MgoLog) GetType() core.M_Modules {
|
||||||
return comm.ModuleLogModel
|
return comm.ModuleMgoLog
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DBService) OnInstallComp() {
|
func (this *MgoLog) OnInstallComp() {
|
||||||
this.ModuleBase.OnInstallComp()
|
this.ModuleBase.OnInstallComp()
|
||||||
this.db_comp = this.RegisterComp(new(DB_Comp)).(*DB_Comp)
|
this.db_comp = this.RegisterComp(new(DB_Comp)).(*DB_Comp)
|
||||||
}
|
}
|
@ -23,6 +23,7 @@ type ModuleBase struct {
|
|||||||
cbase.ModuleBase
|
cbase.ModuleBase
|
||||||
module core.IModule
|
module core.IModule
|
||||||
service base.IRPCXService
|
service base.IRPCXService
|
||||||
|
options IOptions
|
||||||
scomp comm.ISC_GateRouteComp //网关服务组件
|
scomp comm.ISC_GateRouteComp //网关服务组件
|
||||||
//常用的一些通用模块 在底层注册好
|
//常用的一些通用模块 在底层注册好
|
||||||
ModuleUser comm.IUser //用户模块
|
ModuleUser comm.IUser //用户模块
|
||||||
@ -32,11 +33,17 @@ type ModuleBase struct {
|
|||||||
ModuleTask comm.ITask //任务
|
ModuleTask comm.ITask //任务
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//重构模块配置对象
|
||||||
|
func (this *ModuleBase) NewOptions() (options core.IModuleOptions) {
|
||||||
|
return new(Options)
|
||||||
|
}
|
||||||
|
|
||||||
//模块初始化接口
|
//模块初始化接口
|
||||||
func (this *ModuleBase) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
|
func (this *ModuleBase) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
|
||||||
err = this.ModuleBase.Init(service, module, options)
|
err = this.ModuleBase.Init(service, module, options)
|
||||||
this.service = service.(base.IRPCXService)
|
this.service = service.(base.IRPCXService)
|
||||||
this.module = module
|
this.module = module
|
||||||
|
this.options = options.(IOptions)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,3 +235,29 @@ func (this *ModuleBase) DispenseRes(uid string, res []*cfg.Game_atn) (code pb.Er
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//日志接口
|
||||||
|
func (this *ModuleBase) Debugf(format string, a ...interface{}) {
|
||||||
|
if this.options.GetDebug() {
|
||||||
|
this.options.GetLog().Debugf(fmt.Sprintf("[Module:%s] ", this.module.GetType())+format, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *ModuleBase) Infof(format string, a ...interface{}) {
|
||||||
|
if this.options.GetDebug() {
|
||||||
|
this.options.GetLog().Infof(fmt.Sprintf("[Module:%s] ", this.module.GetType())+format, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *ModuleBase) Warnf(format string, a ...interface{}) {
|
||||||
|
if this.options.GetDebug() {
|
||||||
|
this.options.GetLog().Warnf(fmt.Sprintf("[Module:%s] ", this.module.GetType())+format, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (this *ModuleBase) Errorf(format string, a ...interface{}) {
|
||||||
|
this.options.GetLog().Errorf(fmt.Sprintf("[Module:%s] ", this.module.GetType())+format, a...)
|
||||||
|
}
|
||||||
|
func (this *ModuleBase) Panicf(format string, a ...interface{}) {
|
||||||
|
this.options.GetLog().Panicf(fmt.Sprintf("[Module:%s] ", this.module.GetType())+format, a...)
|
||||||
|
}
|
||||||
|
func (this *ModuleBase) Fatalf(format string, a ...interface{}) {
|
||||||
|
this.options.GetLog().Fatalf(fmt.Sprintf("[Module:%s] ", this.module.GetType())+format, a...)
|
||||||
|
}
|
||||||
|
29
modules/notify/api.go
Normal file
29
modules/notify/api.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package notify
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go_dreamfactory/modules"
|
||||||
|
|
||||||
|
"go_dreamfactory/lego/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
API
|
||||||
|
*/
|
||||||
|
type apiComp struct {
|
||||||
|
modules.MCompGate
|
||||||
|
service core.IService
|
||||||
|
module *Notification
|
||||||
|
}
|
||||||
|
|
||||||
|
//组件初始化接口
|
||||||
|
func (this *apiComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
|
||||||
|
this.MCompGate.Init(service, module, comp, options)
|
||||||
|
this.module = module.(*Notification)
|
||||||
|
this.service = service
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *apiComp) Start() (err error) {
|
||||||
|
err = this.MCompGate.Start()
|
||||||
|
return
|
||||||
|
}
|
38
modules/notify/api_getlist.go
Normal file
38
modules/notify/api_getlist.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package notify
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go_dreamfactory/comm"
|
||||||
|
"go_dreamfactory/pb"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
//参数校验
|
||||||
|
func (this *apiComp) GetlistCheck(session comm.IUserSession, req *pb.NotifyGetListReq) (code pb.ErrorCode) {
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
///获取系统公告
|
||||||
|
func (this *apiComp) Getlist(session comm.IUserSession, req *pb.NotifyGetListReq) (code pb.ErrorCode, data proto.Message) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
userexpand *pb.DBUserExpand
|
||||||
|
notify []*pb.DBSystemNotify
|
||||||
|
)
|
||||||
|
defer func() {
|
||||||
|
session.SendMsg(string(this.module.GetType()), "getlist", &pb.NotifyGetListResp{LastReadTime: userexpand.Lastreadnotiftime, SysNotify: notify})
|
||||||
|
}()
|
||||||
|
if notify, err = this.module.modelNotify.GetFullNotify(); err != nil {
|
||||||
|
code = pb.ErrorCode_DBError
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if session.GetUserId() != "" {
|
||||||
|
if userexpand, err = this.module.modelNotify.GetUserExpand(session.GetUserId()); err != nil {
|
||||||
|
code = pb.ErrorCode_DBError
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
userexpand = &pb.DBUserExpand{}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
1
modules/notify/core.go
Normal file
1
modules/notify/core.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package notify
|
69
modules/notify/modelNotify.go
Normal file
69
modules/notify/modelNotify.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package notify
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"go_dreamfactory/lego/core"
|
||||||
|
"go_dreamfactory/modules"
|
||||||
|
"go_dreamfactory/pb"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-redis/redis/v8"
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/x/bsonx"
|
||||||
|
)
|
||||||
|
|
||||||
|
///论坛 数据组件
|
||||||
|
type modelNotifyComp struct {
|
||||||
|
modules.MCompModel
|
||||||
|
module *Notification
|
||||||
|
}
|
||||||
|
|
||||||
|
//组件初始化接口
|
||||||
|
func (this *modelNotifyComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
|
||||||
|
this.MCompModel.Init(service, module, comp, opt)
|
||||||
|
this.module = module.(*Notification)
|
||||||
|
this.TableName = "notify"
|
||||||
|
//创建uid索引
|
||||||
|
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
|
||||||
|
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取全部公告
|
||||||
|
func (this *modelNotifyComp) GetFullNotify() (result []*pb.DBSystemNotify, err error) {
|
||||||
|
var (
|
||||||
|
notifys map[string]*pb.DBSystemNotify = make(map[string]*pb.DBSystemNotify)
|
||||||
|
c *mongo.Cursor
|
||||||
|
)
|
||||||
|
if err = this.Redis.HGetAll(this.TableName, notifys); err != nil && err == redis.Nil {
|
||||||
|
if c, err = this.DB.Find(core.SqlTable(this.TableName), bson.M{}); err == nil {
|
||||||
|
for c.Next(context.Background()) {
|
||||||
|
notify := &pb.DBSystemNotify{}
|
||||||
|
if err = c.Decode(notify); err != nil {
|
||||||
|
this.module.Errorf("GetFullNotify err:%v", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
notifys[notify.Id] = notify
|
||||||
|
}
|
||||||
|
if len(notifys) > 0 {
|
||||||
|
if err = this.Redis.HMSet(this.TableName, notifys); err != nil {
|
||||||
|
this.module.Errorf("GetFullNotify err:%v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(notifys) > 0 {
|
||||||
|
n := 0
|
||||||
|
now := time.Now().Unix()
|
||||||
|
result = make([]*pb.DBSystemNotify, len(notifys))
|
||||||
|
for _, v := range notifys {
|
||||||
|
if now >= v.Rtime {
|
||||||
|
result[n] = v
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
42
modules/notify/module.go
Normal file
42
modules/notify/module.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package notify
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go_dreamfactory/comm"
|
||||||
|
"go_dreamfactory/lego/core"
|
||||||
|
"go_dreamfactory/modules"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
模块名:公告系统
|
||||||
|
是否跨服:是
|
||||||
|
描述:提供运营后台发布全服公告
|
||||||
|
开发:李伟
|
||||||
|
*/
|
||||||
|
func NewModule() core.IModule {
|
||||||
|
m := new(Notification)
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
type Notification struct {
|
||||||
|
modules.ModuleBase
|
||||||
|
api_comp *apiComp
|
||||||
|
modelNotify *modelNotifyComp
|
||||||
|
}
|
||||||
|
|
||||||
|
//模块名
|
||||||
|
func (this *Notification) GetType() core.M_Modules {
|
||||||
|
return comm.ModuleEquipment
|
||||||
|
}
|
||||||
|
|
||||||
|
//模块初始化接口 注册用户创建角色事件
|
||||||
|
func (this *Notification) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
|
||||||
|
err = this.ModuleBase.Init(service, module, options)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//装备组件
|
||||||
|
func (this *Notification) OnInstallComp() {
|
||||||
|
this.ModuleBase.OnInstallComp()
|
||||||
|
this.api_comp = this.RegisterComp(new(apiComp)).(*apiComp)
|
||||||
|
this.modelNotify = this.RegisterComp(new(modelNotifyComp)).(*modelNotifyComp)
|
||||||
|
}
|
74
modules/notify/module_test.go
Normal file
74
modules/notify/module_test.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package notify
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"go_dreamfactory/comm"
|
||||||
|
"go_dreamfactory/lego"
|
||||||
|
"go_dreamfactory/lego/base/rpcx"
|
||||||
|
"go_dreamfactory/lego/core"
|
||||||
|
"go_dreamfactory/lego/sys/log"
|
||||||
|
"go_dreamfactory/services"
|
||||||
|
"go_dreamfactory/sys/cache"
|
||||||
|
"go_dreamfactory/sys/configure"
|
||||||
|
"go_dreamfactory/sys/db"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newService(ops ...rpcx.Option) core.IService {
|
||||||
|
s := new(TestService)
|
||||||
|
s.Configure(ops...)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
//梦工厂基础服务对象
|
||||||
|
type TestService struct {
|
||||||
|
rpcx.RPCXService
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化相关系统
|
||||||
|
func (this *TestService) InitSys() {
|
||||||
|
this.RPCXService.InitSys()
|
||||||
|
if err := cache.OnInit(this.GetSettings().Sys["cache"]); err != nil {
|
||||||
|
panic(fmt.Sprintf("init sys.cache err: %s", err.Error()))
|
||||||
|
} else {
|
||||||
|
log.Infof("init sys.cache success!")
|
||||||
|
}
|
||||||
|
if err := db.OnInit(this.GetSettings().Sys["db"]); err != nil {
|
||||||
|
panic(fmt.Sprintf("init sys.db err: %s", err.Error()))
|
||||||
|
} else {
|
||||||
|
log.Infof("init sys.db success!")
|
||||||
|
}
|
||||||
|
if err := configure.OnInit(this.GetSettings().Sys["configure"]); err != nil {
|
||||||
|
panic(fmt.Sprintf("init sys.configure err: %s", err.Error()))
|
||||||
|
} else {
|
||||||
|
log.Infof("init sys.configure success!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var service core.IService
|
||||||
|
var s_gateComp comm.ISC_GateRouteComp = services.NewGateRouteComp()
|
||||||
|
var module = new(Notification)
|
||||||
|
|
||||||
|
//测试环境下初始化db和cache 系统
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
service = newService(
|
||||||
|
rpcx.SetConfPath("../../bin/conf/worker_1.yaml"),
|
||||||
|
rpcx.SetVersion("1.0.0.0"),
|
||||||
|
)
|
||||||
|
service.OnInstallComp( //装备组件
|
||||||
|
s_gateComp, //此服务需要接受用户的消息 需要装备网关组件
|
||||||
|
)
|
||||||
|
go func() {
|
||||||
|
lego.Run(service, //运行模块
|
||||||
|
module,
|
||||||
|
)
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
|
defer os.Exit(m.Run())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Module(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
42
modules/options.go
Normal file
42
modules/options.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package modules
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"go_dreamfactory/lego/core"
|
||||||
|
"go_dreamfactory/lego/sys/log"
|
||||||
|
"go_dreamfactory/lego/utils/mapstructure"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
IOptions interface {
|
||||||
|
core.IModuleOptions
|
||||||
|
GetDebug() bool
|
||||||
|
GetLog() log.ILog
|
||||||
|
}
|
||||||
|
Options struct {
|
||||||
|
Debug bool //日志是否开启
|
||||||
|
Log log.ILog
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (this *Options) GetDebug() bool {
|
||||||
|
return this.Debug
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Options) GetLog() log.ILog {
|
||||||
|
return this.Log
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Options) LoadConfig(settings map[string]interface{}) (err error) {
|
||||||
|
if settings != nil {
|
||||||
|
err = mapstructure.Decode(settings, this)
|
||||||
|
}
|
||||||
|
if this.Debug && this.Log == nil {
|
||||||
|
this.Log = log.Clone()
|
||||||
|
if this.Log == nil {
|
||||||
|
err = fmt.Errorf("Log is nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
@ -3,7 +3,6 @@ package shop
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"go_dreamfactory/lego/core"
|
"go_dreamfactory/lego/core"
|
||||||
"go_dreamfactory/lego/sys/log"
|
|
||||||
"go_dreamfactory/modules"
|
"go_dreamfactory/modules"
|
||||||
"go_dreamfactory/pb"
|
"go_dreamfactory/pb"
|
||||||
cfg "go_dreamfactory/sys/configure/structs"
|
cfg "go_dreamfactory/sys/configure/structs"
|
||||||
@ -17,11 +16,13 @@ const (
|
|||||||
///背包配置管理组件
|
///背包配置管理组件
|
||||||
type configureComp struct {
|
type configureComp struct {
|
||||||
modules.MCompConfigure
|
modules.MCompConfigure
|
||||||
|
module *Shop
|
||||||
}
|
}
|
||||||
|
|
||||||
//组件初始化接口
|
//组件初始化接口
|
||||||
func (this *configureComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
|
func (this *configureComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
|
||||||
this.ModuleCompBase.Init(service, module, comp, options)
|
this.ModuleCompBase.Init(service, module, comp, options)
|
||||||
|
this.module = module.(*Shop)
|
||||||
this.LoadConfigure(game_shop, cfg.NewGame_shop)
|
this.LoadConfigure(game_shop, cfg.NewGame_shop)
|
||||||
this.LoadConfigure(game_shopitem, cfg.NewGame_shopitem)
|
this.LoadConfigure(game_shopitem, cfg.NewGame_shopitem)
|
||||||
return
|
return
|
||||||
@ -34,12 +35,12 @@ func (this *configureComp) GetShopConfigure(id int32) (configure *cfg.Game_shopD
|
|||||||
ok bool
|
ok bool
|
||||||
)
|
)
|
||||||
if v, err = this.GetConfigure(game_shop); err != nil {
|
if v, err = this.GetConfigure(game_shop); err != nil {
|
||||||
log.Errorf("err:%v", err)
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
if configure, ok = v.(*cfg.Game_shop).GetDataMap()[id]; !ok {
|
if configure, ok = v.(*cfg.Game_shop).GetDataMap()[id]; !ok {
|
||||||
err = fmt.Errorf("ShopConfigure not found:%d ", id)
|
err = fmt.Errorf("ShopConfigure not found:%d ", id)
|
||||||
log.Errorf("err:%v", err)
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,12 +54,12 @@ func (this *configureComp) GetShopItemsConfigure(key int32) (result *cfg.Game_sh
|
|||||||
ok bool
|
ok bool
|
||||||
)
|
)
|
||||||
if v, err = this.GetConfigure(game_shopitem); err != nil {
|
if v, err = this.GetConfigure(game_shopitem); err != nil {
|
||||||
log.Errorf("err:%v", err)
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
if result, ok = v.(*cfg.Game_shopitem).GetDataMap()[key]; !ok {
|
if result, ok = v.(*cfg.Game_shopitem).GetDataMap()[key]; !ok {
|
||||||
err = fmt.Errorf("ShopConfigure not found:%d ", key)
|
err = fmt.Errorf("ShopConfigure not found:%d ", key)
|
||||||
log.Errorf("err:%v", err)
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,7 +74,7 @@ func (this *configureComp) GetShopItemsConfigureByGroups(groupid int32, user *pb
|
|||||||
table *cfg.Game_shopitem
|
table *cfg.Game_shopitem
|
||||||
)
|
)
|
||||||
if v, err = this.GetConfigure(game_shopitem); err != nil {
|
if v, err = this.GetConfigure(game_shopitem); err != nil {
|
||||||
log.Errorf("err:%v", err)
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
table = v.(*cfg.Game_shopitem)
|
table = v.(*cfg.Game_shopitem)
|
||||||
@ -99,7 +100,7 @@ func (this *configureComp) GetShopItemsConfigureByIds(keys ...int32) (result []*
|
|||||||
ok bool
|
ok bool
|
||||||
)
|
)
|
||||||
if v, err = this.GetConfigure(game_shopitem); err != nil {
|
if v, err = this.GetConfigure(game_shopitem); err != nil {
|
||||||
log.Errorf("err:%v", err)
|
this.module.Errorf("err:%v", err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
table = v.(*cfg.Game_shopitem)
|
table = v.(*cfg.Game_shopitem)
|
||||||
@ -107,7 +108,7 @@ func (this *configureComp) GetShopItemsConfigureByIds(keys ...int32) (result []*
|
|||||||
if item, ok = table.GetDataMap()[v]; ok {
|
if item, ok = table.GetDataMap()[v]; ok {
|
||||||
result = append(result, item)
|
result = append(result, item)
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("no found GetShopItemsConfigureByIds:%d", v)
|
this.module.Errorf("no found GetShopItemsConfigureByIds:%d", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package shop
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"go_dreamfactory/lego/core"
|
"go_dreamfactory/lego/core"
|
||||||
"go_dreamfactory/lego/sys/log"
|
|
||||||
"go_dreamfactory/lego/sys/mgo"
|
"go_dreamfactory/lego/sys/mgo"
|
||||||
"go_dreamfactory/modules"
|
"go_dreamfactory/modules"
|
||||||
"go_dreamfactory/pb"
|
"go_dreamfactory/pb"
|
||||||
@ -35,6 +34,7 @@ func (this *modelShopItemsComp) QueryUserShopData(uId string) (result map[int32]
|
|||||||
result = make(map[int32]*pb.DBShopItem)
|
result = make(map[int32]*pb.DBShopItem)
|
||||||
data := make([]*pb.DBShopItem, 0)
|
data := make([]*pb.DBShopItem, 0)
|
||||||
if err = this.GetList(uId, &data); err != nil && err != mgo.MongodbNil {
|
if err = this.GetList(uId, &data); err != nil && err != mgo.MongodbNil {
|
||||||
|
err = nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = nil
|
err = nil
|
||||||
@ -52,7 +52,7 @@ func (this *modelShopItemsComp) QueryUserShopDataByGoodId(uId string, goodId int
|
|||||||
)
|
)
|
||||||
data = make([]*pb.DBShopItem, 0)
|
data = make([]*pb.DBShopItem, 0)
|
||||||
if err = this.GetList(uId, &data); err != nil {
|
if err = this.GetList(uId, &data); err != nil {
|
||||||
log.Errorf("err%v", err)
|
this.module.Errorf("err%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, v := range data {
|
for _, v := range data {
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"go_dreamfactory/pb"
|
"go_dreamfactory/pb"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -39,20 +40,35 @@ func (this *apiComp) Challenge(session comm.IUserSession, req *pb.StoryChallenge
|
|||||||
if len(list) > 0 {
|
if len(list) > 0 {
|
||||||
curChapter = list[0] // 取第一条(第一条肯定是最新的)
|
curChapter = list[0] // 取第一条(第一条肯定是最新的)
|
||||||
}
|
}
|
||||||
if curChapter == nil {
|
|
||||||
code = pb.ErrorCode_StoryNotFindChapter // 没有找到主线关卡信息
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 先校验是不是分支
|
// 先校验是不是分支
|
||||||
chaptConfig := this.module.configure.GetStoryChapter(int32(req.ChapterId)) // 根据配置文件找
|
chaptConfig := this.module.configure.GetStoryChapter(int32(req.ChapterId)) // 根据配置文件找
|
||||||
if chaptConfig == nil {
|
if chaptConfig == nil {
|
||||||
code = pb.ErrorCode_ConfigNoFound
|
code = pb.ErrorCode_ConfigNoFound
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if curChapter == nil {
|
||||||
|
if len(chaptConfig.Fubendata) <= 0 {
|
||||||
|
code = pb.ErrorCode_ConfigNoFound
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if int32(req.ChapterId) != 1 {
|
||||||
|
code = pb.ErrorCode_ReqParameterError
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_data := &pb.DBStory{}
|
||||||
|
_data.Id = primitive.NewObjectID().Hex()
|
||||||
|
_data.ChapterId = int32(req.ChapterId)
|
||||||
|
_mData := make(map[string]interface{}, 0)
|
||||||
|
_mData[_data.Id] = _data
|
||||||
|
this.module.modelStory.addNewChapter(session.GetUserId(), _mData)
|
||||||
|
curChapter = _data
|
||||||
|
//curChapter.StoryId = chaptConfig.Fubendata[0] // 第一次挑战
|
||||||
|
}
|
||||||
// 根据难度找对应的配置文件
|
// 根据难度找对应的配置文件
|
||||||
if chaptConfig.Intensity == "1" { // 这里安临时配置读取 后面会修改
|
if chaptConfig.Intensity == "1" { // 这里按临时配置读取 后面会修改
|
||||||
con := this.module.configure.GetStoryEasyChapter(int32(req.StoryId)) // 根据配置文件找
|
con := this.module.configure.GetStoryEasyChapter(int32(req.StoryId)) // 根据配置文件找
|
||||||
if con != nil {
|
if con == nil {
|
||||||
code = pb.ErrorCode_ConfigNoFound
|
code = pb.ErrorCode_ConfigNoFound
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -66,13 +82,16 @@ func (this *apiComp) Challenge(session comm.IUserSession, req *pb.StoryChallenge
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO 调用战斗逻辑
|
// TODO 调用战斗逻辑
|
||||||
|
// 挑战成功
|
||||||
|
curChapter.StoryId += 1 // 临时数据 后面配置表完善查找
|
||||||
if bBranch {
|
if bBranch {
|
||||||
curChapter.BranchID = append(curChapter.BranchID, int32(req.ChapterId)) // 记录分支关卡
|
curChapter.BranchID = append(curChapter.BranchID, int32(req.ChapterId)) // 记录分支关卡
|
||||||
}
|
}
|
||||||
if curChapter.ChapterId == int32(req.ChapterId) && curChapter.StoryId == int32(req.StoryId) {
|
if curChapter.ChapterId == int32(req.ChapterId) && curChapter.StoryId == int32(req.StoryId) {
|
||||||
update := map[string]interface{}{
|
update := map[string]interface{}{
|
||||||
"storyId": req.StoryId,
|
"storyId": req.StoryId,
|
||||||
"branchID": curChapter.BranchID,
|
"ChapterId": req.ChapterId,
|
||||||
|
"branchID": curChapter.BranchID,
|
||||||
}
|
}
|
||||||
err = this.module.modelStory.modifyStoryData(session.GetUserId(), curChapter.Id, update)
|
err = this.module.modelStory.modifyStoryData(session.GetUserId(), curChapter.Id, update)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package story
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"go_dreamfactory/lego/core"
|
"go_dreamfactory/lego/core"
|
||||||
|
"go_dreamfactory/lego/sys/log"
|
||||||
"go_dreamfactory/modules"
|
"go_dreamfactory/modules"
|
||||||
"go_dreamfactory/pb"
|
"go_dreamfactory/pb"
|
||||||
)
|
)
|
||||||
@ -33,3 +34,13 @@ func (this *ModelStory) getStoryList(uid string) (storys []*pb.DBStory, err erro
|
|||||||
func (this *ModelStory) modifyStoryData(uid string, objid string, data map[string]interface{}) error {
|
func (this *ModelStory) modifyStoryData(uid string, objid string, data map[string]interface{}) error {
|
||||||
return this.moduleStory.modelStory.ChangeList(uid, objid, data)
|
return this.moduleStory.modelStory.ChangeList(uid, objid, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 增加新的章节数据
|
||||||
|
func (this *ModelStory) addNewChapter(uId string, data map[string]interface{}) (err error) {
|
||||||
|
|
||||||
|
if err = this.AddLists(uId, data); err != nil {
|
||||||
|
log.Errorf("err:%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (this *apiComp) AddResCheck(session comm.IUserSession, req *pb.UserAddResReq) (code pb.ErrorCode) {
|
func (this *apiComp) AddResCheck(session comm.IUserSession, req *pb.UserAddResReq) (code pb.ErrorCode) {
|
||||||
if req.Res.A == "" || req.Res.T == "" || req.Res.N > 0 {
|
if req.Res.A == "" || req.Res.T == "" || req.Res.N <= 0 {
|
||||||
code = pb.ErrorCode_ReqParameterError
|
code = pb.ErrorCode_ReqParameterError
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -122,7 +122,7 @@ type ItemsUseItemReq struct {
|
|||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
GridId int32 `protobuf:"varint,1,opt,name=GridId,proto3" json:"GridId"` //格子Id
|
GridId string `protobuf:"bytes,1,opt,name=GridId,proto3" json:"GridId"` //格子Id
|
||||||
ItemId int32 `protobuf:"varint,2,opt,name=ItemId,proto3" json:"ItemId"` //物品Id
|
ItemId int32 `protobuf:"varint,2,opt,name=ItemId,proto3" json:"ItemId"` //物品Id
|
||||||
Amount uint32 `protobuf:"varint,3,opt,name=Amount,proto3" json:"Amount"` //使用数量
|
Amount uint32 `protobuf:"varint,3,opt,name=Amount,proto3" json:"Amount"` //使用数量
|
||||||
}
|
}
|
||||||
@ -159,11 +159,11 @@ func (*ItemsUseItemReq) Descriptor() ([]byte, []int) {
|
|||||||
return file_items_items_msg_proto_rawDescGZIP(), []int{2}
|
return file_items_items_msg_proto_rawDescGZIP(), []int{2}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ItemsUseItemReq) GetGridId() int32 {
|
func (x *ItemsUseItemReq) GetGridId() string {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.GridId
|
return x.GridId
|
||||||
}
|
}
|
||||||
return 0
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ItemsUseItemReq) GetItemId() int32 {
|
func (x *ItemsUseItemReq) GetItemId() int32 {
|
||||||
@ -225,7 +225,7 @@ type ItemsSellItemReq struct {
|
|||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
GridId int32 `protobuf:"varint,1,opt,name=GridId,proto3" json:"GridId"` //格子Id
|
GridId string `protobuf:"bytes,1,opt,name=GridId,proto3" json:"GridId"` //格子Id
|
||||||
ItemId int32 `protobuf:"varint,2,opt,name=ItemId,proto3" json:"ItemId"` //物品Id
|
ItemId int32 `protobuf:"varint,2,opt,name=ItemId,proto3" json:"ItemId"` //物品Id
|
||||||
Amount uint32 `protobuf:"varint,3,opt,name=Amount,proto3" json:"Amount"` //使用数量
|
Amount uint32 `protobuf:"varint,3,opt,name=Amount,proto3" json:"Amount"` //使用数量
|
||||||
}
|
}
|
||||||
@ -262,11 +262,11 @@ func (*ItemsSellItemReq) Descriptor() ([]byte, []int) {
|
|||||||
return file_items_items_msg_proto_rawDescGZIP(), []int{4}
|
return file_items_items_msg_proto_rawDescGZIP(), []int{4}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ItemsSellItemReq) GetGridId() int32 {
|
func (x *ItemsSellItemReq) GetGridId() string {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.GridId
|
return x.GridId
|
||||||
}
|
}
|
||||||
return 0
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ItemsSellItemReq) GetItemId() int32 {
|
func (x *ItemsSellItemReq) GetItemId() int32 {
|
||||||
@ -336,14 +336,14 @@ var file_items_items_msg_proto_rawDesc = []byte{
|
|||||||
0x73, 0x65, 0x72, 0x49, 0x74, 0x65, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x52, 0x05, 0x47, 0x72, 0x69,
|
0x73, 0x65, 0x72, 0x49, 0x74, 0x65, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x52, 0x05, 0x47, 0x72, 0x69,
|
||||||
0x64, 0x73, 0x22, 0x59, 0x0a, 0x0f, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x55, 0x73, 0x65, 0x49, 0x74,
|
0x64, 0x73, 0x22, 0x59, 0x0a, 0x0f, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x55, 0x73, 0x65, 0x49, 0x74,
|
||||||
0x65, 0x6d, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x72, 0x69, 0x64, 0x49, 0x64, 0x18,
|
0x65, 0x6d, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x72, 0x69, 0x64, 0x49, 0x64, 0x18,
|
||||||
0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x47, 0x72, 0x69, 0x64, 0x49, 0x64, 0x12, 0x16, 0x0a,
|
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x47, 0x72, 0x69, 0x64, 0x49, 0x64, 0x12, 0x16, 0x0a,
|
||||||
0x06, 0x49, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x49,
|
0x06, 0x49, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x49,
|
||||||
0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18,
|
0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18,
|
||||||
0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x12, 0x0a,
|
0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x12, 0x0a,
|
||||||
0x10, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x55, 0x73, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73,
|
0x10, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x55, 0x73, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73,
|
||||||
0x70, 0x22, 0x5a, 0x0a, 0x10, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x53, 0x65, 0x6c, 0x6c, 0x49, 0x74,
|
0x70, 0x22, 0x5a, 0x0a, 0x10, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x53, 0x65, 0x6c, 0x6c, 0x49, 0x74,
|
||||||
0x65, 0x6d, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x72, 0x69, 0x64, 0x49, 0x64, 0x18,
|
0x65, 0x6d, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x72, 0x69, 0x64, 0x49, 0x64, 0x18,
|
||||||
0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x47, 0x72, 0x69, 0x64, 0x49, 0x64, 0x12, 0x16, 0x0a,
|
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x47, 0x72, 0x69, 0x64, 0x49, 0x64, 0x12, 0x16, 0x0a,
|
||||||
0x06, 0x49, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x49,
|
0x06, 0x49, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x49,
|
||||||
0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18,
|
0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18,
|
||||||
0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x13, 0x0a,
|
0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x13, 0x0a,
|
||||||
|
189
pb/notify_db.pb.go
Normal file
189
pb/notify_db.pb.go
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// protoc-gen-go v1.28.0
|
||||||
|
// protoc v3.20.0
|
||||||
|
// source: notify/notify_db.proto
|
||||||
|
|
||||||
|
package pb
|
||||||
|
|
||||||
|
import (
|
||||||
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
|
reflect "reflect"
|
||||||
|
sync "sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Verify that this generated code is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||||
|
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||||
|
)
|
||||||
|
|
||||||
|
//系统公告数据结构
|
||||||
|
type DBSystemNotify struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id"` //数据公告Id
|
||||||
|
Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title"` //公告标题
|
||||||
|
Content string `protobuf:"bytes,3,opt,name=content,proto3" json:"content"` //公告内容
|
||||||
|
Istop bool `protobuf:"varint,4,opt,name=istop,proto3" json:"istop"` //是否置顶
|
||||||
|
Ctime int64 `protobuf:"varint,5,opt,name=ctime,proto3" json:"ctime"` //创建时间
|
||||||
|
Rtime int64 `protobuf:"varint,6,opt,name=rtime,proto3" json:"rtime"` //发布时间
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DBSystemNotify) Reset() {
|
||||||
|
*x = DBSystemNotify{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_notify_notify_db_proto_msgTypes[0]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DBSystemNotify) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DBSystemNotify) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *DBSystemNotify) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_notify_notify_db_proto_msgTypes[0]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use DBSystemNotify.ProtoReflect.Descriptor instead.
|
||||||
|
func (*DBSystemNotify) Descriptor() ([]byte, []int) {
|
||||||
|
return file_notify_notify_db_proto_rawDescGZIP(), []int{0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DBSystemNotify) GetId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Id
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DBSystemNotify) GetTitle() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Title
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DBSystemNotify) GetContent() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Content
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DBSystemNotify) GetIstop() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.Istop
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DBSystemNotify) GetCtime() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Ctime
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DBSystemNotify) GetRtime() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Rtime
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var File_notify_notify_db_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
|
var file_notify_notify_db_proto_rawDesc = []byte{
|
||||||
|
0x0a, 0x16, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f,
|
||||||
|
0x64, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x92, 0x01, 0x0a, 0x0e, 0x44, 0x42, 0x53,
|
||||||
|
0x79, 0x73, 0x74, 0x65, 0x6d, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
||||||
|
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74,
|
||||||
|
0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c,
|
||||||
|
0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01,
|
||||||
|
0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69,
|
||||||
|
0x73, 0x74, 0x6f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x69, 0x73, 0x74, 0x6f,
|
||||||
|
0x70, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03,
|
||||||
|
0x52, 0x05, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x74, 0x69, 0x6d, 0x65,
|
||||||
|
0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x72, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x06, 0x5a,
|
||||||
|
0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
file_notify_notify_db_proto_rawDescOnce sync.Once
|
||||||
|
file_notify_notify_db_proto_rawDescData = file_notify_notify_db_proto_rawDesc
|
||||||
|
)
|
||||||
|
|
||||||
|
func file_notify_notify_db_proto_rawDescGZIP() []byte {
|
||||||
|
file_notify_notify_db_proto_rawDescOnce.Do(func() {
|
||||||
|
file_notify_notify_db_proto_rawDescData = protoimpl.X.CompressGZIP(file_notify_notify_db_proto_rawDescData)
|
||||||
|
})
|
||||||
|
return file_notify_notify_db_proto_rawDescData
|
||||||
|
}
|
||||||
|
|
||||||
|
var file_notify_notify_db_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||||
|
var file_notify_notify_db_proto_goTypes = []interface{}{
|
||||||
|
(*DBSystemNotify)(nil), // 0: DBSystemNotify
|
||||||
|
}
|
||||||
|
var file_notify_notify_db_proto_depIdxs = []int32{
|
||||||
|
0, // [0:0] is the sub-list for method output_type
|
||||||
|
0, // [0:0] is the sub-list for method input_type
|
||||||
|
0, // [0:0] is the sub-list for extension type_name
|
||||||
|
0, // [0:0] is the sub-list for extension extendee
|
||||||
|
0, // [0:0] is the sub-list for field type_name
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { file_notify_notify_db_proto_init() }
|
||||||
|
func file_notify_notify_db_proto_init() {
|
||||||
|
if File_notify_notify_db_proto != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !protoimpl.UnsafeEnabled {
|
||||||
|
file_notify_notify_db_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*DBSystemNotify); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type x struct{}
|
||||||
|
out := protoimpl.TypeBuilder{
|
||||||
|
File: protoimpl.DescBuilder{
|
||||||
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
|
RawDescriptor: file_notify_notify_db_proto_rawDesc,
|
||||||
|
NumEnums: 0,
|
||||||
|
NumMessages: 1,
|
||||||
|
NumExtensions: 0,
|
||||||
|
NumServices: 0,
|
||||||
|
},
|
||||||
|
GoTypes: file_notify_notify_db_proto_goTypes,
|
||||||
|
DependencyIndexes: file_notify_notify_db_proto_depIdxs,
|
||||||
|
MessageInfos: file_notify_notify_db_proto_msgTypes,
|
||||||
|
}.Build()
|
||||||
|
File_notify_notify_db_proto = out.File
|
||||||
|
file_notify_notify_db_proto_rawDesc = nil
|
||||||
|
file_notify_notify_db_proto_goTypes = nil
|
||||||
|
file_notify_notify_db_proto_depIdxs = nil
|
||||||
|
}
|
@ -30,7 +30,7 @@ type NotifyErrorNotifyPush struct {
|
|||||||
ReqSubType string `protobuf:"bytes,2,opt,name=ReqSubType,proto3" json:"ReqSubType"` // 请求协议函数 例如:login 对应项目中 user的模块中 api_login 的处理函数
|
ReqSubType string `protobuf:"bytes,2,opt,name=ReqSubType,proto3" json:"ReqSubType"` // 请求协议函数 例如:login 对应项目中 user的模块中 api_login 的处理函数
|
||||||
Code ErrorCode `protobuf:"varint,3,opt,name=Code,proto3,enum=ErrorCode" json:"Code"` // 执行返回错误码 对应 errorcode.proto 枚举
|
Code ErrorCode `protobuf:"varint,3,opt,name=Code,proto3,enum=ErrorCode" json:"Code"` // 执行返回错误码 对应 errorcode.proto 枚举
|
||||||
Message string `protobuf:"bytes,4,opt,name=Message,proto3" json:"Message"` // 错误消息
|
Message string `protobuf:"bytes,4,opt,name=Message,proto3" json:"Message"` // 错误消息
|
||||||
Data string `protobuf:"bytes,6,opt,name=Data,proto3" json:"Data"` // 错误数据
|
Data string `protobuf:"bytes,5,opt,name=Data,proto3" json:"Data"` // 错误数据
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *NotifyErrorNotifyPush) Reset() {
|
func (x *NotifyErrorNotifyPush) Reset() {
|
||||||
@ -100,24 +100,128 @@ func (x *NotifyErrorNotifyPush) GetData() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取系统公告 请求
|
||||||
|
type NotifyGetListReq struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NotifyGetListReq) Reset() {
|
||||||
|
*x = NotifyGetListReq{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_notify_notify_msg_proto_msgTypes[1]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NotifyGetListReq) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*NotifyGetListReq) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *NotifyGetListReq) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_notify_notify_msg_proto_msgTypes[1]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use NotifyGetListReq.ProtoReflect.Descriptor instead.
|
||||||
|
func (*NotifyGetListReq) Descriptor() ([]byte, []int) {
|
||||||
|
return file_notify_notify_msg_proto_rawDescGZIP(), []int{1}
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取系统公告 回应
|
||||||
|
type NotifyGetListResp struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
LastReadTime int64 `protobuf:"varint,1,opt,name=LastReadTime,proto3" json:"LastReadTime"` //最后一次阅读时间
|
||||||
|
SysNotify []*DBSystemNotify `protobuf:"bytes,2,rep,name=SysNotify,proto3" json:"SysNotify"` //公告列表
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NotifyGetListResp) Reset() {
|
||||||
|
*x = NotifyGetListResp{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_notify_notify_msg_proto_msgTypes[2]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NotifyGetListResp) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*NotifyGetListResp) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *NotifyGetListResp) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_notify_notify_msg_proto_msgTypes[2]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use NotifyGetListResp.ProtoReflect.Descriptor instead.
|
||||||
|
func (*NotifyGetListResp) Descriptor() ([]byte, []int) {
|
||||||
|
return file_notify_notify_msg_proto_rawDescGZIP(), []int{2}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NotifyGetListResp) GetLastReadTime() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.LastReadTime
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NotifyGetListResp) GetSysNotify() []*DBSystemNotify {
|
||||||
|
if x != nil {
|
||||||
|
return x.SysNotify
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var File_notify_notify_msg_proto protoreflect.FileDescriptor
|
var File_notify_notify_msg_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
var file_notify_notify_msg_proto_rawDesc = []byte{
|
var file_notify_notify_msg_proto_rawDesc = []byte{
|
||||||
0x0a, 0x17, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f,
|
0x0a, 0x17, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f,
|
||||||
0x6d, 0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0f, 0x65, 0x72, 0x72, 0x6f, 0x72,
|
0x6d, 0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0f, 0x65, 0x72, 0x72, 0x6f, 0x72,
|
||||||
0x63, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa7, 0x01, 0x0a, 0x15, 0x4e,
|
0x63, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x16, 0x6e, 0x6f, 0x74, 0x69,
|
||||||
0x6f, 0x74, 0x69, 0x66, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79,
|
0x66, 0x79, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x64, 0x62, 0x2e, 0x70, 0x72, 0x6f,
|
||||||
0x50, 0x75, 0x73, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x4d, 0x61, 0x69, 0x6e, 0x54,
|
0x74, 0x6f, 0x22, 0xa7, 0x01, 0x0a, 0x15, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x45, 0x72, 0x72,
|
||||||
0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x52, 0x65, 0x71, 0x4d, 0x61,
|
0x6f, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x50, 0x75, 0x73, 0x68, 0x12, 0x20, 0x0a, 0x0b,
|
||||||
0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x52, 0x65, 0x71, 0x53, 0x75, 0x62,
|
0x52, 0x65, 0x71, 0x4d, 0x61, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||||
0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x52, 0x65, 0x71, 0x53,
|
0x09, 0x52, 0x0b, 0x52, 0x65, 0x71, 0x4d, 0x61, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e,
|
||||||
0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x03,
|
0x0a, 0x0a, 0x52, 0x65, 0x71, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||||
0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65,
|
0x28, 0x09, 0x52, 0x0a, 0x52, 0x65, 0x71, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e,
|
||||||
0x52, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x45,
|
||||||
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x18,
|
||||||
0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||||
0x44, 0x61, 0x74, 0x61, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
|
0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61,
|
||||||
0x6f, 0x74, 0x6f, 0x33,
|
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x12, 0x0a, 0x10,
|
||||||
|
0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71,
|
||||||
|
0x22, 0x66, 0x0a, 0x11, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x73,
|
||||||
|
0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x22, 0x0a, 0x0c, 0x4c, 0x61, 0x73, 0x74, 0x52, 0x65, 0x61,
|
||||||
|
0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x4c, 0x61, 0x73,
|
||||||
|
0x74, 0x52, 0x65, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x09, 0x53, 0x79, 0x73,
|
||||||
|
0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x44,
|
||||||
|
0x42, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x09, 0x53,
|
||||||
|
0x79, 0x73, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62,
|
||||||
|
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -132,18 +236,22 @@ func file_notify_notify_msg_proto_rawDescGZIP() []byte {
|
|||||||
return file_notify_notify_msg_proto_rawDescData
|
return file_notify_notify_msg_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_notify_notify_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
var file_notify_notify_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||||
var file_notify_notify_msg_proto_goTypes = []interface{}{
|
var file_notify_notify_msg_proto_goTypes = []interface{}{
|
||||||
(*NotifyErrorNotifyPush)(nil), // 0: NotifyErrorNotifyPush
|
(*NotifyErrorNotifyPush)(nil), // 0: NotifyErrorNotifyPush
|
||||||
(ErrorCode)(0), // 1: ErrorCode
|
(*NotifyGetListReq)(nil), // 1: NotifyGetListReq
|
||||||
|
(*NotifyGetListResp)(nil), // 2: NotifyGetListResp
|
||||||
|
(ErrorCode)(0), // 3: ErrorCode
|
||||||
|
(*DBSystemNotify)(nil), // 4: DBSystemNotify
|
||||||
}
|
}
|
||||||
var file_notify_notify_msg_proto_depIdxs = []int32{
|
var file_notify_notify_msg_proto_depIdxs = []int32{
|
||||||
1, // 0: NotifyErrorNotifyPush.Code:type_name -> ErrorCode
|
3, // 0: NotifyErrorNotifyPush.Code:type_name -> ErrorCode
|
||||||
1, // [1:1] is the sub-list for method output_type
|
4, // 1: NotifyGetListResp.SysNotify:type_name -> DBSystemNotify
|
||||||
1, // [1:1] is the sub-list for method input_type
|
2, // [2:2] is the sub-list for method output_type
|
||||||
1, // [1:1] is the sub-list for extension type_name
|
2, // [2:2] is the sub-list for method input_type
|
||||||
1, // [1:1] is the sub-list for extension extendee
|
2, // [2:2] is the sub-list for extension type_name
|
||||||
0, // [0:1] is the sub-list for field type_name
|
2, // [2:2] is the sub-list for extension extendee
|
||||||
|
0, // [0:2] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_notify_notify_msg_proto_init() }
|
func init() { file_notify_notify_msg_proto_init() }
|
||||||
@ -152,6 +260,7 @@ func file_notify_notify_msg_proto_init() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
file_errorcode_proto_init()
|
file_errorcode_proto_init()
|
||||||
|
file_notify_notify_db_proto_init()
|
||||||
if !protoimpl.UnsafeEnabled {
|
if !protoimpl.UnsafeEnabled {
|
||||||
file_notify_notify_msg_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
file_notify_notify_msg_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*NotifyErrorNotifyPush); i {
|
switch v := v.(*NotifyErrorNotifyPush); i {
|
||||||
@ -165,6 +274,30 @@ func file_notify_notify_msg_proto_init() {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
file_notify_notify_msg_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*NotifyGetListReq); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_notify_notify_msg_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*NotifyGetListResp); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
type x struct{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
@ -172,7 +305,7 @@ func file_notify_notify_msg_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_notify_notify_msg_proto_rawDesc,
|
RawDescriptor: file_notify_notify_msg_proto_rawDesc,
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 1,
|
NumMessages: 3,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
},
|
},
|
||||||
|
@ -14,7 +14,7 @@ message ItemsGetlistResp {
|
|||||||
|
|
||||||
//使用物品请求
|
//使用物品请求
|
||||||
message ItemsUseItemReq {
|
message ItemsUseItemReq {
|
||||||
int32 GridId = 1; //格子Id
|
string GridId = 1; //格子Id
|
||||||
int32 ItemId = 2; //物品Id
|
int32 ItemId = 2; //物品Id
|
||||||
uint32 Amount = 3; //使用数量
|
uint32 Amount = 3; //使用数量
|
||||||
}
|
}
|
||||||
@ -26,7 +26,7 @@ message ItemsUseItemResp {
|
|||||||
|
|
||||||
//出售道具请求sailitem
|
//出售道具请求sailitem
|
||||||
message ItemsSellItemReq {
|
message ItemsSellItemReq {
|
||||||
int32 GridId = 1; //格子Id
|
string GridId = 1; //格子Id
|
||||||
int32 ItemId = 2; //物品Id
|
int32 ItemId = 2; //物品Id
|
||||||
uint32 Amount = 3; //使用数量
|
uint32 Amount = 3; //使用数量
|
||||||
}
|
}
|
||||||
|
12
pb/proto/notify/notify_db.proto
Normal file
12
pb/proto/notify/notify_db.proto
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
option go_package = ".;pb";
|
||||||
|
|
||||||
|
//系统公告数据结构
|
||||||
|
message DBSystemNotify {
|
||||||
|
string id = 1; //数据公告Id
|
||||||
|
string title = 2; //公告标题
|
||||||
|
string content = 3; //公告内容
|
||||||
|
bool istop = 4; //是否置顶
|
||||||
|
int64 ctime = 5; //创建时间
|
||||||
|
int64 rtime = 6; //发布时间
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
option go_package = ".;pb";
|
option go_package = ".;pb";
|
||||||
import "errorcode.proto";
|
import "errorcode.proto";
|
||||||
|
import "notify/notify_db.proto";
|
||||||
|
|
||||||
//统一错误码推送
|
//统一错误码推送
|
||||||
message NotifyErrorNotifyPush {
|
message NotifyErrorNotifyPush {
|
||||||
@ -8,5 +9,15 @@ message NotifyErrorNotifyPush {
|
|||||||
string ReqSubType = 2; // 请求协议函数 例如:login 对应项目中 user的模块中 api_login 的处理函数
|
string ReqSubType = 2; // 请求协议函数 例如:login 对应项目中 user的模块中 api_login 的处理函数
|
||||||
ErrorCode Code = 3; // 执行返回错误码 对应 errorcode.proto 枚举
|
ErrorCode Code = 3; // 执行返回错误码 对应 errorcode.proto 枚举
|
||||||
string Message = 4; // 错误消息
|
string Message = 4; // 错误消息
|
||||||
string Data = 6; // 错误数据
|
string Data = 5; // 错误数据
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取系统公告 请求
|
||||||
|
message NotifyGetListReq {
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取系统公告 回应
|
||||||
|
message NotifyGetListResp {
|
||||||
|
int64 LastReadTime = 1; //最后一次阅读时间
|
||||||
|
repeated DBSystemNotify SysNotify = 2; //公告列表
|
||||||
|
}
|
10
pb/proto/userexpand.proto
Normal file
10
pb/proto/userexpand.proto
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
option go_package = ".;pb";
|
||||||
|
|
||||||
|
|
||||||
|
//用户扩展数据
|
||||||
|
message DBUserExpand {
|
||||||
|
string id = 1; //主键id
|
||||||
|
string uid = 2; //用户id
|
||||||
|
int64 lastreadnotiftime = 3; //最后阅读公告时间
|
||||||
|
}
|
162
pb/userexpand.pb.go
Normal file
162
pb/userexpand.pb.go
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// protoc-gen-go v1.28.0
|
||||||
|
// protoc v3.20.0
|
||||||
|
// source: userexpand.proto
|
||||||
|
|
||||||
|
package pb
|
||||||
|
|
||||||
|
import (
|
||||||
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
|
reflect "reflect"
|
||||||
|
sync "sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Verify that this generated code is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||||
|
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||||
|
)
|
||||||
|
|
||||||
|
//用户扩展数据
|
||||||
|
type DBUserExpand struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id"` //主键id
|
||||||
|
Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid"` //用户id
|
||||||
|
Lastreadnotiftime int64 `protobuf:"varint,3,opt,name=lastreadnotiftime,proto3" json:"lastreadnotiftime"` //最后阅读公告时间
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DBUserExpand) Reset() {
|
||||||
|
*x = DBUserExpand{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_userexpand_proto_msgTypes[0]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DBUserExpand) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DBUserExpand) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *DBUserExpand) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_userexpand_proto_msgTypes[0]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use DBUserExpand.ProtoReflect.Descriptor instead.
|
||||||
|
func (*DBUserExpand) Descriptor() ([]byte, []int) {
|
||||||
|
return file_userexpand_proto_rawDescGZIP(), []int{0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DBUserExpand) GetId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Id
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DBUserExpand) GetUid() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Uid
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DBUserExpand) GetLastreadnotiftime() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Lastreadnotiftime
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var File_userexpand_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
|
var file_userexpand_proto_rawDesc = []byte{
|
||||||
|
0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x2e, 0x70, 0x72, 0x6f,
|
||||||
|
0x74, 0x6f, 0x22, 0x5e, 0x0a, 0x0c, 0x44, 0x42, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x70, 0x61,
|
||||||
|
0x6e, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
|
||||||
|
0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||||
|
0x03, 0x75, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x72, 0x65, 0x61, 0x64,
|
||||||
|
0x6e, 0x6f, 0x74, 0x69, 0x66, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||||
|
0x11, 0x6c, 0x61, 0x73, 0x74, 0x72, 0x65, 0x61, 0x64, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x74, 0x69,
|
||||||
|
0x6d, 0x65, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||||
|
0x6f, 0x33,
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
file_userexpand_proto_rawDescOnce sync.Once
|
||||||
|
file_userexpand_proto_rawDescData = file_userexpand_proto_rawDesc
|
||||||
|
)
|
||||||
|
|
||||||
|
func file_userexpand_proto_rawDescGZIP() []byte {
|
||||||
|
file_userexpand_proto_rawDescOnce.Do(func() {
|
||||||
|
file_userexpand_proto_rawDescData = protoimpl.X.CompressGZIP(file_userexpand_proto_rawDescData)
|
||||||
|
})
|
||||||
|
return file_userexpand_proto_rawDescData
|
||||||
|
}
|
||||||
|
|
||||||
|
var file_userexpand_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||||
|
var file_userexpand_proto_goTypes = []interface{}{
|
||||||
|
(*DBUserExpand)(nil), // 0: DBUserExpand
|
||||||
|
}
|
||||||
|
var file_userexpand_proto_depIdxs = []int32{
|
||||||
|
0, // [0:0] is the sub-list for method output_type
|
||||||
|
0, // [0:0] is the sub-list for method input_type
|
||||||
|
0, // [0:0] is the sub-list for extension type_name
|
||||||
|
0, // [0:0] is the sub-list for extension extendee
|
||||||
|
0, // [0:0] is the sub-list for field type_name
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { file_userexpand_proto_init() }
|
||||||
|
func file_userexpand_proto_init() {
|
||||||
|
if File_userexpand_proto != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !protoimpl.UnsafeEnabled {
|
||||||
|
file_userexpand_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*DBUserExpand); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type x struct{}
|
||||||
|
out := protoimpl.TypeBuilder{
|
||||||
|
File: protoimpl.DescBuilder{
|
||||||
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
|
RawDescriptor: file_userexpand_proto_rawDesc,
|
||||||
|
NumEnums: 0,
|
||||||
|
NumMessages: 1,
|
||||||
|
NumExtensions: 0,
|
||||||
|
NumServices: 0,
|
||||||
|
},
|
||||||
|
GoTypes: file_userexpand_proto_goTypes,
|
||||||
|
DependencyIndexes: file_userexpand_proto_depIdxs,
|
||||||
|
MessageInfos: file_userexpand_proto_msgTypes,
|
||||||
|
}.Build()
|
||||||
|
File_userexpand_proto = out.File
|
||||||
|
file_userexpand_proto_rawDesc = nil
|
||||||
|
file_userexpand_proto_goTypes = nil
|
||||||
|
file_userexpand_proto_depIdxs = nil
|
||||||
|
}
|
@ -15,11 +15,31 @@ import (
|
|||||||
"go_dreamfactory/lego/core/cbase"
|
"go_dreamfactory/lego/core/cbase"
|
||||||
"go_dreamfactory/lego/sys/event"
|
"go_dreamfactory/lego/sys/event"
|
||||||
"go_dreamfactory/lego/sys/log"
|
"go_dreamfactory/lego/sys/log"
|
||||||
|
"go_dreamfactory/lego/utils/mapstructure"
|
||||||
|
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
"google.golang.org/protobuf/types/known/anypb"
|
"google.golang.org/protobuf/types/known/anypb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//用户协议处理函数注册的反射对象
|
||||||
|
type msghandle struct {
|
||||||
|
rcvr reflect.Value
|
||||||
|
msgType reflect.Type //消息请求类型
|
||||||
|
handle reflect.Method //处理函数
|
||||||
|
}
|
||||||
|
|
||||||
|
//组件参数
|
||||||
|
type CompOptions struct {
|
||||||
|
Debug bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CompOptions) LoadConfig(settings map[string]interface{}) (err error) {
|
||||||
|
if settings != nil {
|
||||||
|
err = mapstructure.Decode(settings, this)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
服务网关组件 用于接收网关服务发送过来的消息
|
服务网关组件 用于接收网关服务发送过来的消息
|
||||||
*/
|
*/
|
||||||
@ -29,16 +49,10 @@ func NewGateRouteComp() comm.ISC_GateRouteComp {
|
|||||||
return comp
|
return comp
|
||||||
}
|
}
|
||||||
|
|
||||||
//用户协议处理函数注册的反射对象
|
|
||||||
type msghandle struct {
|
|
||||||
rcvr reflect.Value
|
|
||||||
msgType reflect.Type //消息请求类型
|
|
||||||
handle reflect.Method //处理函数
|
|
||||||
}
|
|
||||||
|
|
||||||
//服务网关组件
|
//服务网关组件
|
||||||
type SCompGateRoute struct {
|
type SCompGateRoute struct {
|
||||||
cbase.ServiceCompBase
|
cbase.ServiceCompBase
|
||||||
|
options *CompOptions
|
||||||
service base.IRPCXService //rpc服务对象 通过这个对象可以发布服务和调用其他服务的接口
|
service base.IRPCXService //rpc服务对象 通过这个对象可以发布服务和调用其他服务的接口
|
||||||
mrlock sync.RWMutex //msghandles 对象的锁
|
mrlock sync.RWMutex //msghandles 对象的锁
|
||||||
msghandles map[string]*msghandle //处理函数的管理对象
|
msghandles map[string]*msghandle //处理函数的管理对象
|
||||||
@ -50,9 +64,14 @@ func (this *SCompGateRoute) GetName() core.S_Comps {
|
|||||||
return comm.SC_ServiceGateRouteComp
|
return comm.SC_ServiceGateRouteComp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *SCompGateRoute) NewOptions() (options core.ICompOptions) {
|
||||||
|
return new(CompOptions)
|
||||||
|
}
|
||||||
|
|
||||||
//组件初始化函数
|
//组件初始化函数
|
||||||
func (this *SCompGateRoute) Init(service core.IService, comp core.IServiceComp, options core.ICompOptions) (err error) {
|
func (this *SCompGateRoute) Init(service core.IService, comp core.IServiceComp, options core.ICompOptions) (err error) {
|
||||||
err = this.ServiceCompBase.Init(service, comp, options)
|
err = this.ServiceCompBase.Init(service, comp, options)
|
||||||
|
this.options = options.(*CompOptions)
|
||||||
this.service = service.(base.IRPCXService)
|
this.service = service.(base.IRPCXService)
|
||||||
this.msghandles = make(map[string]*msghandle)
|
this.msghandles = make(map[string]*msghandle)
|
||||||
this.pools = sync.Pool{
|
this.pools = sync.Pool{
|
||||||
@ -74,7 +93,7 @@ func (this *SCompGateRoute) Start() (err error) {
|
|||||||
|
|
||||||
//业务模块注册用户消息处理路由
|
//业务模块注册用户消息处理路由
|
||||||
func (this *SCompGateRoute) RegisterRoute(methodName string, comp reflect.Value, msg reflect.Type, handele reflect.Method) {
|
func (this *SCompGateRoute) RegisterRoute(methodName string, comp reflect.Value, msg reflect.Type, handele reflect.Method) {
|
||||||
log.Debugf("注册用户路由【%s】", methodName)
|
//log.Debugf("注册用户路由【%s】", methodName)
|
||||||
this.mrlock.RLock()
|
this.mrlock.RLock()
|
||||||
_, ok := this.msghandles[methodName]
|
_, ok := this.msghandles[methodName]
|
||||||
this.mrlock.RUnlock()
|
this.mrlock.RUnlock()
|
||||||
@ -95,11 +114,11 @@ func (this *SCompGateRoute) RegisterRoute(methodName string, comp reflect.Value,
|
|||||||
func (this *SCompGateRoute) ReceiveMsg(ctx context.Context, args *pb.AgentMessage, reply *pb.RPCMessageReply) (err error) {
|
func (this *SCompGateRoute) ReceiveMsg(ctx context.Context, args *pb.AgentMessage, reply *pb.RPCMessageReply) (err error) {
|
||||||
defer func() { //程序异常 收集异常信息传递给前端显示
|
defer func() { //程序异常 收集异常信息传递给前端显示
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 4096)
|
||||||
l := runtime.Stack(buf, false)
|
l := runtime.Stack(buf, false)
|
||||||
reply.Code = pb.ErrorCode_Exception
|
reply.Code = pb.ErrorCode_Exception
|
||||||
reply.ErrorMessage = fmt.Sprintf("%v: %s", r, buf[:l])
|
reply.ErrorMessage = fmt.Sprintf("%v: %s", r, buf[:l])
|
||||||
log.Errorf("HandleUserMsg:[%s-%s] err:%s", args.MainType, args.SubType, reply.ErrorMessage)
|
log.Errorf("[Handle Api]:[%s-%s] err:%s", args.MainType, args.SubType, reply.ErrorMessage)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
method := fmt.Sprintf("%s.%s", args.MainType, args.SubType)
|
method := fmt.Sprintf("%s.%s", args.MainType, args.SubType)
|
||||||
@ -126,11 +145,10 @@ func (this *SCompGateRoute) ReceiveMsg(ctx context.Context, args *pb.AgentMessag
|
|||||||
//执行处理流
|
//执行处理流
|
||||||
stime := time.Now()
|
stime := time.Now()
|
||||||
handlereturn := msghandle.handle.Func.Call([]reflect.Value{msghandle.rcvr, reflect.ValueOf(session), reflect.ValueOf(msg)})
|
handlereturn := msghandle.handle.Func.Call([]reflect.Value{msghandle.rcvr, reflect.ValueOf(session), reflect.ValueOf(msg)})
|
||||||
log.Debugf("[Handle Api] consumetime:%v method:%s uid:%s msg:%v", time.Since(stime), method, args.UserId, msg)
|
|
||||||
errcode := pb.ErrorCode(handlereturn[0].Int())
|
errcode := pb.ErrorCode(handlereturn[0].Int())
|
||||||
errdata := handlereturn[1].Interface()
|
errdata := handlereturn[1].Interface()
|
||||||
if errcode != pb.ErrorCode_Success { //处理返货错误码 返回用户错误信息
|
if errcode != pb.ErrorCode_Success { //处理返货错误码 返回用户错误信息
|
||||||
log.Errorf("[Handle Api] method:%s uid:%s msg:%v code:%d", method, msg, errcode)
|
log.Errorf("[Handle Api] method:%s msg:%v code:%d", method, msg, errcode)
|
||||||
reply.Code = errcode
|
reply.Code = errcode
|
||||||
reply.ErrorMessage = pb.GetErrorCodeMsg(errcode)
|
reply.ErrorMessage = pb.GetErrorCodeMsg(errcode)
|
||||||
if errdata != nil {
|
if errdata != nil {
|
||||||
@ -139,6 +157,9 @@ func (this *SCompGateRoute) ReceiveMsg(ctx context.Context, args *pb.AgentMessag
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reply.Reply = session.Polls()
|
reply.Reply = session.Polls()
|
||||||
|
if this.options.Debug {
|
||||||
|
log.Debugf("[Handle Api] consumetime:%v method:%s uid:%s msg:%v reply:%#v", time.Since(stime), method, args.UserId, msg, reply)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else { //未找到消息处理函数
|
} else { //未找到消息处理函数
|
||||||
log.Errorf("[Handle Api] no found handle %s", method)
|
log.Errorf("[Handle Api] no found handle %s", method)
|
||||||
|
@ -3,7 +3,8 @@ package main
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go_dreamfactory/modules/dbservice"
|
"go_dreamfactory/modules/gm"
|
||||||
|
"go_dreamfactory/modules/mgolog"
|
||||||
"go_dreamfactory/services"
|
"go_dreamfactory/services"
|
||||||
"go_dreamfactory/sys/cache"
|
"go_dreamfactory/sys/cache"
|
||||||
"go_dreamfactory/sys/db"
|
"go_dreamfactory/sys/db"
|
||||||
@ -15,11 +16,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
服务类型:dbservice
|
服务类型:mainte
|
||||||
服务描述:处理梦工厂的具体业务需求,包含 user,pack,mail,friend...功能业务模块
|
服务描述:数据库维护以及GM后台接口 服务
|
||||||
*/
|
*/
|
||||||
var (
|
var (
|
||||||
conf = flag.String("conf", "./conf/dbservice.yaml", "获取需要启动的服务配置文件") //启动服务的Id
|
conf = flag.String("conf", "./conf/mainte.yaml", "获取需要启动的服务配置文件") //启动服务的Id
|
||||||
)
|
)
|
||||||
|
|
||||||
/*服务启动的入口函数*/
|
/*服务启动的入口函数*/
|
||||||
@ -33,9 +34,9 @@ func main() {
|
|||||||
//services.NewGateRouteComp(), //此服务需要接受用户的消息 需要装备网关组件
|
//services.NewGateRouteComp(), //此服务需要接受用户的消息 需要装备网关组件
|
||||||
)
|
)
|
||||||
lego.Run(s, //运行模块
|
lego.Run(s, //运行模块
|
||||||
dbservice.NewModule(),
|
mgolog.NewModule(),
|
||||||
|
gm.NewModule(),
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewService(ops ...rpcx.Option) core.IService {
|
func NewService(ops ...rpcx.Option) core.IService {
|
@ -1,61 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"go_dreamfactory/modules/web"
|
|
||||||
"go_dreamfactory/services"
|
|
||||||
"go_dreamfactory/sys/cache"
|
|
||||||
"go_dreamfactory/sys/db"
|
|
||||||
|
|
||||||
"go_dreamfactory/lego"
|
|
||||||
"go_dreamfactory/lego/base/rpcx"
|
|
||||||
"go_dreamfactory/lego/core"
|
|
||||||
"go_dreamfactory/lego/sys/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
服务类型:web
|
|
||||||
服务描述:提供一些http服务,方便后期维护和开发过程中的测试,只包含 web 业务模块
|
|
||||||
*/
|
|
||||||
var (
|
|
||||||
conf = flag.String("conf", "./conf/web_1.yaml", "获取需要启动的服务配置文件") //启动服务的Id
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
s := NewService(
|
|
||||||
rpcx.SetConfPath(*conf),
|
|
||||||
rpcx.SetVersion("1.0.0.0"),
|
|
||||||
)
|
|
||||||
s.OnInstallComp( //装备组件
|
|
||||||
)
|
|
||||||
lego.Run(s, //运行模块
|
|
||||||
web.NewModule(),
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewService(ops ...rpcx.Option) core.IService {
|
|
||||||
s := new(Service)
|
|
||||||
s.Configure(ops...)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
type Service struct {
|
|
||||||
services.ServiceBase
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Service) InitSys() {
|
|
||||||
this.ServiceBase.InitSys()
|
|
||||||
if err := cache.OnInit(this.GetSettings().Sys["cache"]); err != nil {
|
|
||||||
panic(fmt.Sprintf("init sys.cache err: %s", err.Error()))
|
|
||||||
} else {
|
|
||||||
log.Infof("init sys.cache success!")
|
|
||||||
}
|
|
||||||
if err := db.OnInit(this.GetSettings().Sys["db"]); err != nil {
|
|
||||||
panic(fmt.Sprintf("init sys.db err: %s", err.Error()))
|
|
||||||
} else {
|
|
||||||
log.Infof("init sys.db success!")
|
|
||||||
}
|
|
||||||
}
|
|
@ -27,7 +27,7 @@ import (
|
|||||||
服务描述:处理梦工厂的具体业务需求,包含 user,pack,mail,friend...功能业务模块
|
服务描述:处理梦工厂的具体业务需求,包含 user,pack,mail,friend...功能业务模块
|
||||||
*/
|
*/
|
||||||
var (
|
var (
|
||||||
conf = flag.String("conf", "./conf/worker.yaml", "获取需要启动的服务配置文件") //启动服务的Id
|
conf = flag.String("conf", "./conf/worker_1.yaml", "获取需要启动的服务配置文件") //启动服务的Id
|
||||||
)
|
)
|
||||||
|
|
||||||
/*服务启动的入口函数*/
|
/*服务启动的入口函数*/
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user