Counters.cpp

Go to the documentation of this file.
00001 /* vim: set ts=4 expandtab shiftwidth=4: */
00002 
00003 /******************************************************************************
00004 
00005     Copyright 2005 Digital Aggregates Corp., Arvada CO 80001-0587, USA.
00006     This file is part of the Digital Aggregates Desperado library.
00007     
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Lesser General Public
00010     License as published by the Free Software Foundation; either
00011     version 2.1 of the License, or (at your option) any later version.
00012 
00013     As a special exception, if other files instantiate templates or
00014     use macros or inline functions from this file, or you compile
00015     this file and link it with other works to produce a work based on
00016     this file, this file does not by itself cause the resulting work
00017     to be covered by the GNU Lesser General Public License. However
00018     the source code for this file must still be made available in
00019     accordance with the GNU Lesser General Public License.
00020 
00021     This exception does not invalidate any other reasons why a work
00022     based on this file might be covered by the GNU Lesser General
00023     Public License.
00024 
00025     Alternative commercial licensing terms are available from the copyright
00026     holder. Contact Digital Aggregates Corporation for more information.
00027 
00028     This library is distributed in the hope that it will be useful,
00029     but WITHOUT ANY WARRANTY; without even the implied warranty of
00030     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00031     GNU Lesser General Public License for more details.
00032 
00033     You should have received a copy of the GNU Lesser General
00034     Public License along with this library; if not, write to the
00035     Free Software Foundation, Inc., 59 Temple Place, Suite 330,
00036     Boston, MA 02111-1307 USA, or http://www.gnu.org/copyleft/lesser.txt.
00037 
00038     $Name:  $
00039 
00040     $Id: Counters.cpp,v 1.7 2006/09/04 13:49:56 jsloan Exp $
00041 
00042 ******************************************************************************/
00043 
00044 
00060 #include <new>
00061 #include "stdio.h"
00062 #include "target.h"
00063 #include "string.h"
00064 #include "Counters.h"
00065 #include "Print.h"
00066 #include "Platform.h"
00067 
00068 
00069 //
00070 //  Constructor.
00071 //
00072 Counters::Counters(
00073     size_t ncounters,
00074     Counter* vcounters,
00075     const char** vlabels
00076 ) :
00077     countersn(((0 == ncounters) || (0 == vcounters)) ? 0 : ncounters),
00078     countersv(((0 == ncounters) || (0 == vcounters)) ? 0 : vcounters),
00079     labelsv(  ((0 == ncounters) || (0 == vcounters)) ? 0 : vlabels  )
00080 {
00081 }
00082 
00083 
00084 //
00085 //  Destructor.
00086 //
00087 Counters::~Counters() {
00088 }
00089 
00090 
00091 //
00092 //    Initializer.
00093 //
00094 bool Counters::initialize(
00095     size_t ncounters,
00096     Counter* vcounters,
00097     const char** vlabels
00098 ) {
00099     bool rc = false;
00100     try {
00101         this->Counters::~Counters();
00102         new(this) Counters(ncounters, vcounters, vlabels);
00103         rc = true;
00104     } catch (...) {
00105         rc = false;
00106     }
00107     return rc;
00108 }
00109 
00110 
00111 //
00112 //  Reset all counters to a value.
00113 //
00114 void Counters::reset(Counter value) {
00115     if (0 != this->countersv) {
00116         for (unsigned int index = 0; index < this->countersn; ++index) {
00117             this->countersv[index] = value;
00118         }
00119     }
00120 }
00121 
00122 
00123 //
00124 //  Generate a usable label for a counter identified by its index.
00125 //
00126 const char* Counters::generate(unsigned int index, Label buffer) const {
00127     const char* result;
00128 
00129     if ((0 != this->labelsv) && (0 != this->labelsv[index])) {
00130         result = this->labelsv[index];
00131     } else {
00132         std::sprintf(static_cast<char*>(buffer), "N%010u", index);
00133         result = buffer;
00134     }
00135 
00136     return result;
00137 }
00138 
00139 
00140 //
00141 // Apply a functor to all counters.
00142 //
00143 bool Counters::apply(Functor& functor) {
00144     Label label;
00145 
00146     for (unsigned int index = 0; index < this->countersn; ++index) {
00147         if (!functor(
00148             index,
00149             this->generate(index, label),
00150             this->countersv[index]
00151         )){
00152             return false;
00153         }
00154     }
00155 
00156     return true;
00157 }
00158 
00159 
00160 //
00161 // Format a counter for output.
00162 //
00163 const char* Counters::format(unsigned int index, Label buffer) const {
00164     if (0 < this->countersv[index]) {
00165         ::snprintf(buffer, sizeof(Label), "%11d", this->countersv[index]);
00166     } else {
00167         std::memset(buffer, ' ', sizeof(Label) - 1);
00168         buffer[sizeof(Label) - 2] = '.';
00169         buffer[sizeof(Label) - 1] = '\0';
00170     }
00171     return buffer;
00172 }
00173 
00174 
00175 //
00176 //  Show this object on the output object.
00177 //
00178 void Counters::show(int level, Output* display, int indent) const {
00179     Platform& pl = Platform::instance();
00180     Print printf(display);
00181     const char* sp = printf.output().indentation(indent);
00182 
00183     if (0 == level) {
00184         char component[sizeof(__FILE__)];
00185         printf("%s%s(%p)[%lu]:\n",
00186             sp, pl.component(__FILE__, component, sizeof(component)),
00187             this, sizeof(*this));
00188         printf("%s countersn=%lu\n", sp, this->countersn);
00189         printf("%s countersv=%p\n", sp, this->countersv);
00190         printf("%s labelsv=%p\n", sp, this->countersv);
00191         return;
00192     }
00193 
00194     if (0 == this->countersn) {
00195         return;
00196     }
00197 
00198     //
00199     //  Print labels.
00200     //
00201 
00202     Label label[5];
00203     size_t remaining = (0 != this->labelsv) ? this->countersn : 0;
00204     unsigned int index = 0;
00205 
00206     while (remaining > 0) {
00207     
00208         if (remaining >= 5) {
00209 
00210             printf(
00211                 "%s%11.11s %11.11s %11.11s %11.11s %11.11s [%d..%d]\n",
00212                 sp,
00213                 this->generate(index + 0, label[0]),
00214                 this->generate(index + 1, label[1]),
00215                 this->generate(index + 2, label[2]),
00216                 this->generate(index + 3, label[3]),
00217                 this->generate(index + 4, label[4]),
00218                 index + 0, index + 4);
00219 
00220             index += 5;
00221             remaining -= 5;
00222     
00223         } else if (remaining >= 4) {
00224 
00225             printf(
00226                 "%s%11.11s %11.11s %11.11s %11.11s %11.11s [%d..%d]\n",
00227                 sp,
00228                 this->generate(index + 0, label[0]),
00229                 this->generate(index + 1, label[1]),
00230                 this->generate(index + 2, label[2]),
00231                 this->generate(index + 3, label[3]),
00232                 "",
00233                 index + 0, index + 3);
00234 
00235             index += 4;
00236             remaining -= 4;
00237         
00238         } else if (remaining >= 3) {
00239 
00240             printf(
00241                 "%s%11.11s %11.11s %11.11s %11.11s %11.11s [%d..%d]\n",
00242                 sp,
00243                 this->generate(index + 0, label[0]),
00244                 this->generate(index + 1, label[1]),
00245                 this->generate(index + 2, label[2]),
00246                 "",
00247                 "",
00248                 index + 0, index + 2);
00249 
00250             index += 3;
00251             remaining -= 3;
00252         
00253         } else if (remaining == 2) {
00254     
00255             printf(
00256                 "%s%11.11s %11.11s %11.11s %11.11s %11.11s [%d..%d]\n",
00257                 sp,
00258                 this->generate(index + 0, label[0]),
00259                 this->generate(index + 1, label[1]),
00260                 "",
00261                 "",
00262                 "",
00263                 index + 0, index + 1);
00264 
00265             index += 2;
00266             remaining -= 2;
00267         
00268         } else {
00269 
00270             printf(
00271                 "%s%11.11s %11.11s %11.11s %11.11s %11.11s [%d..%d]\n",
00272                 sp,
00273                 this->generate(index + 0, label[0]),
00274                 "",
00275                 "",
00276                 "",
00277                 "",
00278                 index + 0, index + 0);
00279 
00280             index += 1;
00281             remaining -= 1;
00282         
00283         }
00284 
00285     }
00286 
00287     //
00288     //  Print values.
00289     //
00290 
00291     remaining = this->countersn;
00292     index = 0;
00293     
00294     while (remaining > 0) {
00295 
00296         if (remaining >= 5) {
00297 
00298             printf("%s%11.11s %11.11s %11.11s %11.11s %11.11s [%d..%d]\n",
00299                 sp,
00300                 this->format(index + 0, label[0]),
00301                 this->format(index + 1, label[1]),
00302                 this->format(index + 2, label[2]),
00303                 this->format(index + 3, label[3]),
00304                 this->format(index + 4, label[4]),
00305                 index + 0, index + 4);
00306 
00307             index += 5;
00308             remaining -= 5;
00309 
00310         } else if (remaining >= 4) {
00311 
00312             printf("%s%11.11s %11.11s %11.11s %11.11s %11.11s [%d..%d]\n",
00313                 sp,
00314                 this->format(index + 0, label[0]),
00315                 this->format(index + 1, label[1]),
00316                 this->format(index + 2, label[2]),
00317                 this->format(index + 3, label[3]),
00318                 "",
00319                 index + 0, index + 3);
00320 
00321             index += 4;
00322             remaining -= 4;
00323     
00324         } else if (remaining >= 3) {
00325 
00326             printf("%s%11.11s %11.11s %11.11s %11.11s %11.11s [%d..%d]\n",
00327                 sp,
00328                 this->format(index + 0, label[0]),
00329                 this->format(index + 1, label[1]),
00330                 this->format(index + 2, label[2]),
00331                 "",
00332                 "",
00333                 index + 0, index + 2);
00334 
00335             index += 3;
00336             remaining -= 3;
00337     
00338         } else if (remaining == 2) {
00339 
00340             printf("%s%11.11s %11.11s %11.11s %11.11s %11.11s [%d..%d]\n",
00341                 sp,
00342                 this->format(index + 0, label[0]),
00343                 this->format(index + 1, label[1]),
00344                 "",
00345                 "",
00346                 "",
00347                 index + 0, index + 1);
00348 
00349             index += 2;
00350             remaining -= 2;
00351     
00352         } else {
00353 
00354             printf("%s%11.11s %11.11s %11.11s %11.11s %11.11s [%d..%d]\n",
00355                 sp,
00356                 this->format(index + 0, label[0]),
00357                 "",
00358                 "",
00359                 "",
00360                 "",
00361                 index + 0, index + 0);
00362 
00363             index += 1;
00364             remaining -= 1;
00365     
00366         }
00367     
00368     }
00369 
00370 }
00371 
00372 
00373 
00374 //
00375 //  Virtual destructor for Functor.
00376 //
00377 Counters::Functor::~Functor() {
00378 }
Copyright © 2006 Digital Aggregates Corp., Arvada CO 80001-0587, USA.
Distributed under the terms of the GNU Free Documentation License.
http://www.diag.com/navigation/downloads/Desperado.html