00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef CGATOOLS_UTIL_PARSE_HPP_
00016 #define CGATOOLS_UTIL_PARSE_HPP_ 1
00017
00020
00021 #include "cgatools/core.hpp"
00022 #include "cgatools/util/Exception.hpp"
00023 #include <string>
00024 #include <vector>
00025 #include <string.h>
00026 #include <boost/static_assert.hpp>
00027
00028 namespace cgatools { namespace util {
00029
00030 template <typename Value, bool IsSigned>
00031 struct ValueParser
00032 {
00033 static Value parse(const char* first, const char* last)
00034 {
00035
00036
00037
00038 BOOST_STATIC_ASSERT(0 == sizeof(Value));
00039 }
00040 };
00041
00042 template <typename Value>
00043 struct ValueParser<Value, true>
00044 {
00045 static Value parse(const char* first, const char* last)
00046 {
00047 if (first == last)
00048 throw Exception("failed to parse int: empty string");
00049
00050 bool neg = '-' == *first;
00051
00052 const char* current = first;
00053 if (neg)
00054 ++current;
00055
00056 if (current == last)
00057 throw Exception("failed to parse int: empty string");
00058
00059 Value val(0);
00060 Value maxVal = std::numeric_limits<Value>::max() / 10;
00061 for(; current<last; current++)
00062 {
00063 if (*current < '0' || *current > '9')
00064 throw Exception("failed to parse int: "+std::string(first, last));
00065 Value digit = *current - '0';
00066 if (val >= maxVal)
00067 {
00068 Value maxDigit = std::numeric_limits<Value>::max() % 10;
00069 if (neg && current+1 == last)
00070 maxDigit++;
00071 if (val > maxVal || digit > maxDigit)
00072 throw Exception("failed to parse int: overflow: "+std::string(first, last));
00073 }
00074 val = val*10 + digit;
00075 }
00076 if (neg)
00077 val = -val;
00078 return val;
00079 }
00080 };
00081
00082 template <typename Value>
00083 struct ValueParser<Value, false>
00084 {
00085 static Value parse(const char* first, const char* last)
00086 {
00087 if (first == last)
00088 throw Exception("failed to parse int: empty string");
00089
00090 Value val(0);
00091 Value maxVal = std::numeric_limits<Value>::max() / 10;
00092 for(const char* current=first; current<last; current++)
00093 {
00094 if (*current < '0' || *current > '9')
00095 throw Exception("failed to parse int: "+std::string(first, last));
00096 Value digit = *current - '0';
00097 if (val >= maxVal)
00098 {
00099 Value maxDigit = std::numeric_limits<Value>::max() % 10;
00100 if (val > maxVal || digit > maxDigit)
00101 throw Exception("failed to parse int: overflow: "+std::string(first, last));
00102 }
00103 val = val*10 + digit;
00104 }
00105 return val;
00106 }
00107 };
00108
00109 float parseFloat (const char* first, const char* last);
00110 double parseDouble(const char* first, const char* last);
00111
00112 template <>
00113 struct ValueParser<float, true>
00114 {
00115 static float parse(const char* first, const char* last)
00116 {
00117 return parseFloat(first, last);
00118 }
00119 };
00120
00121 template <>
00122 struct ValueParser<double, true>
00123 {
00124 static double parse(const char* first, const char* last)
00125 {
00126 return parseDouble(first, last);
00127 }
00128 };
00129
00150 template <typename Value>
00151 Value parseValue(const char* first, const char* last)
00152 {
00153 return ValueParser<Value, std::numeric_limits<Value>::is_signed>::parse(first, last);
00154 }
00155
00158 template <typename Value> Value parseValue(const char* str)
00159 {
00160 const char* strEnd = str + strlen(str);
00161 return parseValue<Value>(str, strEnd);
00162 }
00163
00166 template <typename Value> Value parseValue(const std::string& str)
00167 {
00168 return parseValue<Value>(str.c_str(), str.c_str()+str.length());
00169 }
00170
00173 void parseTokenString(std::string const & inputString, char const * sep,
00174 std::vector<std::string> & tokens,
00175 bool trimWhitespace = false,
00176 bool compressEmpty = false);
00177
00178 } }
00179
00180 #endif // CGATOOLS_UTIL_PARSE_HPP_