zeek/src/Tag.h
2021-09-16 15:35:39 -07:00

152 lines
3.6 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#pragma once
#include <stdint.h>
#include <string>
#include "zeek/IntrusivePtr.h"
#include "zeek/util.h"
#include "zeek/zeek-config.h"
namespace zeek
{
class EnumVal;
class EnumType;
using EnumTypePtr = IntrusivePtr<EnumType>;
using EnumValPtr = IntrusivePtr<EnumVal>;
/**
* Class to identify an analyzer type.
*
* Each analyzer type gets a tag consisting of a main type and subtype. The
* former is an identifier that's unique across all analyzer classes. The latter is
* passed through to the analyzer instances for their use, yet not further
* interpreted by the analyzer infrastructure; it allows an analyzer to
* branch out into a set of sub-analyzers internally. Jointly, main type and
* subtype form an analyzer "tag". Each unique tag corresponds to a single
* "analyzer" from the user's perspective. At the script layer, these tags
* are mapped into enums of type \c Analyzer::Tag or Files::Tag. Internally,
* the analyzer::Manager and file_analysis::Manager maintain the mapping of tag
* to analyzer (and it also assigns them their main types), and
* analyzer::Component and file_analysis::Component create new tag.
*
* The Tag class supports all operations necessary to act as an index in a
* \c std::map.
*/
class Tag
{
public:
/**
* Type for the analyzer's main type.
*/
typedef uint32_t type_t;
/**
* Type for the analyzer's subtype.
*/
typedef uint32_t subtype_t;
/**
* Returns the tag's main type.
*/
type_t Type() const { return type; }
/**
* Returns the tag's subtype.
*/
subtype_t Subtype() const { return subtype; }
/**
* Returns the numerical values for main and subtype inside a string
* suitable for printing. This is primarily for debugging.
*/
std::string AsString() const;
protected:
/*
* Copy constructor.
*/
Tag(const Tag& other);
/**
* Default constructor. This initializes the tag with an error value
* that will make \c operator \c bool return false.
*/
Tag();
/**
* Destructor.
*/
~Tag();
/**
* Assignment operator.
*/
Tag& operator=(const Tag& other);
/**
* Move assignment operator.
*/
Tag& operator=(const Tag&& other) noexcept;
/**
* Compares two tags for equality.
*/
bool operator==(const Tag& other) const
{
return type == other.type && subtype == other.subtype;
}
/**
* Compares two tags for inequality.
*/
bool operator!=(const Tag& other) const
{
return type != other.type || subtype != other.subtype;
}
/**
* Compares two tags for less-than relationship.
*/
bool operator<(const Tag& other) const
{
return type != other.type ? type < other.type : (subtype < other.subtype);
}
/**
* Returns the script-layer enum that corresponds to this tag.
* The returned value does not have its ref-count increased.
*
* @param etype the script-layer enum type associated with the tag.
*/
const EnumValPtr& AsVal(const EnumTypePtr& etype) const;
/**
* Constructor.
*
* @param etype the script-layer enum type associated with the tag.
*
* @param type The main type. Note that the manager class manages the
* the value space internally, so noone else should assign main types.
*
* @param subtype The sub type, which is left to an analyzer for
* interpretation. By default it's set to zero.
*/
Tag(const EnumTypePtr& etype, type_t type, subtype_t subtype = 0);
/**
* Constructor.
*
* @param val An enum value of script type \c Analyzer::Tag.
*/
explicit Tag(EnumValPtr val);
private:
type_t type; // Main type.
subtype_t subtype; // Subtype.
mutable EnumValPtr val; // Script-layer value.
};
} // namespace zeek