blob: 775cd098770d61aa7a5bb635f5d1ab8eb09d3875 [file] [log] [blame]
// 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)
}