File indexing completed on 2026-04-09 07:49:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <iostream>
0022 #include <iomanip>
0023 #include <cstring>
0024 #include <cassert>
0025 #include <sstream>
0026
0027 #include "SDice.hh"
0028
0029 #include "SASCII.hh"
0030
0031
0032 const char SASCII::UPPER[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
0033 const char SASCII::LOWER[] = "abcdefghijklmnopqrstuvwxyz" ;
0034 const char SASCII::NUMBER[] = "0123456789" ;
0035 const char SASCII::OTHER[] = "_" ;
0036 const char SASCII::EXTRA[] = "-" ;
0037 const char SASCII::ALLOWED[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
0038 "abcdefghijklmnopqrstuvwxyz"
0039 "0123456789"
0040 "_"
0041 "-"
0042 ;
0043
0044
0045
0046 int SASCII::Index(const char* arr, int num, char s )
0047 {
0048 int idx = -1 ;
0049 for(int i=0 ; i < num ; i++ ) if(arr[i] == s) idx = i ;
0050 return idx ;
0051 }
0052
0053 int SASCII::LowerIndex(char s){ return Index(LOWER, sizeof(LOWER)/sizeof(char), s ) ; }
0054 int SASCII::UpperIndex(char s){ return Index(UPPER, sizeof(UPPER)/sizeof(char), s ) ; }
0055
0056
0057 char SASCII::ToUpper(char s )
0058 {
0059 int idx = LowerIndex(s) ;
0060 return idx == -1 ? s : UPPER[idx] ;
0061 }
0062 char SASCII::ToLower(char s )
0063 {
0064 int idx = UpperIndex(s) ;
0065 return idx == -1 ? s : LOWER[idx] ;
0066 }
0067 const char* SASCII::ToUpper( const char* str )
0068 {
0069 char* s = strdup(str);
0070 for(unsigned i=0 ; i < strlen(s) ; i++ ) s[i] = ToUpper(s[i] );
0071 return s ;
0072 }
0073 const char* SASCII::ToLower( const char* str )
0074 {
0075 char* s = strdup(str);
0076 for(unsigned i=0 ; i < strlen(s) ; i++ ) s[i] = ToLower(s[i] );
0077 return s ;
0078 }
0079
0080
0081
0082
0083 void SASCII::dump() const
0084 {
0085 unsigned num_upper = sizeof(UPPER)/sizeof(char) ;
0086 unsigned num_lower = sizeof(LOWER)/sizeof(char) ;
0087 unsigned num_number = sizeof(NUMBER)/sizeof(char) ;
0088 unsigned num_other = sizeof(OTHER)/sizeof(char) ;
0089
0090 std::cout << " num_upper " << num_upper << std::endl ;
0091 std::cout << " num_lower " << num_lower << std::endl ;
0092 std::cout << " num_number " << num_number << std::endl ;
0093 std::cout << " num_other " << num_other << std::endl ;
0094
0095 assert( num_upper == 26+1 );
0096 assert( num_lower == 26+1 );
0097 assert( num_number == 10+1 );
0098 assert( num_other == 1+1 );
0099
0100 SDice<26> rng ;
0101
0102 for(unsigned i=0 ; i < 100 ; i++ )
0103 {
0104 unsigned u = rng();
0105 char c = UPPER[u] ;
0106 std::cout
0107 << " i " << std::setw(4) << i
0108 << " u " << std::setw(4) << u
0109 << " c [" << std::setw(1) << c << "]"
0110 << std::endl
0111 ;
0112 }
0113
0114
0115 }
0116
0117
0118 unsigned SASCII::Count( char c, const char* list )
0119 {
0120 int count(0) ;
0121 for(unsigned i=0 ; i < strlen(list) ; i++ )
0122 {
0123 if(list[i] == c) count++ ;
0124 }
0125 return count ;
0126 }
0127
0128 bool SASCII::IsUpper( char c ){ return 1 == Count(c, UPPER) ; }
0129 bool SASCII::IsLower( char c ){ return 1 == Count(c, LOWER) ; }
0130 bool SASCII::IsNumber( char c ){ return 1 == Count(c, NUMBER) ; }
0131 bool SASCII::IsOther( char c ){ return 1 == Count(c, OTHER) ; }
0132 bool SASCII::IsExtra( char c ){ return 1 == Count(c, EXTRA) ; }
0133 bool SASCII::IsAllowed( char c ){ return 1 == Count(c, ALLOWED) ; }
0134
0135
0136 char SASCII::Classify( char c )
0137 {
0138 if(IsUpper(c)) return 'U' ;
0139 else if(IsLower(c)) return 'L' ;
0140 else if(IsNumber(c)) return 'N' ;
0141 else if(IsOther(c)) return 'O' ;
0142 else if(IsExtra(c)) return 'X' ;
0143 else return '?' ;
0144 }
0145
0146
0147
0148 void SASCII::DumpAllowed()
0149 {
0150 Dump(ALLOWED) ;
0151 }
0152
0153 void SASCII::Dump(const char* s)
0154 {
0155 char* p = strdup(s) ;
0156 while(*p)
0157 {
0158 int i = *p ;
0159 std::cout
0160 << std::setw(5) << *p
0161 << std::setw(5) << i
0162 << std::setw(5) << Classify(*p)
0163 << std::endl ;
0164 p++;
0165 }
0166 }
0167
0168
0169 SASCII::SASCII(const char* s_)
0170 :
0171 s(strdup(s_)),
0172 len(strlen(s)),
0173 upper(0),
0174 lower(0),
0175 number(0),
0176 other(0),
0177 extra(0),
0178 allowed(0),
0179 first_upper_index(-1),
0180 first_other_index(-1),
0181 first_extra_index(-1),
0182 first_number_index(-1)
0183 {
0184 init();
0185 }
0186
0187 void SASCII::init()
0188 {
0189 for(unsigned i=0 ; i < len ; i++)
0190 {
0191 char c = s[i];
0192 if(IsUpper(c)) upper++ ;
0193 if(IsLower(c)) lower++ ;
0194 if(IsNumber(c)) number++ ;
0195 if(IsOther(c)) other++ ;
0196 if(IsExtra(c)) extra++ ;
0197 if(IsAllowed(c)) allowed++ ;
0198
0199 if(IsUpper(c) && upper == 1) first_upper_index = int(i) ;
0200 if(IsNumber(c) && number == 1) first_number_index = int(i) ;
0201 if(IsOther(c) && other == 1) first_other_index = int(i) ;
0202 if(IsExtra(c) && extra == 1) first_extra_index = int(i) ;
0203 }
0204 assert( len == allowed );
0205 }
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216 std::string SASCII::getFirst(unsigned n) const
0217 {
0218 std::stringstream ss ;
0219 unsigned num(0);
0220 for(unsigned i=0 ; i < len ; i++)
0221 {
0222 char c = s[i];
0223 if(num < n)
0224 {
0225 ss << c ;
0226 num++ ;
0227 }
0228 }
0229 return ss.str();
0230 }
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 std::string SASCII::getFirstUpper(unsigned n) const
0243 {
0244 std::stringstream ss ;
0245 unsigned num(0);
0246 for(unsigned i=0 ; i < len ; i++)
0247 {
0248 char c = s[i];
0249 if(IsUpper(c) && num < n)
0250 {
0251 ss << c ;
0252 num++ ;
0253 }
0254 }
0255 return ss.str();
0256 }
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266 std::string SASCII::getFirstLast() const
0267 {
0268 std::stringstream ss ;
0269 ss << s[0] ;
0270 ss << s[len-1] ;
0271 return ss.str();
0272 }
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283 std::string SASCII::getTwoChar(unsigned first, unsigned second) const
0284 {
0285 std::stringstream ss ;
0286 for(unsigned i=0 ; i < len ; i++)
0287 {
0288 char c = s[i];
0289 if( i == first ) ss << c ;
0290 if( i == second ) ss << c ;
0291 }
0292 return ss.str();
0293 }
0294
0295
0296 std::string SASCII::getTwoRandom(SDice<26>& rng ) const
0297 {
0298 std::stringstream ss ;
0299 unsigned u0 = rng();
0300 unsigned u1 = rng();
0301 ss << UPPER[u0] << UPPER[u1] ;
0302 return ss.str() ;
0303 }
0304
0305
0306