github.com/jmigpin/editor@v1.6.0/core/godebug/debug/encode.go (about) 1 package debug 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "encoding/gob" 7 "fmt" 8 "io" 9 "reflect" 10 ) 11 12 func registerForEncodeDecode(encoderId string, v interface{}) { 13 // commented: needs encoderId to avoid name clashes when self debugging 14 //gob.Register(v) 15 16 rt := reflect.TypeOf(v) 17 name := rt.String() // ex: *debug.ReqFilesDataMsg 18 19 // after: rt = rt.Elem() 20 // rt.Name() // ex: ReqFilesDataMsg 21 // rt.PkgPath() // ex: github.com/jmigpin/editor/core/godebug/debug 22 // rt.PkgPath() // ex: godebugconfig/debug 23 24 s := fmt.Sprintf("%v:%v", encoderId, name) 25 gob.RegisterName(s, v) 26 } 27 28 //---------- 29 30 func EncodeMessage(msg interface{}) ([]byte, error) { 31 // message buffer 32 bbuf := &bytes.Buffer{} 33 34 // reserve space to encode v size 35 sizeBuf := make([]byte, 4) 36 if _, err := bbuf.Write(sizeBuf[:]); err != nil { 37 return nil, err 38 } 39 40 // encode v 41 enc := gob.NewEncoder(bbuf) 42 if err := enc.Encode(&msg); err != nil { // decoder uses &interface{} 43 return nil, err 44 } 45 46 // get bytes 47 buf := bbuf.Bytes() 48 49 // encode v size at buffer start 50 l := uint32(len(buf) - len(sizeBuf)) 51 binary.BigEndian.PutUint32(buf, l) 52 53 return buf, nil 54 } 55 56 func DecodeMessage(rd io.Reader) (interface{}, error) { 57 // read size 58 sizeBuf := make([]byte, 4) 59 if _, err := io.ReadFull(rd, sizeBuf); err != nil { 60 return nil, err 61 } 62 l := int(binary.BigEndian.Uint32(sizeBuf)) 63 64 // read msg 65 msgBuf := make([]byte, l) 66 if _, err := io.ReadFull(rd, msgBuf); err != nil { 67 return nil, err 68 } 69 70 // decode msg 71 buf := bytes.NewBuffer(msgBuf) 72 dec := gob.NewDecoder(buf) 73 msg := interface{}(nil) 74 if err := dec.Decode(&msg); err != nil { 75 return nil, err 76 } 77 78 return msg, nil 79 } 80 81 //---------- 82 83 // TODO: document why this simplified version doesn't work (hangs) 84 85 //func EncodeMessage(msg interface{}) ([]byte, error) { 86 // var buf bytes.Buffer 87 // enc := gob.NewEncoder(&buf) 88 // if err := enc.Encode(&msg); err != nil { 89 // return nil, err 90 // } 91 // return buf.Bytes(), nil 92 //} 93 94 //func DecodeMessage(reader io.Reader) (interface{}, error) { 95 // dec := gob.NewDecoder(reader) 96 // var msg interface{} 97 // if err := dec.Decode(&msg); err != nil { 98 // return nil, err 99 // } 100 // return msg, nil 101 //} 102 103 //----------