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