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-2019 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
26namespace 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*/
35class 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 Format {
42 F_16, // base 16: 2, 4, 8 bytes (depending on value)
43 F_16_1, // base 16: 1 byte wide
44 F_16_2, // base 16: 2 bytes wide
45 F_16_2_2, // base 16: fractional value shown as xx.xx
46 F_16_3_2, // base 16: fractional value shown as xxx.xx
47 F_16_4, // base 16: 4 bytes wide
48 F_16_8, // base 16: 8 bytes wide
49 F_10, // base 10: 3 or 5 bytes (depending on value)
50 F_10_02, // base 10: 02 digits
51 F_10_3, // base 10: 3 digits
52 F_10_4, // base 10: 4 digits
53 F_10_5, // base 10: 5 digits
54 F_2, // base 2: 8 or 16 bits (depending on value)
55 F_2_8, // base 2: 1 byte (8 bits) wide
56 F_2_16, // base 2: 2 bytes (16 bits) wide
57 F_DEFAULT
58 };
59
60 public:
61 /** Get/set the number base when parsing numeric values */
62 static void setFormat(Base::Format base) { myDefaultBase = base; }
63 static Base::Format format() { return myDefaultBase; }
64
65 /** Get/set HEX output to be upper/lower case */
66 static void setHexUppercase(bool enable) {
67 if(enable) myHexflags |= std::ios_base::uppercase;
68 else myHexflags &= ~std::ios_base::uppercase;
69 }
70 static bool hexUppercase() { return myHexflags & std::ios_base::uppercase; }
71
72 /** Output HEX digits in 0.5/1/2/4 byte format */
73 static inline std::ostream& HEX1(std::ostream& os) {
74 os.flags(myHexflags);
75 return os << std::setw(1);
76 }
77 static inline std::ostream& HEX2(std::ostream& os) {
78 os.flags(myHexflags);
79 return os << std::setw(2) << std::setfill('0');
80 }
81 static inline std::ostream& HEX3(std::ostream& os)
82 {
83 os.flags(myHexflags);
84 return os << std::setw(3) << std::setfill('0');
85 }
86 static inline std::ostream& HEX4(std::ostream& os) {
87 os.flags(myHexflags);
88 return os << std::setw(4) << std::setfill('0');
89 }
90 static inline std::ostream& HEX8(std::ostream& os) {
91 os.flags(myHexflags);
92 return os << std::setw(8) << std::setfill('0');
93 }
94
95 /** Convert integer to a string in the given base format */
96 static string toString(int value,
97 Common::Base::Format outputBase = Common::Base::F_DEFAULT);
98
99 private:
100 // Default format to use when none is specified
101 static Format myDefaultBase;
102
103 // Upper or lower case for HEX digits
104 static std::ios_base::fmtflags myHexflags;
105
106 private:
107 // Following constructors and assignment operators not supported
108 Base() = delete;
109 Base(const Base&) = delete;
110 Base(Base&&) = delete;
111 Base& operator=(const Base&) = delete;
112 Base& operator=(Base&&) = delete;
113};
114
115} // Namespace Common
116
117#endif
118