Add a distinct tag class for file analyzers.

This should prevent assignment mismatches between file and protocol
analyzer tags.
This commit is contained in:
Jon Siwek 2013-07-30 15:19:48 -05:00
parent d84f6e012c
commit 8df4df0b8b
13 changed files with 407 additions and 161 deletions

View file

@ -14,6 +14,7 @@ set(file_analysis_SRCS
Analyzer.h
AnalyzerSet.cc
Component.cc
Tag.cc
)
bif_target(file_analysis.bif)

View file

@ -8,17 +8,17 @@
using namespace file_analysis;
analyzer::Tag::type_t Component::type_counter = 0;
file_analysis::Tag::type_t Component::type_counter = 0;
Component::Component(const char* arg_name, factory_callback arg_factory,
analyzer::Tag::subtype_t arg_subtype)
file_analysis::Tag::subtype_t arg_subtype)
: plugin::Component(plugin::component::FILE_ANALYZER)
{
name = copy_string(arg_name);
canon_name = canonify_name(arg_name);
factory = arg_factory;
tag = analyzer::Tag(++type_counter, arg_subtype);
tag = file_analysis::Tag(++type_counter, arg_subtype);
}
Component::Component(const Component& other)
@ -36,7 +36,7 @@ Component::~Component()
delete [] canon_name;
}
analyzer::Tag Component::Tag() const
file_analysis::Tag Component::Tag() const
{
return tag;
}

View file

@ -3,7 +3,7 @@
#ifndef FILE_ANALYZER_PLUGIN_COMPONENT_H
#define FILE_ANALYZER_PLUGIN_COMPONENT_H
#include "analyzer/Tag.h"
#include "Tag.h"
#include "plugin/Component.h"
#include "Val.h"
@ -41,12 +41,12 @@ public:
*
* @param subtype A subtype associated with this component that
* further distinguishes it. The subtype will be integrated into
* the analyzer::Tag that the manager associates with this analyzer,
* and analyzer instances can accordingly access it via analyzer::Tag().
* If not used, leave at zero.
* the file_analysis::Tag that the manager associates with this analyzer,
* and analyzer instances can accordingly access it via
* file_analysis::Tag(). If not used, leave at zero.
*/
Component(const char* name, factory_callback factory,
analyzer::Tag::subtype_t subtype = 0);
file_analysis::Tag::subtype_t subtype = 0);
/**
* Copy constructor.
@ -84,7 +84,7 @@ public:
* generated for each new Components, and hence unique across all of
* them.
*/
analyzer::Tag Tag() const;
file_analysis::Tag Tag() const;
/**
* Generates a human-readable description of the component's main
@ -98,10 +98,10 @@ private:
const char* name; // The analyzer's name.
const char* canon_name; // The analyzer's canonical name.
factory_callback factory; // The analyzer's factory callback.
analyzer::Tag tag; // The automatically assigned analyzer tag.
file_analysis::Tag tag; // The automatically assigned analyzer tag.
// Global counter used to generate unique tags.
static analyzer::Tag::type_t type_counter;
static file_analysis::Tag::type_t type_counter;
};
}

View file

@ -294,7 +294,7 @@ protected:
private:
typedef map<string, Component*> analyzer_map_by_name;
typedef map<analyzer::Tag, Component*> analyzer_map_by_tag;
typedef map<file_analysis::Tag, Component*> analyzer_map_by_tag;
typedef map<int, Component*> analyzer_map_by_val;
void RegisterAnalyzerComponent(Component* component);

24
src/file_analysis/Tag.cc Normal file
View file

@ -0,0 +1,24 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "Tag.h"
#include "Manager.h"
using namespace file_analysis;
file_analysis::Tag file_analysis::Tag::Error;
file_analysis::Tag::Tag(type_t type, subtype_t subtype)
: ::Tag(file_mgr->GetTagEnumType(), type, subtype)
{
}
file_analysis::Tag& file_analysis::Tag::operator=(const file_analysis::Tag& other)
{
::Tag::operator=(other);
return *this;
}
EnumVal* file_analysis::Tag::AsEnumVal() const
{
return ::Tag::AsEnumVal(file_mgr->GetTagEnumType());
}

115
src/file_analysis/Tag.h Normal file
View file

@ -0,0 +1,115 @@
// See the file "COPYING" in the main distribution directory for copyright.
#ifndef FILE_ANALYZER_TAG_H
#define FILE_ANALYZER_TAG_H
#include "config.h"
#include "util.h"
#include "../Tag.h"
class EnumVal;
namespace file_analysis {
class Manager;
class Component;
/**
* Class to identify a file analyzer type.
*
* The script-layer analogue is Files::Tag.
*/
class Tag : public ::Tag {
public:
/*
* Copy constructor.
*/
Tag(const Tag& other) : ::Tag(other) {}
/**
* Default constructor. This initializes the tag with an error value
* that will make \c operator \c bool return false.
*/
Tag() : ::Tag() {}
/**
* Destructor.
*/
~Tag() {}
/**
* Returns false if the tag represents an error value rather than a
* legal analyzer type.
* TODO: make this conversion operator "explicit" (C++11) or use a
* "safe bool" idiom (not necessary if "explicit" is available),
* otherwise this may allow nonsense/undesired comparison operations.
*
*/
operator bool() const { return *this != Tag(); }
/**
* Assignment operator.
*/
Tag& operator=(const Tag& other);
/**
* Compares two tags for equality.
*/
bool operator==(const Tag& other) const
{
return ::Tag::operator==(other);
}
/**
* Compares two tags for inequality.
*/
bool operator!=(const Tag& other) const
{
return ::Tag::operator!=(other);
}
/**
* Compares two tags for less-than relationship.
*/
bool operator<(const Tag& other) const
{
return ::Tag::operator<(other);
}
/**
* Returns the \c Files::Tag 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.
*/
EnumVal* AsEnumVal() const;
static Tag Error;
protected:
friend class file_analysis::Manager;
friend class file_analysis::Component;
/**
* Constructor.
*
* @param type The main type. Note that the \a file_analysis::Manager
* manages the value space internally, so noone else should assign
* main tyoes.
*
* @param subtype The sub type, which is left to an analyzer for
* interpretation. By default it's set to zero.
*/
Tag(type_t type, subtype_t subtype = 0);
/**
* Constructor.
*
* @param val An enum value of script type \c Files::Tag.
*/
Tag(EnumVal* val) : ::Tag(val) {}
};
}
#endif