Add another raw_convert type.
[libdcp.git] / src / raw_convert.cc
1 /*
2     Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
3
4     This file is part of libdcp.
5
6     libdcp is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     libdcp is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with libdcp.  If not, see <http://www.gnu.org/licenses/>.
18
19     In addition, as a special exception, the copyright holders give
20     permission to link the code of portions of this program with the
21     OpenSSL library under certain conditions as described in each
22     individual source file, and distribute linked combinations
23     including the two.
24
25     You must obey the GNU General Public License in all respects
26     for all of the code used other than OpenSSL.  If you modify
27     file(s) with this exception, you may extend this exception to your
28     version of the file(s), but you are not obligated to do so.  If you
29     do not wish to do so, delete this exception statement from your
30     version.  If you delete this exception statement from all source
31     files in the program, then also delete it here.
32 */
33
34 #include "raw_convert.h"
35 #include "locale_convert.h"
36 #include <boost/algorithm/string.hpp>
37
38 using std::string;
39 using std::wstring;
40
41 /** @param v Numeric value as an ASCII string */
42 static
43 string
44 make_raw (string v)
45 {
46         struct lconv* lc = localeconv ();
47         /* thousands_sep may be . so remove them before changing decimal points */
48         boost::algorithm::replace_all (v, lc->thousands_sep, "");
49         boost::algorithm::replace_all (v, lc->decimal_point, ".");
50         return v;
51 }
52
53 static
54 string
55 make_local (string v)
56 {
57         struct lconv* lc = localeconv ();
58         boost::algorithm::replace_all (v, ".", lc->decimal_point);
59         /* We hope it's ok not to add in thousands separators here */
60         return v;
61 }
62
63 template <>
64 string
65 dcp::raw_convert (unsigned char v, int precision, bool fixed)
66 {
67         return make_raw (locale_convert<string> (v, precision, fixed));
68 }
69
70 template <>
71 string
72 dcp::raw_convert (unsigned short int v, int precision, bool fixed)
73 {
74         return make_raw (locale_convert<string> (v, precision, fixed));
75 }
76
77 template <>
78 string
79 dcp::raw_convert (int v, int precision, bool fixed)
80 {
81         return make_raw (locale_convert<string> (v, precision, fixed));
82 }
83
84 template <>
85 string
86 dcp::raw_convert (unsigned int v, int precision, bool fixed)
87 {
88         return make_raw (locale_convert<string> (v, precision, fixed));
89 }
90
91 template <>
92 string
93 dcp::raw_convert (long v, int precision, bool fixed)
94 {
95         return make_raw (locale_convert<string> (v, precision, fixed));
96 }
97
98 template <>
99 string
100 dcp::raw_convert (unsigned long v, int precision, bool fixed)
101 {
102         return make_raw (locale_convert<string> (v, precision, fixed));
103 }
104
105 template <>
106 string
107 dcp::raw_convert (long long v, int precision, bool fixed)
108 {
109         return make_raw (locale_convert<string> (v, precision, fixed));
110 }
111
112 template <>
113 string
114 dcp::raw_convert (unsigned long long v, int precision, bool fixed)
115 {
116         return make_raw (locale_convert<string> (v, precision, fixed));
117 }
118
119 template <>
120 string
121 dcp::raw_convert (float v, int precision, bool fixed)
122 {
123         return make_raw (locale_convert<string> (v, precision, fixed));
124 }
125
126 template <>
127 string
128 dcp::raw_convert (double v, int precision, bool fixed)
129 {
130         return make_raw (locale_convert<string> (v, precision, fixed));
131 }
132
133 template <>
134 string
135 dcp::raw_convert (char const * v, int, bool)
136 {
137         return v;
138 }
139
140 template <>
141 string
142 dcp::raw_convert (char* v, int, bool)
143 {
144         return v;
145 }
146
147 template <>
148 string
149 dcp::raw_convert (string v, int, bool)
150 {
151         return v;
152 }
153
154 template <>
155 string
156 dcp::raw_convert (char v, int, bool)
157 {
158         string s;
159         s += v;
160         return s;
161 }
162
163 template <>
164 string
165 dcp::raw_convert (wchar_t const * v, int, bool)
166 {
167         wstring w (v);
168         return string (w.begin(), w.end());
169 }
170
171 template <>
172 unsigned char
173 dcp::raw_convert (std::string v, int precision, bool fixed)
174 {
175         return locale_convert<unsigned char> (make_local (v), precision, fixed);
176 }
177
178 template <>
179 unsigned short int
180 dcp::raw_convert (std::string v, int precision, bool fixed)
181 {
182         return locale_convert<unsigned short int> (make_local (v), precision, fixed);
183 }
184
185 template <>
186 int
187 dcp::raw_convert (string v, int precision, bool fixed)
188 {
189         return locale_convert<int> (make_local (v), precision, fixed);
190 }
191
192 template <>
193 long
194 dcp::raw_convert (string v, int precision, bool fixed)
195 {
196         return locale_convert<long> (make_local (v), precision, fixed);
197 }
198
199 template <>
200 unsigned long
201 dcp::raw_convert (string v, int precision, bool fixed)
202 {
203         return locale_convert<unsigned long> (make_local (v), precision, fixed);
204 }
205
206 template <>
207 long long
208 dcp::raw_convert (string v, int precision, bool fixed)
209 {
210         return locale_convert<long long> (make_local (v), precision, fixed);
211 }
212
213 template <>
214 unsigned long long
215 dcp::raw_convert (string v, int precision, bool fixed)
216 {
217         return locale_convert<unsigned long long> (make_local (v), precision, fixed);
218 }
219
220 template <>
221 int
222 dcp::raw_convert (char const * v, int precision, bool fixed)
223 {
224         return locale_convert<int> (make_local (v), precision, fixed);
225 }
226
227 template <>
228 float
229 dcp::raw_convert (string v, int precision, bool fixed)
230 {
231         return locale_convert<float> (make_local (v), precision, fixed);
232 }
233
234 template <>
235 float
236 dcp::raw_convert (char const * v, int precision, bool fixed)
237 {
238         return locale_convert<float> (make_local (v), precision, fixed);
239 }
240
241 template <>
242 double
243 dcp::raw_convert (string v, int precision, bool fixed)
244 {
245         return locale_convert<double> (make_local (v), precision, fixed);
246 }
247
248 template <>
249 double
250 dcp::raw_convert (char const * v, int precision, bool fixed)
251 {
252         return locale_convert<double> (make_local (v), precision, fixed);
253 }