// Copyright 2012 Google, Inc. All rights reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the LICENSE file in the root of the source // tree. package gopacket // LayerClass is a set of LayerTypes, used for grabbing one of a number of // different types from a packet. type LayerClass interface { // Contains returns true if the given layer type should be considered part // of this layer class. Contains(LayerType) bool // LayerTypes returns the set of all layer types in this layer class. // Note that this may not be a fast operation on all LayerClass // implementations. LayerTypes() []LayerType } // Contains implements LayerClass. func (l LayerType) Contains(a LayerType) bool { return l == a } // LayerTypes implements LayerClass. func (l LayerType) LayerTypes() []LayerType { return []LayerType{l} } // LayerClassSlice implements a LayerClass with a slice. type LayerClassSlice []bool // Contains returns true if the given layer type should be considered part // of this layer class. func (s LayerClassSlice) Contains(t LayerType) bool { return int(t) < len(s) && s[t] } // LayerTypes returns all layer types in this LayerClassSlice. // Because of LayerClassSlice's implementation, this could be quite slow. func (s LayerClassSlice) LayerTypes() (all []LayerType) { for i := 0; i < len(s); i++ { if s[i] { all = append(all, LayerType(i)) } } return } // NewLayerClassSlice creates a new LayerClassSlice by creating a slice of // size max(types) and setting slice[t] to true for each type t. Note, if // you implement your own LayerType and give it a high value, this WILL create // a very large slice. func NewLayerClassSlice(types []LayerType) LayerClassSlice { var max LayerType for _, typ := range types { if typ > max { max = typ } } t := make([]bool, int(max+1)) for _, typ := range types { t[typ] = true } return t } // LayerClassMap implements a LayerClass with a map. type LayerClassMap map[LayerType]bool // Contains returns true if the given layer type should be considered part // of this layer class. func (m LayerClassMap) Contains(t LayerType) bool { return m[t] } // LayerTypes returns all layer types in this LayerClassMap. func (m LayerClassMap) LayerTypes() (all []LayerType) { for t := range m { all = append(all, t) } return } // NewLayerClassMap creates a LayerClassMap and sets map[t] to true for each // type in types. func NewLayerClassMap(types []LayerType) LayerClassMap { m := LayerClassMap{} for _, typ := range types { m[typ] = true } return m } // NewLayerClass creates a LayerClass, attempting to be smart about which type // it creates based on which types are passed in. func NewLayerClass(types []LayerType) LayerClass { for _, typ := range types { if typ > maxLayerType { // NewLayerClassSlice could create a very large object, so instead create // a map. return NewLayerClassMap(types) } } return NewLayerClassSlice(types) }