• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

yapet/pwgen/charpool.cc

Go to the documentation of this file.
00001 // $Id: charpool.cc 3343 2010-09-17 18:36:31Z java $
00002 //
00003 // Copyright (C) 2009-2010  Rafael Ostertag
00004 //
00005 // This file is part of YAPET.
00006 //
00007 // YAPET is free software: you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the Free Software
00009 // Foundation, either version 3 of the License, or (at your option) any later
00010 // version.
00011 //
00012 // YAPET is distributed in the hope that it will be useful, but WITHOUT ANY
00013 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 // FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00015 // details.
00016 //
00017 // You should have received a copy of the GNU General Public License along with
00018 // YAPET.  If not, see <http://www.gnu.org/licenses/>.
00019 //
00020 
00021 #ifdef HAVE_CONFIG_H
00022 # include <config.h>
00023 #endif
00024 
00025 #ifdef HAVE_STRING_H
00026 # include <string.h>
00027 #endif
00028 
00029 #if defined(DEBUG) && defined(HAVE_IOSTREAM)
00030 # include <iostream>
00031 #endif
00032 
00033 #include "../../intl.h"
00034 
00035 #include "charpool.h"
00036 
00037 using namespace YAPET::PWGEN;
00038 
00039 const char CharacterPool::letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
00040 const char CharacterPool::digits[] = "0123456789";
00041 const char CharacterPool::punct[] = ".,;:-!?'";
00042 const char CharacterPool::special[] = "_+\"*%&/()[]={}<>";
00043 const char CharacterPool::other[] = "§°@#\\|$£~`^";
00044 
00045 inline const char* CharacterPool::get_letters() {
00046     return letters;
00047 }
00048 inline const char* CharacterPool::get_digits() {
00049     return digits;
00050 }
00051 inline const char* CharacterPool::get_punct() {
00052     return punct;
00053 }
00054 inline const char* CharacterPool::get_special() {
00055     return special;
00056 }
00057 inline const char* CharacterPool::get_other() {
00058     return other;
00059 }
00060 
00061 void
00062 CharacterPool::init (int p) throw (std::runtime_error) {
00063     if (p == 0)
00064         throw std::runtime_error (_ ("Subpools may not be zero") );
00065 
00066     for (int i=LETTERS; i <= OTHER; i = i << 1) {
00067     if (isPoolAllocated((SUBPOOLS)i))
00068         pool_length += pool_len((SUBPOOLS)i);
00069     }
00070 
00071     pool = new char[pool_length];
00072 #ifdef DEBUG
00073     assert (pool != NULL);
00074 #else
00075 
00076     if (pool == NULL) {
00077         // Good luck!
00078         throw std::runtime_error (_ ("Out of memory") );
00079     }
00080 
00081 #endif
00082     size_t copy_pos = 0;
00083 
00084     //
00085     //
00086     //
00087     //               .::!! HEY YOU WITH THE EDITOR !!::.
00088     //
00089     // Do not carelessly change the order of allocation of the pools. The
00090     // operator[] and getPoolPos() rely on the exact order to calculate which
00091     // pools have been read so far.
00092     //
00093     //
00094     //
00095     if  (isPoolAllocated(LETTERS)) {
00096         memcpy ( (void*) (pool + copy_pos), (void*) letters, pool_letters_len() );
00097         copy_pos += pool_letters_len();
00098     }
00099 
00100     if  (isPoolAllocated(DIGITS)) {
00101         memcpy ( (void*) (pool + copy_pos), (void*) digits, pool_digits_len() );
00102         copy_pos += pool_digits_len();
00103     }
00104 
00105     if  (isPoolAllocated(PUNCT)) {
00106         memcpy ( (void*) (pool + copy_pos), (void*) punct, pool_punct_len() );
00107         copy_pos += pool_punct_len();
00108     }
00109 
00110     if  (isPoolAllocated(SPECIAL)) {
00111         memcpy ( (void*) (pool + copy_pos), (void*) special, pool_special_len() );
00112         copy_pos += pool_special_len();
00113     }
00114 
00115     if  (isPoolAllocated(OTHER)) {
00116         memcpy ( (void*) (pool + copy_pos), (void*) other, pool_other_len() );
00117         copy_pos += pool_other_len();
00118     }
00119 
00120     assert (copy_pos == pool_length);
00121 }
00122 
00123 CharacterPool::CharacterPool (int p)  throw (std::runtime_error) : pool (NULL),
00124                                    pool_length (0),
00125                                    pools_allocated (p),
00126                                    pools_reads(0)
00127 {
00128     init (p);
00129 }
00130 
00131 CharacterPool::CharacterPool (SUBPOOLS p)  throw (std::runtime_error) : pool (NULL),
00132                                     pool_length (0),
00133                                     pools_allocated (p),
00134                                     pools_reads(0)
00135 {
00136     init (p);
00137 }
00138 
00139 CharacterPool::~CharacterPool() throw() {
00140     assert (pool != NULL);
00141     delete[] pool;
00142 }
00143 
00144 //
00145 // Copy constructor
00146 //
00147 CharacterPool::CharacterPool (const CharacterPool& cp) throw (std::runtime_error) :     pool (NULL),
00148         pool_length (cp.pool_length),
00149                                             pools_allocated (cp.pools_allocated),
00150                                             pools_reads (cp.pools_reads) {
00151     assert (cp.pool != NULL);
00152     assert (cp.pool_length > 0);
00153     pool = new char[pool_length];
00154 #ifdef DEBUG
00155     assert (pool != NULL);
00156 #else
00157 
00158     if (pool == NULL) {
00159         // Good luck!
00160         throw std::runtime_error (_ ("Out of memory") );
00161     }
00162 
00163 #endif
00164     memcpy ( (void*) pool, (void*) cp.pool, pool_length);
00165 }
00166 
00167 int
00168 CharacterPool::numPoolsAllocated() const {
00169     int tmp=0;
00170     for (int i=LETTERS; i<=OTHER; i=i<<1)
00171     if (isPoolAllocated((SUBPOOLS)i))
00172         tmp++;
00173 
00174     return tmp;
00175 }
00176 
00177 int
00178 CharacterPool::numPoolsNotRead() const {
00179     int retval = 0;
00180     
00181     for (int i=LETTERS; i <= OTHER; i = i << 1)
00182     if ( isPoolAllocated((SUBPOOLS)i) &&
00183          ! hadPoolReads((SUBPOOLS)i) )
00184         retval++;
00185 
00186     return retval;
00187 }
00188 
00203 size_t
00204 CharacterPool::getPoolPos(SUBPOOLS p, size_t* start) const {
00205     if (start == NULL)
00206     return 0;
00207 
00208     if (!isPoolAllocated(p)) {
00209     *start=0;
00210     return 0;
00211     }
00212 
00213     *start = 0;
00214     int i = 0;
00215     for (i=LETTERS; i < p; i = i<<1) {
00216     if (isPoolAllocated((SUBPOOLS)i) ) {
00217         (*start)+=pool_len((SUBPOOLS)i);
00218         
00219     }
00220     }
00221     return pool_len((SUBPOOLS)i);
00222 }
00223 
00224 SUBPOOLS
00225 CharacterPool::fromPool(char c) const {
00226     if (strchr(letters, c))
00227     return LETTERS;
00228     if (strchr(digits, c))
00229     return DIGITS;
00230     if (strchr(punct, c))
00231     return PUNCT;
00232     if (strchr(special, c))
00233     return SPECIAL;
00234     if (strchr(other, c))
00235     return OTHER;
00236     assert(0);
00237     return NOPOOL;
00238 }
00239 
00249 char
00250 CharacterPool::operator[] (size_t pos) throw (std::logic_error) {
00251     if (pos >= pool_length)
00252         throw std::out_of_range (_ ("No character at given position") );
00253 
00254     // Update the pools_reads variable. This relies on the knowledge of the
00255     // order we internally allocate pools
00256     for (int i=LETTERS; i <= OTHER; i = i<<1) {
00257     if (isPoolAllocated((SUBPOOLS)i)) {
00258         size_t start;
00259         size_t len = getPoolPos((SUBPOOLS)i, &start);
00260 
00261         if (start<=pos && 
00262         (start+len) > pos)
00263         pools_reads |= i;
00264     }
00265     }
00266     // Finished updating pools_reads.
00267 
00268     return pool[pos];
00269 }
00270 
00271 const CharacterPool&
00272 CharacterPool::operator= (const CharacterPool & cp) throw (std::runtime_error) {
00273     assert (pool != NULL);
00274 
00275     if (&cp == this) return *this;
00276 
00277     delete[] pool;
00278     //CharacterPool::CharacterPool(cp);
00279     assert (cp.pool_length > 0);
00280     pool_length = cp.pool_length;
00281     pools_allocated = cp.pools_allocated;
00282     pools_reads = cp.pools_reads;
00283     pool = new char[pool_length];
00284 #ifdef DEBUG
00285     assert (pool != NULL);
00286 #else
00287 
00288     if (pool == NULL) {
00289         // Good luck!
00290         throw std::runtime_error (_ ("Out of memory") );
00291     }
00292 
00293 #endif
00294     memcpy ( (void*) pool, (void*) cp.pool, pool_length);
00295     return *this;
00296 }
00297 
00298 #ifdef DEBUG
00299 int
00300 CharacterPool::print_pools_allocated() const {
00301     // Used to count the pools used
00302     int tmp = 0;
00303     if  (pools_allocated & LETTERS) {
00304         std::cout << "LETTERS (" << LETTERS << ")" << std::endl;
00305     tmp++;
00306     }
00307 
00308     if  (pools_allocated & DIGITS) {
00309         std::cout << "DIGITS (" << DIGITS << ")" << std::endl;
00310     tmp++;
00311     }
00312 
00313     if  (pools_allocated & PUNCT) {
00314         std::cout << "PUNCT (" << PUNCT << ")" << std::endl;
00315     tmp++;
00316     }
00317 
00318     if  (pools_allocated & SPECIAL) {
00319         std::cout << "SPECIAL (" << SPECIAL << ")" << std::endl;
00320     tmp++;
00321     }
00322 
00323     if  (pools_allocated & OTHER) {
00324         std::cout << "OTHER (" << OTHER << ")" << std::endl;
00325     tmp++;
00326     }
00327     assert(tmp == numPoolsAllocated());
00328     return tmp;
00329 }
00330 #endif

Generated on Sun Sep 19 2010 15:37:14 for YAPET by  doxygen 1.7.1