This commit is contained in:
zhaocy 2022-07-13 16:17:38 +08:00
commit 0b7f26bab3
101 changed files with 6702 additions and 386 deletions

View File

@ -203,6 +203,9 @@ func (r *Robot) onUserLoaded() {
//task
r.RunTask()
// story
r.RunStory()
}
//注册账号

45
cmd/robot/story.go Normal file
View 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()
}

View File

@ -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服务接口定义处

View File

@ -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,

View File

@ -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))

View File

@ -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
View 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
View 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
View 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,
}
}

View 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
}

View 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
}

View 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
}

View 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)
}

View 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))
}

View 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)))
}

View 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)
}

View 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
}

View 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
View 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
}

View 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
}

View 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
}

View 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
View 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
}
}

View 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
View 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))
}

View 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
}
}

View File

@ -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
}

View File

@ -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...) }

View File

@ -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
}

View File

@ -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) {

View File

@ -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

View File

@ -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()

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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)
}

View 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)
}
)

View File

@ -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",

View File

@ -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)
}
}

View File

@ -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) {

View File

@ -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

View File

@ -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()

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View 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)
}

View 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
}

View File

@ -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)

View File

@ -10,7 +10,9 @@ import (
type (
Options struct {
ListenPort int //websocket 监听端口
Debug bool //日志开关
GinDebug bool //web引擎日志开关
ListenPort int //websocket 监听端口
}
)

View File

@ -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
}

View File

@ -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)

View 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)
}

View File

@ -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,
})

View File

@ -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)
}

View File

@ -1,4 +1,4 @@
package web
package gm
import (
"fmt"

9
modules/gm/core.go Normal file
View 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
View 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
}

View File

@ -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)

View File

@ -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

View File

@ -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
}

View File

@ -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 { //已经过期

View File

@ -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)
}
}
}

View File

@ -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)

View File

@ -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 {

View File

@ -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)
}

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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
}

View File

@ -1,4 +1,4 @@
package dbservice
package mgolog
import (
"go_dreamfactory/lego/core"

View File

@ -1,4 +1,4 @@
package dbservice
package mgolog
import (
"context"

View File

@ -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)
}

View File

@ -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
View 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
}

View 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
View File

@ -0,0 +1 @@
package notify

View 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
View 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)
}

View 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
View 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
}

View File

@ -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)
}
}
}

View File

@ -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 {

View File

@ -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)
}

View File

@ -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
}

View File

@ -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

View File

@ -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
View 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
}

View File

@ -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,
},

View File

@ -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; //使
}

View 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; //
}

View File

@ -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
View 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
View 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
}

View File

@ -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)

View File

@ -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 {

View File

@ -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!")
}
}

View File

@ -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