github.com/annchain/OG@v0.0.9/tests/msg_marshal/msg.go (about)

     1  // Copyright © 2019 Annchain Authors <EMAIL ADDRESS>
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package msg_marshal
    15  
    16  import (
    17  	"encoding/binary"
    18  	"fmt"
    19  	"github.com/tinylib/msgp/msgp"
    20  )
    21  
    22  //go:generate msgp
    23  
    24  type FooI interface {
    25  	String() string
    26  	// implemented by msgp
    27  	DecodeMsg(dc *msgp.Reader) (err error)
    28  	EncodeMsg(en *msgp.Writer) (err error)
    29  	MarshalMsg(b []byte) (o []byte, err error)
    30  	UnmarshalMsg(bts []byte) (o []byte, err error)
    31  	Msgsize() (s int)
    32  	GetType() uint16
    33  	GetName() string
    34  }
    35  
    36  //msgp:tuple Person
    37  type Person struct {
    38  	Name string
    39  	Age  int
    40  	Type uint16
    41  }
    42  
    43  //msgp:tuple Student
    44  type Student struct {
    45  	Person
    46  	Score int
    47  }
    48  
    49  //msgp:tuple Teacher
    50  type Teacher struct {
    51  	Person
    52  	Teach bool
    53  }
    54  
    55  func (p *Person) GetName() string {
    56  	return p.Name
    57  }
    58  
    59  func (p *Person) GetType() uint16 {
    60  	return p.Type
    61  }
    62  
    63  func (p Person) String() string {
    64  	return p.Name + " person"
    65  }
    66  
    67  func (s Student) String() string {
    68  	return s.Person.String() + " student"
    69  }
    70  
    71  func (s Teacher) String() string {
    72  	return s.Person.String() + " teacher"
    73  }
    74  
    75  func MashalFoo(f FooI, b []byte) ([]byte, error) {
    76  	if f == nil {
    77  		panic("nil foo")
    78  	}
    79  	tail := make([]byte, 2)
    80  	binary.BigEndian.PutUint16(tail, f.GetType())
    81  	b = append(b, tail...)
    82  	o, err := f.MarshalMsg(b)
    83  	return o, err
    84  }
    85  
    86  func UnmarShalFoo(b []byte) (o []byte, f FooI, err error) {
    87  	if len(b) < 3 {
    88  		return b, nil, fmt.Errorf("size mismatch")
    89  	}
    90  	tp := binary.BigEndian.Uint16(b)
    91  	switch tp {
    92  	case 1:
    93  		var s Student
    94  		o, err := s.UnmarshalMsg(b[2:])
    95  		if err != nil {
    96  			return o, nil, err
    97  		}
    98  		return o, &s, nil
    99  	case 2:
   100  		var s Teacher
   101  		o, err := s.UnmarshalMsg(b[2:])
   102  		if err != nil {
   103  			return o, nil, err
   104  		}
   105  		return o, &s, nil
   106  	default:
   107  		return b, nil, fmt.Errorf("unkown type")
   108  	}
   109  }