Elaboradar  0.1
 Tutto Classi Namespace File Funzioni Variabili Tipi enumerati (enum) Gruppi
utils.cpp
1 #include "utils.h"
2 #include "logging.h"
3 #include <cstdlib>
4 #include <string>
5 #include <stdexcept>
6 #include <cstring>
7 #include <cerrno>
8 
9 using namespace std;
10 
11 namespace radarelab {
12 
13 File::File()
14  : logging_category(log4c_category_get("radar.utils"))
15 {
16 }
17 
18 File::File(File&& f)
19  : logging_category(f.logging_category),
20  fname(std::move(f.fname)),
21  fdesc(std::move(f.fdesc)),
22  fd(f.fd)
23 {
24  f.fd = 0;
25 }
26 
27 File::File(log4c_category_t* logging_category)
28  : logging_category(logging_category)
29 {
30 }
31 
32 File::~File()
33 {
34  if (fd) fclose(fd);
35 }
36 
37 bool File::open_from_env(const char* varname, const char* mode, const char* desc)
38 {
39  const char* envfname = getenv(varname);
40  if (!envfname)
41  {
42  LOG_ERROR("$%s is not set", varname);
43  return false;
44  }
45 
46  return open(envfname, mode, desc);
47 }
48 
49 bool File::open(const std::string& pathname, const char* mode, const char* desc)
50 {
51  if (fd)
52  {
53  fclose(fd);
54  fd = nullptr;
55  fname.clear();
56  fdesc.clear();
57  }
58 
59  fd = fopen(pathname.c_str(), mode);
60  if (!fd)
61  {
62  if (desc)
63  LOG_ERROR("Cannot open %s (%s): %s", pathname.c_str(), desc, strerror(errno));
64  else
65  LOG_ERROR("Cannot open %s: %s", pathname.c_str(), strerror(errno));
66  return false;
67  }
68 
69  fname = pathname;
70  if (desc) fdesc = desc;
71 
72  return true;
73 }
74 
75 void File::read_lines(std::function<void (char*, size_t)> line_cb)
76 {
77  char *line = NULL;
78  size_t len = 0;
79 
80  while (true)
81  {
82  errno = 0;
83  ssize_t read = getline(&line, &len, fd);
84  if (read == -1)
85  {
86  if (errno == 0)
87  {
88  break;
89  } else {
90  string errmsg("cannot read ");
91  errmsg += fname;
92  errmsg += ": ";
93  errmsg += strerror(errno);
94  if (line) free(line);
95  throw runtime_error(errmsg);
96  }
97  }
98  try {
99  line_cb(line, read);
100  } catch (...) {
101  if (line) free(line);
102  throw;
103  }
104  }
105 
106  if (line) free(line);
107 }
108 
109 bool File::fread(void* buf, size_t size)
110 {
111  if (::fread(buf, size, 1, fd) != 1)
112  {
113  if (feof(fd))
114  return false;
115 
116  string errmsg("read failed on ");
117  errmsg += fname;
118  errmsg += ": ";
119  errmsg += strerror(errno);
120  throw runtime_error(errmsg);
121  }
122  return true;
123 }
124 
125 void File::fseek(size_t seek_par, int origin)
126 {
127  if (::fseek(fd,seek_par,origin) == -1)
128  {
129  string errmsg("fseek failed on ");
130  errmsg += fname;
131  errmsg += ": ";
132  errmsg += strerror(errno);
133  throw runtime_error(errmsg);
134  }
135 }
136 
137 const char* getenv_default(const char* envname, const char* default_value)
138 {
139  const char* res = getenv(envname);
140  if (res) return res;
141  return default_value;
142 }
143 
144 FILE* fopen_checked(const char* fname, const char* mode, const char* description)
145 {
146  FILE* res = fopen(fname, mode);
147  if (!res)
148  {
149  string errmsg("cannot open ");
150  if (description)
151  {
152  errmsg += description;
153  errmsg += " ";
154  }
155  errmsg += fname;
156  errmsg += " (";
157  errmsg += mode;
158  errmsg += "): ";
159  errmsg += strerror(errno);
160  throw runtime_error(errmsg);
161  }
162  return res;
163 }
164 
165 void str_split(char* str, const char* sep, std::function<void (const char* tok)> val_cb)
166 {
167  char* saveptr;
168  while (true)
169  {
170  char* tok = strtok_r(str, sep, &saveptr);
171  if (tok == NULL) break;
172  val_cb(tok);
173  str = NULL;
174  }
175 }
176 
177 }
bool fread(void *buf, size_t size)
Performs a fread on the file, throwing an exception if anything goes wrong.
Definition: utils.cpp:109
void read_lines(std::function< void(char *, size_t)> line_cb)
Read the file line by line, calling line_cb on each line read.
Definition: utils.cpp:75
FILE * fopen_checked(const char *fname, const char *mode, const char *description)
A wrapper of fopen that throws an exception if it cannot open the file.
Definition: utils.cpp:144
void str_split(char *str, const char *sep, std::function< void(const char *tok)> val_cb)
Split a string in tokens, skipping the given separator characters.
Definition: utils.cpp:165
bool open_from_env(const char *varname, const char *mode, const char *desc=nullptr)
Opens a file taking its name from the environment variable envname.
Definition: utils.cpp:37
const char * getenv_default(const char *envname, const char *default_value)
A wrapper of getenv, that returns &#39;default_value&#39; if the given environment name is not defined...
Definition: utils.cpp:137
bool open(const std::string &fname, const char *mode, const char *desc=nullptr)
Opens a file by its pathname.
Definition: utils.cpp:49