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