trafficsource.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:26k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 2001 University of Southern California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *      This product includes software developed by the Information Sciences
  16.  *      Institute of the University of Southern California.
  17.  * 4. Neither the name of the University nor of the Institute may be used
  18.  *    to endorse or promote products derived from this software without
  19.  *    specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  */
  34. #include <stdlib.h>
  35. #include <math.h>
  36. #ifdef WIN32
  37. #include <windows.h>
  38. #endif
  39. #include "netview.h"
  40. #include "psview.h"
  41. #include "node.h"
  42. #include "feature.h"
  43. #include "agent.h"
  44. #include "edge.h"
  45. #include "paint.h"
  46. #include "monitor.h"
  47. #include "sincos.h"
  48. #include "trafficsource.h"
  49. #define PROPERTY_STRING_LENGTH 256
  50. static int g_trafficsource_number = 1;
  51. //----------------------------------------------------------------------
  52. //  Wrapper for creating Traffic Sources in OTcl
  53. //----------------------------------------------------------------------
  54. static class TrafficSourceClass : public TclClass {
  55. public:
  56.   TrafficSourceClass() : TclClass("TrafficSource") {}
  57.   TclObject* create(int argc, const char * const * argv) {
  58.     const char * type;
  59.     int id;
  60.     double size;
  61.     type = argv[4];
  62.     id = strtol(argv[5], NULL, 10);
  63.     size = strtod(argv[6], NULL);
  64.     
  65.     return (new TrafficSource(type, id, size));
  66.   }
  67. } class_trafficsource;
  68. //----------------------------------------------------------------------
  69. // TrafficSource::TrafficSource(const char* type, double _size)
  70. //----------------------------------------------------------------------
  71. TrafficSource::TrafficSource(const char* type, int id, double _size) :
  72.   Animation(0, 0) {
  73.   setDefaults();
  74.   number_ = id;
  75.   if (g_trafficsource_number++ <= id) {
  76.     g_trafficsource_number = id + 1;
  77.   }
  78.   label_ = new char[strlen(type) + 1];
  79.   strcpy(label_, type);
  80.   width_ = 50.0 * strlen(type);
  81.   height_ = size_/2.0;
  82.   size_ = _size;
  83.   size(_size);
  84. }
  85. //----------------------------------------------------------------------
  86. // TrafficSource::TrafficSource(const char* name, double size)
  87. //----------------------------------------------------------------------
  88. TrafficSource::TrafficSource(const char* name, double _size) :
  89.   Animation(0, 0) {
  90.   setDefaults();
  91.   
  92.   number_ = g_trafficsource_number;
  93.   g_trafficsource_number++;
  94.   width_ = 50.0 * strlen(name);
  95.   height_ = size_/2.0;
  96.   size_ = _size;
  97.   label_ = new char[strlen(name) + 1];
  98.   strcpy(label_, name);
  99.   size(_size);
  100.   timelist.add(0.0);
  101.   timelist.add(60.0);
  102.   // Bind tcl variables to c++ ones
  103. //  bind("start_", &start_);
  104. //  bind("stop_", &stop_);
  105. //  bind("packet_size_", &packet_size_);
  106. //  bind("interval_", &interval_);
  107. }
  108. //----------------------------------------------------------------------
  109. //----------------------------------------------------------------------
  110. void
  111. TrafficSource::setDefaults() {
  112.   previous_ = NULL;
  113.   next_ = NULL;
  114.   editornetmodel_next_ = NULL;
  115.   agent_ = NULL;
  116.   packet_size_ = 500;
  117.   interval_ = 0.00195;
  118.   // Exponential & Pareto
  119.   burst_time_ = 500;
  120.   idle_time_ = 500;
  121.   rate_ = 100;
  122.   // Pareto
  123.   shape_ = 1.5;
  124.   
  125.   x_ = 0.0;
  126.   y_ = 0.0;
  127.   angle_ = NO_ANGLE;
  128.   window_ = 20;
  129.   windowInit_ = 1;
  130.   maxcwnd_ = 0;
  131.   color_ = "green";
  132.   anchor_ = 0;
  133.   paint_ = Paint::instance()->thin();
  134.   maxpkts_ = 256;
  135. }
  136. //----------------------------------------------------------------------
  137. // void
  138. // TrafficSource::attach(Agent * agent)
  139. //   - Attach this traffic source to an agents list of traffic sources
  140. //----------------------------------------------------------------------
  141. void
  142. TrafficSource::attachTo(Agent * agent) {
  143.   agent_ = agent;
  144.   previous_ = agent_->addTrafficSource(this);
  145.   size(agent_->size()); 
  146.   place();
  147. }
  148. //----------------------------------------------------------------------
  149. //----------------------------------------------------------------------
  150. void
  151. TrafficSource::removeFromAgent() {
  152.   // previous_ should be NULL for the first traffic source
  153.   // attached to the agent
  154.   agent_->removeTrafficSource(this);
  155.   next_ = NULL;
  156.   previous_ = NULL;
  157.   agent_ = NULL;
  158. }
  159. //----------------------------------------------------------------------
  160. // double 
  161. // TrafficSource::distance(double x, double y) const {
  162. //----------------------------------------------------------------------
  163. double
  164. TrafficSource::distance(double x, double y) const {
  165.   return sqrt((x_-x)*(x_-x) + (y_-y)*(y_-y));
  166. }
  167. //----------------------------------------------------------------------
  168. //----------------------------------------------------------------------
  169. void
  170. TrafficSource::color(const char * name) {
  171.   if (color_) {
  172.     delete []color_;
  173.   }
  174.   color_ = new char[strlen(name) + 1];
  175.   strcpy(color_, name);
  176. }
  177. //----------------------------------------------------------------------
  178. //----------------------------------------------------------------------
  179. void TrafficSource::size(double s) {
  180.   size_ = s;
  181.   width_ = 10.0 + 25.0*strlen(label_);
  182.   height_ = s/2.0;
  183.   update_bb();
  184. }
  185. //----------------------------------------------------------------------
  186. //----------------------------------------------------------------------
  187. void TrafficSource::update_bb() {
  188.   bb_.xmin = x_;
  189.   bb_.ymin = y_;
  190.   bb_.xmax = x_ + width_;
  191.   bb_.ymax = y_ + height_;
  192. }
  193. //----------------------------------------------------------------------
  194. //----------------------------------------------------------------------
  195. void TrafficSource::label(const char* name) {
  196.   if (label_) {
  197.     delete label_;
  198.   }
  199.   label_ = new char[strlen(name) + 1];
  200.   strcpy(label_, name);
  201. }
  202. //----------------------------------------------------------------------
  203. //----------------------------------------------------------------------
  204. void TrafficSource::drawlabel(View* view) const {
  205.   // Check out anchor
  206.   if (label_) {
  207.     view->string(x_, y_, size_, label_, anchor_);
  208.   }
  209. }
  210. //----------------------------------------------------------------------
  211. //----------------------------------------------------------------------
  212. //void TrafficSource::drawlabel(PSView* nv) const {
  213. //  if (label_)
  214. //    nv->string(x_, y_, size_, label_, anchor_);
  215. //}
  216. //----------------------------------------------------------------------
  217. //----------------------------------------------------------------------
  218. void TrafficSource::reset(double) {
  219.   paint_ = Paint::instance()->thick();
  220. }
  221. //----------------------------------------------------------------------
  222. // void
  223. // TrafficSource::place()  
  224. //   - place the traffic source in relation to the agent  to 
  225. //     which it is attached.
  226. //----------------------------------------------------------------------
  227. void
  228. TrafficSource::place() {
  229.   if (previous_) {
  230.     placeNextTo(previous_);
  231.   } else {
  232.     placeOnAgent();
  233.   }
  234. }
  235. //----------------------------------------------------------------------
  236. // void 
  237. // TrafficSource::placeNextTo(TrafficSource * neighbor)
  238. //   - Place this traffic source to the right of its neighbor
  239. //----------------------------------------------------------------------
  240. void 
  241. TrafficSource::placeNextTo(TrafficSource * neighbor)  {
  242.   if (neighbor) {
  243.     x_ = neighbor->x() + neighbor->width(); 
  244.     y_ = neighbor->y(); 
  245.     update_bb();
  246.   }
  247. }
  248. //----------------------------------------------------------------------
  249. // void
  250. // TrafficSource::placeOnAgent() 
  251. //   - Place this traffic source on top of the Agent
  252. //----------------------------------------------------------------------
  253. void
  254. TrafficSource::placeOnAgent() { 
  255.   if (agent_) {
  256.     x_ = agent_->x();
  257.     y_ = agent_->y() + agent_->height(); // Agent scales it's height, 
  258.                                      // It's messy but works
  259.     update_bb();
  260.   }
  261. }
  262. //----------------------------------------------------------------------
  263. //----------------------------------------------------------------------
  264. const char* TrafficSource::info() const {
  265.   static char text[128];
  266.   sprintf(text, "TrafficSource: %s nAttached to Agent: %s-%d",
  267.                  label_, agent_->name(), agent_->number());
  268.   return (text);
  269. }
  270. //----------------------------------------------------------------------
  271. //----------------------------------------------------------------------
  272. double 
  273. TrafficSource::stopAt() {
  274. return timelist.lastStopTime();
  275. }
  276. //----------------------------------------------------------------------
  277. //----------------------------------------------------------------------
  278. const char* TrafficSource::getname() const
  279. {
  280.   static char text[128];
  281.   sprintf(text, "a %s", label_);
  282.   return (text);
  283. }
  284. //----------------------------------------------------------------------
  285. // int 
  286. // TrafficSource::inside(double, float px, float py) const 
  287. //   - Check to see if point (px, py) is within the Traffic Source box
  288. //----------------------------------------------------------------------
  289. int 
  290. TrafficSource::inside(double, float px, float py) const {
  291.   return (px >= x_ && 
  292.           px <= (x_ + width_) &&
  293.           py >= y_ && 
  294.           py <= (y_ + height_));
  295. }
  296. //----------------------------------------------------------------------
  297. // void
  298. // TrafficSource::draw(View * view, double ) const
  299. //   - Draw the Traffic Source on top of its parent agent and
  300. //     after the other traffic sources before it
  301. //----------------------------------------------------------------------
  302. void
  303. TrafficSource::draw(View * view, double time) {
  304. double label_width, label_height, label_x, label_y;
  305. int paint_color_id; 
  306. static char full_label[128];
  307. // Draw label centered inside of border
  308. if (label_) {
  309. //sprintf(full_label, "%s - %d", label_, number_);
  310. sprintf(full_label, "%s", label_);
  311. // We have to keep calculting the label width and height because
  312. // we have no way of knowing if the user has zoomed in or out 
  313. // on the current network view.
  314. label_height = 0.9 * height_;
  315. label_width = view->getStringWidth(full_label, label_height);
  316. // Add 10% of padding to width for the box
  317. setWidth(1.1 * label_width);
  318. // Center label in box
  319. label_x = x_ + (width_ - label_width);
  320. label_y = y_ + (height_ - label_height);
  321. view->string(full_label, label_x , label_y, label_height, NULL);
  322. update_bb();
  323. }
  324. // Draw Rectangle Border
  325. if (timelist.isOn(time)) {
  326. paint_color_id = Paint::instance()->lookup("darkgreen", 3);
  327. if (paint_color_id >= 0) {
  328. view->rect(x_, y_, x_ + width_, y_ + height_, paint_color_id);
  329. }
  330. } else {
  331. view->rect(x_, y_, x_ + width_, y_ + height_ , paint_);
  332. }
  333. }
  334. //----------------------------------------------------------------------
  335. // int
  336. // TrafficSource::writeNsDefinitionScript(FILE * file)
  337. //  - outputs ns script format for creating traffic sources
  338. //  - This only outputs the intialization part for the trafficsource
  339. //    and attaches it to the agent, more dynamic control of the 
  340. //    agent is outputed by int TrafficSource::writeNsActionScript
  341. //----------------------------------------------------------------------
  342. int
  343. TrafficSource::writeNsDefinitionScript(FILE * file) {
  344.   // CBR traffic source has a slightly different syntax
  345.   if (!strcmp(name(), "CBR")) {
  346.     fprintf(file, "set traffic_source(%d) [new Application/Traffic/%s]n",
  347.                    number_, label_);
  348.     fprintf(file, "$traffic_source(%d) attach-agent $agent(%d)n", 
  349.                    number_, agent_->number());
  350. //    fprintf(file, "$traffic_source(%d) set packetSize_ %dn",
  351. //                   number_, packet_size_);
  352.     fprintf(file, "$traffic_source(%d) set interval_ %fn",
  353.                    number_, interval_);
  354.   } else if (!strcmp(name(), "Exponential")) {
  355.     fprintf(file, "set traffic_source(%d) [new Application/Traffic/%s]n",
  356.                    number_, label_);
  357.     fprintf(file, "$traffic_source(%d) attach-agent $agent(%d)n", 
  358.                    number_, agent_->number());
  359. //    fprintf(file, "$traffic_source(%d) set packetSize_ %dn",
  360. //                   number_, packet_size_);
  361.     fprintf(file, "$traffic_source(%d) set burst_time_ %dmsn",
  362.                    number_, burst_time_);
  363.     fprintf(file, "$traffic_source(%d) set idle_time_ %dmsn",
  364.                    number_, idle_time_);
  365.     fprintf(file, "$traffic_source(%d) set rate_ %dkn",
  366.                    number_, rate_);
  367.   } else if (!strcmp(name(), "FTP")) {
  368.     fprintf(file, "set traffic_source(%d) [new Application/%s]n",
  369.                    number_, label_);
  370.     fprintf(file, "$traffic_source(%d) attach-agent $agent(%d)n", 
  371.                    number_, agent_->number());
  372.     fprintf(file, "$traffic_source(%d) set maxpkts_ %dn",
  373.                    number_, maxpkts_);
  374.   } else if (!strcmp(name(), "Pareto")) {
  375.     fprintf(file, "set traffic_source(%d) [new Application/Traffic/%s]n",
  376.                    number_, label_);
  377.     fprintf(file, "$traffic_source(%d) attach-agent $agent(%d)n", 
  378.                    number_, agent_->number());
  379. //    fprintf(file, "$traffic_source(%d) set packetSize_ %dn",
  380. //                   number_, packet_size_);
  381.     fprintf(file, "$traffic_source(%d) set burst_time_ %dmsn",
  382.                    number_, burst_time_);
  383.     fprintf(file, "$traffic_source(%d) set idle_time_ %dmsn",
  384.                    number_, idle_time_);
  385.     fprintf(file, "$traffic_source(%d) set rate_ %dkn",
  386.                    number_, rate_);
  387.     fprintf(file, "$traffic_source(%d) set shape_ %fn",
  388.                    number_, shape_);
  389.   } else if (!strcmp(name(), "Telnet")) {
  390.     fprintf(file, "set traffic_source(%d) [new Application/%s]n",
  391.                    number_, label_);
  392.     fprintf(file, "$traffic_source(%d) attach-agent $agent(%d)n", 
  393.                    number_, agent_->number());
  394.     fprintf(file, "$traffic_source(%d) set interval_ %fn",
  395.                    number_, interval_);
  396.   }
  397.                           
  398.   return 0;
  399. }
  400. //----------------------------------------------------------------------
  401. // int
  402. // TrafficSource::writeNsActionScript(FILE * file)
  403. //----------------------------------------------------------------------
  404. int
  405. TrafficSource::writeNsActionScript(FILE *file) {
  406. TimeElement * time;
  407. bool start = true;
  408. // if (!strcmp(name(), "CBR")) {
  409. for (time = timelist.head(); time; time = time->next_) {
  410. if (start) {
  411. fprintf(file, "$ns at %f "$traffic_source(%d) start"n",
  412. time->time_, number_);
  413. start = false;
  414. } else {
  415. fprintf(file, "$ns at %f "$traffic_source(%d) stop"nn",
  416. time->time_, number_);
  417. start = true;
  418. }
  419. }
  420. // } else if (!strcmp(name(), "FTP")) {
  421. // for (time = timelist.head(); time; time = time->next_) {
  422. // if (start) {
  423. // fprintf(file, "$ns at %f "$traffic_source(%d) start"n",
  424. // time->time_, number_);
  425. // start = false;
  426. // } else {
  427. // fprintf(file, "$ns at %f "$traffic_source(%d) stop"nn",
  428. // time->time_, number_);
  429. // start = true;
  430. // }
  431. // }
  432. // }
  433.   return 0;
  434. }
  435. //----------------------------------------------------------------------
  436. //
  437. //----------------------------------------------------------------------
  438. int TrafficSource::saveAsEnam(FILE *file) {
  439.   return 0;
  440. }
  441. //----------------------------------------------------------------------
  442. // TrafficSource::property()
  443. //   - return the list of traffic source configuration parameters
  444. //     (properties) to be shown in the property edit window
  445. //----------------------------------------------------------------------
  446. const char*
  447. TrafficSource::property() {
  448.   static char text[PROPERTY_STRING_LENGTH];
  449.   char timelist_string[200];
  450.   char * property_list;
  451.   int total_written = 0;
  452.   property_list = text;
  453.   total_written = sprintf(text,
  454.           "{"Traffic Source %s %d" title title "TrafficSource %d"} ",
  455.           name(), number_, number_);
  456.   property_list = &text[strlen(text)];
  457.   total_written += sprintf(property_list,
  458.                 "{"Agent %s" agent_name label  } ", agent_->name());
  459.   // ---- CBR -> Constant Bit Rate
  460.   if (strcmp(name(), "CBR") == 0) {
  461.     timelist.getListString(timelist_string, 200);
  462.     property_list = &text[strlen(text)];
  463.     total_written += sprintf(property_list,
  464.                             "{"Start/Stop Time" timelist timelist {%s}} ", 
  465.                             timelist_string);
  466.     property_list = &text[strlen(text)];
  467.     total_written += sprintf(property_list,
  468.                       "{"Interval" interval_ text %f} ", interval_);
  469.   // ---- Exponential
  470.   } else if (!strcmp(name(), "Exponential")) {  // strcmp returns 0 when equal
  471.     timelist.getListString(timelist_string, 200);
  472.     property_list = &text[strlen(text)];
  473.     total_written += sprintf(property_list,
  474.                             "{"Start/Stop Time" timelist timelist {%s}} ", 
  475.                             timelist_string);
  476. //    --- Why Packet size for both traffic generators and agents?
  477. //    property_list = &text[strlen(text)];
  478. //    total_written += sprintf(property_list,
  479. //                      "{"Interval" packet_size_ text %d} ", packet_size_);
  480.     property_list = &text[strlen(text)];
  481.     total_written += sprintf(property_list,
  482.                       "{"Burst Time (ms)" burst_time_ text %d} ", burst_time_);
  483.     property_list = &text[strlen(text)];
  484.     total_written += sprintf(property_list,
  485.                       "{"Idle Time (ms)" idle_time_ text %d} ", idle_time_);
  486.     property_list = &text[strlen(text)];
  487.     total_written += sprintf(property_list,
  488.                       "{"Rate (k)" rate_ text %d} ", rate_);
  489.   // ---- FTP
  490.   } else if (!strcmp(name(), "FTP")) {  // strcmp returns 0 when equal
  491.     timelist.getListString(timelist_string, 200);
  492.     property_list = &text[strlen(text)];
  493.     total_written += sprintf(property_list,
  494.                             "{"Start/Stop Time" timelist timelist {%s}} ", 
  495.                             timelist_string);
  496.     property_list = &text[strlen(text)];
  497.     total_written += sprintf(property_list,
  498.        "{"Maximum Number of Packets to Send" maxpkts_ text %d} ", maxpkts_);
  499.   
  500.   
  501.   // ---- Pareto
  502.   } else if (!strcmp(name(), "Pareto")) {  // strcmp returns 0 when equal
  503.     timelist.getListString(timelist_string, 200);
  504.     property_list = &text[strlen(text)];
  505.     total_written += sprintf(property_list,
  506.                             "{"Start/Stop Time" timelist timelist {%s}} ", 
  507.                             timelist_string);
  508. //    --- Why Packet size for both traffic generators and agents?
  509. //    property_list = &text[strlen(text)];
  510. //    total_written += sprintf(property_list,
  511. //                      "{"Interval" packet_size_ text %d} ", packet_size_);
  512.     property_list = &text[strlen(text)];
  513.     total_written += sprintf(property_list,
  514.                       "{"Burst Time (ms)" burst_time_ text %d} ", burst_time_);
  515.     property_list = &text[strlen(text)];
  516.     total_written += sprintf(property_list,
  517.                       "{"Idle Time (ms)" idle_time_ text %d} ", idle_time_);
  518.     property_list = &text[strlen(text)];
  519.     total_written += sprintf(property_list,
  520.                       "{"Rate (k)" rate_ text %d} ", rate_);
  521.     property_list = &text[strlen(text)];
  522.     total_written += sprintf(property_list,
  523.                       "{"Shape" shape_ text %f} ", shape_);
  524.   // ---- Telnet
  525.   } else if (!strcmp(name(), "Telnet")) {  // strcmp returns 0 when equal
  526.     timelist.getListString(timelist_string, 200);
  527.     property_list = &text[strlen(text)];
  528.     total_written += sprintf(property_list,
  529.                             "{"Start/Stop Time" timelist timelist {%s}} ", 
  530.                             timelist_string);
  531.     property_list = &text[strlen(text)];
  532.     total_written += sprintf(property_list,
  533.        "{"Exponetial Distribution Interval" interval_ text %f} ", interval_);
  534.   }
  535.   return(text);
  536. }
  537. //----------------------------------------------------------------------
  538. //----------------------------------------------------------------------
  539. TimeList::TimeList(double time) {
  540. head_ = NULL;
  541. add(time);
  542. }
  543. //----------------------------------------------------------------------
  544. // TimeList::~TimeList()
  545. //   - deletes the remaining part of the list
  546. //----------------------------------------------------------------------
  547. TimeList::~TimeList() {
  548. clear();
  549. }
  550. //----------------------------------------------------------------------
  551. // void
  552. // TimeList::clear() {
  553. //   - deletes all items on the list
  554. //----------------------------------------------------------------------
  555. void
  556. TimeList::clear() {
  557. TimeElement * run;
  558. for (run = head_->next_; run; run = run->next_) {
  559. delete head_;
  560. head_ = run;
  561. }
  562. if (head_) {
  563. delete head_;
  564. }
  565. head_ = NULL;
  566. }
  567. //----------------------------------------------------------------------
  568. // TimeList *
  569. // TimeList::add(double time) 
  570. //    - adds a new time value to the list which is 
  571. //      sorted in ascending order
  572. //----------------------------------------------------------------------
  573. void
  574. TimeList::add(double time) {
  575. TimeElement * new_time, * run, * previous;
  576. if (!head_) {
  577. // First element on list
  578. head_ = new TimeElement(time);
  579. } else {
  580. // Have to place down on list
  581. previous = NULL;
  582. run = head_;
  583. for (run = head_; run; run = run->next_) {
  584. if (time == run->time_) {
  585. // No duplicate times allowed
  586. break;
  587. } else if (time < run->time_) {
  588. if (previous) {
  589. // Place in middle of list
  590. new_time = new TimeElement(time);
  591. new_time->next_ = run;
  592. previous->next_ = new_time;
  593. } else {
  594. // Add to front of list
  595. new_time = new TimeElement(time);
  596. new_time->next_ = head_;
  597. head_ = new_time;
  598. }
  599. break;
  600. }
  601. previous = run;
  602. }
  603. if (!run) {
  604. // We ran to the end of the list and couldn't place
  605. // the new time so we have to place it at the end 
  606. previous->next_ = new TimeElement(time);
  607. }
  608. }
  609. }
  610. //----------------------------------------------------------------------
  611. // TimeList * 
  612. // TimeList::remove(double time)
  613. //    - removes time from the list 
  614. //----------------------------------------------------------------------
  615. void
  616. TimeList::remove(double time) {
  617. TimeElement * run, * previous;
  618. previous = NULL;
  619. for (run = head_; run; run = run->next_) {
  620. if (run->time_ == time) {
  621. if (previous) {
  622. previous->next_ = run->next_;
  623. delete run;
  624. } else {
  625. // Element is at the front of the list
  626. head_ = run->next_;
  627. }
  628. break;
  629. }
  630. previous = run;
  631. }
  632. }
  633. //----------------------------------------------------------------------
  634. //----------------------------------------------------------------------
  635. void
  636. TimeList::setList(const char * list_string) {
  637. const char *run;
  638. char *next;
  639. double time;
  640. // Erase all items on the list 
  641. clear();
  642. // Run down the list string and add values to the list
  643. run = list_string;
  644. while (run) {
  645. time = strtod(run, &next);
  646. if (run != next) {
  647. add(time);
  648. } else {
  649. break;
  650. }
  651. run = next;
  652. }
  653. }
  654. //----------------------------------------------------------------------
  655. // void 
  656. // TimeList::getListString(char * buffer, int buffer_size)
  657. //   - fills buffer with a space delimited list of all values on the
  658. //     time list sorted in ascending order
  659. //
  660. //   - the returned list should be freed when it is not needed anymore
  661. //----------------------------------------------------------------------
  662. void
  663. TimeList::getListString(char * buffer, int buffer_size) {
  664. int total_written, just_written;
  665. TimeElement * run;
  666. total_written = 1; // Need space for the /0 character
  667. for (run = head_; run; run = run->next_) {
  668. just_written = sprintf(buffer, 
  669. "%f ", run->time_);
  670. if (just_written == -1) {
  671. fprintf(stderr, "Ran out of buffer space when creating time list stringn");
  672. break;
  673. }
  674. //Advance buffer pointer past written characters
  675. buffer += just_written;
  676. total_written += just_written;
  677. }
  678. }
  679. //----------------------------------------------------------------------
  680. // bool
  681. // TimeList::isOn(double time)
  682. //   - checks the timelist to see if time falls between a
  683. //     start-stop period or a stop-start period
  684. //   - if it is start-stop the object should be on so it will return
  685. //     true.  Otherwise the object is off and will return false.
  686. //----------------------------------------------------------------------
  687. bool
  688. TimeList::isOn(double time) {
  689. TimeElement * element;
  690. bool on = false;
  691. for (element = head(); element; element = element->next_) {
  692. if (time < element->time_) {
  693. break;
  694. }
  695. if (on) {
  696. on = false;
  697. } else {
  698. on = true;
  699. }
  700. }
  701. return on;
  702. }
  703. //----------------------------------------------------------------------
  704. //
  705. //----------------------------------------------------------------------
  706. double
  707. TimeList::lastStopTime() {
  708. TimeElement * element;
  709. double stop_time = 0.0;
  710. bool start = true;
  711. for (element = head(); element; element = element->next_) {
  712. if (start) {
  713. start = false;
  714. } else {
  715. stop_time = element->time_;
  716. start = true;
  717. }
  718. }
  719. return stop_time;
  720. }
  721. //----------------------------------------------------------------------
  722. //----------------------------------------------------------------------
  723. TimeElement::TimeElement(double time) {
  724. next_ = NULL;
  725. time_ = time;
  726. }
  727. //----------------------------------------------------------------------
  728. //----------------------------------------------------------------------
  729. TimeElement::~TimeElement() {
  730. next_ = NULL;
  731. }