FairRoot
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TriviallyCopyableDataSaver.h
Go to the documentation of this file.
1 /*
2  * File: TriviallyCopyableDataSaver.h
3  * Author: winckler
4  *
5  * Created on October 22, 2014, 5:45 PM
6  */
7 
8 #ifndef TRIVIALLYCOPYABLEDATASAVER_H
9 #define TRIVIALLYCOPYABLEDATASAVER_H
10 
11 #include <FairMQMessage.h>
12 
13 template<typename TPayload>
15 {
16  public:
19 
20  virtual void InitOutputFile() {}
21 
22  void Write(std::ofstream& outfile, TPayload* ObjArr, long sizeArr = 1)
23  {
24  // if (std::is_trivially_copyable<TPayload>::value) not implemented yet in gcc 4.8.2
25  if (std::is_trivial<TPayload>::value) {
26  write_pod_array<TPayload>(outfile, ObjArr, sizeArr);
27  outfile.close();
28  }
29  }
30 
31  void Write(std::ofstream& outfile, FairMQMessage* msg)
32  {
33  int inputSize = msg->GetSize();
34  long sizeArr = 0;
35  if (inputSize > 0) {
36  sizeArr = inputSize / sizeof(TPayload);
37  }
38  TPayload* ObjArr = static_cast<TPayload*>(msg->GetData());
39  // if (std::is_trivially_copyable<TPayload>::value)
40  if (std::is_trivial<TPayload>::value) {
41  write_pod_array<TPayload>(outfile, ObjArr, sizeArr);
42  outfile.close();
43  }
44  }
45 
46  std::vector<std::vector<TPayload>> Read(std::ifstream& infile)
47  {
48  std::vector<std::vector<TPayload>> DataContainer;
49  ReadArr(infile, DataContainer);
50  return DataContainer;
51  }
52 
53  void ReadArr(std::ifstream& infile, std::vector<std::vector<TPayload>>& DataContainer)
54  {
55  // if (std::is_trivially_copyable<TPayload>::value)
56  if (std::is_trivial<TPayload>::value) {
57  int c = infile.peek();
58  if (c == EOF) {
59  if (infile.eof()) {
60  infile.close();
61  }
62  } else {
63  long sizeArr;
64  read_pod<long>(infile, sizeArr);
65  TPayload* ObjArr = new TPayload[sizeArr];
66  infile.read(reinterpret_cast<char*>(ObjArr), sizeArr * sizeof(TPayload));
67  std::vector<TPayload> DataVector(ObjArr, ObjArr + sizeArr);
68  delete[] ObjArr;
69  DataContainer.push_back(DataVector);
70  ReadArr(infile, DataContainer);
71  }
72  } else {
73  LOG(error) << "In ReadArr(std::ifstream& , std::vector<std::vector<TPayload> >& ) :";
74  LOG(error)
75  << "(de)serialization of object is not supported (Object must be a 'trivially copyable' data class).";
76  }
77  }
78 
79  template<typename T>
80  void ReadArr(std::ifstream& infile, T* ObjArr, long posArr = 0)
81  {
82  // if(std::is_trivially_copyable<T>::value)
83  if (std::is_trivial<TPayload>::value) {
84  int c = infile.peek();
85  if (c == EOF) {
86  if (infile.eof()) {
87  infile.close();
88  }
89  } else {
90  posArr += read_pod_array<T>(infile, ObjArr, posArr);
91  ReadArr<T>(infile, ObjArr, posArr);
92  }
93  } else {
94  LOG(error) << "In ReadArr(std::ifstream& infile, T* ObjArr, long posArr = 0):";
95  LOG(error)
96  << "(de)serialization of object is not supported (Object must be a 'trivially copyable' data class).";
97  }
98  }
99 
100  template<typename T>
101  void write_pod(std::ofstream& out, T& t)
102  {
103  out.write(reinterpret_cast<char*>(&t), sizeof(T));
104  }
105 
106  template<typename T>
107  void read_pod(std::ifstream& in, T& t)
108  {
109  in.read(reinterpret_cast<char*>(&t), sizeof(T));
110  }
111 
112  template<typename T>
113  void write_pod_vector(std::ofstream& out, std::vector<T>& vect)
114  {
115  long size = vect.size();
116  write_pod<long>(out, size);
117  out.write(reinterpret_cast<char*>(vect.front()), size * sizeof(T));
118  }
119 
120  template<typename T>
121  void read_pod_vector(std::ifstream& in, std::vector<T>& vect)
122  {
123  long size;
124  read_pod(in, size);
125  vect.resize(size);
126  in.read(reinterpret_cast<char*>(vect.front()), size * sizeof(T));
127  }
128 
129  template<typename T>
130  void write_pod_array(std::ofstream& out, T* objarr, long size)
131  {
132  write_pod<long>(out, size);
133  out.write(reinterpret_cast<char*>(objarr), size * sizeof(T));
134  }
135 
136  template<typename T>
137  int count_podObj_inFile(std::ifstream& in)
138  {
139  int count = 0;
140  // if (std::is_trivially_copyable<T>::value)
141  if (std::is_trivial<TPayload>::value) {
142  int c = in.peek();
143  if (c == EOF) {
144  if (in.eof()) {
145  in.close();
146  }
147  } else {
148  long size;
149  read_pod<long>(in, size);
150  count += size;
151  in.seekg(size * sizeof(T), std::ios::cur);
152  count += count_podObj_inFile<T>(in);
153  }
154  }
155  return count;
156  }
157 
158  template<typename T>
159  long read_pod_array(std::ifstream& in, T* objarr, long posArr = 0)
160  {
161  long size;
162  read_pod<long>(in, size);
163  in.read(reinterpret_cast<char*>(objarr + posArr), size * sizeof(T));
164  return size;
165  }
166 };
167 
168 #endif /* TRIVIALLYCOPYABLEDATASAVER_H */
void read_pod(std::ifstream &in, T &t)
std::vector< std::vector< TPayload > > Read(std::ifstream &infile)
void write_pod_vector(std::ofstream &out, std::vector< T > &vect)
void Write(std::ofstream &outfile, TPayload *ObjArr, long sizeArr=1)
void ReadArr(std::ifstream &infile, std::vector< std::vector< TPayload >> &DataContainer)
void write_pod_array(std::ofstream &out, T *objarr, long size)
void Write(std::ofstream &outfile, FairMQMessage *msg)
void ReadArr(std::ifstream &infile, T *ObjArr, long posArr=0)
int count_podObj_inFile(std::ifstream &in)
void write_pod(std::ofstream &out, T &t)
void read_pod_vector(std::ifstream &in, std::vector< T > &vect)
long read_pod_array(std::ifstream &in, T *objarr, long posArr=0)