📄 timefilter.cc
字号:
// -*- mode: c++; c-basic-offset: 4 -*-/* * timefilter.{cc,hh} -- element filters packets by timestamp * Eddie Kohler * * Copyright (c) 2001 International Computer Science Institute * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include <click/error.hh>#include "timefilter.hh"#include <click/confparse.hh>#include <click/router.hh>#include <click/handlercall.hh>CLICK_DECLSTimeFilter::TimeFilter() : Element(1, 1), _last_h(0){}TimeFilter::~TimeFilter(){ delete _last_h;}voidTimeFilter::notify_noutputs(int n){ set_noutputs(n <= 1 ? 1 : 2);}intTimeFilter::configure(Vector<String> &conf, ErrorHandler *errh){ Timestamp first, last, first_init, last_init, first_delta, last_delta, interval; bool stop = false; if (cp_va_parse(conf, this, errh, cpKeywords, "START", cpTimestamp, "start time", &first, "END", cpTimestamp, "end time", &last, "START_DELAY", cpTimestamp, "start T after initialization", &first_init, "END_DELAY", cpTimestamp, "end T after initialization", &last_init, "START_AFTER", cpTimestamp, "start T after first packet", &first_delta, "END_AFTER", cpTimestamp, "end T after first packet", &last_delta, "INTERVAL", cpTimestamp, "interval", &interval, "STOP", cpBool, "stop when after end?", &stop, "END_CALL", cpWriteHandlerCall, "handler to call at end", &_last_h, cpEnd) < 0) return -1; _first_relative = _first_init_relative = _last_relative = _last_init_relative = _last_interval = false; if ((bool) first + (bool) first_delta + (bool) first_init > 1) return errh->error("'START', 'START_AFTER', and 'START_AFTER_INIT' are mutually exclusive"); else if (first) _first = first; else if (first_init) _first = first_init, _first_init_relative = true; else _first = first_delta, _first_relative = true; if ((bool) last + (bool) last_delta + (bool) last_init + (bool) interval > 1) return errh->error("'END', 'END_AFTER', 'END_AFTER_INIT', and 'INTERVAL'\nare mutually exclusive"); else if (last) _last = last; else if (last_delta) _last = last_delta, _last_relative = true; else if (last_init) _last = last_init, _last_init_relative = true; else if (interval) _last = interval, _last_interval = true; else _last.set_sec(0x7FFFFFFF); if (_last_h && stop) return errh->error("'END_CALL' and 'STOP' are mutually exclusive"); else if (stop) _last_h = new HandlerCall("stop true"); _ready = false; return 0;}intTimeFilter::initialize(ErrorHandler *errh){ if (_last_h && _last_h->initialize_write(this, errh) < 0) return -1; if (_first_init_relative || _last_init_relative) { Timestamp now = Timestamp::now(); if (_first_init_relative) _first += now; if (_last_init_relative) _last += now; } _last_h_ready = (_last_h != 0); return 0;}voidTimeFilter::first_packet(const Timestamp& tv){ if (_first_relative) _first += tv; if (_last_relative) _last += tv; else if (_last_interval) _last += _first; _ready = true;}Packet *TimeFilter::kill(Packet *p){ checked_output_push(1, p); return 0;}Packet *TimeFilter::simple_action(Packet *p){ const Timestamp& tv = p->timestamp_anno(); if (!_ready) first_packet(tv); if (tv < _first) return kill(p); else if (tv < _last) return p; else { if (_last_h && _last_h_ready) { _last_h_ready = false; (void) _last_h->call_write(); } return kill(p); }}enum { H_EXTEND_INTERVAL };intTimeFilter::write_handler(const String &s_in, Element *e, void *thunk, ErrorHandler *errh){ TimeFilter *tf = static_cast<TimeFilter *>(e); String s = cp_uncomment(s_in); switch ((intptr_t)thunk) { case H_EXTEND_INTERVAL: { Timestamp t; if (cp_time(s, &t)) { tf->_last += t; if (tf->_last_h) tf->_last_h_ready = true; return 0; } else return errh->error("'extend_interval' takes a time interval"); } default: return -EINVAL; }}voidTimeFilter::add_handlers(){ add_write_handler("extend_interval", write_handler, (void *)H_EXTEND_INTERVAL);}CLICK_ENDDECLSEXPORT_ELEMENT(TimeFilter)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -