licornea_tools
io.cc
Go to the documentation of this file.
1 #include "io.h"
2 
3 #include <istream>
4 #include <ostream>
5 #include <fstream>
6 #include <stdexcept>
7 #include <cstdint>
8 #include <type_traits>
9 #include <cctype>
10 
11 namespace tlz {
12 
13 namespace {
14  bool check_host_little_endian_() {
15  union {
16  std::uint16_t s;
17  std::uint8_t c[2];
18  } d;
19  d.s = 1;
20  return d.c[0] == 1;
21  }
22 }
23 
24 
26 
28  std::numeric_limits<float>::is_iec559 && std::numeric_limits<double>::is_iec559;
29 
30 const bool host_is_little_endian = check_host_little_endian_();
31 
32 
33 
34 line_delimitor detect_line_delimitor(std::istream& str, std::size_t max_offset) {
35  std::size_t counter = 0;
37  auto old_position = str.tellg();
38  while(ld == line_delimitor::unknown) {
39  if(++counter > max_offset) throw std::runtime_error("could not detect file line ending");
40  char c;
41  str.get(c);
42  if(c == '\n') ld = line_delimitor::LF;
43  else if(c == '\r') {
44  if(str.peek() == '\n') ld = line_delimitor::CRLF;
45  else ld = line_delimitor::CR;
46  }
47  }
48  str.seekg(old_position);
49  return ld;
50 }
51 
52 void read_line(std::istream& str, std::string& line, line_delimitor ld) {
53  if(ld == line_delimitor::unknown) throw std::invalid_argument("line delimitor not specified");
54 
55  if(ld == line_delimitor::CRLF) {
56  std::getline(str, line, '\r');
57  while(str.peek() != '\n') {
58  std::string part_line;
59  std::getline(str, part_line, '\r');
60  line.append(1, '\r').append(part_line);
61  }
62  str.get();
63  } else {
64  std::getline(str, line, (ld == line_delimitor::LF ? '\n' : '\r'));
65  }
66 }
67 
68 void skip_line(std::istream& str, line_delimitor ld) {
69  if(ld == line_delimitor::unknown) throw std::invalid_argument("line delimitor not specified");
70  const auto max_count = std::numeric_limits<std::streamsize>::max();
71 
72  if(ld == line_delimitor::CRLF) {
73  str.ignore(max_count, '\r');
74  while(str.peek() != '\n') str.ignore(max_count, '\r');
75  str.ignore();
76  } else {
77  str.ignore(max_count, (ld == line_delimitor::LF ? '\n' : '\r'));
78  }
79 }
80 
81 
82 void write_line(std::ostream& str, const std::string& line, line_delimitor ld) {
83  str << line;
84  end_line(str, ld);
85 }
86 
87 
88 void end_line(std::ostream& str, line_delimitor ld) {
89  switch(ld) {
90  case line_delimitor::LF: str << '\n'; break;
91  case line_delimitor::CR: str << '\r'; break;
92  case line_delimitor::CRLF: str << "\r\n"; break;
93  default: throw std::invalid_argument("line delimitor not specified");
94  }
95 }
96 
97 
98 
99 
100 void flip_endianness(byte* data, std::size_t sz) {
101  if(sz < 2) return;
102  std::ptrdiff_t i = sz/2 - 1;
103  std::ptrdiff_t o = sz - i - 1;
104  while(i >= 0) std::swap(data[i--], data[o++]);
105 }
106 
107 
108 }
const bool host_is_little_endian
Definition: io.cc:30
void end_line(std::ostream &str, line_delimitor ld)
Definition: io.cc:88
void skip_line(std::istream &str, line_delimitor ld)
Definition: io.cc:68
const line_delimitor default_line_delimitor
Definition: io.cc:25
void read_line(std::istream &str, std::string &line, line_delimitor ld)
Definition: io.cc:52
const bool host_has_iec559_float
Definition: io.cc:27
line_delimitor
Definition: io.h:11
line_delimitor detect_line_delimitor(std::istream &str, std::size_t max_offset)
Detects line delimitor used in given file.
Definition: io.cc:34
std::uint8_t byte
Definition: common.h:17
void write_line(std::ostream &str, const std::string &line, line_delimitor ld)
Definition: io.cc:82
void flip_endianness(byte *data, std::size_t sz)
Definition: io.cc:100