00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 #define UNIX_FIRST_YEAR 1970
00027
00028 #include <cmath>
00029 #include <cstdio>
00030 #include <cstdlib>
00031 #include <iostream>
00032
00033 #include <tlelib/tlefunc.h>
00034 #include <tlelib/tleexception.h>
00035
00036 namespace tlelib
00037 {
00038
00039 std::string int2string(const int val, const std::size_t fieldLength, const bool leftAlign)
00040 {
00041 char *str = new char(6);
00042 sprintf(str, "%d", val);
00043 std::string res(str);
00044 delete str;
00045
00046 return string2string(trim(res), fieldLength, leftAlign, false);
00047 }
00048
00049
00050 std::string double2string(const double val, const std::size_t fieldLength, const std::size_t precission, const bool scientific, const bool decimalPointAssumed, const bool leftAlign)
00051 {
00052 char str[fieldLength];
00053 double val1 = val;
00054 if (decimalPointAssumed)
00055 {
00056 double val3;
00057 val1 = modf(val, &val3);
00058 }
00059 sprintf(str, ("%" + int2string(fieldLength) + "." + int2string(precission+(scientific ? 1 : 0)) + (scientific ? "e" : "f")).c_str(), val1);
00060 std::string res(str);
00061
00062
00063 std::size_t pos = res.find(".");
00064 bool replaced = false;
00065 int n = 0;
00066 if (decimalPointAssumed && pos != std::string::npos && scientific)
00067 {
00068 n = -pos;
00069 res.replace(pos, 1, "");
00070 replaced = true;
00071 }
00072 else
00073 if (decimalPointAssumed && !scientific)
00074 {
00075 pos = res.find("0.");
00076 if (pos != std::string::npos)
00077 res.replace(pos, 2, "");
00078 }
00079
00080
00081 if (scientific)
00082 {
00083 std::size_t e_pos = res.find("e");
00084 std::string base = res.substr(0, e_pos);
00085 std::string a = res.substr(e_pos + 1, res.length() - e_pos - 1);
00086 std::size_t pos1 = base.find(".");
00087 if (pos1 != std::string::npos)
00088 {
00089 n = base.length() - pos1 - 1;
00090 base.replace(pos1, 1, "");
00091 }
00092 int new_a = string2int(a) - n;
00093 if (string2double(base) == 0) new_a = 0;
00094 res = base + (new_a > 0 ? "+" : "-") + int2string(abs(new_a));
00095 }
00096 res = trim(res);
00097
00098
00099 if (res.substr(0, 2) == "0.")
00100 res = res.substr(1, res.length() - 1);
00101 else
00102 if (res.substr(0, 3) == "-0.")
00103 res = "-" + res.substr(2, res.length() - 2);
00104
00105 return string2string(res, fieldLength, leftAlign, false);
00106 }
00107
00108
00109 std::string string2string(const std::string &str, const std::size_t fieldLength, const bool leftAlign, const bool allowCutOff)
00110 {
00111 std::string res(str);
00112 if (res.length() > fieldLength && allowCutOff)
00113 {
00114 res = res.substr(0, fieldLength);
00115 }
00116 else
00117 if (res.length() <= fieldLength)
00118 {
00119 while (res.length() < fieldLength)
00120 {
00121 if (leftAlign)
00122 res += " ";
00123 else
00124 res = " " + res;
00125 }
00126 }
00127 return res;
00128 }
00129
00130
00131 std::string date2string(const double date, const std::size_t fieldLength, const bool leftAlign)
00132 {
00133 double dt = date;
00134 std::size_t year = UNIX_FIRST_YEAR;
00135 while (true)
00136 {
00137 bool leap = !(year % 4) && ( (year % 100) || !(year % 400));
00138 std::time_t l = (leap ? 366 : 365) * 86400;
00139 if (dt < l) break;
00140 dt -= l;
00141 year++;
00142 }
00143 year -= year>2000 ? 2000 : 1900;
00144 double res = year * 1000 + dt / 86400.0;
00145
00146 std::string pref = year < 10 ? "0" : "";
00147 std::size_t length = year < 10 ? fieldLength - 1 : fieldLength;
00148 return pref + double2string(res, length, fieldLength - 6, false, false, leftAlign);
00149 }
00150
00151
00152 int string2int(const std::string &str)
00153 {
00154 std::string val = trim(str);
00155
00156 for (std::size_t i=0; i<val.length(); i++)
00157 if (!isdigit(val[i]) && !( i == 0 && (val[i] == '-' || val[i] == '+') ))
00158 throw tle_invalid_format(str);
00159
00160 return atoi(val.c_str());
00161 }
00162
00163
00164 double string2double(const std::string &str)
00165 {
00166 std::string val = trim(str);
00167
00168 for (std::size_t i=0; i<val.length(); i++)
00169 {
00170 bool valid = isdigit(val[i]);
00171 valid = valid || (i == 0 && (val[i] == '-' || val[i] == '+'));
00172
00173 valid = valid || (i>0 && (val[i] == 'e' || val[i] == 'E') && (isdigit(val[i-1]) || val[i-1] == '.') && i < val.length()-1);
00174
00175 valid = valid || (i>0 && (val[i] == '-' || val[i] == '+') && (val[i-1] == 'e' || val[i-1] == 'E') && i < val.length()-1);
00176
00177 valid = valid || (val[i] == '.');
00178
00179 if (!valid)
00180 {
00181 throw tle_invalid_format(str);
00182 }
00183 }
00184 return atof(val.c_str());
00185 }
00186
00187
00188 std::string trim(const std::string &str)
00189 {
00190 std::string res(str);
00191 while (res.length() && res[0] == ' ') res = res.substr(1, res.length() - 1);
00192 while (res.length() && res[res.length() - 1] == ' ') res = res.substr(0, res.length() - 1);
00193 return res;
00194 }
00195
00196
00197 char parseChar(const std::string *line, const std::size_t index)
00198 {
00199 char res = '\0';
00200 if (line)
00201 {
00202 if (line->length() - 1 < index)
00203 throw tle_too_short_string(*line);
00204 res = (*line)[index];
00205 }
00206
00207 return res;
00208 }
00209
00210
00211 std::string parseString(const std::string *line, const std::size_t start, const std::size_t length)
00212 {
00213 std::string res = "";
00214 if (line)
00215 {
00216 if (line->length() < start + length)
00217 throw tle_too_short_string(*line);
00218
00219 res = line->substr(start, length);
00220 }
00221
00222 return res;
00223 }
00224
00225
00226 int parseInt(const std::string *line, const std::size_t start, const std::size_t length)
00227 {
00228 int res = 0;
00229 if (line)
00230 {
00231 if (line->length() < start + length)
00232 throw tle_too_short_string(*line);
00233
00234 std::string val = trim(line->substr(start, length));
00235
00236
00237 try{
00238 res = string2int(val.c_str());
00239 } catch(...) {
00240 throw tle_invalid_format(*line);
00241 }
00242 }
00243
00244 return res;
00245 }
00246
00247
00248 double parseDouble(const std::string *line, const std::size_t start, const std::size_t length, const bool decimalPointAssumed)
00249 {
00250 double res = 0;
00251 if (line)
00252 {
00253 if (line->length() < start + length)
00254 throw tle_too_short_string(*line);
00255
00256 std::string val = trim(line->substr(start, length));
00257
00258
00259 if (decimalPointAssumed) val = "0." + val;
00260
00261 std::size_t pos = val.rfind('-');
00262 if (pos != std::string::npos && pos && val[pos - 1] != 'e' && val[pos - 1] != 'E')
00263 {
00264 val.replace(pos, 1, "e-");
00265 }
00266 else
00267 {
00268 std::size_t pos = val.rfind('+');
00269 if (pos != std::string::npos)
00270 val.replace(pos, 1, "e");
00271 }
00272
00273
00274 try{
00275 res = string2double(val.c_str());
00276 } catch(...) {
00277 throw tle_invalid_format(*line);
00278 }
00279 }
00280
00281 return res;
00282 }
00283
00284
00285 double string2date(const std::string &str)
00286 {
00287 std::string str1(trim(str));
00288
00289 if (str1.find('-') != std::string::npos)
00290 throw tle_invalid_format(str);
00291
00292
00293 int year = string2int(str1.substr(0, 2).c_str());
00294 year += year < (UNIX_FIRST_YEAR - (UNIX_FIRST_YEAR / 100) * 100) ? 2000 : 1900;
00295
00296 double res = 0;
00297 for (int y = UNIX_FIRST_YEAR; y < year; y++)
00298 {
00299
00300 bool leap = !(y % 4) && ( (y % 100) || !(y % 400));
00301 res += leap ? 366 : 365;
00302 }
00303
00304
00305 res *= 86400;
00306
00307
00308 res += string2double(str1.substr(2, str1.length() - 2)) * 86400;
00309 return res;
00310 }
00311
00312
00313 int checksum(const std::string &str)
00314 {
00315 int checksum = 0;
00316 for (std::size_t i=0; i<str.length(); i++)
00317 checksum += isdigit(str[i]) ? atoi(str.substr(i, 1).c_str()) : (str[i] == '-' ? 1 : 0);
00318
00319 checksum -= (checksum/10) * 10;
00320
00321 return checksum;
00322 }
00323
00324
00325 }