package msgpack
import (
)
type extInfo struct {
Type reflect.Type
Decoder func(d *Decoder, v reflect.Value, extLen int) error
}
var extTypes = make(map[int8]*extInfo)
type MarshalerUnmarshaler interface {
Marshaler
Unmarshaler
}
func ( int8, MarshalerUnmarshaler) {
RegisterExtEncoder(, , func( *Encoder, reflect.Value) ([]byte, error) {
:= .Interface().(Marshaler)
return .MarshalMsgpack()
})
RegisterExtDecoder(, , func( *Decoder, reflect.Value, int) error {
, := .readN()
if != nil {
return
}
return .Interface().(Unmarshaler).UnmarshalMsgpack()
})
}
func ( int8) {
unregisterExtEncoder()
unregisterExtDecoder()
}
func (
int8,
interface{},
func( *Encoder, reflect.Value) ([]byte, error),
) {
unregisterExtEncoder()
:= reflect.TypeOf()
:= makeExtEncoder(, , )
typeEncMap.Store(, )
typeEncMap.Store(, )
if .Kind() == reflect.Ptr {
typeEncMap.Store(.Elem(), makeExtEncoderAddr())
}
}
func ( int8) {
, := typeEncMap.Load()
if ! {
return
}
typeEncMap.Delete()
:= .(reflect.Type)
typeEncMap.Delete()
if .Kind() == reflect.Ptr {
typeEncMap.Delete(.Elem())
}
}
func (
int8,
reflect.Type,
func( *Encoder, reflect.Value) ([]byte, error),
) encoderFunc {
:= .Kind() == reflect.Ptr
return func( *Encoder, reflect.Value) error {
if && .IsNil() {
return .EncodeNil()
}
, := (, )
if != nil {
return
}
if := .EncodeExtHeader(, len()); != nil {
return
}
return .write()
}
}
func ( encoderFunc) encoderFunc {
return func( *Encoder, reflect.Value) error {
if !.CanAddr() {
return fmt.Errorf("msgpack: Decode(nonaddressable %T)", .Interface())
}
return (, .Addr())
}
}
func (
int8,
interface{},
func( *Decoder, reflect.Value, int) error,
) {
unregisterExtDecoder()
:= reflect.TypeOf()
:= makeExtDecoder(, , )
extTypes[] = &extInfo{
Type: ,
Decoder: ,
}
typeDecMap.Store(, )
typeDecMap.Store(, )
if .Kind() == reflect.Ptr {
typeDecMap.Store(.Elem(), makeExtDecoderAddr())
}
}
func ( int8) {
, := typeDecMap.Load()
if ! {
return
}
typeDecMap.Delete()
delete(extTypes, )
:= .(reflect.Type)
typeDecMap.Delete()
if .Kind() == reflect.Ptr {
typeDecMap.Delete(.Elem())
}
}
func (
int8,
reflect.Type,
func( *Decoder, reflect.Value, int) error,
) decoderFunc {
return nilAwareDecoder(, func( *Decoder, reflect.Value) error {
, , := .DecodeExtHeader()
if != nil {
return
}
if != {
return fmt.Errorf("msgpack: got ext type=%d, wanted %d", , )
}
return (, , )
})
}
func ( decoderFunc) decoderFunc {
return func( *Decoder, reflect.Value) error {
if !.CanAddr() {
return fmt.Errorf("msgpack: Decode(nonaddressable %T)", .Interface())
}
return (, .Addr())
}
}
func ( *Encoder) ( int8, int) error {
if := .encodeExtLen(); != nil {
return
}
if := .w.WriteByte(byte()); != nil {
return
}
return nil
}
func ( *Encoder) ( int) error {
switch {
case 1:
return .writeCode(msgpcode.FixExt1)
case 2:
return .writeCode(msgpcode.FixExt2)
case 4:
return .writeCode(msgpcode.FixExt4)
case 8:
return .writeCode(msgpcode.FixExt8)
case 16:
return .writeCode(msgpcode.FixExt16)
}
if <= math.MaxUint8 {
return .write1(msgpcode.Ext8, uint8())
}
if <= math.MaxUint16 {
return .write2(msgpcode.Ext16, uint16())
}
return .write4(msgpcode.Ext32, uint32())
}
func ( *Decoder) () ( int8, int, error) {
, := .readCode()
if != nil {
return
}
return .extHeader()
}
func ( *Decoder) ( byte) (int8, int, error) {
, := .parseExtLen()
if != nil {
return 0, 0,
}
, := .readCode()
if != nil {
return 0, 0,
}
return int8(), , nil
}
func ( *Decoder) ( byte) (int, error) {
switch {
case msgpcode.FixExt1:
return 1, nil
case msgpcode.FixExt2:
return 2, nil
case msgpcode.FixExt4:
return 4, nil
case msgpcode.FixExt8:
return 8, nil
case msgpcode.FixExt16:
return 16, nil
case msgpcode.Ext8:
, := .uint8()
return int(),
case msgpcode.Ext16:
, := .uint16()
return int(),
case msgpcode.Ext32:
, := .uint32()
return int(),
default:
return 0, fmt.Errorf("msgpack: invalid code=%x decoding ext len", )
}
}
func ( *Decoder) ( byte) (interface{}, error) {
, , := .extHeader()
if != nil {
return nil,
}
, := extTypes[]
if ! {
return nil, fmt.Errorf("msgpack: unknown ext id=%d", )
}
:= reflect.New(.Type).Elem()
if nilable(.Kind()) && .IsNil() {
.Set(reflect.New(.Type.Elem()))
}
if := .Decoder(, , ); != nil {
return nil,
}
return .Interface(), nil
}
func ( *Decoder) ( byte) error {
, := .parseExtLen()
if != nil {
return
}
return .skipN( + 1)
}
func ( *Decoder) ( byte) error {
, := .readCode()
if != nil {
return
}
for := 0; < extHeaderLen(); ++ {
, := .readCode()
if != nil {
return
}
}
return nil
}
func ( byte) int {
switch {
case msgpcode.Ext8:
return 1
case msgpcode.Ext16:
return 2
case msgpcode.Ext32:
return 4
}
return 0
}