Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00078 throw std::runtime_error (_ ("Out of memory") );
00079 }
00080
00081 #endif
00082 size_t copy_pos = 0;
00083
00084
00085
00086
00087
00088
00089
00090
00091
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
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
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
00255
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
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
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
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
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