Unify plugin::Component and plugin::TaggedComponent into a single class

These two are almost always used in conjunction with each other, and
TaggedComponent is never used by itself. Combining them together into
a single class will help simplify some of the code around managing
the mapping between Tags and Components.
This commit is contained in:
Tim Wojtulewicz 2021-09-30 13:34:42 -07:00
parent 8b544d648d
commit 7d66f4252f
18 changed files with 90 additions and 158 deletions

View file

@ -379,7 +379,6 @@ set(MAIN_SRCS
plugin/Component.cc plugin/Component.cc
plugin/ComponentManager.h plugin/ComponentManager.h
plugin/TaggedComponent.cc
plugin/Manager.cc plugin/Manager.cc
plugin/Plugin.cc plugin/Plugin.cc

View file

@ -17,7 +17,9 @@ Tag::Tag(const EnumTypePtr& etype, type_t arg_type, subtype_t arg_subtype)
assert(arg_type > 0); assert(arg_type > 0);
int64_t i = (int64_t)(type) | ((int64_t)subtype << 31); int64_t i = (int64_t)(type) | ((int64_t)subtype << 31);
val = etype->GetEnumVal(i);
if ( etype )
val = etype->GetEnumVal(i);
} }
Tag::Tag(EnumValPtr arg_val) Tag::Tag(EnumValPtr arg_val)
@ -36,13 +38,13 @@ Tag::Tag(const Tag& other)
type = other.type; type = other.type;
subtype = other.subtype; subtype = other.subtype;
val = other.val; val = other.val;
etype = other.etype;
} }
Tag::Tag() Tag::Tag()
{ {
type = 0;
subtype = 0;
val = nullptr; val = nullptr;
etype = nullptr;
} }
Tag::~Tag() = default; Tag::~Tag() = default;
@ -54,6 +56,7 @@ Tag& Tag::operator=(const Tag& other)
type = other.type; type = other.type;
subtype = other.subtype; subtype = other.subtype;
val = other.val; val = other.val;
etype = other.etype;
} }
return *this; return *this;
@ -66,24 +69,12 @@ Tag& Tag::operator=(const Tag&& other) noexcept
type = other.type; type = other.type;
subtype = other.subtype; subtype = other.subtype;
val = std::move(other.val); val = std::move(other.val);
etype = std::move(other.etype);
} }
return *this; return *this;
} }
const EnumValPtr& Tag::AsVal() const
{
// TODO: this probably isn't valid, and we should just return the null val
// if it's null.
if ( ! val )
{
assert(type == 0 && subtype == 0 && etype != nullptr);
val = etype->GetEnumVal(0);
}
return val;
}
std::string Tag::AsString() const std::string Tag::AsString() const
{ {
return util::fmt("%" PRIu32 "/%" PRIu32, type, subtype); return util::fmt("%" PRIu32 "/%" PRIu32, type, subtype);

View file

@ -153,7 +153,7 @@ public:
* *
* @param etype the script-layer enum type associated with the tag. * @param etype the script-layer enum type associated with the tag.
*/ */
const EnumValPtr& AsVal() const; const EnumValPtr& AsVal() const { return val; }
/** /**
* Returns false if the tag represents an error value rather than a * Returns false if the tag represents an error value rather than a
@ -164,10 +164,10 @@ public:
static const Tag Error; static const Tag Error;
private: private:
type_t type; // Main type. type_t type = 0; // Main type.
subtype_t subtype; // Subtype. subtype_t subtype = 0; // Subtype.
mutable EnumValPtr val; // Script-layer value. EnumValPtr val; // Script-layer value.
mutable EnumTypePtr etype; EnumTypePtr etype;
}; };
} // namespace zeek } // namespace zeek

View file

@ -12,9 +12,9 @@ namespace zeek::analyzer
Component::Component(const std::string& name, factory_callback arg_factory, Component::Component(const std::string& name, factory_callback arg_factory,
zeek::Tag::subtype_t arg_subtype, bool arg_enabled, bool arg_partial, zeek::Tag::subtype_t arg_subtype, bool arg_enabled, bool arg_partial,
bool arg_adapter) bool arg_adapter)
: plugin::Component( : plugin::Component(arg_adapter ? plugin::component::SESSION_ADAPTER
arg_adapter ? plugin::component::SESSION_ADAPTER : plugin::component::ANALYZER, name), : plugin::component::ANALYZER,
plugin::TaggedComponent(arg_subtype, analyzer_mgr->GetTagType()) name, arg_subtype, analyzer_mgr->GetTagType())
{ {
factory = arg_factory; factory = arg_factory;
enabled = arg_enabled; enabled = arg_enabled;
@ -27,8 +27,6 @@ void Component::Initialize()
analyzer_mgr->RegisterComponent(this, "ANALYZER_"); analyzer_mgr->RegisterComponent(this, "ANALYZER_");
} }
Component::~Component() { }
void Component::DoDescribe(ODesc* d) const void Component::DoDescribe(ODesc* d) const
{ {
if ( factory ) if ( factory )

View file

@ -6,7 +6,6 @@
#include "zeek/Tag.h" #include "zeek/Tag.h"
#include "zeek/plugin/Component.h" #include "zeek/plugin/Component.h"
#include "zeek/plugin/TaggedComponent.h"
#include "zeek/util.h" #include "zeek/util.h"
namespace zeek namespace zeek
@ -25,7 +24,7 @@ class Analyzer;
* A plugin can provide a specific protocol analyzer by registering this * A plugin can provide a specific protocol analyzer by registering this
* analyzer component, describing the analyzer. * analyzer component, describing the analyzer.
*/ */
class Component : public plugin::Component, public plugin::TaggedComponent class Component : public plugin::Component
{ {
public: public:
using factory_callback = Analyzer* (*)(Connection* conn); using factory_callback = Analyzer* (*)(Connection* conn);
@ -68,7 +67,7 @@ public:
/** /**
* Destructor. * Destructor.
*/ */
~Component() override; ~Component() override = default;
/** /**
* Initialization function. This function has to be called before any * Initialization function. This function has to be called before any

View file

@ -11,9 +11,7 @@ namespace zeek::file_analysis
Component::Component(const std::string& name, factory_function arg_factory, Tag::subtype_t subtype, Component::Component(const std::string& name, factory_function arg_factory, Tag::subtype_t subtype,
bool arg_enabled) bool arg_enabled)
: plugin::Component(plugin::component::FILE_ANALYZER, name), plugin::TaggedComponent( : plugin::Component(plugin::component::FILE_ANALYZER, name, subtype, file_mgr->GetTagType())
subtype,
file_mgr->GetTagType())
{ {
factory_func = arg_factory; factory_func = arg_factory;
enabled = arg_enabled; enabled = arg_enabled;

View file

@ -6,7 +6,6 @@
#include "zeek/Tag.h" #include "zeek/Tag.h"
#include "zeek/plugin/Component.h" #include "zeek/plugin/Component.h"
#include "zeek/plugin/TaggedComponent.h"
namespace zeek namespace zeek
{ {
@ -27,7 +26,7 @@ class Manager;
* A plugin can provide a specific file analyzer by registering this * A plugin can provide a specific file analyzer by registering this
* analyzer component, describing the analyzer. * analyzer component, describing the analyzer.
*/ */
class Component : public plugin::Component, public plugin::TaggedComponent class Component : public plugin::Component
{ {
public: public:
using factory_function = Analyzer* (*)(RecordValPtr args, File* file); using factory_function = Analyzer* (*)(RecordValPtr args, File* file);

View file

@ -10,8 +10,7 @@ namespace zeek::input
{ {
Component::Component(const std::string& name, factory_callback arg_factory) Component::Component(const std::string& name, factory_callback arg_factory)
: plugin::Component(plugin::component::READER, name), plugin::TaggedComponent( : plugin::Component(plugin::component::READER, name, 0, input_mgr->GetTagType())
0, input_mgr->GetTagType())
{ {
factory = arg_factory; factory = arg_factory;
} }

View file

@ -4,7 +4,6 @@
#include "zeek/Tag.h" #include "zeek/Tag.h"
#include "zeek/plugin/Component.h" #include "zeek/plugin/Component.h"
#include "zeek/plugin/TaggedComponent.h"
namespace zeek::input namespace zeek::input
{ {
@ -15,7 +14,7 @@ class ReaderBackend;
/** /**
* Component description for plugins providing log readers. * Component description for plugins providing log readers.
*/ */
class Component : public plugin::Component, public plugin::TaggedComponent class Component : public plugin::Component
{ {
public: public:
using factory_callback = ReaderBackend* (*)(ReaderFrontend* frontend); using factory_callback = ReaderBackend* (*)(ReaderFrontend* frontend);

View file

@ -10,8 +10,7 @@ namespace zeek::logging
{ {
Component::Component(const std::string& name, factory_callback arg_factory) Component::Component(const std::string& name, factory_callback arg_factory)
: plugin::Component(plugin::component::WRITER, name), plugin::TaggedComponent( : plugin::Component(plugin::component::WRITER, name, 0, log_mgr->GetTagType())
0, log_mgr->GetTagType())
{ {
factory = arg_factory; factory = arg_factory;
} }

View file

@ -4,7 +4,6 @@
#include "zeek/Tag.h" #include "zeek/Tag.h"
#include "zeek/plugin/Component.h" #include "zeek/plugin/Component.h"
#include "zeek/plugin/TaggedComponent.h"
namespace zeek::logging namespace zeek::logging
{ {
@ -15,7 +14,7 @@ class WriterBackend;
/** /**
* Component description for plugins providing log writers. * Component description for plugins providing log writers.
*/ */
class Component : public plugin::Component, public plugin::TaggedComponent class Component : public plugin::Component
{ {
public: public:
using factory_callback = WriterBackend* (*)(WriterFrontend* frontend); using factory_callback = WriterBackend* (*)(WriterFrontend* frontend);

View file

@ -9,9 +9,8 @@ using namespace zeek::packet_analysis;
Component::Component(const std::string& name, factory_callback arg_factory, Component::Component(const std::string& name, factory_callback arg_factory,
Tag::subtype_t arg_subtype) Tag::subtype_t arg_subtype)
: plugin::Component(plugin::component::PACKET_ANALYZER, name), plugin::TaggedComponent( : plugin::Component(plugin::component::PACKET_ANALYZER, name, arg_subtype,
arg_subtype, packet_mgr->GetTagType())
packet_mgr->GetTagType())
{ {
factory = arg_factory; factory = arg_factory;
} }

View file

@ -8,7 +8,6 @@
#include "zeek/Tag.h" #include "zeek/Tag.h"
#include "zeek/plugin/Component.h" #include "zeek/plugin/Component.h"
#include "zeek/plugin/TaggedComponent.h"
#include "zeek/util.h" #include "zeek/util.h"
namespace zeek::packet_analysis namespace zeek::packet_analysis
@ -17,7 +16,7 @@ namespace zeek::packet_analysis
class Analyzer; class Analyzer;
using AnalyzerPtr = std::shared_ptr<Analyzer>; using AnalyzerPtr = std::shared_ptr<Analyzer>;
class Component : public plugin::Component, public plugin::TaggedComponent class Component : public plugin::Component
{ {
public: public:
using factory_callback = std::function<AnalyzerPtr()>; using factory_callback = std::function<AnalyzerPtr()>;

View file

@ -8,25 +8,16 @@
namespace zeek::plugin namespace zeek::plugin
{ {
Component::Component(component::Type arg_type, const std::string& arg_name) Tag::type_t Component::type_counter(0);
Component::Component(component::Type arg_type, const std::string& arg_name,
Tag::subtype_t tag_subtype, zeek::EnumTypePtr etype)
: type(arg_type), name(arg_name), tag(etype, 1, 0), etype(std::move(etype)),
tag_subtype(tag_subtype)
{ {
type = arg_type;
name = arg_name;
canon_name = util::canonify_name(name); canon_name = util::canonify_name(name);
} }
Component::~Component() { }
const std::string& Component::Name() const
{
return name;
}
component::Type Component::Type() const
{
return type;
}
void Component::Describe(ODesc* d) const void Component::Describe(ODesc* d) const
{ {
d->Add(" "); d->Add(" ");
@ -84,4 +75,20 @@ void Component::Describe(ODesc* d) const
d->Add(")"); d->Add(")");
} }
void Component::InitializeTag()
{
assert(tag_initialized == false);
tag_initialized = true;
tag = zeek::Tag(etype, ++type_counter, tag_subtype);
}
/**
* @return The component's tag.
*/
zeek::Tag Component::Tag() const
{
assert(tag_initialized);
return tag;
}
} // namespace zeek::plugin } // namespace zeek::plugin

View file

@ -6,6 +6,9 @@
#include <string> #include <string>
#include "zeek/Tag.h"
#include "zeek/Type.h"
namespace zeek namespace zeek
{ {
@ -49,13 +52,27 @@ public:
* *
* @param name A descriptive name for the component. This name must * @param name A descriptive name for the component. This name must
* be unique across all components of the same type. * be unique across all components of the same type.
*
* @param tag_subtype A subtype associated with this component that
* further distinguishes it. The subtype will be integrated into
* the Tag that the manager associates with this component,
* and component instances can accordingly access it via Tag().
* If not used, leave at zero.
*
* @param etype An enum type that describes the type for the tag in
* script-land.
*/ */
Component(component::Type type, const std::string& name); Component(component::Type type, const std::string& name, Tag::subtype_t tag_subtype = 0,
zeek::EnumTypePtr etype = nullptr);
/** /**
* Destructor. * Destructor.
*/ */
virtual ~Component(); virtual ~Component() = default;
// Disable.
Component(const Component& other) = delete;
Component operator=(const Component& other) = delete;
/** /**
* Initialization function. This function has to be called before any * Initialization function. This function has to be called before any
@ -67,12 +84,12 @@ public:
/** /**
* Returns the compoment's type. * Returns the compoment's type.
*/ */
component::Type Type() const; component::Type Type() const { return type; }
/** /**
* Returns the compoment's name. * Returns the compoment's name.
*/ */
const std::string& Name() const; const std::string& Name() const { return name; }
/** /**
* Returns a canonocalized version of the components's name. The * Returns a canonocalized version of the components's name. The
@ -93,6 +110,17 @@ public:
*/ */
void Describe(ODesc* d) const; void Describe(ODesc* d) const;
/**
* Initializes tag by creating the unique tag value for this component.
* Has to be called exactly once.
*/
void InitializeTag();
/**
* @return The component's tag.
*/
zeek::Tag Tag() const;
protected: protected:
/** /**
* Adds type specific information to the output of Describe(). * Adds type specific information to the output of Describe().
@ -104,13 +132,18 @@ protected:
virtual void DoDescribe(ODesc* d) const { } virtual void DoDescribe(ODesc* d) const { }
private: private:
// Disable.
Component(const Component& other);
Component operator=(const Component& other);
component::Type type; component::Type type;
std::string name; std::string name;
std::string canon_name; std::string canon_name;
/** The automatically assigned component tag */
zeek::Tag tag;
EnumTypePtr etype;
Tag::subtype_t tag_subtype;
bool tag_initialized = false;
/** Used to generate globally unique tags */
static Tag::type_t type_counter;
}; };
} // namespace plugin } // namespace plugin

View file

@ -21,7 +21,7 @@ namespace zeek::plugin
* installs identifiers in the script-layer to identify them by a unique tag, * installs identifiers in the script-layer to identify them by a unique tag,
* (a script-layer enum value). * (a script-layer enum value).
* *
* @tparam C A plugin::TaggedComponent type derivative. * @tparam C A plugin::Component type derivative.
*/ */
template <class C> class ComponentManager template <class C> class ComponentManager
{ {

View file

@ -1,36 +0,0 @@
#include "zeek/plugin/TaggedComponent.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/Type.h"
namespace zeek::plugin
{
Tag::type_t TaggedComponent::type_counter(0);
TaggedComponent::TaggedComponent(Tag::subtype_t subtype, EnumTypePtr etype)
: tag(etype, 1, 0), subtype(subtype), initialized(false), etype(std::move(etype))
{
}
/**
* Initializes tag by creating the unique tag value for thos componend.
* Has to be called exactly once.
*/
void TaggedComponent::InitializeTag()
{
assert(initialized == false);
initialized = true;
tag = zeek::Tag(etype, ++type_counter, subtype);
}
/**
* @return The component's tag.
*/
zeek::Tag TaggedComponent::Tag() const
{
assert(initialized);
return tag;
}
} // namespace zeek::plugin

View file

@ -1,50 +0,0 @@
#pragma once
#include <cassert>
#include "zeek/Tag.h"
#include "zeek/Type.h"
namespace zeek::plugin
{
/**
* A class which has a tag of a given type associated with it.
*/
class TaggedComponent
{
public:
/**
* Constructor for TaggedComponend. Note that a unique value
* for this component is only created when InitializeTag is
* called.
*
* @param subtype A subtype associated with this component that
* further distinguishes it. The subtype will be integrated into
* the Tag that the manager associates with this component,
* and component instances can accordingly access it via Tag().
* If not used, leave at zero.
*/
explicit TaggedComponent(Tag::subtype_t subtype = 0, zeek::EnumTypePtr etype = nullptr);
/**
* Initializes tag by creating the unique tag value for thos componend.
* Has to be called exactly once.
*/
void InitializeTag();
/**
* @return The component's tag.
*/
zeek::Tag Tag() const;
private:
zeek::Tag tag; /**< The automatically assigned analyzer tag. */
Tag::subtype_t subtype;
bool initialized;
EnumTypePtr etype;
static Tag::type_t type_counter; /**< Used to generate globally
unique tags. */
};
} // namespace zeek::plugin