// See the file "COPYING" in the main distribution directory for copyright. #pragma once #include "zeek/input/ReaderBackend.h" #include "zeek/threading/SerialTypes.h" namespace zeek { class EnumVal; namespace input { class Manager; /** * Bridge class between the input::Manager and backend input threads. The * Manager instantiates one \a ReaderFrontend for each open input stream. * Each frontend in turns instantiates a ReaderBackend-derived class * internally that's specific to the particular input format. That backend * spawns a new thread, and it receives messages from the frontend that * correspond to method called by the manager. */ class ReaderFrontend { public: /** * Constructor. * * info: The meta information struct for the writer. * * type: The backend writer type, with the value corresponding to the * script-level \c Input::Reader enum (e.g., \a READER_ASCII). The * frontend will internally instantiate a ReaderBackend of the * corresponding type. * * Frontends must only be instantiated by the main thread. */ ReaderFrontend(const ReaderBackend::ReaderInfo& info, EnumVal* type); /** * Destructor. * * Frontends must only be destroyed by the main thread. */ virtual ~ReaderFrontend(); /** * Initializes the reader. * * This method generates a message to the backend reader and triggers * the corresponding message there. If the backend method fails, it * sends a message back that will asynchronously call Disable(). * * See ReaderBackend::Init() for arguments. * * This method must only be called from the main thread. */ void Init(const int arg_num_fields, const threading::Field* const* fields); /** * Force an update of the current input source. Actual action depends * on the opening mode and on the input source. * * This method generates a message to the backend reader and triggers * the corresponding message there. * * This method must only be called from the main thread. */ void Update(); /** * Finalizes reading from this stream. * * This method generates a message to the backend reader and triggers * the corresponding message there. This method must only be called * from the main thread. */ void Stop(); /** * Disables the reader frontend. From now on, all method calls that * would normally send message over to the backend, turn into no-ops. * Note though that it does not stop the backend itself, use Finish() * to do that as well (this method is primarily for use as callback * when the backend wants to disable the frontend). * * Disabled frontends will eventually be discarded by the * input::Manager. * * This method must only be called from the main thread. */ void SetDisable() { disabled = true; } /** * Returns true if the reader frontend has been disabled with * SetDisable(). */ bool Disabled() { return disabled; } /** * Returns a descriptive name for the reader, including the type of * the backend and the source used. * * This method is safe to call from any thread. */ const char* Name() const; /** * Returns the additional reader information passed into the constructor. */ const ReaderBackend::ReaderInfo& Info() const { assert(info); return *info; } /** * Returns the number of log fields as passed into the constructor. */ int NumFields() const { return num_fields; } /** * Returns the log fields as passed into the constructor. */ const threading::Field* const * Fields() const { return fields; } protected: friend class Manager; private: ReaderBackend* backend; // The backend we have instanatiated. ReaderBackend::ReaderInfo* info; // Meta information. const threading::Field* const* fields; // The input fields. int num_fields; // Information as passed to Init(). bool disabled; // True if disabled. bool initialized; // True if initialized. const char* name; // Descriptive name. }; } // namespace input } // namespace zeek