74 #include <boost/regex.hpp> 75 #include <boost/tokenizer.hpp> 97 const size_t pos = s.find_last_of(
' ');
98 if (pos==string::npos)
125 wout <<
" (" << val <<
")";
128 reinterpret_cast<const char*
>(&val),
129 reinterpret_cast<const char*>(&val+1));
151 wout <<
" (" << val <<
")";
171 wout <<
" (" << val <<
")";
173 v.insert(v.end(), val.begin(), val.end()+1);
191 wout <<
" (" << val <<
")";
223 line.clear(ios::eofbit);
227 if (line.peek()==
'x')
267 transform(buf.begin(), buf.end(), buf.begin(), ::tolower);
269 if (buf==
"yes" || buf==
"true" || buf==
"on" || buf==
"1")
272 if (buf==
"no" || buf==
"false" || buf==
"off" || buf==
"0")
275 line.clear(ios::failbit);
296 while (line.peek()==
' ')
300 if (line.peek()==
'\"')
303 getline(line, buf,
'\"');
305 line.clear(ios::eofbit);
330 const istream_iterator<char> eol;
331 const string text(istream_iterator<char>(line), eol);
336 const char b = str[0];
337 const char e = str[str.length()-1];
339 if ((b==
'\"' && e==
'\"') || (b==
'\'' && e==
'\''))
341 typedef boost::escaped_list_separator<char> separator;
342 const boost::tokenizer<separator> tok(str, separator(
"\\",
" ",
"\"'"));
369 const T &
t = *
reinterpret_cast<const T*
>(ptr);
371 ostringstream stream;
381 ostringstream stream;
382 stream << (int64_t)*ptr;
406 str +=
' ' + GetString<T>(ptr);
427 vec.push_back(*reinterpret_cast<const T*>(ptr));
444 const string txt(ptr);
446 ptr += txt.length()+1;
462 const string txt(ptr);
464 ptr += txt.length()+1;
483 : wout(out), fFormat(Clean(fmt)), fList(Compile(out, fmt, strict))
528 throw runtime_error(
"Compiled format invalid!");
531 if (
empty() && str.empty())
538 stringstream line(str);
542 for (Converter::FormatList::const_iterator
i=
fList.begin();
i<
fList.end()-1;
i++)
544 if (*
i->first.first ==
typeid(
string))
547 line.clear(ios::eofbit);
552 for (
int j=0; j<
i->second.first; j++)
554 switch (
i->first.first->name()[0])
557 case 's':
GetBinImp(data, Get<short> (line));
break;
558 case 'i':
GetBinImp(data, Get<int> (line));
break;
559 case 'l':
GetBinImp(data, Get<long> (line));
break;
560 case 'f':
GetBinImp(data, Get<float> (line));
break;
561 case 'd':
GetBinImp(data, Get<double> (line));
break;
562 case 'x':
GetBinImp(data, Get<long long>(line));
break;
565 const unsigned short val = Get<unsigned short>(line);
567 line.setstate(ios::failbit);
568 GetBinImp(data, static_cast<unsigned char>(val));
573 if (*
i->first.first ==
typeid(
O))
574 line.clear(ios::goodbit|(line.rdstate()&ios::eofbit));
578 throw runtime_error(
"Format '"+
string(
i->first.first->name())+
" not supported!");
590 if (line.fail() && !line.eof())
595 err <<
"Error converting argument at " << arg <<
" [fmt=" <<
fFormat <<
"]!\n";
596 err << line.str() <<
"\n";
597 err << setw(
int(line.tellg())) <<
" " <<
"^\n";
598 throw runtime_error(err.str());
602 if (line.fail() && line.eof())
607 err <<
"Not enough arguments [fmt=" <<
fFormat <<
"]!\n";
608 err << line.str() <<
"\n";
609 err << setw(
int(line.tellg())+1) <<
" " <<
"^\n";
610 throw runtime_error(err.str());
616 if (line.good() && !line.eof())
619 err <<
"More arguments available than expected [fmt=" <<
fFormat <<
"]!\n";
620 err << line.str() <<
"\n";
621 err << setw(
int(line.tellg())+1) <<
" " <<
"^\n";
622 throw runtime_error(err.str());
631 return Get<boost::any>(
str);
636 return Get<char>(
str);
659 throw runtime_error(
"Compiled format invalid!");
662 throw runtime_error(
"Data pointer == NULL!");
664 const char *ptr =
reinterpret_cast<const char *
>(dat);
667 for (Converter::FormatList::const_iterator
i=
fList.begin();
i<
fList.end()-1;
i++)
672 err <<
"Format description [fmt=" <<
fFormat <<
"|size=" <<
GetSize() <<
"] exceeds available data size (" << size <<
")";
673 throw runtime_error(err.str());
676 if (*
i->first.first ==
typeid(
string))
686 for (
int j=0; j<
i->second.first; j++)
688 switch (
i->first.first->name()[0])
690 case 'b': Add<bool> (text, ptr);
break;
691 case 'c': Add<char> (text, ptr);
break;
692 case 's': Add<short> (text, ptr);
break;
693 case 'i': Add<int> (text, ptr);
break;
694 case 'l': Add<long> (text, ptr);
break;
695 case 'f': Add<float> (text, ptr);
break;
696 case 'd': Add<double> (text, ptr);
break;
697 case 'x': Add<long long>(text, ptr);
break;
702 throw runtime_error(
"Type 'void' not supported!");
704 throw runtime_error(
"TypeId '"+
string(
i->first.first->name())+
"' not known!");
712 err <<
"Data block size (" << size <<
") doesn't fit format description [fmt=" <<
fFormat <<
"|size=" <<
GetSize() <<
"]";
713 throw runtime_error(err.str());
721 return Get<vector<boost::any>>(dat,
size);
729 data.insert(data.begin(), ref.begin()+1, ref.end());
737 const string s = Get<string>(dat,
size);
738 return s.empty() ? s : s.substr(1);
745 t.first = &
typeid(T);
746 t.second =
sizeof(T);
754 t.first = &
typeid(T);
779 stringstream stream(fmt);
782 static const boost::regex expr1(
"^([CSILFDXBOW])(:([1-9]+[0-9]*))?$");
783 static const boost::regex expr2(
"^([CSILFDX])(:([1-9]+[0-9]*))?$");
790 while (getline(stream, buffer,
';'))
793 if (!boost::regex_match(buffer, what, strict?expr2:expr1))
795 out <<
kRed <<
"Wrong format string '" << buffer <<
"'!" << endl;
799 const string t = what[1];
800 const string n = what[3];
802 const int cnt = n.empty() ? 0 : stoi(n);
805 format.second.first = cnt == 0 ? 1 : cnt;
816 if (t[0]==
'C' && cnt==0)
818 format.first = GetType<string>();
819 list.push_back(format);
820 format.second.second = 0;
827 case 'B': format.first = GetType<bool>();
break;
828 case 'C': format.first = GetType<char>();
break;
829 case 'S': format.first = GetType<short>();
break;
830 case 'I': format.first = GetType<int>();
break;
831 case 'L': format.first = GetType<long>();
break;
832 case 'F': format.first = GetType<float>();
break;
833 case 'D': format.first = GetType<double>();
break;
834 case 'X': format.first = GetType<long long>();
break;
835 case 'O': format.first = GetVoid<O>();
break;
836 case 'W': format.first = GetVoid<W>();
break;
839 out <<
kRed <<
"Format '" << t[0] <<
" not known!" << endl;
843 list.push_back(format);
844 format.second.second += format.first.second * format.second.first;
847 format.first = GetVoid<void>();
848 format.second.first = 0;
850 list.push_back(format);
863 return Compile(cout, fmt, strict);
868 const boost::regex reg(expr);
871 if (!boost::regex_match(line, what, reg, boost::match_extra))
872 return vector<string>();
875 for (
unsigned int i=0;
i<what.size();
i++)
876 ret.push_back(what[
i]);
899 char *charDest =
static_cast<char*
>(dest);
900 const char *charSrc =
static_cast<const char*
>(src);
903 for (Converter::FormatList::const_iterator
i=
fList.begin();
i!=
fList.end()-1;
i++)
916 const char type =
i->first.first->name()[0];
919 charSrc += strlen(charSrc)+1;
923 const int s =
i->first.second;
924 const int n =
i->second.first;
928 throw runtime_error(
string(
"Type '")+type+
"' not supported converting to FITS.");
933 case 1: memcpy(charDest, charSrc, s*n); charSrc+=s*n; charDest+=s*n;
break;
934 case 2:
for (
int j=0; j<n; j++) { reverse_copy(charSrc, charSrc+2, charDest); charSrc+=2; charDest+=2; }
break;
935 case 4:
for (
int j=0; j<n; j++) { reverse_copy(charSrc, charSrc+4, charDest); charSrc+=4; charDest+=4; }
break;
936 case 8:
for (
int j=0; j<n; j++) { reverse_copy(charSrc, charSrc+8, charDest); charSrc+=8; charDest+=8; }
break;
940 if (charDest-size!=dest)
943 err <<
"ToFits - Data block size (" << size <<
") doesn't fit format description [fmt=" <<
fFormat <<
"|size=" <<
GetSize() <<
"]";
944 throw runtime_error(err.str());
950 const char *charSrc =
static_cast<const char*
>(src);
954 for (Converter::FormatList::const_iterator
i=
fList.begin();
i!=
fList.end();
i++)
964 const char type =
i->first.first->name()[0];
968 if (type==
'S' || type==
'N')
970 const string str(charSrc);
972 charSrc += str.length()+1;
980 const int s =
i->first.second;
981 const int n =
i->second.first;
999 vector<char> dest(size);
1007 for (vector<string>::const_iterator it=fits.begin(); it!=fits.end(); it++)
1028 case 'B': str <<
";C:" << n;
break;
1029 case 'J': str <<
";I:" << n;
break;
1030 case 'I': str <<
";S:" << n;
break;
1031 case 'K': str <<
";X:" << n;
break;
1032 case 'E': str <<
";F:" << n;
break;
1033 case 'D': str <<
";D:" << n;
break;
1035 throw runtime_error(
"ToFormat - id not known.");
1039 return str.str().substr(1);
1047 for (FormatList::const_iterator it=
fList.begin(); it!=
fList.end(); it++)
1049 ostringstream dataQualifier;
1050 dataQualifier << it->second.first;
1052 switch (it->first.first->name()[0])
1054 case 'c': dataQualifier <<
'B';
break;
1055 case 's': dataQualifier <<
'I';
break;
1056 case 'i': dataQualifier <<
'J';
break;
1057 case 'l': dataQualifier <<
'J';
break;
1058 case 'f': dataQualifier <<
'E';
break;
1059 case 'd': dataQualifier <<
'D';
break;
1060 case 'x': dataQualifier <<
'K';
break;
1067 throw runtime_error(
string(
"GetFitsFormat - unknown FITS format [")+it->first.first->name()[0]+
"]");
1070 vec.push_back(dataQualifier.str());
1078 for (FormatList::const_iterator
i=
fList.begin();
i!=
fList.end();
i++)
1080 out <<
"Type=" <<
i->first.first->name() <<
"[" <<
i->first.second <<
"] ";
1081 out <<
"N=" <<
i->second.first <<
" ";
1082 out <<
"offset=" <<
i->second.second << endl;
std::vector< Format > FormatList
T Get(std::stringstream &line) const
Compiled format description.
void Add(std::string &str, const char *&ptr) const
std::vector< boost::any > GetAny(const void *d, size_t size) const
std::string GetString(std::stringstream &line) const
static std::string Clean(std::string s)
void GetBinImp(std::vector< char > &v, const T &val) const
static FormatList Compile(std::ostream &out, const std::string &fmt, bool strict=false)
static std::vector< std::string > Regex(const std::string &expr, const std::string &line)
void GetBinString(std::vector< char > &v, const std::string &val) const
bool GetBool(std::stringstream &line) const
std::pair< const std::type_info *, int > Type
std::pair< Type, Offset > Format
static std::string ToFormat(const std::vector< std::string > &fits)
std::string GetStringEol(std::stringstream &line) const
Converter(std::ostream &out, const std::string &fmt, bool strict=true)
const FormatList fList
Original format string.
void AddString(std::string &str, const char *&ptr) const
std::vector< std::string > ToStrings(const void *src) const
const std::string fFormat
ostream to which output is redirected
std::vector< std::string > GetFitsFormat() const
std::vector< char > GetVector(const void *d, size_t size) const
void ToFits(void *dest, const void *src, size_t size) const