#ifndef LIB_SAFEIO_H #define LIB_SAFEIO_H #include "streamfer.h" #include #include #include #include #include #include #include #include #include #include #include extern const class SafeIOError:public exception { virtual const char *what() const noexcept override { return "SafeIOError"; } } exception_SafeIOError; extern const class SafeIOEOF:public SafeIOError { virtual const char *what() const noexcept override { return "SafeIOEOF"; } } exception_SafeIOEOF; void read_safe(int fd ,void *buf,size_t len); void read_safe(FILE *f,void *buf,size_t len); template void read_safe(F f, T &obj) { read_safe(f,&obj,sizeof(obj)); } template void read_safe(F f,vector &vec) { size_t size; read_safe(f,size); vec.resize(size); if (size) read_safe(f,vec.data(),vec.size()*sizeof(vec[0])); } template void read_safe(F f,deque &vec) { size_t size; read_safe(f,size); vec.resize(size); for (auto &elem:vec) read_safe(f,elem); } template void read_safe(F f,string &str) { uint8_t len8=0; // false GCC warning read_safe(f,len8); str.resize(len8); if (len8) read_safe(f,&str[0],str.length()); } template string read_safe_string(F f) { string str; read_safe(f,str); return str; } void write_safe(int fd ,const void *buf,size_t count); void write_safe(FILE *f,const void *buf,size_t count); void writev_safe_(int fd,const struct iovec *iov, int iovcnt); constexpr iovec writev_iovec(const void *base,size_t len) { return iovec{const_cast(base),len}; } static inline const/*FIXME:constexpr c_str()*/ iovec iovec_for_string(const string &str) { return iovec{const_cast(str.c_str()),str.length()}; } template constexpr iovec iovec_for_object(T &object) { return iovec{reinterpret_cast(const_cast::type *>(&object)),sizeof(object)}; } template void writev_safe(int fd,std::array iov) { writev_safe_(fd,iov.data(),iovcnt); } template void write_safe(F f,const T &obj) { write_safe(f,&obj,sizeof(obj)); } template void write_safe(F f,const vector &vec) { const size_t size(vec.size()); write_safe(f,size); if (size) write_safe(f,vec.data(),size*sizeof(vec[0])); } template void write_safe(F f,const deque &vec) { const size_t size(vec.size()); write_safe(f,size); for (const auto &elem:vec) write_safe(f,elem); } template void write_safe(F f,const string &str) { const uint8_t len8(str.length()); assert(len8==str.length()); write_safe(f,len8); if (!str.empty()) write_safe(f,str.c_str(),len8); } #endif /* LIB_SAFEIO_H */