]> git.tdb.fi Git - libs/core.git/blob - source/fmt.cpp
Initial upload
[libs/core.git] / source / fmt.cpp
1 #include <msp/error.h>
2 #include "fmt.h"
3
4 using namespace std;
5
6 namespace Msp {
7
8 /**
9 Resets the format to the default.  Mainly used by constructors.
10 */
11 Fmt &Fmt::reset()
12 {
13         wd=0;
14         prec=6;
15         spos=false;
16         fillc=' ';
17         base=DEC;
18         sbase=false;
19         fmode=EXP;
20         spoint=false;
21         align=RIGHT;
22         ucase=false;
23
24         return *this;
25 }
26
27 /**
28 Applies the format to the given ostream.  All existing formatting information
29 is overwritten.
30 */
31 void Fmt::apply(ostream &out) const
32 {
33         out.flags(((base==HEX) ? ios_base::hex : (base==OCT) ? ios_base::oct : ios_base::dec)
34                 | ((fmode==SCI) ? ios_base::scientific : (fmode==FIXED) ? ios_base::fixed : ios_base::fmtflags(0))
35                 | (fillc ? ios_base::internal : (align==LEFT) ? ios_base::left : ios_base::right)
36                 | (sbase ? ios_base::showbase : ios_base::fmtflags(0))
37                 | (spoint ? ios_base::showpoint : ios_base::fmtflags(0))
38                 | (spos ? ios_base::showpos : ios_base::fmtflags(0))
39                 | (ucase ? ios_base::uppercase : ios_base::fmtflags(0)));
40         out.fill(fillc);
41         out.width(wd);
42         out.precision(prec);
43 }
44
45 /**
46 Parses a printf-style conversion specification.  Called from constructors.
47 */
48 void Fmt::parse(const char *f)
49 {
50         if(*f=='%') ++f;
51
52         for(; *f; ++f)
53         {
54                 if(*f=='#')
55                 {
56                         sbase=true;
57                         spoint=true;
58                 }
59                 else if(*f=='0')
60                         fillc='0';
61                 else if(*f=='-')
62                         align=LEFT;
63                 else if(*f=='+')
64                         spos=true;
65                 else
66                         break;
67         }
68
69         wd=0;
70         for(; *f; ++f)
71         {
72                 if(*f>='0' && *f<='9')
73                         wd=wd*10+(*f-'0');
74                 else
75                         break;
76         }
77
78         if(*f=='.')
79         {
80                 ++f;
81                 prec=0;
82                 for(; *f; ++f)
83                 {
84                         if(*f>='0' && *f<='9')
85                                 prec=prec*10+(*f-'0');
86                         else
87                                 break;
88                 }
89         }
90
91         if(*f=='x' || *f=='X')
92                 base=HEX;
93         else if(*f=='o')
94                 base=OCT;
95         else if(*f=='e' || *f=='E')
96                 fmode=EXP;
97         else if(*f=='f' || *f=='F')
98                 fmode=FIXED;
99         else if(*f=='g' || *f=='G')
100                 fmode=SCI;
101         else if(*f=='p')
102         {
103                 base=HEX;
104                 sbase=true;
105         }
106         else if(*f=='d' || *f=='i' || *f=='u' || *f=='c' || *f=='s')
107                 ;
108         else
109                 throw InvalidParameterValue("Invalid conversion specifier");
110
111         if(*f=='E' || *f=='F' || *f=='G' || *f=='X')
112                 ucase=true;
113
114         ++f;
115
116         if(*f)
117                 throw InvalidParameterValue("Extra characters in conversion specification");
118 }
119
120 } // namespace Msp