ugorji / go

idiomatic codec and rpc lib for msgpack, cbor, json, etc. msgpack.org[Go]
MIT License
1.87k stars 295 forks source link

msgpack extension #89

Closed juanolon closed 9 years ago

juanolon commented 9 years ago

Hi there, are msgpack extension types supported? and how? i already tried this also found another way to define the extension but both of them are not working for me.

thanks

ugorji commented 9 years ago

Please provider a small reproducer for what didn't work. It should work.

ugorji commented 9 years ago

Please use the extension support at http://ugorji.net/blog/go-codec-primer#using-extensions and re-open with a reproducer if it still doesn't work. It should work.

juanolon commented 9 years ago

hi ugori, thanks, for the blog entry. finally after some time, i got myself to work on this again. this is the code it isn't working. the data i try to decode, was generated by the nvim rpc api. below, is also a link to a gist, which has the whole code.

package main

import (
    "fmt"
    "log"
    "reflect"

    "github.com/davecgh/go-spew/spew"
    "github.com/ugorji/go/codec"
)

func main() {

    // 00000000  94 01 00 92 00 c4 30 57  72 6f 6e 67 20 6e 75 6d  |......0Wrong num|
    // 00000010  62 65 72 20 6f 66 20 61  72 67 75 6d 65 6e 74 73  |ber of arguments|
    // 00000020  3a 20 65 78 70 65 63 74  69 6e 67 20 30 20 62 75  |: expecting 0 bu|
    // 00000030  74 20 67 6f 74 20 31 c0  00 00 00 00 00 00 00 00  |t got 1.........|
    callResult := []byte{
        0x94, 0x01, 0x00, 0x92, 0x00, 0xc4, 0x30, 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x6e, 0x75, 0x6d,
        0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73,
        0x3a, 0x20, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x30, 0x20, 0x62, 0x75,
        0x74, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x31, 0xc0,
    }

    var mh codec.MsgpackHandle
    mh.RawToString = true

    mh.WriteExt = true
    mh.SetExt(reflect.TypeOf(NvimError{}), 0x92, &NvimErrorExt{})

    dec := codec.NewDecoderBytes(callResult, &mh)

    var result []byte
    err := dec.Decode(&result)
    if err != nil {
        log.Fatal(err)
    }
    spew.Dump(result)
}

type NvimError struct {
    msg []byte
}

func (e NvimError) Error() string {
    return fmt.Sprintf("NvimError: %v", e.msg)
}

type NvimErrorExt struct{}

func (e NvimErrorExt) WriteExt(interface{}) []byte {
    panic("unsupported")
}

func (e NvimErrorExt) ReadExt(interface{}, []byte) {
    panic("unsupported")
}

func (e NvimErrorExt) ConvertExt(v interface{}) interface{} {
    switch v2 := v.(type) {
    default:
        spew.Dump("converting type", v2)
        panic(fmt.Sprintf("unsupported format for time conversin: expecting time.Time; got %T", v))
    }
}

func (e NvimErrorExt) UpdateExt(dest interface{}, v interface{}) {
    spew.Dump("update v2", dest)
    tt := dest.(*NvimError)
    switch v2 := v.(type) {
    default:
        spew.Dump("update v2", v2)
        spew.Dump("update tt", tt)
        // return NvimError{[]byte("babababa")}
        panic(fmt.Sprintf("unsupported format for time conversion: expectiong int64/uint; got %T", v))
    }
}

the error i'm getting is readContainerLen: Unrecognized descriptor byte: hex: 94, dec: 148

https://gist.github.com/juanolon/de0c752a92d0cc2ef4f2

ugorji commented 9 years ago

Your problem seems to be that you are using 0x94, which is an array identifier, when you should be using a binary or string identifier i.e. one of fixstr OR str 8/16/32 or bin 8/16/32.

See https://github.com/msgpack/msgpack/blob/master/spec.md