1 /***************************************************************************
2  *                                                                         *
3  *   Copyright : (C) 2010 The University of Toronto                        *
4  *   email     : netterfield@astro.utoronto.ca                             *
5  *                                                                         *
6  *   This program 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  ***************************************************************************/
12 
13 #ifndef KST_ATOF_H
14 #define KST_ATOF_H
15 
16 #include <QByteArray>
17 #include <QString>
18 #include <stdlib.h>
19 
20 #include "math_kst.h"
21 
22 #ifdef Q_CC_MSVC
23   #define KST_THREAD_LOCAL __declspec(thread)
24 #else
25  #ifndef KST_NO_THREAD_LOCAL
26    #define KST_THREAD_LOCAL __thread
27   #else
28    #define KST_THREAD_LOCAL
29   #endif
30 #endif
31 
32 class LexicalCast
33 {
34 public:
35 
36   static LexicalCast& instance();
37 
38 
39   enum NaNMode {
40     NullValue,
41     NaNValue,
42     PreviousValue
43   };
44 
45   struct AutoReset {
46     AutoReset(bool useDot, NaNMode);
47     ~AutoReset();
48   };
49 
50   void setUseDotAsDecimalSeparator(bool useDot);
51 
52   char localSeparator() const;
53 
54 #ifdef KST_USE_KST_ATOF
55   double fromDouble(const char* p) const;
56 #else
fromDouble(const char * p)57   inline double fromDouble(const char* p) const { return atof(p); }
58 #endif
59   double fromTime(const char*) const;
toDouble(const char * p)60   inline double toDouble(const char* p) const { return _isFormattedTime ? fromTime(p) : fromDouble(p); }
61 
62   void setTimeFormat(const QString& format);
63 
64   double nanValue() const;
65 
66 private:
67   LexicalCast();
68   ~LexicalCast();
69 
70   NaNMode _nanMode;
71   static KST_THREAD_LOCAL double _previousValue;
72   char _separator;
73 
74   QByteArray _originalLocal;
75   QString _timeFormat;
76   int _timeFormatLength;
77   bool _isFormattedTime;
78   bool _timeWithDate;
79 
80   void resetLocal();
81 
isDigit(const char c)82   inline bool isDigit(const char c) const {
83     return (c >= 48) && (c <= 57) ? true : false;
84   }
85 };
86 
87 
88 //-------------------------------------------------------------------------------------------
nanValue()89 inline double LexicalCast::nanValue() const
90 {
91   switch (_nanMode) {
92   case NullValue:     return 0;
93   case NaNValue:      return Kst::NOPOINT;
94   case PreviousValue: return _previousValue;
95   default:            return 0;
96   }
97 }
98 
99 
100 #endif
101 
102 // vim: ts=2 sw=2 et
103