📄 hvalues.cc
字号:
#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <click/config.h>#include "hvalues.hh"#include "cdriver.hh"#include <gdk/gdkkeysyms.h>#include <click/confparse.hh>extern "C" {#include "interface.h"#include "support.h"}namespace clicky {/***** * * handler_value, including autorefresh * */const String handler_value::no_hvalue_string = String::make_stable("???", 3);namespace {struct autorefresher { handler_value *hv; crouter *cr; int period; autorefresher(handler_value *hv_, crouter *cr_, int period_) : hv(hv_), cr(cr_), period(period_) { }};extern "C" {static gboolean on_autorefresh(gpointer user_data){ autorefresher *wa = reinterpret_cast<autorefresher *>(user_data); return wa->hv->on_autorefresh(wa->cr, wa->period);}static void destroy_autorefresh(gpointer user_data) { autorefresher *wa = reinterpret_cast<autorefresher *>(user_data); delete wa;}}}void handler_value::refresh(crouter *cr, bool clear_outstanding){ if (empty() && handler_name().equals("handlers", 8)) _flags |= hflag_r; if (clear_outstanding) _flags &= ~hflag_outstanding; else if (_flags & hflag_outstanding) return; // nothing to do if (_flags & (hflag_r | hflag_rparam)) { int read_flags = (_flags & hflag_raw ? 0 : cdriver::dflag_nonraw); _flags |= hflag_outstanding; cr->driver()->do_read(_hname, _hparam, read_flags); } else if (empty()) _flags |= hflag_outstanding;}void handler_value::create_autorefresh(crouter *cr){ autorefresher *a = new autorefresher(this, cr, _autorefresh_period); _autorefresh_source = g_timeout_add_full (G_PRIORITY_DEFAULT, _autorefresh_period, clicky::on_autorefresh, a, destroy_autorefresh);}gboolean handler_value::on_autorefresh(crouter *cr, int period){ if ((_flags & hflag_autorefresh) != 0 && readable() && cr->driver()) { refresh(cr); if (period != _autorefresh_period) { create_autorefresh(cr); return FALSE; } else return TRUE; } else { _autorefresh_source = 0; return FALSE; }}void handler_value::set_flags(crouter *cr, int new_flags){ if (_autorefresh_source && ((new_flags & hflag_autorefresh) == 0 || (new_flags & hflag_r) == 0)) { g_source_remove(_autorefresh_source); _autorefresh_source = 0; } else if (_autorefresh_source == 0 && (new_flags & hflag_autorefresh) != 0 && (new_flags & hflag_r)) create_autorefresh(cr); if ((new_flags & hflag_have_hvalue) == 0) _hvalue = (new_flags & hflag_r ? no_hvalue_string : String()); _flags = new_flags & ~hflag_private_mask; _driver_mask &= ~(_flags ^ _driver_flags);}/***** * * handler_values * */handler_values::handler_values(crouter *cr) : _cr(cr){}handler_values::iterator handler_values::begin(const String &ename){ HashTable<handler_value>::iterator iter = _hv.find(ename + ".handlers"); if (iter && (iter->_driver_flags & hflag_dead) == 0) return iterator(iter.operator->()); else return iterator(0);}handler_value *handler_values::set(const String &hname, const String &hparam, const String &hvalue, bool &changed){ if (hname.length() > 9 && memcmp(hname.end() - 9, ".handlers", 9) == 0) set_handlers(hname, hparam, hvalue); handler_value *hv = _hv.find_insert(hname).get(); changed = (!hv->have_hvalue() || hparam != hv->_hparam || hvalue != hv->_hvalue); hv->_hparam = hparam; hv->_hvalue = hvalue; hv->_flags = (hv->_flags & ~hflag_outstanding) | hflag_have_hvalue; return hv;}void handler_values::set_handlers(const String &hname, const String &, const String &hvalue){ assert(hname.length() > 9 && memcmp(hname.end() - 9, ".handlers", 9) == 0); handler_value *handlers = _hv.find_insert(hname).get(); if (handlers && handlers->hvalue() == hvalue) return; Vector<handler_value *> old_handlers; for (handler_value *v = handlers; v; v = v->_next) { v->_driver_flags |= hflag_dead; old_handlers.push_back(v); } handlers->_next = 0; // parse handler data into _hinfo const char *s = hvalue.begin(); bool syntax_error = false; while (s != hvalue.end()) { const char *name_start = s; while (s != hvalue.end() && !isspace((unsigned char) *s)) ++s; if (s == name_start || s == hvalue.end() || *s != '\t') { syntax_error = true; break; } String name = hvalue.substring(name_start, s); while (s != hvalue.end() && isspace((unsigned char) *s)) ++s; int flags = 0; for (; s != hvalue.end() && !isspace((unsigned char) *s); ++s) switch (*s) { case 'r': flags |= hflag_r; break; case 'w': flags |= hflag_w; break; case '+': flags |= hflag_rparam; break; case '%': flags |= hflag_raw; break; case '.': flags |= hflag_calm; break; case '$': flags |= hflag_expensive; break; case 'b': flags |= hflag_button; break; case 'c': flags |= hflag_checkbox; break; case 'U': flags |= hflag_uncommon; break; case 'D': flags |= hflag_deprecated; break; } if (!(flags & hflag_r)) flags &= ~hflag_rparam; if (flags & hflag_r) flags &= ~hflag_button; if (flags & hflag_rparam) flags &= ~hflag_checkbox; // default appearance if (name == "class" || name == "name") flags |= hflag_special; else if (name == "config") flags |= hflag_multiline | hflag_special | hflag_visible | hflag_refresh; else if (name == "ports" || name == "icounts" || name == "ocounts") flags |= hflag_collapse | hflag_visible; else if (name == "handlers") flags |= hflag_collapse; else if (!(flags & (hflag_uncommon | hflag_deprecated))) flags |= hflag_visible; if (handler_value::default_refreshable(flags)) flags |= hflag_refresh; String full_name = hname.substring(0, hname.length() - 8) + name; handler_value *v = _hv.find_insert(full_name).get(); if (v != handlers) { v->_next = handlers->_next; handlers->_next = v; } bool was_empty = v->empty(); v->set_driver_flags(_cr, flags); if (was_empty || v->notify_delt()) _cr->on_handler_create(v, was_empty); if (was_empty && (v->_flags & hflag_outstanding)) { v->_flags &= ~hflag_outstanding; if (flags & hflag_refresh) v->refresh(_cr); } while (s != hvalue.end() && *s != '\r' && *s != '\n') ++s; if (s + 1 < hvalue.end() && *s == '\r' && s[1] == '\n') s += 2; else if (s != hvalue.end()) ++s; } for (handler_value **hv = old_handlers.begin(); hv != old_handlers.end(); ++hv) if ((*hv)->_flags & hflag_dead) _hv.erase((*hv)->_hname);}handler_value *handler_values::hard_find_placeholder(const String &hname, int flags, int autorefresh_period){ if (!_cr->driver()) return 0; int dot = hname.find_right('.'); String base = (dot > 0 ? hname.substring(0, dot + 1) : String()); handler_value *hh = _hv.find_insert(base + "handlers").get(); if (hh->have_hvalue()) return 0; hh->refresh(_cr); handler_value *hv = _hv.find_insert(hname).get(); hv->set_flags(_cr, hv->flags() | flags); if (autorefresh_period > 10 && hv->autorefresh_period() > autorefresh_period) hv->set_autorefresh_period(autorefresh_period); return hv;}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -