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/ComponentManager.h
plugin/TaggedComponent.cc
plugin/Manager.cc
plugin/Plugin.cc

View file

@ -17,6 +17,8 @@ Tag::Tag(const EnumTypePtr& etype, type_t arg_type, subtype_t arg_subtype)
assert(arg_type > 0);
int64_t i = (int64_t)(type) | ((int64_t)subtype << 31);
if ( etype )
val = etype->GetEnumVal(i);
}
@ -36,13 +38,13 @@ Tag::Tag(const Tag& other)
type = other.type;
subtype = other.subtype;
val = other.val;
etype = other.etype;
}
Tag::Tag()
{
type = 0;
subtype = 0;
val = nullptr;
etype = nullptr;
}
Tag::~Tag() = default;
@ -54,6 +56,7 @@ Tag& Tag::operator=(const Tag& other)
type = other.type;
subtype = other.subtype;
val = other.val;
etype = other.etype;
}
return *this;
@ -66,24 +69,12 @@ Tag& Tag::operator=(const Tag&& other) noexcept
type = other.type;
subtype = other.subtype;
val = std::move(other.val);
etype = std::move(other.etype);
}
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
{
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.
*/
const EnumValPtr& AsVal() const;
const EnumValPtr& AsVal() const { return val; }
/**
* Returns false if the tag represents an error value rather than a
@ -164,10 +164,10 @@ public:
static const Tag Error;
private:
type_t type; // Main type.
subtype_t subtype; // Subtype.
mutable EnumValPtr val; // Script-layer value.
mutable EnumTypePtr etype;
type_t type = 0; // Main type.
subtype_t subtype = 0; // Subtype.
EnumValPtr val; // Script-layer value.
EnumTypePtr etype;
};
} // namespace zeek

View file

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

View file

@ -6,7 +6,6 @@
#include "zeek/Tag.h"
#include "zeek/plugin/Component.h"
#include "zeek/plugin/TaggedComponent.h"
#include "zeek/util.h"
namespace zeek
@ -25,7 +24,7 @@ class Analyzer;
* A plugin can provide a specific protocol analyzer by registering this
* analyzer component, describing the analyzer.
*/
class Component : public plugin::Component, public plugin::TaggedComponent
class Component : public plugin::Component
{
public:
using factory_callback = Analyzer* (*)(Connection* conn);
@ -68,7 +67,7 @@ public:
/**
* Destructor.
*/
~Component() override;
~Component() override = default;
/**
* 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,
bool arg_enabled)
: plugin::Component(plugin::component::FILE_ANALYZER, name), plugin::TaggedComponent(
subtype,
file_mgr->GetTagType())
: plugin::Component(plugin::component::FILE_ANALYZER, name, subtype, file_mgr->GetTagType())
{
factory_func = arg_factory;
enabled = arg_enabled;

View file

@ -6,7 +6,6 @@
#include "zeek/Tag.h"
#include "zeek/plugin/Component.h"
#include "zeek/plugin/TaggedComponent.h"
namespace zeek
{
@ -27,7 +26,7 @@ class Manager;
* A plugin can provide a specific file analyzer by registering this
* analyzer component, describing the analyzer.
*/
class Component : public plugin::Component, public plugin::TaggedComponent
class Component : public plugin::Component
{
public:
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)
: plugin::Component(plugin::component::READER, name), plugin::TaggedComponent(
0, input_mgr->GetTagType())
: plugin::Component(plugin::component::READER, name, 0, input_mgr->GetTagType())
{
factory = arg_factory;
}

View file

@ -4,7 +4,6 @@
#include "zeek/Tag.h"
#include "zeek/plugin/Component.h"
#include "zeek/plugin/TaggedComponent.h"
namespace zeek::input
{
@ -15,7 +14,7 @@ class ReaderBackend;
/**
* Component description for plugins providing log readers.
*/
class Component : public plugin::Component, public plugin::TaggedComponent
class Component : public plugin::Component
{
public:
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)
: plugin::Component(plugin::component::WRITER, name), plugin::TaggedComponent(
0, log_mgr->GetTagType())
: plugin::Component(plugin::component::WRITER, name, 0, log_mgr->GetTagType())
{
factory = arg_factory;
}

View file

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

View file

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

View file

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

View file

@ -8,25 +8,16 @@
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);
}
Component::~Component() { }
const std::string& Component::Name() const
{
return name;
}
component::Type Component::Type() const
{
return type;
}
void Component::Describe(ODesc* d) const
{
d->Add(" ");
@ -84,4 +75,20 @@ void Component::Describe(ODesc* d) const
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

View file

@ -6,6 +6,9 @@
#include <string>
#include "zeek/Tag.h"
#include "zeek/Type.h"
namespace zeek
{
@ -49,13 +52,27 @@ public:
*
* @param name A descriptive name for the component. This name must
* 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.
*/
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
@ -67,12 +84,12 @@ public:
/**
* Returns the compoment's type.
*/
component::Type Type() const;
component::Type Type() const { return type; }
/**
* 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
@ -93,6 +110,17 @@ public:
*/
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:
/**
* Adds type specific information to the output of Describe().
@ -104,13 +132,18 @@ protected:
virtual void DoDescribe(ODesc* d) const { }
private:
// Disable.
Component(const Component& other);
Component operator=(const Component& other);
component::Type type;
std::string 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

View file

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