1 //============================================================================ 2 // 3 // SSSS tt lll lll 4 // SS SS tt ll ll 5 // SS tttttt eeee ll ll aaaa 6 // SSSS tt ee ee ll ll aa 7 // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" 8 // SS SS tt ee ll ll aa aa 9 // SSSS ttt eeeee llll llll aaaaa 10 // 11 // Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony 12 // and the Stella Team 13 // 14 // See the file "License.txt" for information on usage and redistribution of 15 // this file, and for a DISCLAIMER OF ALL WARRANTIES. 16 //============================================================================ 17 18 #ifndef BASE_HXX 19 #define BASE_HXX 20 21 #include <iostream> 22 #include <iomanip> 23 24 #include "bspf.hxx" 25 26 namespace Common { 27 28 /** 29 This class implements several functions for converting integer data 30 into strings in multiple bases, with different formats (# of characters, 31 upper/lower-case, etc). 32 33 @author Stephen Anthony 34 */ 35 class Base 36 { 37 public: 38 // The base to use for conversion from integers to strings 39 // Note that the actual number of places will be determined by 40 // the magnitude of the value itself in the general case 41 enum class Fmt { 42 _16, // base 16: 2, 4, 8 bytes (depending on value) 43 _16_1, // base 16: 1 byte wide 44 _16_2, // base 16: 2 bytes wide 45 _16_2_2, // base 16: fractional value shown as xx.xx 46 _16_3_2, // base 16: fractional value shown as xxx.xx 47 _16_4, // base 16: 4 bytes wide 48 _16_8, // base 16: 8 bytes wide 49 _10, // base 10: 3 or 5 bytes (depending on value) 50 _10_02, // base 10: 02 digits 51 _10_3, // base 10: 3 digits 52 _10_4, // base 10: 4 digits 53 _10_5, // base 10: 5 digits 54 _10_6, // base 10: 6 digits 55 _10_8, // base 10: 8 digits 56 _2, // base 2: 8 or 16 bits (depending on value) 57 _2_8, // base 2: 1 byte (8 bits) wide 58 _2_16, // base 2: 2 bytes (16 bits) wide 59 _DEFAULT 60 }; 61 62 public: 63 /** Get/set the number base when parsing numeric values */ setFormat(Base::Fmt base)64 static void setFormat(Base::Fmt base) { myDefaultBase = base; } format()65 static Base::Fmt format() { return myDefaultBase; } 66 67 /** Get/set HEX output to be upper/lower case */ setHexUppercase(bool enable)68 static void setHexUppercase(bool enable) { 69 if(enable) myHexflags |= std::ios_base::uppercase; 70 else myHexflags &= ~std::ios_base::uppercase; 71 } hexUppercase()72 static bool hexUppercase() { return myHexflags & std::ios_base::uppercase; } 73 74 /** Output HEX digits in 0.5/1/2/4 byte format */ HEX1(std::ostream & os)75 static inline std::ostream& HEX1(std::ostream& os) { 76 os.flags(myHexflags); 77 return os << std::setw(1); 78 } HEX2(std::ostream & os)79 static inline std::ostream& HEX2(std::ostream& os) { 80 os.flags(myHexflags); 81 return os << std::setw(2) << std::setfill('0'); 82 } HEX3(std::ostream & os)83 static inline std::ostream& HEX3(std::ostream& os) 84 { 85 os.flags(myHexflags); 86 return os << std::setw(3) << std::setfill('0'); 87 } HEX4(std::ostream & os)88 static inline std::ostream& HEX4(std::ostream& os) { 89 os.flags(myHexflags); 90 return os << std::setw(4) << std::setfill('0'); 91 } HEX8(std::ostream & os)92 static inline std::ostream& HEX8(std::ostream& os) { 93 os.flags(myHexflags); 94 return os << std::setw(8) << std::setfill('0'); 95 } 96 97 /** Convert integer to a string in the given base format */ 98 static string toString(int value, 99 Common::Base::Fmt outputBase = Common::Base::Fmt::_DEFAULT); 100 101 private: 102 // Default format to use when none is specified 103 static Base::Fmt myDefaultBase; 104 105 // Upper or lower case for HEX digits 106 static std::ios_base::fmtflags myHexflags; 107 108 private: 109 // Following constructors and assignment operators not supported 110 Base() = delete; 111 Base(const Base&) = delete; 112 Base(Base&&) = delete; 113 Base& operator=(const Base&) = delete; 114 Base& operator=(Base&&) = delete; 115 }; 116 117 } // Namespace Common 118 119 #endif 120