src/: +streamfer*
[nethome.git] / src / safeio.h
1 #ifndef LIB_SAFEIO_H
2 #define LIB_SAFEIO_H
3
4 #include "streamfer.h"
5 #include <sys/uio.h>
6 #include <stdio.h>
7 #include <unistd.h>
8 #include <exception>
9 #include <vector>
10 #include <string>
11 #include <array>
12 #include <deque>
13 #include <cassert>
14 #include <cstdint>
15 #include <cstring>
16
17 extern const class SafeIOError:public exception {
18   virtual const char *what() const noexcept override { return "SafeIOError"; }
19 } exception_SafeIOError;
20 extern const class SafeIOEOF:public SafeIOError {
21   virtual const char *what() const noexcept override { return "SafeIOEOF"; }
22 } exception_SafeIOEOF;
23
24 void read_safe(int fd ,void *buf,size_t len);
25 void read_safe(FILE *f,void *buf,size_t len);
26
27 template<class F,class T> void read_safe(F f,       T  &obj) { read_safe(f,&obj,sizeof(obj)); }
28
29 template<class F,class T> void read_safe(F f,vector<T> &vec) {
30   size_t size;
31   read_safe(f,size);
32   vec.resize(size);
33   if (size)
34     read_safe(f,vec.data(),vec.size()*sizeof(vec[0]));
35 }
36
37 template<class F,class T> void read_safe(F f,deque<T> &vec) {
38   size_t size;
39   read_safe(f,size);
40   vec.resize(size);
41   for (auto &elem:vec)
42     read_safe(f,elem);
43 }
44
45 template<class F> void read_safe(F f,string &str) {
46   uint8_t len8=0; // false GCC warning
47   read_safe(f,len8);
48   str.resize(len8);
49   if (len8)
50     read_safe(f,&str[0],str.length());
51 }
52
53 template<class F> string read_safe_string(F f) { string str; read_safe(f,str); return str; }
54
55 void write_safe(int fd ,const void *buf,size_t count);
56 void write_safe(FILE *f,const void *buf,size_t count);
57 void writev_safe_(int fd,const struct iovec *iov, int iovcnt);
58 constexpr iovec writev_iovec(const void *base,size_t len) { return iovec{const_cast<void *>(base),len}; }
59 static inline const/*FIXME:constexpr c_str()*/ iovec iovec_for_string(const string &str) { return iovec{const_cast<char *>(str.c_str()),str.length()}; }
60 template<class T> constexpr iovec iovec_for_object(T &object) { return iovec{reinterpret_cast<void *>(const_cast<typename std::remove_const<T>::type *>(&object)),sizeof(object)}; }
61 template<size_t iovcnt> void writev_safe(int fd,std::array<iovec,iovcnt> iov) {
62   writev_safe_(fd,iov.data(),iovcnt);
63 }
64
65 template<class F,class T> void write_safe(F f,const        T  &obj) { write_safe(f,&obj,sizeof(obj)); }
66
67 template<class F,class T> void write_safe(F f,const vector<T> &vec) {
68   const size_t size(vec.size());
69   write_safe(f,size);
70   if (size)
71     write_safe(f,vec.data(),size*sizeof(vec[0]));
72 }
73
74 template<class F,class T> void write_safe(F f,const deque<T> &vec) {
75   const size_t size(vec.size());
76   write_safe(f,size);
77   for (const auto &elem:vec)
78     write_safe(f,elem);
79 }
80
81 template<class F> void write_safe(F f,const string &str) {
82   const uint8_t len8(str.length());
83   assert(len8==str.length());
84   write_safe(f,len8);
85   if (!str.empty())
86     write_safe(f,str.c_str(),len8);
87 }
88
89 #endif /* LIB_SAFEIO_H */