1// @author Couchbase <info@couchbase.com> 2// @copyright 2014 Couchbase, Inc. 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15 16package common 17 18import ( 19 "reflect" 20) 21 22var gRegistry = NewPacketRegistry() 23 24///////////////////////////////////////////////////////////////////////////// 25// Type Declaration 26///////////////////////////////////////////////////////////////////////////// 27 28type Packet interface { 29 // Name of the message 30 Name() string 31 32 // Encode function shall marshal message to byte array. 33 Encode() (data []byte, err error) 34 35 // Decode function shall unmarshal byte array back to message. 36 Decode(data []byte) (err error) 37 38 GetVersion() uint32 39 40 // Debug Representation 41 String() string 42} 43 44type PacketRegistry struct { 45 mapping map[string]Packet 46} 47 48///////////////////////////////////////////////////////////////////////////// 49// Public Function 50///////////////////////////////////////////////////////////////////////////// 51 52func NewPacketRegistry() *PacketRegistry { 53 return &PacketRegistry{mapping: make(map[string]Packet)} 54} 55 56func RegisterPacketByName(name string, instance Packet) { 57 gRegistry.mapping[name] = instance 58} 59 60func CreatePacketByName(name string) (Packet, error) { 61 sample := gRegistry.mapping[name] 62 if sample == nil { 63 panic("Packet " + name + " is not registered with message factory. Cannot create new packet.") 64 } 65 66 return reflect.New(FindPacketConcreteType(sample)).Interface().(Packet), nil 67} 68 69func FindPacketConcreteType(packet Packet) reflect.Type { 70 return reflect.ValueOf(packet).Elem().Type() 71} 72 73func IsValidType(name string) bool { 74 75 _, ok := gRegistry.mapping[name] 76 return ok 77} 78