ROSE  0.11.50.0
io-utility.h
1 #ifndef ROSE_BinaryAnalysis_Concolic_io_utility_H
2 #define ROSE_BinaryAnalysis_Concolic_io_utility_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_CONCOLIC_TESTING
5 #include <Rose/BinaryAnalysis/Concolic.h>
6 
8 
9 #include <fstream>
10 #include <streambuf>
11 #include <string>
12 #include <vector>
13 
14 namespace Rose {
15 namespace BinaryAnalysis {
16 namespace Concolic {
17 
25 template <class Container>
26 Container
27 loadFile(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)
28 {
29  typedef std::istreambuf_iterator<char> stream_iterator;
30 
31  std::ifstream stream(filename.c_str(), mode);
32 
33  if (!stream.good())
34  throw std::runtime_error("Unable to open " + filename + ".");
35 
36  Container res;
37 
38  // \todo reserve capacity in res
39  std::copy(stream_iterator(stream), stream_iterator(), std::back_inserter(res));
40  return res;
41 }
42 
43 
48 template <class T, class CharT = char, class Traits = std::char_traits<CharT> >
49 struct OStreamBinaryIterator : std::iterator<std::output_iterator_tag, void, void, void, void>
50 {
51  typedef std::basic_ostream<CharT, Traits> ostream_type;
52  typedef Traits traits_type;
53  typedef CharT char_type;
54 
56  explicit
57  OStreamBinaryIterator(ostream_type& s) : stream(s) { }
58 
60  OStreamBinaryIterator& operator=(const T& value)
61  {
62  stream.write(reinterpret_cast<const char*>(&value), sizeof(T));
63  return *this;
64  }
65 
69  OStreamBinaryIterator& operator*() { return *this; }
70  OStreamBinaryIterator& operator++() { return *this; }
71  OStreamBinaryIterator& operator++(int) { return *this; }
74  private:
75  ostream_type& stream;
76 
77  OStreamBinaryIterator();
78  OStreamBinaryIterator& operator=(const OStreamBinaryIterator&);
79 };
80 
87 template <class T>
88 struct FileSink
89 {
90  typedef OStreamBinaryIterator<T> insert_iterator;
91 
93  explicit
94  FileSink(std::ostream& stream)
95  : datastream(stream)
96  {}
97 
99  void reserve(size_t) {}
100 
102  insert_iterator
103  inserter()
104  {
105  return insert_iterator(datastream);
106  }
107 
108  private:
109  std::ostream& datastream;
110 };
111 
112 
121 template <class Container>
122 void
123 storeFile(const Container& data, const std::string& filename, std::ios_base::openmode mode = std::ios_base::out)
124 {
125  std::ofstream stream(filename.c_str(), mode);
126 
127  if (!stream.good())
128  throw std::runtime_error("Unable to open " + filename + ".");
129 
130  FileSink<char> sink(stream);
131 
132  sink.reserve(data.size());
133  std::copy(data.begin(), data.end(), sink.inserter());
134 }
135 
136 
137 namespace
138 {
143  inline
144  std::string
145  loadTextFile(const boost::filesystem::path& path)
146  {
147  return loadFile<std::string>(path.string());
148  }
149 
150 
155  inline
156  void
157  storeTextFile(const std::string& data, const boost::filesystem::path& path)
158  {
159  storeFile(data, path.string());
160  }
161 
162 
167  inline
168  std::vector<uint8_t>
169  loadBinaryFile(const boost::filesystem::path& path)
170  {
171  return loadFile<std::vector<uint8_t> >(path.string(), std::ios::in | std::ios::binary);
172  }
173 
178  inline
179  void
180  storeBinaryFile(const std::vector<uint8_t>& data, const boost::filesystem::path& path)
181  {
182  storeFile(data, path.string(), std::ofstream::binary);
183  }
184 } // anonymous namespace
185 
186 } // namespace Concolic
187 } // namespace BinaryAnalysis
188 } // namespace Rose
189 
190 #endif
191 #endif
Main namespace for the ROSE library.