FACT++  1.0
Converter.cc
Go to the documentation of this file.
1 // **************************************************************************
64 // **************************************************************************
65 #include "Converter.h"
66 
67 #include <iostream>
68 #include <iomanip>
69 #include <sstream>
70 
71 #include <cctype> // std::tolower
72 #include <algorithm> // std::transform
73 
74 #include <boost/regex.hpp>
75 #include <boost/tokenizer.hpp>
76 
77 #include "tools.h"
78 #include "WindowLog.h"
79 
80 using namespace std;
81 
82 // --------------------------------------------------------------------------
83 //
92 //
93 std::string Converter::Clean(std::string s)
94 {
95  while (1)
96  {
97  const size_t pos = s.find_last_of(' ');
98  if (pos==string::npos)
99  break;
100  s.erase(pos, pos+1);
101  }
102 
103  return s;
104 }
105 
106 // --------------------------------------------------------------------------
107 //
122 template <class T>
123 void Converter::GetBinImp(std::vector<char> &v, const T &val) const
124 {
125  wout << " (" << val << ")";
126 
127  v.insert(v.end(),
128  reinterpret_cast<const char*>(&val),
129  reinterpret_cast<const char*>(&val+1));
130 }
131 
132 // --------------------------------------------------------------------------
133 //
148 template <class T>
149 void Converter::GetBinImp(std::vector<boost::any> &v, const T &val) const
150 {
151  wout << " (" << val << ")";
152 
153  v.push_back(val);
154 }
155 
156 // --------------------------------------------------------------------------
157 //
169 void Converter::GetBinString(std::vector<char> &v, const string &val) const
170 {
171  wout << " (" << val << ")";
172 
173  v.insert(v.end(), val.begin(), val.end()+1);
174 }
175 
176 // --------------------------------------------------------------------------
177 //
189 void Converter::GetBinString(std::vector<boost::any> &v, const string &val) const
190 {
191  wout << " (" << val << ")";
192 
193  v.push_back(val);
194  v.push_back('\n');
195 }
196 
197 // --------------------------------------------------------------------------
198 //
211 template <class T>
212 T Converter::Get(std::stringstream &line) const
213 {
214  char c;
215  line >> c;
216  if (!line)
217  return T();
218 
219  if (c=='0')
220  {
221  if (line.peek()==-1)
222  {
223  line.clear(ios::eofbit);
224  return 0;
225  }
226 
227  if (line.peek()=='x')
228  {
229  line >> c;
230  line >> hex;
231  }
232  else
233  {
234  line.unget();
235  line >> oct;
236  }
237  }
238  else
239  {
240  line.unget();
241  line >> dec;
242  }
243 
244 
245  T val;
246  line >> val;
247  return val;
248 }
249 
250 // --------------------------------------------------------------------------
251 //
263 bool Converter::GetBool(std::stringstream &line) const
264 {
265  string buf;
266  line >> buf;
267  transform(buf.begin(), buf.end(), buf.begin(), ::tolower);
268 
269  if (buf=="yes" || buf=="true" || buf=="on" || buf=="1")
270  return true;
271 
272  if (buf=="no" || buf=="false" || buf=="off" || buf=="0")
273  return false;
274 
275  line.clear(ios::failbit);
276 
277  return false;
278 }
279 
280 // --------------------------------------------------------------------------
281 //
294 string Converter::GetString(std::stringstream &line) const
295 {
296  while (line.peek()==' ')
297  line.get();
298 
299  string buf;
300  if (line.peek()=='\"')
301  {
302  line.get();
303  getline(line, buf, '\"');
304  if (line.peek()==-1)
305  line.clear(ios::eofbit);
306  }
307  else
308  line >> buf;
309 
310  return buf;
311 }
312 
313 // --------------------------------------------------------------------------
314 //
326 string Converter::GetStringEol(stringstream &line) const
327 {
328  line >> noskipws;
329 
330  const istream_iterator<char> eol; // end-of-line iterator
331  const string text(istream_iterator<char>(line), eol);
332 
333  string str = Tools::Trim(text);
334  if (str.length()>=2)
335  {
336  const char b = str[0];
337  const char e = str[str.length()-1];
338 
339  if ((b=='\"' && e=='\"') || (b=='\'' && e=='\''))
340  {
341  typedef boost::escaped_list_separator<char> separator;
342  const boost::tokenizer<separator> tok(str, separator("\\", " ", "\"'"));
343 
344  str = *tok.begin();
345  }
346  }
347 
348  return str + '\0';
349 }
350 
351 // --------------------------------------------------------------------------
352 //
366 template<class T>
367 string Converter::GetString(const char* &ptr) const
368 {
369  const T &t = *reinterpret_cast<const T*>(ptr);
370 
371  ostringstream stream;
372  stream << t;
373  ptr += sizeof(T);
374 
375  return stream.str();
376 }
377 
378 template<char>
379 string Converter::GetString(const char* &ptr) const
380 {
381  ostringstream stream;
382  stream << (int64_t)*ptr;
383  ptr += 1;
384 
385  return stream.str();
386 }
387 
388 // --------------------------------------------------------------------------
389 //
403 template<class T>
404 void Converter::Add(string &str, const char* &ptr) const
405 {
406  str += ' ' + GetString<T>(ptr);
407 }
408 
409 // --------------------------------------------------------------------------
410 //
424 template<class T>
425 void Converter::Add(vector<boost::any> &vec, const char* &ptr) const
426 {
427  vec.push_back(*reinterpret_cast<const T*>(ptr));
428  ptr += sizeof(T);
429 }
430 
431 // --------------------------------------------------------------------------
432 //
442 void Converter::AddString(string &str, const char* &ptr) const
443 {
444  const string txt(ptr);
445  str += ' '+txt;
446  ptr += txt.length()+1;
447 }
448 
449 // --------------------------------------------------------------------------
450 //
460 void Converter::AddString(vector<boost::any> &vec, const char* &ptr) const
461 {
462  const string txt(ptr);
463  vec.push_back(txt);
464  ptr += txt.length()+1;
465 }
466 
467 // --------------------------------------------------------------------------
468 //
482 Converter::Converter(std::ostream &out, const std::string &fmt, bool strict)
483 : wout(out), fFormat(Clean(fmt)), fList(Compile(out, fmt, strict))
484 {
485 }
486 
487 // --------------------------------------------------------------------------
488 //
501 Converter::Converter(const std::string &fmt, bool strict)
502 : wout(cout), fFormat(Clean(fmt)), fList(Compile(fmt, strict))
503 {
504 }
505 
506 // --------------------------------------------------------------------------
507 //
524 template <class T>
525 vector<T> Converter::Get(const std::string &str) const
526 {
527  if (!valid())
528  throw runtime_error("Compiled format invalid!");
529 
530  // If the format is empty we are already done
531  if (empty() && str.empty())
532  {
533  wout << endl;
534  return vector<T>();
535  }
536 
537  int arg = 0;
538  stringstream line(str);
539 
540  vector<T> data;
541 
542  for (Converter::FormatList::const_iterator i=fList.begin(); i<fList.end()-1; i++)
543  {
544  if (*i->first.first == typeid(string))
545  {
546  GetBinString(data, GetStringEol(line));
547  line.clear(ios::eofbit);
548  continue;
549  }
550 
551  // Get as many items from the input line as requested
552  for (int j=0; j<i->second.first; j++)
553  {
554  switch (i->first.first->name()[0])
555  {
556  case 'b': GetBinImp(data, GetBool(line)); break;
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;
563  case 'c':
564  {
565  const unsigned short val = Get<unsigned short>(line);
566  if (val>255)
567  line.setstate(ios::failbit);
568  GetBinImp(data, static_cast<unsigned char>(val));
569  }
570  break;
571  case 'N':
572  GetBinString(data, GetString(line));
573  if (*i->first.first == typeid(O))
574  line.clear(ios::goodbit|(line.rdstate()&ios::eofbit));
575  break;
576  default:
577  // This should never happen!
578  throw runtime_error("Format '"+string(i->first.first->name())+" not supported!");
579  }
580 
581  arg++;
582  }
583 
584  if (!line)
585  break;
586  }
587  wout << endl;
588 
589  // Something wrong with the conversion (e.g. 5.5 for an int)
590  if (line.fail() && !line.eof())
591  {
592  line.clear(); // This is necesasary to get a proper response from tellg()
593 
594  ostringstream err;
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());
599  }
600 
601  // Not enough arguments, we have not reached the end
602  if (line.fail() && line.eof())
603  {
604  line.clear();
605 
606  ostringstream err;
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());
611  }
612 
613  // Too many arguments, we have not reached the end
614  // Unfortunately, this can also mean that there is something
615  // wrong with the last argument
616  if (line.good() && !line.eof())
617  {
618  ostringstream err;
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());
623  }
624 
625  return data;
626 
627 }
628 
629 std::vector<boost::any> Converter::GetAny(const std::string &str) const
630 {
631  return Get<boost::any>(str);
632 }
633 
634 std::vector<char> Converter::GetVector(const std::string &str) const
635 {
636  return Get<char>(str);
637 }
638 
639 // --------------------------------------------------------------------------
640 //
655 template<class T>
656 T Converter::Get(const void *dat, size_t size) const
657 {
658  if (!valid())
659  throw runtime_error("Compiled format invalid!");
660 
661  if (dat==0)
662  throw runtime_error("Data pointer == NULL!");
663 
664  const char *ptr = reinterpret_cast<const char *>(dat);
665 
666  T text;
667  for (Converter::FormatList::const_iterator i=fList.begin(); i<fList.end()-1; i++)
668  {
669  if (ptr-size>dat)
670  {
671  ostringstream err;
672  err << "Format description [fmt=" << fFormat << "|size=" << GetSize() << "] exceeds available data size (" << size << ")";
673  throw runtime_error(err.str());
674  }
675 
676  if (*i->first.first == typeid(string))
677  {
678  if (size>0)
679  AddString(text, ptr);
680  if (ptr-size<=dat)
681  return text;
682  break;
683  }
684 
685  // Get as many items from the input line as requested
686  for (int j=0; j<i->second.first; j++)
687  {
688  switch (i->first.first->name()[0])
689  {
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;
698  case 'N': AddString(text, ptr); break;
699 
700  case 'v':
701  // This should never happen!
702  throw runtime_error("Type 'void' not supported!");
703  default:
704  throw runtime_error("TypeId '"+string(i->first.first->name())+"' not known!");
705  }
706  }
707  }
708 
709  if (ptr-size!=dat)
710  {
711  ostringstream err;
712  err << "Data block size (" << size << ") doesn't fit format description [fmt=" << fFormat << "|size=" << GetSize() <<"]";
713  throw runtime_error(err.str());
714  }
715 
716  return text;
717 }
718 
719 std::vector<boost::any> Converter::GetAny(const void *dat, size_t size) const
720 {
721  return Get<vector<boost::any>>(dat, size);
722 }
723 
724 std::vector<char> Converter::GetVector(const void *dat, size_t size) const
725 {
726  const string ref = GetString(dat, size);
727 
728  vector<char> data;
729  data.insert(data.begin(), ref.begin()+1, ref.end());
730  data.push_back(0);
731 
732  return data;
733 }
734 
735 string Converter::GetString(const void *dat, size_t size) const
736 {
737  const string s = Get<string>(dat, size);
738  return s.empty() ? s : s.substr(1);
739 }
740 
741 template<class T>
743 {
744  Type t;
745  t.first = &typeid(T);
746  t.second = sizeof(T);
747  return t;
748 }
749 
750 template<class T>
752 {
753  Type t;
754  t.first = &typeid(T);
755  t.second = 0;
756  return t;
757 }
758 
759 // --------------------------------------------------------------------------
760 //
774 Converter::FormatList Converter::Compile(std::ostream &out, const std::string &fmt, bool strict)
775 {
776  ostringstream text;
777 
778  // Access both, the data and the format through a stringstream
779  stringstream stream(fmt);
780 
781  // For better performance we could use sregex
782  static const boost::regex expr1("^([CSILFDXBOW])(:([1-9]+[0-9]*))?$");
783  static const boost::regex expr2("^([CSILFDX])(:([1-9]+[0-9]*))?$");
784 
785  FormatList list;
786  Format format;
787 
788  // Tokenize the format
789  string buffer;
790  while (getline(stream, buffer, ';'))
791  {
792  boost::smatch what;
793  if (!boost::regex_match(buffer, what, strict?expr2:expr1))
794  {
795  out << kRed << "Wrong format string '" << buffer << "'!" << endl;
796  return FormatList();
797  }
798 
799  const string t = what[1]; // type id
800  const string n = what[3]; // counter
801 
802  const int cnt = n.empty() ? 0 : stoi(n);
803 
804  // if the :N part was not given assume 1
805  format.second.first = cnt == 0 ? 1 : cnt;
806 
807  /*
808  if (strict && t[0]=='C' && cnt>0)
809  {
810  out << kRed << "Dim doesn't support the format C with N>0!" << endl;
811  return FormatList();
812  }*/
813 
814  // Check if the format is just C (without a number)
815  // That would mean that it is a \0 terminated string
816  if (t[0]=='C' && cnt==0)
817  {
818  format.first = GetType<string>();
819  list.push_back(format);
820  format.second.second = 0; // end position not known
821  break;
822  }
823 
824  // Get as many items from the input line as requested
825  switch (t[0])
826  {
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;
837  default:
838  // This should never happen!
839  out << kRed << "Format '" << t[0] << " not known!" << endl;
840  return list;
841  }
842 
843  list.push_back(format);
844  format.second.second += format.first.second * format.second.first;
845  }
846 
847  format.first = GetVoid<void>();
848  format.second.first = 0;
849 
850  list.push_back(format);
851 
852  return list;
853 }
854 
855 // --------------------------------------------------------------------------
856 //
861 Converter::FormatList Converter::Compile(const std::string &fmt, bool strict)
862 {
863  return Compile(cout, fmt, strict);
864 }
865 
866 vector<string> Converter::Regex(const string &expr, const string &line)
867 {
868  const boost::regex reg(expr);
869 
870  boost::smatch what;
871  if (!boost::regex_match(line, what, reg, boost::match_extra))
872  return vector<string>();
873 
874  vector<string> ret;
875  for (unsigned int i=0; i<what.size(); i++)
876  ret.push_back(what[i]);
877 
878  return ret;
879 }
880 
881 // --------------------------------------------------------------------------
882 //
891 void Converter::ToFits(void *dest, const void *src, size_t size) const
892 {
893  // crawl through the src buffer and copy the data appropriately to the
894  // destination buffer
895  // Assumption: the string is always last. This way we
896  // use the provided size to determine the number
897  // of character to copy
898 
899  char *charDest = static_cast<char*>(dest);
900  const char *charSrc = static_cast<const char*>(src);
901 
902  // We skip the last element 'v'
903  for (Converter::FormatList::const_iterator i=fList.begin(); i!=fList.end()-1; i++)
904  {
905  /*
906  // For speed reasons we don't do a check in the loop
907  if (charDest-size>dest || charSrc-size>src)
908  {
909  ostringstream err;
910  err << "Format description [fmt=" << fFormat << "] exceeds available data size (" << size << ")";
911  throw runtime_error(err.str());
912  }
913  */
914 
915  // Skip strings (must be the last, so we could just skip it)
916  const char type = i->first.first->name()[0];
917  if (type=='S')
918  {
919  charSrc += strlen(charSrc)+1;
920  continue;
921  }
922 
923  const int s = i->first.second; // size of element
924  const int n = i->second.first; // number of elements
925 
926  // Check if there are types with unknown sizes
927  if (s==0 || n==0)
928  throw runtime_error(string("Type '")+type+"' not supported converting to FITS.");
929 
930  // Let the compiler do some optimization
931  switch (s)
932  {
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;
937  }
938  }
939 
940  if (charDest-size!=dest/* || charSrc-size!=src*/)
941  {
942  ostringstream err;
943  err << "ToFits - Data block size (" << size << ") doesn't fit format description [fmt=" << fFormat << "|size=" << GetSize() << "]";
944  throw runtime_error(err.str());
945  }
946 }
947 
948 vector<string> Converter::ToStrings(const void *src/*, size_t size*/) const
949 {
950  const char *charSrc = static_cast<const char*>(src);
951 
952  vector<string> rc;
953 
954  for (Converter::FormatList::const_iterator i=fList.begin(); i!=fList.end(); i++)
955  {
956  /*
957  if (charSrc-size>src)
958  {
959  ostringstream err;
960  err << "Format description [fmt=" << fFormat << "] exceeds available data size (" << size << ")";
961  throw runtime_error(err.str());
962  }*/
963 
964  const char type = i->first.first->name()[0];
965  if (type=='v')
966  break;
967 
968  if (type=='S' || type=='N')
969  {
970  const string str(charSrc);
971  rc.push_back(str);
972  charSrc += str.length()+1;
973  continue;
974  }
975 
976  // string types
977  //if (string("bsilfdxc").find_first_of(type)==string::npos)
978  // throw runtime_error(string("Type '")+type+"' not supported converting to FITS.");
979 
980  const int s = i->first.second; // size of element
981  const int n = i->second.first; // number of elements
982 
983  charSrc += s*n;
984  }
985 
986  return rc;
987 
988  /*
989  if (charSrc-size!=src)
990  {
991  ostringstream err;
992  err << "Data block size (" << size << ") doesn't fit format description [fmt=" << fFormat << "]";
993  throw runtime_error(err.str());
994  }*/
995 }
996 
997 vector<char> Converter::ToFits(const void *src, size_t size) const
998 {
999  vector<char> dest(size);
1000  ToFits(dest.data(), src, size);
1001  return dest;
1002 }
1003 
1004 string Converter::ToFormat(const vector<string> &fits)
1005 {
1006  ostringstream str;
1007  for (vector<string>::const_iterator it=fits.begin(); it!=fits.end(); it++)
1008  {
1009  size_t id=0;
1010  int n;
1011 
1012  try
1013  {
1014  n = stoi(*it, &id);
1015  }
1016  catch (exception&)
1017  {
1018  n = 1;
1019  }
1020 
1021  if (n==0)
1022  continue;
1023 
1024  switch ((*it)[id])
1025  {
1026  case 'A':
1027  case 'L':
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;
1034  default:
1035  throw runtime_error("ToFormat - id not known.");
1036  }
1037  }
1038 
1039  return str.str().substr(1);
1040 }
1041 
1042 vector<string> Converter::GetFitsFormat() const
1043 {
1044  //we've got a nice structure describing the format of this service's messages.
1045  //Let's create the appropriate FITS columns
1046  vector<string> vec;
1047  for (FormatList::const_iterator it=fList.begin(); it!=fList.end(); it++)
1048  {
1049  ostringstream dataQualifier;
1050  dataQualifier << it->second.first;
1051 
1052  switch (it->first.first->name()[0])
1053  {
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;
1061  case 'v':
1062  case 'S': //we skip the variable length strings
1063  case 'N':
1064  continue;
1065 
1066  default:
1067  throw runtime_error(string("GetFitsFormat - unknown FITS format [")+it->first.first->name()[0]+"]");
1068  };
1069 
1070  vec.push_back(dataQualifier.str());
1071  }
1072 
1073  return vec;
1074 }
1075 
1076 void Converter::Print(std::ostream &out) const
1077 {
1078  for (FormatList::const_iterator i=fList.begin(); i!=fList.end(); i++)
1079  {
1080  out << "Type=" << i->first.first->name() << "[" << i->first.second << "] ";
1081  out << "N=" << i->second.first << " ";
1082  out << "offset=" << i->second.second << endl;
1083  }
1084 }
1085 
1086 void Converter::Print() const
1087 {
1088  return Print(cout);
1089 }
char str[20]
Definition: test_client.c:23
std::vector< Format > FormatList
Definition: Converter.h:22
T Get(std::stringstream &line) const
Compiled format description.
Definition: Converter.cc:212
int i
Definition: db_dim_client.c:21
void Add(std::string &str, const char *&ptr) const
Definition: Converter.cc:404
char str[80]
Definition: test_client.c:7
bool valid() const
Definition: Converter.h:83
Set color Red.
Definition: WindowLog.h:17
STL namespace.
std::vector< boost::any > GetAny(const void *d, size_t size) const
Definition: Converter.cc:719
std::string GetString(std::stringstream &line) const
Definition: Converter.cc:294
std::ostream & wout
Definition: Converter.h:30
static std::string Clean(std::string s)
Definition: Converter.cc:93
Definition: fits.h:54
int type
void GetBinImp(std::vector< char > &v, const T &val) const
Definition: Converter.cc:123
static FormatList Compile(std::ostream &out, const std::string &fmt, bool strict=false)
Definition: Converter.cc:774
static std::vector< std::string > Regex(const std::string &expr, const std::string &line)
Definition: Converter.cc:866
void GetBinString(std::vector< char > &v, const std::string &val) const
Definition: Converter.cc:169
static Type GetVoid()
Definition: Converter.cc:751
static Type GetType()
Definition: Converter.cc:742
bool GetBool(std::stringstream &line) const
Definition: Converter.cc:263
int buffer[BUFFSIZE]
Definition: db_dim_client.c:14
std::pair< const std::type_info *, int > Type
Definition: Converter.h:19
int size
Definition: db_dim_server.c:17
float data[4 *1440]
std::pair< Type, Offset > Format
Definition: Converter.h:21
static std::string ToFormat(const std::vector< std::string > &fits)
Definition: Converter.cc:1004
TT t
Definition: test_client.c:26
std::string GetStringEol(std::stringstream &line) const
Definition: Converter.cc:326
Converter(std::ostream &out, const std::string &fmt, bool strict=true)
Definition: Converter.cc:482
std::string Trim(const std::string &str)
Definition: tools.cc:68
const FormatList fList
Original format string.
Definition: Converter.h:33
void Print() const
Definition: Converter.cc:1086
bool empty() const
Definition: Converter.h:80
void AddString(std::string &str, const char *&ptr) const
Definition: Converter.cc:442
size_t GetSize() const
Definition: Converter.h:89
std::vector< std::string > ToStrings(const void *src) const
Definition: Converter.cc:948
const std::string fFormat
ostream to which output is redirected
Definition: Converter.h:32
std::vector< std::string > GetFitsFormat() const
Definition: Converter.cc:1042
std::vector< char > GetVector(const void *d, size_t size) const
Definition: Converter.cc:724
void ToFits(void *dest, const void *src, size_t size) const
Definition: Converter.cc:891