1 /*****************************************************************************\
3 * Name : span_manager *
4 * Author : Chris Koeritz *
6 *******************************************************************************
7 * Copyright (c) 1990-$now By Author. This program is free software; you can *
8 * redistribute it and/or modify it under the terms of the GNU General Public *
9 * License as published by the Free Software Foundation; either version 2 of *
10 * the License or (at your option) any later version. This is online at: *
11 * http://www.fsf.org/copyleft/gpl.html *
12 * Please send any updates to: fred@gruntose.com *
13 \*****************************************************************************/
15 #include "span_manager.h"
17 #include <basis/functions.h>
18 #include <basis/guards.h>
19 #include <basis/astring.h>
20 #include <structures/bit_vector.h>
21 #include <structures/set.h>
23 using namespace basis;
24 using namespace structures;
25 //using namespace basis;
29 span_manager::span_manager(int packs)
30 : _implementation(new bit_vector(packs))
33 span_manager::span_manager(const span_manager &to_copy)
34 : _implementation(new bit_vector(*to_copy._implementation))
37 span_manager::~span_manager() { WHACK(_implementation); }
39 span_manager &span_manager::operator =(const span_manager &to_copy)
41 if (this == &to_copy) return *this;
42 *_implementation = *to_copy._implementation;
46 int span_manager::missing_sequence() const
47 { return _implementation->find_first(0); }
49 void span_manager::reset(int packs) { _implementation->resize(packs); }
51 const bit_vector &span_manager::vector() const { return *_implementation; }
53 bit_vector &span_manager::vector() { return *_implementation; }
55 int span_manager::received_sequence() const
57 int recd_to = _implementation->find_first(0);
58 if (negative(recd_to)) return _implementation->bits() - 1;
62 void span_manager::make_received_list(int_array &to_make, int max_spans) const
65 int zeros_start_at = _implementation->find_first(0);
66 if (negative(zeros_start_at)) {
67 // all bits are set in the vector, so the whole message is received.
68 to_make.concatenate(0);
69 to_make.concatenate(short(_implementation->bits() - 1));
73 // the sequence of ones ends right before the first zero
74 if (zeros_start_at >= 0) {
75 to_make.concatenate(0);
76 to_make.concatenate(short(zeros_start_at));
79 int ones_to_here; // keeps track of the position of the ones.
81 for (int outer_loop = zeros_start_at + 2;
82 outer_loop < _implementation->bits(); ) {
83 // the first zero is zeros_start_at + 1, so we start at the first
85 if (_implementation->on(outer_loop)) {
86 // the bit is a one, so we are in a one-gathering mode.
87 ones_to_here = outer_loop;
88 int inner_loop = outer_loop + 1;
89 while (inner_loop < _implementation->bits()) {
90 if (_implementation->on(inner_loop)) ones_to_here=inner_loop;
91 else break; // a zero is found at this position, so leave loop.
94 // the stretch of ones is entered in the array.
95 to_make.concatenate(short(outer_loop));
96 to_make.concatenate(short(ones_to_here));
97 if ( (max_spans >= 0) && (to_make.length() >= 2 * max_spans) )
99 outer_loop = ones_to_here + 1;
101 // the bit is a zero, so we are gathering zeros.
102 int inner_loop = outer_loop + 1;
103 ones_to_here = _implementation->bits();
104 while (inner_loop < _implementation->bits()) {
105 if (!_implementation->on(inner_loop)) inner_loop++;
107 // ones_to_here is set to the first position of a one, actually.
108 ones_to_here = inner_loop;
112 // the loop variable is set to the first unknown position again.
113 outer_loop = ones_to_here;
118 bool span_manager::update(const int_array &new_spans)
120 for (int i = 0; i < new_spans.length(); i += 2) {
121 if ( (new_spans.get(i) >= _implementation->bits())
122 || (new_spans.get(i+1) >= _implementation->bits()) )
124 for (int j = new_spans.get(i); j <= new_spans.get(i+1); j++)
125 _implementation->light(j);
130 void span_manager::make_missing_list(int_array &to_make, int max_spans) const
133 int ones_start_at = _implementation->find_first(1);
134 if (negative(ones_start_at)) {
135 // all bits are zero in the vector; no packets have been received.
136 to_make.concatenate(0);
137 to_make.concatenate(short(_implementation->bits() - 1));
141 // the sequence of zeros ends right before the first one
142 if (ones_start_at >= 0) {
143 to_make.concatenate(0);
144 to_make.concatenate(short(ones_start_at));
148 for (int outer_loop = ones_start_at + 2;
149 outer_loop < _implementation->bits(); ) {
151 // the first one is ones_start_at+1, so we start at the first unknown bit
152 if (!_implementation->on(outer_loop)) {
153 // the bit is a zero, so we are in a zero-gathering mode.
154 zeros_to_here = outer_loop;
155 int inner_loop = outer_loop + 1;
156 while (inner_loop < _implementation->bits()) {
157 if (!_implementation->on(inner_loop)) zeros_to_here=inner_loop;
159 // a one is found at this position, so leave loop.
162 // the stretch of zeros is entered in the array.
163 to_make.concatenate(short(outer_loop));
164 to_make.concatenate(short(zeros_to_here));
165 if ( (max_spans >= 0) && (to_make.length() >= 2 * max_spans) ) return;
166 outer_loop = zeros_to_here + 1;
168 // the bit is a one, so we are gathering ones.
169 inner_loop = outer_loop + 1;
170 zeros_to_here = _implementation->bits();
171 while (inner_loop < _implementation->bits()) {
172 if (_implementation->on(inner_loop))
175 // zeros_to_here is set to the first position of a zero, actually.
176 zeros_to_here = inner_loop;
180 // the loop variable is set to the first unknown position again.
181 outer_loop = zeros_to_here;
186 astring span_manager::funky_print(const int_array &to_spew, int rec_seq) const
188 astring to_return(astring::SPRINTF, "through %d, [", rec_seq);
189 for (int i = 0; i < to_spew.length(); i += 2) {
190 to_return += astring(astring::SPRINTF, " %d-%d", to_spew.get(i),
193 to_return += astring(" ] ");
197 astring span_manager::print_received_list() const
200 make_received_list(hold_info);
201 astring to_return("received ");
202 to_return += funky_print(hold_info, received_sequence());
206 astring span_manager::print_missing_list() const
209 make_missing_list(hold_info);
210 astring to_return("missing ");
211 to_return += funky_print(hold_info, received_sequence());