#ifndef CLICK_HANDLER_HH #define CLICK_HANDLER_HH 1 #include CLICK_DECLS class Element; class ErrorHandler; class Handler; /** @file * @brief The Handler class for router handlers. */ typedef int (*HandlerCallback)(int operation, String &data, Element *element, const Handler *handler, ErrorHandler *errh); typedef String (*ReadHandlerCallback)(Element *handler, void *user_data); typedef int (*WriteHandlerCallback)(const String &data, Element *element, void *user_data, ErrorHandler *errh); class Handler { public: enum Flags { f_read = 0x0001, ///< @brief Handler supports read operations. f_write = 0x0002, ///< @brief Handler supports write operations. f_read_param = 0x0004, ///< @brief Read handler takes parameters. f_exclusive = 0, ///< @brief Handler is exclusive (the default): /// router threads must stop while it is /// called. f_nonexclusive = 0x0020,///< @brief Handler is nonexclusive: router /// threads don't need to stop while it is /// called. f_raw = 0x0040, ///< @brief Don't add newline to results. f_read_private = 0x0080,///< @brief Read handler private (invisible /// outside the router configuration). f_write_private = 0x0100,///< @brief Write handler private (invisible /// outside the router configuration). f_deprecated = 0x0200, ///< @brief Handler is deprecated and available /// only for compatibility. f_uncommon = 0x0400, ///< @brief User interfaces should not display /// handler by default. f_calm = 0x0800, ///< @brief Read handler value changes rarely. f_expensive = 0x1000, ///< @brief Read handler is expensive to call. f_button = 0x2000, ///< @brief Write handler ignores data. f_checkbox = 0x4000, ///< @brief Read/write handler is boolean and /// should be rendered as a checkbox. f_driver0 = 1U << 26, f_driver1 = 1U << 27, ///< @brief Uninterpreted handler flags /// available for drivers. f_user_shift = 28, f_user0 = 1U << f_user_shift, ///< @brief First uninterpreted handler flag /// available for element-specific use. /// Equals 1 << f_user_shift. f_read_comprehensive = 0x0008, f_write_comprehensive = 0x0010, f_special = f_read | f_write | f_read_param | f_read_comprehensive | f_write_comprehensive ///< @brief These flags may not be set by /// Router::set_handler_flags(). }; /** @brief Return this handler's name. */ inline const String &name() const { return _name; } /** @brief Return this handler's flags. * * The result is a bitwise-or of flags from the Flags enumeration type. */ inline uint32_t flags() const { return _flags; } /** @brief Return this handler's callback data. * @param op either f_read or f_write. */ inline void *user_data(int op) const { return op == f_write ? _write_user_data : _read_user_data; } /** @brief Return this handler's read callback data. */ inline void *read_user_data() const { return _read_user_data; } /** @brief Return this handler's write callback data. */ inline void *write_user_data() const { return _write_user_data; } /** @cond never */ inline void *user_data1() const CLICK_DEPRECATED; inline void *user_data2() const CLICK_DEPRECATED; /** @endcond never */ /** @brief Test if this is a valid read handler. */ inline bool readable() const { return _flags & f_read; } /** @brief Test if this is a valid read handler that may accept * parameters. */ inline bool read_param() const { return _flags & f_read_param; } /** @brief Test if this is a public read handler. * * Private handlers may be not called from outside the router * configuration. Handlers are public by default; to make a read handler * private, add the f_read_private flag. */ inline bool read_visible() const { return (_flags & (f_read | f_read_private)) == f_read; } /** @brief Test if this is a valid write handler. */ inline bool writable() const { return _flags & f_write; } /** @brief Test if this is a public write handler. * * Private handlers may not be called from outside the router * configuration. Handlers are public by default; to make a write handler * private, add the f_write_private flag. */ inline bool write_visible() const { return (_flags & (f_write | f_write_private)) == f_write; } /** @brief Test if this is a public read or write handler. */ inline bool visible() const { return read_visible() || write_visible(); } /** @brief Test if this handler can execute concurrently with other * handlers. */ inline bool allow_concurrent_handlers() const { return (_flags & f_nonexclusive); } /** @brief Test if this handler can execute concurrently with * router threads. */ inline bool allow_concurrent_threads() const { return (_flags & f_nonexclusive); } /** @brief Test if spaces should be preserved when calling this handler. * * Some Click drivers perform some convenience processing on handler * values, for example by removing a terminating newline from write * handler values or adding a terminating newline to read handler values. * Raw handlers do not have their values manipulated in this way. Rawness * is set by the f_raw flag. * * */ inline bool raw() const { return _flags & f_raw; } /** @brief Call a read handler, possibly with parameters. * @param e element on which to call the handler * @param param parameters, or an empty string if no parameters * @param errh optional error handler * * The element must be nonnull; to call a global handler, pass the * relevant router's Router::root_element(). @a errh may be null, in * which case errors are reported to ErrorHandler::silent_handler(). */ String call_read(Element *e, const String ¶m, ErrorHandler *errh) const; /** @brief Call a read handler without parameters. * @param e element on which to call the handler * @param errh error handler * * The element must be nonnull; to call a global handler, pass the * relevant router's Router::root_element(). @a errh may be null, in * which case errors are ignored. */ inline String call_read(Element *e, ErrorHandler *errh = 0) const { return call_read(e, String(), errh); } /** @brief Call a write handler. * @param value value to write to the handler * @param e element on which to call the handler * @param errh optional error handler * * The element must be nonnull; to call a global handler, pass the * relevant router's Router::root_element(). @a errh may be null, in * which case errors are reported to ErrorHandler::silent_handler(). */ int call_write(const String &value, Element *e, ErrorHandler *errh) const; /** @brief Unparse this handler's name. * @param e relevant element * * If @a e is an actual element, then returns "ENAME.HNAME", where ENAME * is @a e's @link Element::name() name@endlink and HNAME is this * handler's name(). Otherwise, just returns name(). */ String unparse_name(Element *e) const; /** @brief Unparse a handler name. * @param e relevant element, if any * @param hname handler name * * If @a e is an actual element on some router, then returns * "ENAME.hname", where ENAME is @a e's @link Element::name() * name@endlink. Otherwise, just returns @a hname.*/ static String unparse_name(Element *e, const String &hname); /** @brief Returns a handler incapable of doing anything. * * The returned handler returns false for readable() and writable() and * has flags() of zero. */ static inline const Handler *blank_handler() { return the_blank_handler; } /** @cond never */ enum { h_read = f_read, h_write = f_write, h_read_param = f_read_param, h_exclusive = f_exclusive, h_nonexclusive = f_nonexclusive, h_raw = f_raw, h_read_private = f_read_private, h_write_private = f_write_private, h_deprecated = f_deprecated, h_uncommon = f_uncommon, h_calm = f_calm, h_expensive = f_expensive, h_button = f_button, h_checkbox = f_checkbox, h_driver_flag_0 = f_driver0, h_driver_flag_1 = f_driver1, h_user_flag_shift = f_user_shift, h_user_flag_0 = f_user0, h_read_comprehensive = f_read_comprehensive, h_write_comprehensive = f_write_comprehensive, h_special_flags = f_special }; enum DeprecatedFlags { OP_READ = f_read, OP_WRITE = f_write, READ_PARAM = f_read_param, RAW = f_raw, // READ_PRIVATE = f_read_private, // WRITE_PRIVATE = f_write_private, // DEPRECATED = f_deprecated, // UNCOMMON = f_uncommon, CALM = f_calm, EXPENSIVE = f_expensive, BUTTON = f_button, CHECKBOX = f_checkbox, USER_FLAG_SHIFT = f_user_shift, USER_FLAG_0 = f_user0 }; enum CLICK_DEPRECATED { EXCLUSIVE = f_exclusive, NONEXCLUSIVE = f_nonexclusive }; /** @endcond never */ /** @cond never */ /** @brief Call a read handler without parameters, passing new user_data(). * @param e element on which to call the handler * @param new_user_data new user data * * This function should only be used for special purposes. It fails * unless called on a handler created with a ReadHandlerCallback. */ inline String __call_read(Element *e, void *new_user_data) const { assert((_flags & (f_read | f_read_comprehensive)) == f_read); return _read_hook.r(e, new_user_data); } /** @endcond never */ private: String _name; union { HandlerCallback h; ReadHandlerCallback r; } _read_hook; union { HandlerCallback h; WriteHandlerCallback w; } _write_hook; void *_read_user_data; void *_write_user_data; uint32_t _flags; int _use_count; int _next_by_name; static const Handler *the_blank_handler; Handler(const String & = String()); inline void combine(const Handler &x); inline bool compatible(const Handler &x) const; friend class Router; }; /* The largest size a write handler is allowed to have. */ #define LARGEST_HANDLER_WRITE 65536 typedef HandlerCallback HandlerHook CLICK_DEPRECATED; typedef ReadHandlerCallback ReadHandlerHook CLICK_DEPRECATED; typedef WriteHandlerCallback WriteHandlerHook CLICK_DEPRECATED; /** @cond never */ inline void * Handler::user_data1() const { return _read_user_data; } inline void * Handler::user_data2() const { return _write_user_data; } /** @endcond never */ CLICK_ENDDECLS #endif