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
|
||||
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 (
|
||||
ModuleGate core.M_Modules = "gateway" //gate模块 网关服务模块
|
||||
ModuleWeb core.M_Modules = "web" //web模块
|
||||
ModuleGM core.M_Modules = "gm" //gm模块
|
||||
ModuleUser core.M_Modules = "user" //用户模块
|
||||
ModulePack core.M_Modules = "pack" //背包模块
|
||||
ModuleMail core.M_Modules = "mail" //邮件模块
|
||||
ModuleFriend core.M_Modules = "friend" //好友模块
|
||||
ModuleLogModel core.M_Modules = "model" //日志模块
|
||||
ModuleMgoLog core.M_Modules = "mgolog" //日志模块
|
||||
ModuleEquipment core.M_Modules = "equipment" //装备模块
|
||||
ModuleHero core.M_Modules = "hero" //英雄模块
|
||||
ModuleForum core.M_Modules = "forum" //论坛模块
|
||||
@ -42,6 +42,7 @@ const (
|
||||
ModuleShop core.M_Modules = "shop" //商店模块
|
||||
ModuleTask core.M_Modules = "task" //任务模块
|
||||
ModuleStory core.M_Modules = "story" //主线模块
|
||||
ModuleNotify core.M_Modules = "notify" //公告模块
|
||||
)
|
||||
|
||||
//RPC服务接口定义处
|
||||
|
@ -118,7 +118,7 @@ func (this *UserSession) UnBind() (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)
|
||||
this.msgqueue = append(this.msgqueue, &pb.UserMessage{
|
||||
MainType: mainType,
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"go_dreamfactory/lego/base"
|
||||
"go_dreamfactory/lego/core"
|
||||
"go_dreamfactory/lego/core/cbase"
|
||||
"go_dreamfactory/lego/sys/codec"
|
||||
"go_dreamfactory/lego/sys/event"
|
||||
"go_dreamfactory/lego/sys/log"
|
||||
"go_dreamfactory/lego/sys/rpcx"
|
||||
@ -83,6 +84,12 @@ func (this *RPCXService) InitSys() {
|
||||
} else {
|
||||
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系统
|
||||
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))
|
||||
|
@ -105,8 +105,8 @@ func (this *ServiceBase) Run(mod ...core.IModule) {
|
||||
mi: v,
|
||||
closeSig: make(chan bool, 1),
|
||||
}
|
||||
log.Warnf("注册模块【%s】 没有对应的配置信息", v.GetType())
|
||||
}
|
||||
log.Infof("注册模块【%s】", v.GetType())
|
||||
}
|
||||
for _, v := range this.modules { //序列化每一个模块的参数对象 完成模块的初始化 过程
|
||||
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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"go_dreamfactory/lego/sys/gin/engine"
|
||||
"go_dreamfactory/lego/utils/crypto/md5"
|
||||
)
|
||||
|
||||
type ISys interface {
|
||||
@ -71,3 +76,41 @@ func Static(relativePath string, root string) engine.IRoutes {
|
||||
func StaticFS(relativePath string, fs http.FileSystem) engine.IRoutes {
|
||||
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 {
|
||||
return defsys.Clone(option...)
|
||||
if defsys != nil {
|
||||
return defsys.Clone(option...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
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/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"go.mongodb.org/mongo-driver/mongo/readconcern"
|
||||
"go.mongodb.org/mongo-driver/mongo/readpref"
|
||||
)
|
||||
|
||||
@ -31,12 +30,12 @@ func (this *Mongodb) init() (err error) {
|
||||
// return fmt.Errorf("数据库设置辅助节点 err=%s", err.Error())
|
||||
// }
|
||||
// wc := writeconcern.New(writeconcern.W(1))
|
||||
readconcern.Majority()
|
||||
// readconcern.Majority()
|
||||
//链接mongo服务
|
||||
opt := options.Client().ApplyURI(this.options.MongodbUrl)
|
||||
// opt.SetLocalThreshold(3 * time.Second) //只使用与mongo操作耗时小于3秒的
|
||||
// opt.SetMaxConnIdleTime(5 * time.Second) //指定连接可以保持空闲的最大毫秒数
|
||||
opt.SetMaxPoolSize(this.options.MaxPoolSize) //使用最大的连接数
|
||||
// opt.SetMaxPoolSize(this.options.MaxPoolSize) //使用最大的连接数
|
||||
// opt.SetReadPreference(want) //表示只使用辅助节点
|
||||
// opt.SetReadConcern(readconcern.Majority()) //指定查询应返回实例的最新数据确认为,已写入副本集中的大多数成员
|
||||
// opt.SetWriteConcern(wc) //请求确认写操作传播到大多数mongod实例
|
||||
@ -48,7 +47,6 @@ func (this *Mongodb) init() (err error) {
|
||||
return fmt.Errorf("数据库不可用 err=%s", err.Error())
|
||||
}
|
||||
this.Database = client.Database(this.options.MongodbDatabase)
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -2,15 +2,14 @@ package cluster
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go_dreamfactory/lego/utils/codec"
|
||||
"go_dreamfactory/lego/sys/redis/core"
|
||||
"time"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
|
||||
func NewSys(RedisUrl []string, RedisPassword string, timeOut time.Duration,
|
||||
encode codec.IEncoder,
|
||||
decode codec.IDecoder,
|
||||
codec core.ICodec,
|
||||
) (sys *Redis, err error) {
|
||||
var (
|
||||
client *redis.ClusterClient
|
||||
@ -22,8 +21,7 @@ func NewSys(RedisUrl []string, RedisPassword string, timeOut time.Duration,
|
||||
sys = &Redis{
|
||||
client: client,
|
||||
timeOut: timeOut,
|
||||
encode: encode,
|
||||
decode: decode,
|
||||
codec: codec,
|
||||
}
|
||||
_, err = sys.Ping()
|
||||
return
|
||||
@ -32,8 +30,7 @@ func NewSys(RedisUrl []string, RedisPassword string, timeOut time.Duration,
|
||||
type Redis struct {
|
||||
client *redis.ClusterClient
|
||||
timeOut time.Duration
|
||||
encode codec.IEncoder
|
||||
decode codec.IDecoder
|
||||
codec core.ICodec
|
||||
}
|
||||
|
||||
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, key)
|
||||
var data map[string]string
|
||||
if data, err = this.encode.EncoderToMapString(v); err != nil {
|
||||
if data, err = this.codec.MarshalMap(v); err != nil {
|
||||
return
|
||||
}
|
||||
for k, v := range data {
|
||||
@ -46,19 +46,30 @@ func (this *Redis) HMSet(key string, v interface{}) (err error) {
|
||||
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 命令用于返回哈希表中指定字段的值
|
||||
*/
|
||||
func (this *Redis) HGet(key string, field string, v interface{}) (err error) {
|
||||
cmd := redis.NewStringCmd(this.getContext(), "HGET", key, field)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
var _result string
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
var _result []byte
|
||||
if _result, err = cmd.Bytes(); err == nil {
|
||||
if len(_result) == 0 {
|
||||
err = redis.Nil
|
||||
return
|
||||
}
|
||||
err = this.decode.DecoderString(_result, v)
|
||||
err = this.codec.Unmarshal(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -76,7 +87,22 @@ func (this *Redis) HGetAll(key string, v interface{}) (err error) {
|
||||
err = redis.Nil
|
||||
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
|
||||
}
|
||||
@ -140,7 +166,7 @@ func (this *Redis) HMGet(key string, v interface{}, fields ...string) (err error
|
||||
err = redis.Nil
|
||||
return
|
||||
}
|
||||
err = this.decode.DecoderMapString(_result, v)
|
||||
err = this.codec.UnmarshalMap(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -152,7 +178,7 @@ Redis Hset 命令用于为哈希表中的字段赋值
|
||||
*/
|
||||
func (this *Redis) HSet(key string, field string, value interface{}) (err error) {
|
||||
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()
|
||||
}
|
||||
return
|
||||
@ -166,7 +192,7 @@ Redis Hsetnx 命令用于为哈希表中不存在的的字段赋值
|
||||
*/
|
||||
func (this *Redis) HSetNX(key string, field string, value interface{}) (err error) {
|
||||
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()
|
||||
}
|
||||
return
|
||||
|
@ -10,13 +10,13 @@ Redis Lindex 命令用于通过索引获取列表中的元素。你也可以使
|
||||
func (this *Redis) Lindex(key string, v interface{}) (err error) {
|
||||
cmd := redis.NewStringCmd(this.getContext(), "LINDEX", key)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
var _result string
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
var _result []byte
|
||||
if _result, err = cmd.Bytes(); err == nil {
|
||||
if len(_result) == 0 {
|
||||
err = redis.Nil
|
||||
return
|
||||
}
|
||||
err = this.decode.DecoderString(_result, v)
|
||||
err = this.codec.Unmarshal(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -28,13 +28,13 @@ Redis Linsert 命令用于在列表的元素前或者后插入元素。当指定
|
||||
*/
|
||||
func (this *Redis) Linsert(key string, isbefore bool, tager interface{}, value interface{}) (err error) {
|
||||
var (
|
||||
tagervalue string
|
||||
resultvalue string
|
||||
tagervalue []byte
|
||||
resultvalue []byte
|
||||
)
|
||||
if tagervalue, err = this.encode.EncoderString(tager); err != nil {
|
||||
if tagervalue, err = this.codec.Marshal(tager); err != nil {
|
||||
return
|
||||
}
|
||||
if resultvalue, err = this.encode.EncoderString(value); err != nil {
|
||||
if resultvalue, err = this.codec.Marshal(value); err != nil {
|
||||
return
|
||||
}
|
||||
if isbefore {
|
||||
@ -59,9 +59,9 @@ Redis Lpop 命令用于移除并返回列表的第一个元素
|
||||
func (this *Redis) LPop(key string, v interface{}) (err error) {
|
||||
cmd := redis.NewStringCmd(this.getContext(), "LPOP", key)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
var _result string
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderString(_result, v)
|
||||
var _result []byte
|
||||
if _result, err = cmd.Bytes(); err == nil {
|
||||
err = this.codec.Unmarshal(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -73,7 +73,7 @@ func (this *Redis) LPush(key string, values ...interface{}) (err error) {
|
||||
agrs := make([]interface{}, 0)
|
||||
agrs = append(agrs, "LPUSH")
|
||||
for _, v := range values {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, result)
|
||||
}
|
||||
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 = append(agrs, "LPUSHX")
|
||||
for _, v := range values {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, result)
|
||||
}
|
||||
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)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -116,8 +116,8 @@ count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,
|
||||
count = 0 : 移除表中所有与 VALUE 相等的值
|
||||
*/
|
||||
func (this *Redis) LRem(key string, count int, target interface{}) (err error) {
|
||||
var resultvalue string
|
||||
if resultvalue, err = this.encode.EncoderString(target); err != nil {
|
||||
var resultvalue []byte
|
||||
if resultvalue, err = this.codec.Marshal(target); err != nil {
|
||||
return
|
||||
}
|
||||
err = this.client.Do(this.getContext(), "LREM", key, count, resultvalue).Err()
|
||||
@ -129,8 +129,8 @@ Redis Lset 通过索引来设置元素的值。
|
||||
当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误
|
||||
*/
|
||||
func (this *Redis) LSet(key string, index int, value interface{}) (err error) {
|
||||
var resultvalue string
|
||||
if resultvalue, err = this.encode.EncoderString(value); err == nil {
|
||||
var resultvalue []byte
|
||||
if resultvalue, err = this.codec.Marshal(value); err == nil {
|
||||
return
|
||||
}
|
||||
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) {
|
||||
cmd := redis.NewStringCmd(this.getContext(), "RPOP", key)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
var _result string
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderString(_result, v)
|
||||
var _result []byte
|
||||
if _result, err = cmd.Bytes(); err == nil {
|
||||
err = this.codec.Unmarshal(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -166,9 +166,9 @@ Redis Rpoplpush 命令用于移除列表的最后一个元素,并将该元素
|
||||
func (this *Redis) RPopLPush(oldkey string, newkey string, v interface{}) (err error) {
|
||||
cmd := redis.NewStringCmd(this.getContext(), "RPOPLPUSH", oldkey, newkey)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
var _result string
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderString(_result, v)
|
||||
var _result []byte
|
||||
if _result, err = cmd.Bytes(); err == nil {
|
||||
err = this.codec.Unmarshal(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -182,7 +182,7 @@ func (this *Redis) RPush(key string, values ...interface{}) (err error) {
|
||||
agrs := make([]interface{}, 0)
|
||||
agrs = append(agrs, "RPUSH")
|
||||
for _, v := range values {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, result)
|
||||
}
|
||||
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 = append(agrs, "RPUSHX")
|
||||
for _, v := range values {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, result)
|
||||
}
|
||||
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, key)
|
||||
for _, v := range values {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, result)
|
||||
}
|
||||
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
|
||||
cmd := this.client.SDiff(this.getContext(), keys...)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -54,7 +54,7 @@ func (this *Redis) SInter(v interface{}, keys ...string) (err error) {
|
||||
var _result []string
|
||||
cmd := this.client.SInter(this.getContext(), keys...)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -82,7 +82,7 @@ func (this *Redis) SMembers(v interface{}, key string) (err error) {
|
||||
var _result []string
|
||||
cmd := this.client.SMembers(this.getContext(), key)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -137,7 +137,7 @@ func (this *Redis) SUnion(v interface{}, keys ...string) (err error) {
|
||||
var _result []string
|
||||
cmd := this.client.SUnion(this.getContext(), keys...)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -11,8 +11,8 @@ import (
|
||||
命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型。
|
||||
*/
|
||||
func (this *Redis) Set(key string, value interface{}, expiration time.Duration) (err error) {
|
||||
var result string
|
||||
if result, err = this.encode.EncoderString(value); err != nil {
|
||||
var result []byte
|
||||
if result, err = this.codec.Marshal(value); err != nil {
|
||||
return
|
||||
}
|
||||
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 = append(agrs, "MSET")
|
||||
for k, v := range v {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, k, result)
|
||||
}
|
||||
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 = append(agrs, "MSETNX")
|
||||
for k, v := range v {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, k, result)
|
||||
}
|
||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||
@ -117,8 +117,8 @@ Redis Append 命令用于为指定的 key 追加值。
|
||||
如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
|
||||
*/
|
||||
func (this *Redis) Append(key string, value interface{}) (err error) {
|
||||
var result string
|
||||
if result, err = this.encode.EncoderString(value); err != nil {
|
||||
var result []byte
|
||||
if result, err = this.codec.Marshal(value); err != nil {
|
||||
return
|
||||
}
|
||||
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 就覆写旧值,且无视类型
|
||||
*/
|
||||
func (this *Redis) Get(key string, value interface{}) (err error) {
|
||||
var result string
|
||||
if result, err = this.client.Get(this.getContext(), key).Result(); err == nil {
|
||||
err = this.decode.DecoderString(result, value)
|
||||
var result []byte
|
||||
if result, err = this.client.Get(this.getContext(), key).Bytes(); err == nil {
|
||||
err = this.codec.Unmarshal(result, value)
|
||||
}
|
||||
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) {
|
||||
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)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
var _result string
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderString(_result, result)
|
||||
var _result []byte
|
||||
if _result, err = cmd.Bytes(); err == nil {
|
||||
err = this.codec.Unmarshal(_result, result)
|
||||
}
|
||||
}
|
||||
return
|
||||
@ -169,7 +169,7 @@ func (this *Redis) MGet(v interface{}, keys ...string) (err error) {
|
||||
if result, err = cmd.Result(); err != nil {
|
||||
return
|
||||
}
|
||||
err = this.decode.DecoderSliceString(result, v)
|
||||
err = this.codec.UnmarshalSlice(result, v)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ func (this *Redis) ZRange(key string, start int64, stop int64, v interface{}) (e
|
||||
var _result []string
|
||||
cmd := this.client.ZRange(this.getContext(), key, start, stop)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -71,7 +71,7 @@ func (this *Redis) ZRangeByLex(key string, opt *redis.ZRangeBy, v interface{}) (
|
||||
var _result []string
|
||||
cmd := this.client.ZRangeByLex(this.getContext(), key, opt)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -83,7 +83,7 @@ func (this *Redis) ZRangeByScore(key string, opt *redis.ZRangeBy, v interface{})
|
||||
var _result []string
|
||||
cmd := this.client.ZRangeByScore(this.getContext(), key, opt)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -135,7 +135,7 @@ func (this *Redis) ZRevRange(key string, start int64, stop int64, v interface{})
|
||||
var _result []string
|
||||
cmd := this.client.ZRevRange(this.getContext(), key, start, stop)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -147,7 +147,7 @@ func (this *Redis) ZRevRangeByScore(key string, opt *redis.ZRangeBy, v interface
|
||||
var _result []string
|
||||
cmd := this.client.ZRevRangeByScore(this.getContext(), key, opt)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -65,12 +65,14 @@ type (
|
||||
HExists(key string, field string) (result bool, err error)
|
||||
HGet(key string, field string, value 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)
|
||||
HIncrByFloat(key string, field string, value float32) (err error)
|
||||
Hkeys(key string) (result []string, err error)
|
||||
Hlen(key string) (result int, err error)
|
||||
HMGet(key string, v interface{}, fields ...string) (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)
|
||||
HSetNX(key string, field string, value interface{}) (err error)
|
||||
/*Set*/
|
||||
@ -325,6 +327,9 @@ func HMGet(key string, v interface{}, fields ...string) (err error) {
|
||||
func HMSet(key string, v interface{}) (err error) {
|
||||
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) {
|
||||
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 (
|
||||
"time"
|
||||
|
||||
"go_dreamfactory/lego/sys/redis/core"
|
||||
"go_dreamfactory/lego/utils/mapstructure"
|
||||
)
|
||||
|
||||
@ -13,14 +14,6 @@ const (
|
||||
Redis_Cluster
|
||||
)
|
||||
|
||||
///redis 存储数据格式化类型
|
||||
type RedisStorageTyoe int8
|
||||
|
||||
const (
|
||||
JsonData RedisStorageTyoe = iota
|
||||
ProtoData
|
||||
)
|
||||
|
||||
type Option func(*Options)
|
||||
type Options struct {
|
||||
RedisType RedisType
|
||||
@ -30,8 +23,8 @@ type Options struct {
|
||||
Redis_Single_PoolSize int
|
||||
Redis_Cluster_Addr []string
|
||||
Redis_Cluster_Password string
|
||||
RedisStorageType RedisStorageTyoe
|
||||
TimeOut time.Duration
|
||||
Codec core.ICodec
|
||||
}
|
||||
|
||||
func SetRedisType(v RedisType) Option {
|
||||
@ -74,11 +67,6 @@ func SetRedis_Cluster_Password(v string) Option {
|
||||
o.Redis_Cluster_Password = v
|
||||
}
|
||||
}
|
||||
func SetRedisStorageType(v RedisStorageTyoe) Option {
|
||||
return func(o *Options) {
|
||||
o.RedisStorageType = v
|
||||
}
|
||||
}
|
||||
|
||||
func SetTimeOut(v time.Duration) Option {
|
||||
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 {
|
||||
options := Options{
|
||||
Redis_Single_Addr: "127.0.0.1:6379",
|
||||
|
@ -5,25 +5,15 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
|
||||
"go_dreamfactory/lego/sys/codec"
|
||||
"go_dreamfactory/lego/sys/redis/cluster"
|
||||
"go_dreamfactory/lego/sys/redis/single"
|
||||
"go_dreamfactory/lego/utils/codec"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func newSys(options Options) (sys *Redis, err error) {
|
||||
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()
|
||||
return
|
||||
}
|
||||
@ -31,8 +21,6 @@ func newSys(options Options) (sys *Redis, err error) {
|
||||
type Redis struct {
|
||||
options Options
|
||||
client IRedis
|
||||
decoder codec.IDecoder
|
||||
encoder codec.IEncoder
|
||||
}
|
||||
|
||||
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_PoolSize,
|
||||
this.options.TimeOut,
|
||||
this.encoder,
|
||||
this.decoder,
|
||||
this,
|
||||
)
|
||||
} else if this.options.RedisType == Redis_Cluster {
|
||||
this.client, err = cluster.NewSys(
|
||||
this.options.Redis_Cluster_Addr,
|
||||
this.options.Redis_Cluster_Password,
|
||||
this.options.TimeOut,
|
||||
this.encoder,
|
||||
this.decoder,
|
||||
this,
|
||||
)
|
||||
} else {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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 (
|
||||
"context"
|
||||
"go_dreamfactory/lego/utils/codec"
|
||||
"go_dreamfactory/lego/sys/redis/core"
|
||||
"time"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
|
||||
func NewSys(RedisUrl, RedisPassword string, RedisDB, PoolSize int, timeOut time.Duration,
|
||||
encode codec.IEncoder,
|
||||
decode codec.IDecoder,
|
||||
codec core.ICodec,
|
||||
) (sys *Redis, err error) {
|
||||
var (
|
||||
client *redis.Client
|
||||
@ -24,8 +23,7 @@ func NewSys(RedisUrl, RedisPassword string, RedisDB, PoolSize int, timeOut time.
|
||||
sys = &Redis{
|
||||
client: client,
|
||||
timeOut: timeOut,
|
||||
encode: encode,
|
||||
decode: decode,
|
||||
codec: codec,
|
||||
}
|
||||
_, err = sys.Ping()
|
||||
return
|
||||
@ -34,8 +32,7 @@ func NewSys(RedisUrl, RedisPassword string, RedisDB, PoolSize int, timeOut time.
|
||||
type Redis struct {
|
||||
client *redis.Client
|
||||
timeOut time.Duration
|
||||
encode codec.IEncoder
|
||||
decode codec.IDecoder
|
||||
codec core.ICodec
|
||||
}
|
||||
|
||||
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, key)
|
||||
var data map[string]string
|
||||
if data, err = this.encode.EncoderToMapString(v); err != nil {
|
||||
if data, err = this.codec.MarshalMap(v); err != nil {
|
||||
return
|
||||
}
|
||||
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()
|
||||
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 命令用于返回哈希表中指定字段的值
|
||||
@ -52,9 +62,9 @@ Redis Hget 命令用于返回哈希表中指定字段的值
|
||||
func (this *Redis) HGet(key string, field string, v interface{}) (err error) {
|
||||
cmd := redis.NewStringCmd(this.getContext(), "HGET", key, field)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
var _result string
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderString(_result, v)
|
||||
var _result []byte
|
||||
if _result, err = cmd.Bytes(); err == nil {
|
||||
err = this.codec.Unmarshal(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -71,7 +81,22 @@ func (this *Redis) HGetAll(key string, v interface{}) (err error) {
|
||||
if len(_result) == 0 {
|
||||
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
|
||||
}
|
||||
@ -131,7 +156,7 @@ func (this *Redis) HMGet(key string, v interface{}, fields ...string) (err error
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
var _result map[string]string
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderMapString(_result, v)
|
||||
err = this.codec.UnmarshalMap(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -143,7 +168,7 @@ Redis Hset 命令用于为哈希表中的字段赋值
|
||||
*/
|
||||
func (this *Redis) HSet(key string, field string, value interface{}) (err error) {
|
||||
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()
|
||||
}
|
||||
return
|
||||
@ -157,7 +182,7 @@ Redis Hsetnx 命令用于为哈希表中不存在的的字段赋值
|
||||
*/
|
||||
func (this *Redis) HSetNX(key string, field string, value interface{}) (err error) {
|
||||
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()
|
||||
}
|
||||
return
|
||||
|
@ -10,9 +10,9 @@ Redis Lindex 命令用于通过索引获取列表中的元素。你也可以使
|
||||
func (this *Redis) Lindex(key string, v interface{}) (err error) {
|
||||
cmd := redis.NewStringCmd(this.getContext(), "LINDEX", key)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
var _result string
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderString(_result, v)
|
||||
var _result []byte
|
||||
if _result, err = cmd.Bytes(); err == nil {
|
||||
err = this.codec.Unmarshal(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -24,13 +24,13 @@ Redis Linsert 命令用于在列表的元素前或者后插入元素。当指定
|
||||
*/
|
||||
func (this *Redis) Linsert(key string, isbefore bool, tager interface{}, value interface{}) (err error) {
|
||||
var (
|
||||
tagervalue string
|
||||
resultvalue string
|
||||
tagervalue []byte
|
||||
resultvalue []byte
|
||||
)
|
||||
if tagervalue, err = this.encode.EncoderString(tager); err != nil {
|
||||
if tagervalue, err = this.codec.Marshal(tager); err != nil {
|
||||
return
|
||||
}
|
||||
if resultvalue, err = this.encode.EncoderString(value); err != nil {
|
||||
if resultvalue, err = this.codec.Marshal(value); err != nil {
|
||||
return
|
||||
}
|
||||
if isbefore {
|
||||
@ -55,9 +55,9 @@ Redis Lpop 命令用于移除并返回列表的第一个元素
|
||||
func (this *Redis) LPop(key string, v interface{}) (err error) {
|
||||
cmd := redis.NewStringCmd(this.getContext(), "LPOP", key)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
var _result string
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderString(_result, v)
|
||||
var _result []byte
|
||||
if _result, err = cmd.Bytes(); err == nil {
|
||||
err = this.codec.Unmarshal(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -69,7 +69,7 @@ func (this *Redis) LPush(key string, values ...interface{}) (err error) {
|
||||
agrs := make([]interface{}, 0)
|
||||
agrs = append(agrs, "LPUSH")
|
||||
for _, v := range values {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, result)
|
||||
}
|
||||
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 = append(agrs, "LPUSHX")
|
||||
for _, v := range values {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, result)
|
||||
}
|
||||
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)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -112,8 +112,8 @@ count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,
|
||||
count = 0 : 移除表中所有与 VALUE 相等的值
|
||||
*/
|
||||
func (this *Redis) LRem(key string, count int, target interface{}) (err error) {
|
||||
var resultvalue string
|
||||
if resultvalue, err = this.encode.EncoderString(target); err != nil {
|
||||
var resultvalue []byte
|
||||
if resultvalue, err = this.codec.Marshal(target); err != nil {
|
||||
return
|
||||
}
|
||||
err = this.client.Do(this.getContext(), "LREM", key, count, resultvalue).Err()
|
||||
@ -125,8 +125,8 @@ Redis Lset 通过索引来设置元素的值。
|
||||
当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误
|
||||
*/
|
||||
func (this *Redis) LSet(key string, index int, value interface{}) (err error) {
|
||||
var resultvalue string
|
||||
if resultvalue, err = this.encode.EncoderString(value); err == nil {
|
||||
var resultvalue []byte
|
||||
if resultvalue, err = this.codec.Marshal(value); err == nil {
|
||||
return
|
||||
}
|
||||
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) {
|
||||
cmd := redis.NewStringCmd(this.getContext(), "RPOP", key)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
var _result string
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderString(_result, v)
|
||||
var _result []byte
|
||||
if _result, err = cmd.Bytes(); err == nil {
|
||||
err = this.codec.Unmarshal(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -162,9 +162,9 @@ Redis Rpoplpush 命令用于移除列表的最后一个元素,并将该元素
|
||||
func (this *Redis) RPopLPush(oldkey string, newkey string, v interface{}) (err error) {
|
||||
cmd := redis.NewStringCmd(this.getContext(), "RPOPLPUSH", oldkey, newkey)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
var _result string
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderString(_result, v)
|
||||
var _result []byte
|
||||
if _result, err = cmd.Bytes(); err == nil {
|
||||
err = this.codec.Unmarshal(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -178,7 +178,7 @@ func (this *Redis) RPush(key string, values ...interface{}) (err error) {
|
||||
agrs := make([]interface{}, 0)
|
||||
agrs = append(agrs, "RPUSH")
|
||||
for _, v := range values {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, result)
|
||||
}
|
||||
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 = append(agrs, "RPUSHX")
|
||||
for _, v := range values {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, result)
|
||||
}
|
||||
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, key)
|
||||
for _, v := range values {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, result)
|
||||
}
|
||||
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
|
||||
cmd := this.client.SDiff(this.getContext(), keys...)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -54,7 +54,7 @@ func (this *Redis) SInter(v interface{}, keys ...string) (err error) {
|
||||
var _result []string
|
||||
cmd := this.client.SInter(this.getContext(), keys...)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -82,7 +82,7 @@ func (this *Redis) SMembers(v interface{}, key string) (err error) {
|
||||
var _result []string
|
||||
cmd := this.client.SMembers(this.getContext(), key)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -137,7 +137,7 @@ func (this *Redis) SUnion(v interface{}, keys ...string) (err error) {
|
||||
var _result []string
|
||||
cmd := this.client.SUnion(this.getContext(), keys...)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -11,8 +11,8 @@ import (
|
||||
命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型。
|
||||
*/
|
||||
func (this *Redis) Set(key string, value interface{}, expiration time.Duration) (err error) {
|
||||
var result string
|
||||
if result, err = this.encode.EncoderString(value); err != nil {
|
||||
var result []byte
|
||||
if result, err = this.codec.Marshal(value); err != nil {
|
||||
return
|
||||
}
|
||||
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 = append(agrs, "MSET")
|
||||
for k, v := range v {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, k, result)
|
||||
}
|
||||
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 = append(agrs, "MSETNX")
|
||||
for k, v := range v {
|
||||
result, _ := this.encode.EncoderString(v)
|
||||
result, _ := this.codec.Marshal(v)
|
||||
agrs = append(agrs, k, result)
|
||||
}
|
||||
err = this.client.Do(this.getContext(), agrs...).Err()
|
||||
@ -117,8 +117,8 @@ Redis Append 命令用于为指定的 key 追加值。
|
||||
如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
|
||||
*/
|
||||
func (this *Redis) Append(key string, value interface{}) (err error) {
|
||||
var result string
|
||||
if result, err = this.encode.EncoderString(value); err != nil {
|
||||
var result []byte
|
||||
if result, err = this.codec.Marshal(value); err != nil {
|
||||
return
|
||||
}
|
||||
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 就覆写旧值,且无视类型
|
||||
*/
|
||||
func (this *Redis) Get(key string, value interface{}) (err error) {
|
||||
var result string
|
||||
if result, err = this.client.Get(this.getContext(), key).Result(); err == nil {
|
||||
err = this.decode.DecoderString(result, value)
|
||||
var result []byte
|
||||
if result, err = this.client.Get(this.getContext(), key).Bytes(); err == nil {
|
||||
err = this.codec.Unmarshal(result, value)
|
||||
}
|
||||
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) {
|
||||
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)
|
||||
this.client.Process(this.getContext(), cmd)
|
||||
var _result string
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderString(_result, result)
|
||||
var _result []byte
|
||||
if _result, err = cmd.Bytes(); err == nil {
|
||||
err = this.codec.Unmarshal(_result, result)
|
||||
}
|
||||
}
|
||||
return
|
||||
@ -169,7 +169,7 @@ func (this *Redis) MGet(v interface{}, keys ...string) (err error) {
|
||||
if result, err = cmd.Result(); err != nil {
|
||||
return
|
||||
}
|
||||
err = this.decode.DecoderSliceString(result, v)
|
||||
err = this.codec.UnmarshalSlice(result, v)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ func (this *Redis) ZRange(key string, start int64, stop int64, v interface{}) (e
|
||||
var _result []string
|
||||
cmd := this.client.ZRange(this.getContext(), key, start, stop)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -71,7 +71,7 @@ func (this *Redis) ZRangeByLex(key string, opt *redis.ZRangeBy, v interface{}) (
|
||||
var _result []string
|
||||
cmd := this.client.ZRangeByLex(this.getContext(), key, opt)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -83,7 +83,7 @@ func (this *Redis) ZRangeByScore(key string, opt *redis.ZRangeBy, v interface{})
|
||||
var _result []string
|
||||
cmd := this.client.ZRangeByScore(this.getContext(), key, opt)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -135,7 +135,7 @@ func (this *Redis) ZRevRange(key string, start int64, stop int64, v interface{})
|
||||
var _result []string
|
||||
cmd := this.client.ZRevRange(this.getContext(), key, start, stop)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -147,7 +147,7 @@ func (this *Redis) ZRevRangeByScore(key string, opt *redis.ZRangeBy, v interface
|
||||
var _result []string
|
||||
cmd := this.client.ZRevRangeByScore(this.getContext(), key, opt)
|
||||
if _result, err = cmd.Result(); err == nil {
|
||||
err = this.decode.DecoderSliceString(_result, v)
|
||||
err = this.codec.UnmarshalSlice(_result, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ func TestMain(m *testing.M) {
|
||||
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_Password(""),
|
||||
redis.SetRedisStorageType(redis.JsonData),
|
||||
); err != nil {
|
||||
fmt.Println("err:", err)
|
||||
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/lego/core"
|
||||
"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/mgo"
|
||||
"go_dreamfactory/lego/sys/redis"
|
||||
"go_dreamfactory/pb"
|
||||
"go_dreamfactory/sys/cache"
|
||||
"go_dreamfactory/sys/db"
|
||||
"reflect"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/modern-go/reflect2"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
@ -70,6 +75,7 @@ func (this *MCompModel) InsertModelLogs(table string, uID string, target interfa
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (this *MCompModel) DeleteModelLogs(table string, uID string, where interface{}) (err error) {
|
||||
|
||||
data := &comm.Autogenerated{
|
||||
@ -88,6 +94,7 @@ func (this *MCompModel) DeleteModelLogs(table string, uID string, where interfac
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (this *MCompModel) UpdateModelLogs(table string, uID string, where bson.M, target interface{}) (err error) {
|
||||
|
||||
data := &comm.Autogenerated{
|
||||
@ -221,8 +228,8 @@ func (this *MCompModel) Get(uid string, data interface{}) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
//获取列表数据 注意 data 必须啊转 切片的指针 *[]type
|
||||
func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
|
||||
//获取列表数据 注意 data 必须是 切片的指针 *[]type 暂时废弃
|
||||
func (this *MCompModel) mGetList(uid string, data interface{}) (err error) {
|
||||
var keys map[string]string = make(map[string]string)
|
||||
var c *mongo.Cursor
|
||||
t := reflect.TypeOf(data)
|
||||
@ -312,6 +319,110 @@ func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
|
||||
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) {
|
||||
this.Redis.HMGet(this.ukey(uid), data, fields...)
|
||||
@ -355,6 +466,21 @@ func (this *MCompModel) DelListlds(uid string, ids ...string) (err error) {
|
||||
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 {
|
||||
ret := cache.OperationAttrs(attrs).Find(cache.ATTR_MGOLOG).Unwrap_Or(nil)
|
||||
|
@ -10,7 +10,9 @@ import (
|
||||
|
||||
type (
|
||||
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)
|
||||
this.options = options.(*Options)
|
||||
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)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package web
|
||||
package gm
|
||||
|
||||
import (
|
||||
"go_dreamfactory/lego/core"
|
||||
@ -11,16 +11,16 @@ import (
|
||||
*/
|
||||
type Api_Comp struct {
|
||||
cbase.ModuleCompBase
|
||||
options *Options //模块参数
|
||||
moduleWeb *Web //当前模块对象
|
||||
gin gin.ISys //gin 框架 web的热门框架
|
||||
options *Options //模块参数
|
||||
module *GM //当前模块对象
|
||||
gin gin.ISys //gin 框架 web的热门框架
|
||||
}
|
||||
|
||||
//组件初始化接口 启动web服务 并注册api
|
||||
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)
|
||||
this.options = options.(*Options)
|
||||
this.moduleWeb = module.(*Web)
|
||||
this.module = module.(*GM)
|
||||
this.gin, err = gin.NewSys(gin.SetListenPort(this.options.Port))
|
||||
this.gin.POST("/register", this.Register)
|
||||
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 (
|
||||
"go_dreamfactory/lego/sys/gin/engine"
|
||||
@ -13,7 +13,7 @@ func (this *Api_Comp) Register(c *engine.Context) {
|
||||
rsp := &pb.UserRegisterResp{}
|
||||
err := c.BindJSON(&req)
|
||||
if err == nil {
|
||||
err := this.moduleWeb.modelUser.User_Create(&pb.DBUser{
|
||||
err := this.module.modelUser.User_Create(&pb.DBUser{
|
||||
Binduid: req.Account,
|
||||
Sid: req.Sid,
|
||||
})
|
@ -1,4 +1,4 @@
|
||||
package web
|
||||
package gm
|
||||
|
||||
import (
|
||||
"go_dreamfactory/lego/sys/gin/engine"
|
||||
@ -7,7 +7,7 @@ import (
|
||||
|
||||
//服务列表
|
||||
func (this *Api_Comp) ServerList(c *engine.Context) {
|
||||
conf := this.moduleWeb.configure.getServerListConf()
|
||||
conf := this.module.configure.getServerListConf()
|
||||
|
||||
c.JSON(http.StatusOK, conf)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package web
|
||||
package gm
|
||||
|
||||
import (
|
||||
"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 (
|
||||
"go_dreamfactory/comm"
|
||||
@ -9,40 +9,41 @@ import (
|
||||
)
|
||||
|
||||
/*
|
||||
模块名:web
|
||||
描述:为服务集群提供一些http服务接口 方便测试和后期运维实现
|
||||
模块名:gm
|
||||
描述:提供管理员相关的http接口
|
||||
开发:李伟
|
||||
*/
|
||||
func NewModule() core.IModule {
|
||||
m := new(Web)
|
||||
m := new(GM)
|
||||
return m
|
||||
}
|
||||
|
||||
type Web struct {
|
||||
type GM struct {
|
||||
cbase.ModuleBase
|
||||
options *Options
|
||||
api_comp *Api_Comp //提供weba pi服务的组件
|
||||
modelUser *user.ModelUser
|
||||
configure *configureComp
|
||||
options *Options
|
||||
api_comp *Api_Comp //提供weba pi服务的组件
|
||||
modelUser *user.ModelUser
|
||||
modelNotify *modelNotifyComp
|
||||
configure *configureComp
|
||||
}
|
||||
|
||||
//模块名
|
||||
func (this *Web) GetType() core.M_Modules {
|
||||
return comm.ModuleWeb
|
||||
func (this *GM) GetType() core.M_Modules {
|
||||
return comm.ModuleGM
|
||||
}
|
||||
|
||||
//模块自定义参数
|
||||
func (this *Web) NewOptions() (options core.IModuleOptions) {
|
||||
func (this *GM) NewOptions() (options core.IModuleOptions) {
|
||||
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)
|
||||
this.options = options.(*Options)
|
||||
return
|
||||
}
|
||||
|
||||
func (this *Web) OnInstallComp() {
|
||||
func (this *GM) OnInstallComp() {
|
||||
this.ModuleBase.OnInstallComp()
|
||||
this.api_comp = this.RegisterComp(new(Api_Comp)).(*Api_Comp)
|
||||
this.modelUser = this.RegisterComp(new(user.ModelUser)).(*user.ModelUser)
|
@ -1,17 +1,23 @@
|
||||
package web
|
||||
package gm
|
||||
|
||||
import (
|
||||
"go_dreamfactory/lego/utils/mapstructure"
|
||||
"go_dreamfactory/modules"
|
||||
)
|
||||
|
||||
type (
|
||||
Options struct {
|
||||
modules.Options
|
||||
Port int
|
||||
Key string
|
||||
}
|
||||
)
|
||||
|
||||
func (this *Options) LoadConfig(settings map[string]interface{}) (err error) {
|
||||
if settings != nil {
|
||||
if err = this.Options.LoadConfig(settings); err != nil {
|
||||
return
|
||||
}
|
||||
err = mapstructure.Decode(settings, this)
|
||||
}
|
||||
return
|
@ -11,6 +11,8 @@ import (
|
||||
|
||||
mengine "github.com/dengsgo/math-engine/engine"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/x/bsonx"
|
||||
)
|
||||
|
||||
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)
|
||||
this.moduleHero = module.(*Hero)
|
||||
this.TableName = "hero"
|
||||
// 通过uid创建索引
|
||||
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
|
||||
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ package items
|
||||
|
||||
import (
|
||||
"go_dreamfactory/comm"
|
||||
"go_dreamfactory/lego/sys/log"
|
||||
"go_dreamfactory/pb"
|
||||
"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})
|
||||
if code == pb.ErrorCode_Success {
|
||||
go func() { //异步处理修改数据
|
||||
this.module.modelItems.Pack_UpdateUserPack(session.GetUserId(), modifys...)
|
||||
this.module.modelItems.Pack_DeleteUserPack(session.GetUserId(), dels...)
|
||||
if len(modifys) > 0 {
|
||||
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 {
|
||||
log.Errorf("QueryUserPackReq err:%v", err)
|
||||
this.module.Errorf("QueryUserPackReq err:%v", err)
|
||||
code = pb.ErrorCode_CacheReadError
|
||||
return
|
||||
} else {
|
||||
tempgrids = this.module.configure.GetPackItemByType(items, req.IType)
|
||||
modifys = make([]*pb.DB_UserItemData, 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()
|
||||
for _, v := range tempgrids {
|
||||
if v.ETime > 0 && v.ETime < nt { //已经过期
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
cfg "go_dreamfactory/sys/configure/structs"
|
||||
|
||||
"go_dreamfactory/lego/core"
|
||||
"go_dreamfactory/lego/sys/log"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -17,11 +16,13 @@ const (
|
||||
///背包配置管理组件
|
||||
type ConfigureComp struct {
|
||||
modules.MCompConfigure
|
||||
module *Items
|
||||
}
|
||||
|
||||
//组件初始化接口
|
||||
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.module = module.(*Items)
|
||||
err = this.LoadConfigure(game_item, cfg.NewGame_item)
|
||||
return
|
||||
}
|
||||
@ -32,7 +33,7 @@ func (this *ConfigureComp) GetItemsConfigure() (items map[int32]*cfg.Game_itemDa
|
||||
v interface{}
|
||||
)
|
||||
if v, err = this.GetConfigure(game_item); err != nil {
|
||||
log.Errorf("err:%v", err)
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
} else {
|
||||
items = v.(*cfg.Game_item).GetDataMap()
|
||||
@ -47,12 +48,12 @@ func (this *ConfigureComp) GetItemConfigure(id int32) (item *cfg.Game_itemData,
|
||||
ok bool
|
||||
)
|
||||
if v, err = this.GetConfigure(game_item); err != nil {
|
||||
log.Errorf("err:%v", err)
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
} else {
|
||||
if item, ok = v.(*cfg.Game_item).GetDataMap()[id]; !ok {
|
||||
err = fmt.Errorf("no found item:%d configure", id)
|
||||
log.Errorf("err:%v", err)
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -70,7 +71,7 @@ func (this *ConfigureComp) GetPackItemByType(itmes []*pb.DB_UserItemData, usetyp
|
||||
err error
|
||||
)
|
||||
if v, err = this.GetConfigure(game_item); err != nil {
|
||||
log.Errorf("err:%v", err)
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
} else {
|
||||
table = v.(*cfg.Game_item)
|
||||
@ -80,7 +81,7 @@ func (this *ConfigureComp) GetPackItemByType(itmes []*pb.DB_UserItemData, usetyp
|
||||
result = append(result, v)
|
||||
}
|
||||
} 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) {
|
||||
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
|
||||
}
|
||||
|
||||
///查询用户指定格子的物品数据
|
||||
func (this *ModelItemsComp) Pack_QueryUserPackByGridId(uId string, grid string) (itme *pb.DB_UserItemData, err error) {
|
||||
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
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
err = this.DelListlds(uId, ids...)
|
||||
if err = this.DelListlds(uId, ids...); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
}
|
||||
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) {
|
||||
err = this.DelListlds(uId, gridIds...)
|
||||
if err = this.DelListlds(uId, gridIds...); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -82,6 +91,7 @@ func (this *ModelItemsComp) Pack_QueryUserPackItemsAmount(uId string, itemid ...
|
||||
err error
|
||||
)
|
||||
if itmes, err = this.Pack_QueryUserPack(uId); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
result = map[int32]uint32{}
|
||||
@ -108,6 +118,7 @@ func (this *ModelItemsComp) Pack_AddItemToUserPack(uId string, itemId int32, add
|
||||
return
|
||||
}
|
||||
if itmes, err = this.Pack_QueryUserPack(uId); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
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 err = this.Pack_AddUserPack(uId, add...); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if len(del) > 0 {
|
||||
if err = this.Pack_DeleteUserPack(uId, del...); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if len(update) > 0 {
|
||||
if err = this.Pack_UpdateUserPack(uId, update...); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -147,6 +161,7 @@ func (this *ModelItemsComp) Pack_AddItemsToUserPack(uId string, items map[int32]
|
||||
leftnum int64
|
||||
)
|
||||
if itmes, err = this.Pack_QueryUserPack(uId); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
for k, v := range items {
|
||||
@ -160,16 +175,19 @@ func (this *ModelItemsComp) Pack_AddItemsToUserPack(uId string, items map[int32]
|
||||
}
|
||||
if len(add) > 0 {
|
||||
if err = this.Pack_AddUserPack(uId, add...); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if len(del) > 0 {
|
||||
if err = this.Pack_DeleteUserPack(uId, del...); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if len(update) > 0 {
|
||||
if err = this.Pack_UpdateUserPack(uId, update...); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -190,10 +208,12 @@ func (this *ModelItemsComp) Pack_AddItemToUserPackByGrid(uId string, gridid stri
|
||||
return
|
||||
}
|
||||
if conf, err = this.module.configure.GetItemConfigure(itemId); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if itme, err = this.Pack_QueryUserPackByGridId(uId, gridid); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
amount = int64(itme.Amount)
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"go_dreamfactory/pb"
|
||||
|
||||
"go_dreamfactory/lego/core"
|
||||
"go_dreamfactory/lego/sys/log"
|
||||
)
|
||||
|
||||
/*
|
||||
@ -48,7 +47,7 @@ func (this *Items) OnInstallComp() {
|
||||
//IItems-------------------------------------------------------------------------------------------------------------------------------
|
||||
///查询用户背包物品数量
|
||||
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
|
||||
if result := this.modelItems.Pack_QueryUserPackItemsAmount(uId, itemid); result != nil && len(result) > 0 {
|
||||
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) {
|
||||
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 {
|
||||
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 {
|
||||
code = pb.ErrorCode_ItemsNoEnough
|
||||
} 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) {
|
||||
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 {
|
||||
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 {
|
||||
code = pb.ErrorCode_ItemsNoEnough
|
||||
} else if err == PackGridNumUpper {
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"go_dreamfactory/modules/equipment"
|
||||
"go_dreamfactory/modules/hero"
|
||||
"go_dreamfactory/modules/items"
|
||||
"go_dreamfactory/modules/task"
|
||||
"go_dreamfactory/modules/user"
|
||||
"go_dreamfactory/pb"
|
||||
"go_dreamfactory/services"
|
||||
@ -74,6 +75,7 @@ func TestMain(m *testing.M) {
|
||||
hero.NewModule(),
|
||||
user.NewModule(),
|
||||
equipment.NewModule(),
|
||||
task.NewModule(),
|
||||
)
|
||||
}()
|
||||
time.Sleep(time.Second * 3)
|
||||
@ -81,10 +83,10 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
|
||||
func Test_Modules(t *testing.T) {
|
||||
data, _ := ptypes.MarshalAny(&pb.ItemsGetlistReq{})
|
||||
s_gateComp.ReceiveMsg(context.Background(), &pb.AgentMessage{MainType: "pack", SubType: "getlist", Message: data}, &pb.RPCMessageReply{})
|
||||
// items, err := module.db_comp.Pack_QueryUserPack("liwei1dao")
|
||||
// log.Debugf("item:%v err:%v", items, err)
|
||||
data, _ := ptypes.MarshalAny(&pb.ItemsGetlistReq{IType: 9})
|
||||
reply := &pb.RPCMessageReply{}
|
||||
s_gateComp.ReceiveMsg(context.Background(), &pb.AgentMessage{UserId: "0_62cd5952f72cc4bdc2d85f6b", MainType: "items", SubType: "getlist", Message: data}, reply)
|
||||
log.Debugf("reply:%v", reply)
|
||||
}
|
||||
|
||||
func Test_Modules_AddItems(t *testing.T) {
|
||||
@ -93,5 +95,5 @@ func Test_Modules_AddItems(t *testing.T) {
|
||||
FuncName: "Test_Modules_AddItems",
|
||||
Describe: "测试模块接口",
|
||||
}, "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"
|
||||
)
|
||||
|
||||
const (
|
||||
QueryUserMailResp = "queryusermailresp"
|
||||
ReadUserMailResp = "readusermailresp"
|
||||
GetUserMailAttachmentResp = "getusermailattachmentresp"
|
||||
DelUserMailResp = "delusermailresp"
|
||||
GetNewEMailResp = "getnewEmailresp"
|
||||
)
|
||||
|
||||
type apiComp struct {
|
||||
modules.MCompGate
|
||||
service core.IService
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
//参数校验
|
||||
func (this *apiComp) DelMailCheck(session comm.IUserSession, req *pb.MailDelMailReq) (code pb.ErrorCode) {
|
||||
if session.GetUserId() == "" || req.ObjID == "" {
|
||||
code = pb.ErrorCode_NoLogin
|
||||
code = pb.ErrorCode_ReqParameterError
|
||||
return
|
||||
}
|
||||
return
|
||||
@ -23,7 +23,7 @@ func (this *apiComp) DelMail(session comm.IUserSession, req *pb.MailDelMailReq)
|
||||
var err error
|
||||
mailinfo := make([]*pb.DBMailData, 0)
|
||||
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
|
||||
if code != pb.ErrorCode_Success {
|
||||
|
@ -22,7 +22,7 @@ func (this *apiComp) GetUserMailAttachment(session comm.IUserSession, req *pb.Ma
|
||||
mail *pb.DBMailData
|
||||
)
|
||||
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
|
||||
|
@ -18,7 +18,7 @@ func (this *apiComp) GetList(session comm.IUserSession, req *pb.MailGetListReq)
|
||||
var err error
|
||||
mailinfo := make([]*pb.DBMailData, 0)
|
||||
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
|
||||
if code != pb.ErrorCode_Success {
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
|
||||
func (this *apiComp) ReadMailCheck(session comm.IUserSession, req *pb.MailReadMailReq) (code pb.ErrorCode) {
|
||||
if session.GetUserId() == "" || req.ObjID == "" {
|
||||
code = pb.ErrorCode_NoLogin
|
||||
code = pb.ErrorCode_ReqParameterError
|
||||
return
|
||||
}
|
||||
return
|
||||
@ -22,7 +22,7 @@ func (this *apiComp) ReadMail(session comm.IUserSession, req *pb.MailReadMailReq
|
||||
mail *pb.DBMailData
|
||||
)
|
||||
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
|
||||
if code != pb.ErrorCode_Success {
|
||||
|
@ -62,6 +62,6 @@ func (this *Mail) CreateNewMail(uId string, mail *pb.DBMailData) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
this.SendMsgToUser(string(this.GetType()), GetNewEMailResp, mail, _cache)
|
||||
this.SendMsgToUser(string(this.GetType()), "newmail", mail, _cache)
|
||||
return true
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package dbservice
|
||||
package mgolog
|
||||
|
||||
import (
|
||||
"go_dreamfactory/lego/core"
|
@ -1,4 +1,4 @@
|
||||
package dbservice
|
||||
package mgolog
|
||||
|
||||
import (
|
||||
"context"
|
@ -1,4 +1,4 @@
|
||||
package dbservice
|
||||
package mgolog
|
||||
|
||||
import (
|
||||
"go_dreamfactory/comm"
|
||||
@ -7,26 +7,26 @@ import (
|
||||
)
|
||||
|
||||
func NewModule() core.IModule {
|
||||
m := new(DBService)
|
||||
m := new(MgoLog)
|
||||
return m
|
||||
}
|
||||
|
||||
type DBService struct {
|
||||
type MgoLog struct {
|
||||
cbase.ModuleBase
|
||||
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)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (this *DBService) GetType() core.M_Modules {
|
||||
return comm.ModuleLogModel
|
||||
func (this *MgoLog) GetType() core.M_Modules {
|
||||
return comm.ModuleMgoLog
|
||||
}
|
||||
|
||||
func (this *DBService) OnInstallComp() {
|
||||
func (this *MgoLog) OnInstallComp() {
|
||||
this.ModuleBase.OnInstallComp()
|
||||
this.db_comp = this.RegisterComp(new(DB_Comp)).(*DB_Comp)
|
||||
}
|
@ -23,6 +23,7 @@ type ModuleBase struct {
|
||||
cbase.ModuleBase
|
||||
module core.IModule
|
||||
service base.IRPCXService
|
||||
options IOptions
|
||||
scomp comm.ISC_GateRouteComp //网关服务组件
|
||||
//常用的一些通用模块 在底层注册好
|
||||
ModuleUser comm.IUser //用户模块
|
||||
@ -32,11 +33,17 @@ type ModuleBase struct {
|
||||
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) {
|
||||
err = this.ModuleBase.Init(service, module, options)
|
||||
this.service = service.(base.IRPCXService)
|
||||
this.module = module
|
||||
this.options = options.(IOptions)
|
||||
return
|
||||
}
|
||||
|
||||
@ -228,3 +235,29 @@ func (this *ModuleBase) DispenseRes(uid string, res []*cfg.Game_atn) (code pb.Er
|
||||
}
|
||||
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 (
|
||||
"fmt"
|
||||
"go_dreamfactory/lego/core"
|
||||
"go_dreamfactory/lego/sys/log"
|
||||
"go_dreamfactory/modules"
|
||||
"go_dreamfactory/pb"
|
||||
cfg "go_dreamfactory/sys/configure/structs"
|
||||
@ -17,11 +16,13 @@ const (
|
||||
///背包配置管理组件
|
||||
type configureComp struct {
|
||||
modules.MCompConfigure
|
||||
module *Shop
|
||||
}
|
||||
|
||||
//组件初始化接口
|
||||
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.module = module.(*Shop)
|
||||
this.LoadConfigure(game_shop, cfg.NewGame_shop)
|
||||
this.LoadConfigure(game_shopitem, cfg.NewGame_shopitem)
|
||||
return
|
||||
@ -34,12 +35,12 @@ func (this *configureComp) GetShopConfigure(id int32) (configure *cfg.Game_shopD
|
||||
ok bool
|
||||
)
|
||||
if v, err = this.GetConfigure(game_shop); err != nil {
|
||||
log.Errorf("err:%v", err)
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
} else {
|
||||
if configure, ok = v.(*cfg.Game_shop).GetDataMap()[id]; !ok {
|
||||
err = fmt.Errorf("ShopConfigure not found:%d ", id)
|
||||
log.Errorf("err:%v", err)
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -53,12 +54,12 @@ func (this *configureComp) GetShopItemsConfigure(key int32) (result *cfg.Game_sh
|
||||
ok bool
|
||||
)
|
||||
if v, err = this.GetConfigure(game_shopitem); err != nil {
|
||||
log.Errorf("err:%v", err)
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
} else {
|
||||
if result, ok = v.(*cfg.Game_shopitem).GetDataMap()[key]; !ok {
|
||||
err = fmt.Errorf("ShopConfigure not found:%d ", key)
|
||||
log.Errorf("err:%v", err)
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -73,7 +74,7 @@ func (this *configureComp) GetShopItemsConfigureByGroups(groupid int32, user *pb
|
||||
table *cfg.Game_shopitem
|
||||
)
|
||||
if v, err = this.GetConfigure(game_shopitem); err != nil {
|
||||
log.Errorf("err:%v", err)
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
} else {
|
||||
table = v.(*cfg.Game_shopitem)
|
||||
@ -99,7 +100,7 @@ func (this *configureComp) GetShopItemsConfigureByIds(keys ...int32) (result []*
|
||||
ok bool
|
||||
)
|
||||
if v, err = this.GetConfigure(game_shopitem); err != nil {
|
||||
log.Errorf("err:%v", err)
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
} else {
|
||||
table = v.(*cfg.Game_shopitem)
|
||||
@ -107,7 +108,7 @@ func (this *configureComp) GetShopItemsConfigureByIds(keys ...int32) (result []*
|
||||
if item, ok = table.GetDataMap()[v]; ok {
|
||||
result = append(result, item)
|
||||
} else {
|
||||
log.Errorf("no found GetShopItemsConfigureByIds:%d", v)
|
||||
this.module.Errorf("no found GetShopItemsConfigureByIds:%d", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package shop
|
||||
|
||||
import (
|
||||
"go_dreamfactory/lego/core"
|
||||
"go_dreamfactory/lego/sys/log"
|
||||
"go_dreamfactory/lego/sys/mgo"
|
||||
"go_dreamfactory/modules"
|
||||
"go_dreamfactory/pb"
|
||||
@ -35,6 +34,7 @@ func (this *modelShopItemsComp) QueryUserShopData(uId string) (result map[int32]
|
||||
result = make(map[int32]*pb.DBShopItem)
|
||||
data := make([]*pb.DBShopItem, 0)
|
||||
if err = this.GetList(uId, &data); err != nil && err != mgo.MongodbNil {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
@ -52,7 +52,7 @@ func (this *modelShopItemsComp) QueryUserShopDataByGoodId(uId string, goodId int
|
||||
)
|
||||
data = make([]*pb.DBShopItem, 0)
|
||||
if err = this.GetList(uId, &data); err != nil {
|
||||
log.Errorf("err%v", err)
|
||||
this.module.Errorf("err%v", err)
|
||||
return
|
||||
}
|
||||
for _, v := range data {
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"go_dreamfactory/pb"
|
||||
"sort"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
@ -39,20 +40,35 @@ func (this *apiComp) Challenge(session comm.IUserSession, req *pb.StoryChallenge
|
||||
if len(list) > 0 {
|
||||
curChapter = list[0] // 取第一条(第一条肯定是最新的)
|
||||
}
|
||||
if curChapter == nil {
|
||||
code = pb.ErrorCode_StoryNotFindChapter // 没有找到主线关卡信息
|
||||
return
|
||||
}
|
||||
|
||||
// 先校验是不是分支
|
||||
chaptConfig := this.module.configure.GetStoryChapter(int32(req.ChapterId)) // 根据配置文件找
|
||||
if chaptConfig == nil {
|
||||
code = pb.ErrorCode_ConfigNoFound
|
||||
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)) // 根据配置文件找
|
||||
if con != nil {
|
||||
if con == nil {
|
||||
code = pb.ErrorCode_ConfigNoFound
|
||||
return
|
||||
}
|
||||
@ -66,13 +82,16 @@ func (this *apiComp) Challenge(session comm.IUserSession, req *pb.StoryChallenge
|
||||
}
|
||||
}
|
||||
// TODO 调用战斗逻辑
|
||||
// 挑战成功
|
||||
curChapter.StoryId += 1 // 临时数据 后面配置表完善查找
|
||||
if bBranch {
|
||||
curChapter.BranchID = append(curChapter.BranchID, int32(req.ChapterId)) // 记录分支关卡
|
||||
}
|
||||
if curChapter.ChapterId == int32(req.ChapterId) && curChapter.StoryId == int32(req.StoryId) {
|
||||
update := map[string]interface{}{
|
||||
"storyId": req.StoryId,
|
||||
"branchID": curChapter.BranchID,
|
||||
"storyId": req.StoryId,
|
||||
"ChapterId": req.ChapterId,
|
||||
"branchID": curChapter.BranchID,
|
||||
}
|
||||
err = this.module.modelStory.modifyStoryData(session.GetUserId(), curChapter.Id, update)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package story
|
||||
|
||||
import (
|
||||
"go_dreamfactory/lego/core"
|
||||
"go_dreamfactory/lego/sys/log"
|
||||
"go_dreamfactory/modules"
|
||||
"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 {
|
||||
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) {
|
||||
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
|
||||
}
|
||||
return
|
||||
|
@ -122,7 +122,7 @@ type ItemsUseItemReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
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
|
||||
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}
|
||||
}
|
||||
|
||||
func (x *ItemsUseItemReq) GetGridId() int32 {
|
||||
func (x *ItemsUseItemReq) GetGridId() string {
|
||||
if x != nil {
|
||||
return x.GridId
|
||||
}
|
||||
return 0
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ItemsUseItemReq) GetItemId() int32 {
|
||||
@ -225,7 +225,7 @@ type ItemsSellItemReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
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
|
||||
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}
|
||||
}
|
||||
|
||||
func (x *ItemsSellItemReq) GetGridId() int32 {
|
||||
func (x *ItemsSellItemReq) GetGridId() string {
|
||||
if x != nil {
|
||||
return x.GridId
|
||||
}
|
||||
return 0
|
||||
return ""
|
||||
}
|
||||
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
|
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 的处理函数
|
||||
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"` // 错误消息
|
||||
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() {
|
||||
@ -100,24 +100,128 @@ func (x *NotifyErrorNotifyPush) GetData() string {
|
||||
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_rawDesc = []byte{
|
||||
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,
|
||||
0x63, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa7, 0x01, 0x0a, 0x15, 0x4e,
|
||||
0x6f, 0x74, 0x69, 0x66, 0x79, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79,
|
||||
0x50, 0x75, 0x73, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x4d, 0x61, 0x69, 0x6e, 0x54,
|
||||
0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x52, 0x65, 0x71, 0x4d, 0x61,
|
||||
0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x52, 0x65, 0x71, 0x53, 0x75, 0x62,
|
||||
0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x52, 0x65, 0x71, 0x53,
|
||||
0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65,
|
||||
0x52, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x44, 0x61, 0x74, 0x61, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
0x63, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x16, 0x6e, 0x6f, 0x74, 0x69,
|
||||
0x66, 0x79, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x64, 0x62, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x22, 0xa7, 0x01, 0x0a, 0x15, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x45, 0x72, 0x72,
|
||||
0x6f, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x50, 0x75, 0x73, 0x68, 0x12, 0x20, 0x0a, 0x0b,
|
||||
0x52, 0x65, 0x71, 0x4d, 0x61, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0b, 0x52, 0x65, 0x71, 0x4d, 0x61, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e,
|
||||
0x0a, 0x0a, 0x52, 0x65, 0x71, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0a, 0x52, 0x65, 0x71, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e,
|
||||
0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x45,
|
||||
0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61,
|
||||
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 (
|
||||
@ -132,18 +236,22 @@ func file_notify_notify_msg_proto_rawDescGZIP() []byte {
|
||||
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{}{
|
||||
(*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{
|
||||
1, // 0: NotifyErrorNotifyPush.Code:type_name -> ErrorCode
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
3, // 0: NotifyErrorNotifyPush.Code:type_name -> ErrorCode
|
||||
4, // 1: NotifyGetListResp.SysNotify:type_name -> DBSystemNotify
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension 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() }
|
||||
@ -152,6 +260,7 @@ func file_notify_notify_msg_proto_init() {
|
||||
return
|
||||
}
|
||||
file_errorcode_proto_init()
|
||||
file_notify_notify_db_proto_init()
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_notify_notify_msg_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*NotifyErrorNotifyPush); i {
|
||||
@ -165,6 +274,30 @@ func file_notify_notify_msg_proto_init() {
|
||||
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{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@ -172,7 +305,7 @@ func file_notify_notify_msg_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_notify_notify_msg_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
@ -14,7 +14,7 @@ message ItemsGetlistResp {
|
||||
|
||||
//使用物品请求
|
||||
message ItemsUseItemReq {
|
||||
int32 GridId = 1; //格子Id
|
||||
string GridId = 1; //格子Id
|
||||
int32 ItemId = 2; //物品Id
|
||||
uint32 Amount = 3; //使用数量
|
||||
}
|
||||
@ -26,7 +26,7 @@ message ItemsUseItemResp {
|
||||
|
||||
//出售道具请求sailitem
|
||||
message ItemsSellItemReq {
|
||||
int32 GridId = 1; //格子Id
|
||||
string GridId = 1; //格子Id
|
||||
int32 ItemId = 2; //物品Id
|
||||
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";
|
||||
option go_package = ".;pb";
|
||||
import "errorcode.proto";
|
||||
import "notify/notify_db.proto";
|
||||
|
||||
//统一错误码推送
|
||||
message NotifyErrorNotifyPush {
|
||||
@ -8,5 +9,15 @@ message NotifyErrorNotifyPush {
|
||||
string ReqSubType = 2; // 请求协议函数 例如:login 对应项目中 user的模块中 api_login 的处理函数
|
||||
ErrorCode Code = 3; // 执行返回错误码 对应 errorcode.proto 枚举
|
||||
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/sys/event"
|
||||
"go_dreamfactory/lego/sys/log"
|
||||
"go_dreamfactory/lego/utils/mapstructure"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
"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
|
||||
}
|
||||
|
||||
//用户协议处理函数注册的反射对象
|
||||
type msghandle struct {
|
||||
rcvr reflect.Value
|
||||
msgType reflect.Type //消息请求类型
|
||||
handle reflect.Method //处理函数
|
||||
}
|
||||
|
||||
//服务网关组件
|
||||
type SCompGateRoute struct {
|
||||
cbase.ServiceCompBase
|
||||
options *CompOptions
|
||||
service base.IRPCXService //rpc服务对象 通过这个对象可以发布服务和调用其他服务的接口
|
||||
mrlock sync.RWMutex //msghandles 对象的锁
|
||||
msghandles map[string]*msghandle //处理函数的管理对象
|
||||
@ -50,9 +64,14 @@ func (this *SCompGateRoute) GetName() core.S_Comps {
|
||||
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) {
|
||||
err = this.ServiceCompBase.Init(service, comp, options)
|
||||
this.options = options.(*CompOptions)
|
||||
this.service = service.(base.IRPCXService)
|
||||
this.msghandles = make(map[string]*msghandle)
|
||||
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) {
|
||||
log.Debugf("注册用户路由【%s】", methodName)
|
||||
//log.Debugf("注册用户路由【%s】", methodName)
|
||||
this.mrlock.RLock()
|
||||
_, ok := this.msghandles[methodName]
|
||||
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) {
|
||||
defer func() { //程序异常 收集异常信息传递给前端显示
|
||||
if r := recover(); r != nil {
|
||||
buf := make([]byte, 1024)
|
||||
buf := make([]byte, 4096)
|
||||
l := runtime.Stack(buf, false)
|
||||
reply.Code = pb.ErrorCode_Exception
|
||||
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)
|
||||
@ -126,11 +145,10 @@ func (this *SCompGateRoute) ReceiveMsg(ctx context.Context, args *pb.AgentMessag
|
||||
//执行处理流
|
||||
stime := time.Now()
|
||||
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())
|
||||
errdata := handlereturn[1].Interface()
|
||||
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.ErrorMessage = pb.GetErrorCodeMsg(errcode)
|
||||
if errdata != nil {
|
||||
@ -139,6 +157,9 @@ func (this *SCompGateRoute) ReceiveMsg(ctx context.Context, args *pb.AgentMessag
|
||||
}
|
||||
} else {
|
||||
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 { //未找到消息处理函数
|
||||
log.Errorf("[Handle Api] no found handle %s", method)
|
||||
|
@ -3,7 +3,8 @@ package main
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"go_dreamfactory/modules/dbservice"
|
||||
"go_dreamfactory/modules/gm"
|
||||
"go_dreamfactory/modules/mgolog"
|
||||
"go_dreamfactory/services"
|
||||
"go_dreamfactory/sys/cache"
|
||||
"go_dreamfactory/sys/db"
|
||||
@ -15,11 +16,11 @@ import (
|
||||
)
|
||||
|
||||
/*
|
||||
服务类型:dbservice
|
||||
服务描述:处理梦工厂的具体业务需求,包含 user,pack,mail,friend...功能业务模块
|
||||
服务类型:mainte
|
||||
服务描述:数据库维护以及GM后台接口 服务
|
||||
*/
|
||||
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(), //此服务需要接受用户的消息 需要装备网关组件
|
||||
)
|
||||
lego.Run(s, //运行模块
|
||||
dbservice.NewModule(),
|
||||
mgolog.NewModule(),
|
||||
gm.NewModule(),
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
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...功能业务模块
|
||||
*/
|
||||
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