From 261ef4356bcb91be640c66dd07ed38421e9a2bc0 Mon Sep 17 00:00:00 2001 From: Bob Polis Date: Sat, 11 Jul 2020 12:41:20 +0200 Subject: [PATCH] minor improvements --- libscio.hpp | 455 ++++++++++++++++++++++++------------------------ mapped_file.cpp | 9 +- 2 files changed, 237 insertions(+), 227 deletions(-) diff --git a/libscio.hpp b/libscio.hpp index cd630fd..598ceed 100644 --- a/libscio.hpp +++ b/libscio.hpp @@ -20,293 +20,298 @@ namespace sc { - namespace io { + namespace io { - class fdiobuf : public std::streambuf { - public: - fdiobuf(int fd) : _fd(fd) {} - fdiobuf() : _fd(-1) {} + class fdiobuf : public std::streambuf { + public: + fdiobuf(int fd) : _fd(fd) {} + fdiobuf() : _fd(-1) {} - int fd() const { return _fd; } - void fd(int fd) { _fd = fd; } + int fd() const { return _fd; } + void fd(int fd) { _fd = fd; } - protected: - int _fd; - char _ch {}; + protected: + int _fd; + char _ch {}; - // input - int_type underflow() override; - std::streamsize xsgetn(char* s, std::streamsize n) override; + // input + int_type underflow() override; + std::streamsize xsgetn(char* s, std::streamsize n) override; - // output - int_type overflow(int_type c) override; - std::streamsize xsputn(const char* s, std::streamsize num) override; + // output + int_type overflow(int_type c) override; + std::streamsize xsputn(const char* s, std::streamsize num) override; - // stream offset positioning - pos_type seekoff(off_type off, - std::ios_base::seekdir dir, - std::ios_base::openmode which - = std::ios_base::in | std::ios_base::out) override; - pos_type seekpos(pos_type pos, std::ios_base::openmode which - = std::ios_base::in | std::ios_base::out) override; - int_type pbackfail(int_type c = EOF) override; - }; + // stream offset positioning + pos_type seekoff(off_type off, + std::ios_base::seekdir dir, + std::ios_base::openmode which + = std::ios_base::in | std::ios_base::out) override; + pos_type seekpos(pos_type pos, std::ios_base::openmode which + = std::ios_base::in | std::ios_base::out) override; + int_type pbackfail(int_type c = EOF) override; + }; - class fdostream : public std::ostream { - public: - fdostream() : std::ostream(&_outbuf), _outbuf(-1) {} - fdostream(int fd) : std::ostream(&_outbuf), _outbuf(fd) {} + class fdostream : public std::ostream { + public: + fdostream() : std::ostream(&_outbuf), _outbuf(-1) {} + fdostream(int fd) : std::ostream(&_outbuf), _outbuf(fd) {} - // no copying - fdostream(const fdostream&) = delete; - fdostream& operator=(const fdostream&) = delete; + // no copying + fdostream(const fdostream&) = delete; + fdostream& operator=(const fdostream&) = delete; - // moving allowed - fdostream(fdostream&& other); - fdostream& operator=(fdostream&& other); + // moving allowed + fdostream(fdostream&& other); + fdostream& operator=(fdostream&& other); - // cleanup: fdostream is RAII class for open file descriptor - virtual ~fdostream(); + // cleanup: fdostream is RAII class for open file descriptor + virtual ~fdostream(); - int fd() const { return _outbuf.fd(); } - void fd(int fd) { _outbuf.fd(fd); } + int fd() const { return _outbuf.fd(); } + void fd(int fd) { _outbuf.fd(fd); } - bool is_open() const { return _outbuf.fd() != -1; } - void close(); + bool is_open() const { return _outbuf.fd() != -1; } + void close(); - protected: - fdiobuf _outbuf; - }; + protected: + fdiobuf _outbuf; + }; - class fdistream : public std::istream { - public: - fdistream() : std::istream(&_inbuf), _inbuf(-1) {} - fdistream(int fd) : std::istream(&_inbuf), _inbuf(fd) {} + class fdistream : public std::istream { + public: + fdistream() : std::istream(&_inbuf), _inbuf(-1) {} + fdistream(int fd) : std::istream(&_inbuf), _inbuf(fd) {} - // no copying - fdistream(const fdistream&) = delete; - fdistream& operator=(const fdistream&) = delete; + // no copying + fdistream(const fdistream&) = delete; + fdistream& operator=(const fdistream&) = delete; - // moving allowed - fdistream(fdistream&& other); - fdistream& operator=(fdistream&& other); + // moving allowed + fdistream(fdistream&& other); + fdistream& operator=(fdistream&& other); - // cleanup: fdistream is RAII class for open file descriptor - virtual ~fdistream(); + // cleanup: fdistream is RAII class for open file descriptor + virtual ~fdistream(); - int fd() const { return _inbuf.fd(); } - void fd(int fd) { _inbuf.fd(fd); } + int fd() const { return _inbuf.fd(); } + void fd(int fd) { _inbuf.fd(fd); } - bool is_open() const { return _inbuf.fd() != -1; } - void close(); + bool is_open() const { return _inbuf.fd() != -1; } + void close(); - protected: - fdiobuf _inbuf; - }; + protected: + fdiobuf _inbuf; + }; - class fdstream : public std::iostream { - public: - fdstream() : std::iostream(&_iobuf) {} - fdstream(int fd) : std::iostream(&_iobuf), _iobuf(fd) {} + class fdstream : public std::iostream { + public: + fdstream() : std::iostream(&_iobuf) {} + fdstream(int fd) : std::iostream(&_iobuf), _iobuf(fd) {} - // no copying - fdstream(const fdstream&) = delete; - fdstream& operator=(const fdstream&) = delete; + // no copying + fdstream(const fdstream&) = delete; + fdstream& operator=(const fdstream&) = delete; - // moving allowed - fdstream(fdstream&& other); - fdstream& operator=(fdstream&& other); + // moving allowed + fdstream(fdstream&& other); + fdstream& operator=(fdstream&& other); - // cleanup: fdstream is RAII class for open file descriptor - virtual ~fdstream(); + // cleanup: fdstream is RAII class for open file descriptor + virtual ~fdstream(); - int fd() const { return _iobuf.fd(); } - void fd(int fd) { _iobuf.fd(fd); } + int fd() const { return _iobuf.fd(); } + void fd(int fd) { _iobuf.fd(fd); } - bool is_open() const { return _iobuf.fd() != -1; } - void close(); + bool is_open() const { return _iobuf.fd() != -1; } + void close(); - protected: - fdiobuf _iobuf {-1}; - }; + protected: + fdiobuf _iobuf {-1}; + }; - struct socket_address { - std::string address; - int port; - }; + struct socket_address { + std::string address; + int port; + }; - class socketstream : public std::iostream { - public: - socketstream(); - socketstream(int domain, int type); + class socketstream : public std::iostream { + public: + socketstream(); + socketstream(int domain, int type); - // copying forbidden - socketstream(const socketstream&) = delete; - socketstream& operator=(const socketstream&) = delete; + // copying forbidden + socketstream(const socketstream&) = delete; + socketstream& operator=(const socketstream&) = delete; - // moving allowed - socketstream(socketstream&& other); - socketstream& operator=(socketstream&& other); + // moving allowed + socketstream(socketstream&& other); + socketstream& operator=(socketstream&& other); - // cleanup: socketstream is RAII class for open socket - virtual ~socketstream(); - bool is_open() { return _iobuf.fd() != -1; } - void close(); + // cleanup: socketstream is RAII class for open socket + virtual ~socketstream(); + bool is_open() { return _iobuf.fd() != -1; } + void close(); - // server - void make_server(const socket_address& sa); - socketstream accept() const; + // server + void make_server(const socket_address& sa); + socketstream accept() const; - // client - void connect(const socket_address& host); + // client + void connect(const socket_address& host); - // convenience: human-readable addresses - std::string address() const; + // convenience: human-readable addresses + std::string address() const; - // address/endpoint conversion methods - void endpoint_from_address(const socket_address& address, - struct sockaddr_storage* endpoint) const; - socket_address address_from_endpoint(const struct sockaddr* endpoint) const; + // address/endpoint conversion methods + void endpoint_from_address(const socket_address& address, + struct sockaddr_storage* endpoint) const; + socket_address address_from_endpoint(const struct sockaddr* endpoint) const; - // getters & setters - int socket() const { return _iobuf.fd(); } - void socket(int sock) { _iobuf.fd(sock); } - int domain() const { return _domain; } - void domain(int dom) { _domain = dom; } - int type() const { return _type; } - void type(int typ) { _type = typ; } - - protected: - fdiobuf _iobuf {-1}; - int _domain {0}; - int _type {0}; - struct sockaddr_storage _sa; - }; + // getters & setters + int socket() const { return _iobuf.fd(); } + void socket(int sock) { _iobuf.fd(sock); } + int domain() const { return _domain; } + void domain(int dom) { _domain = dom; } + int type() const { return _type; } + void type(int typ) { _type = typ; } - struct float_80 { - unsigned char _val[10]; // big endian + protected: + fdiobuf _iobuf {-1}; + int _domain {0}; + int _type {0}; + struct sockaddr_storage _sa; + }; - float_80(); - float_80(double val); - operator double() const; - }; + struct float_80 { + unsigned char _val[10]; // big endian - enum class byte_order { - undefined, - little_endian, - big_endian - }; + float_80(); + float_80(double val); + operator double() const; + }; - class data_streamer { - public: - static byte_order cur_byte_order(); - static inline void byte_swap(void* val, size_t n) { - char* p = reinterpret_cast(val); - for (size_t i = 0; i < n / 2; ++i) { - std::swap(p[i], p[n - 1 - i]); - } - } - template - inline T get(std::istream& file) const { - char buf[sizeof(T)]; - file.read(buf, sizeof(T)); - if (cur_byte_order() != _target_byte_order) { - byte_swap(buf, sizeof(T)); - } - return *reinterpret_cast(buf); - } - template - inline void put(T val, std::ostream& file) const { - if (cur_byte_order() != _target_byte_order) { - byte_swap(&val, sizeof(T)); - } - file.write(reinterpret_cast(&val), sizeof(T)); - } + enum class byte_order { + undefined, + little_endian, + big_endian + }; - data_streamer() = default; + class data_streamer { + public: + static byte_order cur_byte_order(); + static inline void byte_swap(void* val, size_t n) { + char* p = reinterpret_cast(val); + for (size_t i = 0; i < n / 2; ++i) { + std::swap(p[i], p[n - 1 - i]); + } + } + template + inline T get(std::istream& file) const { + char buf[sizeof(T)]; + file.read(buf, sizeof(T)); + if (cur_byte_order() != _target_byte_order) { + byte_swap(buf, sizeof(T)); + } + return *reinterpret_cast(buf); + } + template + inline void put(T val, std::ostream& file) const { + if (cur_byte_order() != _target_byte_order) { + byte_swap(&val, sizeof(T)); + } + file.write(reinterpret_cast(&val), sizeof(T)); + } - byte_order target_byte_order() const { return _target_byte_order; } - void target_byte_order(byte_order new_byte_order) { _target_byte_order = new_byte_order; } + data_streamer() = default; - std::string get4chars(std::istream& file) const; + byte_order target_byte_order() const { return _target_byte_order; } + void target_byte_order(byte_order new_byte_order) { _target_byte_order = new_byte_order; } - uint8_t getui8(std::istream& file) const { return static_cast(file.get()); } - int8_t getsi8(std::istream& file) const { return file.get(); } - uint16_t getui16(std::istream& file) const { return get(file); } - int16_t getsi16(std::istream& file) const { return get(file); } - uint32_t getui24(std::istream& file) const; - int32_t getsi24(std::istream& file) const; - uint32_t getui32(std::istream& file) const { return get(file); } - int32_t getsi32(std::istream& file) const { return get(file); } - uint64_t getui64(std::istream& file) const { return get(file); } - int64_t getsi64(std::istream& file) const { return get(file); } + std::string get4chars(std::istream& file) const; - float getf32(std::istream& file) const { return get(file); } - double getf64(std::istream& file) const { return get(file); } - double getf80(std::istream& file) const; + uint8_t getui8(std::istream& file) const { return static_cast(file.get()); } + int8_t getsi8(std::istream& file) const { return file.get(); } + uint16_t getui16(std::istream& file) const { return get(file); } + int16_t getsi16(std::istream& file) const { return get(file); } + uint32_t getui24(std::istream& file) const; + int32_t getsi24(std::istream& file) const; + uint32_t getui32(std::istream& file) const { return get(file); } + int32_t getsi32(std::istream& file) const { return get(file); } + uint64_t getui64(std::istream& file) const { return get(file); } + int64_t getsi64(std::istream& file) const { return get(file); } - void put4chars(const std::string& s, std::ostream& file) const; + float getf32(std::istream& file) const { return get(file); } + double getf64(std::istream& file) const { return get(file); } + double getf80(std::istream& file) const; - void putui8(uint8_t val, std::ostream& file) const { file.put(val); } - void putsi8(int8_t val, std::ostream& file) const { file.put(val); } - void putui16(uint16_t val, std::ostream& file) const { put(val, file); } - void putsi16(int16_t val, std::ostream& file) const { put(val, file); } - void putui24(uint32_t val, std::ostream& file) const; - void putsi24(int32_t val, std::ostream& file) const; - void putui32(uint32_t val, std::ostream& file) const { put(val, file); } - void putsi32(int32_t val, std::ostream& file) const { put(val, file); } - void putui64(uint64_t val, std::ostream& file) const { put(val, file); } - void putsi64(int64_t val, std::ostream& file) const { put(val, file); } + void put4chars(const std::string& s, std::ostream& file) const; - void putf32(float val, std::ostream& file) const { put(val, file); } - void putf64(double val, std::ostream& file) const { put(val, file); } - void putf80(double val, std::ostream& file) const; + void putui8(uint8_t val, std::ostream& file) const { file.put(val); } + void putsi8(int8_t val, std::ostream& file) const { file.put(val); } + void putui16(uint16_t val, std::ostream& file) const { put(val, file); } + void putsi16(int16_t val, std::ostream& file) const { put(val, file); } + void putui24(uint32_t val, std::ostream& file) const; + void putsi24(int32_t val, std::ostream& file) const; + void putui32(uint32_t val, std::ostream& file) const { put(val, file); } + void putsi32(int32_t val, std::ostream& file) const { put(val, file); } + void putui64(uint64_t val, std::ostream& file) const { put(val, file); } + void putsi64(int64_t val, std::ostream& file) const { put(val, file); } - private: - byte_order _target_byte_order {cur_byte_order()}; - }; + void putf32(float val, std::ostream& file) const { put(val, file); } + void putf64(double val, std::ostream& file) const { put(val, file); } + void putf80(double val, std::ostream& file) const; - class byte_order_changer { - public: - byte_order_changer(data_streamer* ds, byte_order order); - ~byte_order_changer(); + private: + byte_order _target_byte_order {cur_byte_order()}; + }; - byte_order_changer(byte_order_changer&& other); - byte_order_changer& operator=(byte_order_changer&& other); + class byte_order_changer { + public: + byte_order_changer(data_streamer* ds, byte_order order); + ~byte_order_changer(); - byte_order_changer(const byte_order_changer&) = delete; - byte_order_changer& operator=(const byte_order_changer&) = delete; + byte_order_changer(byte_order_changer&& other); + byte_order_changer& operator=(byte_order_changer&& other); - private: - data_streamer* _data_streamer {nullptr}; - byte_order _saved_byte_order {byte_order::undefined}; - }; + byte_order_changer(const byte_order_changer&) = delete; + byte_order_changer& operator=(const byte_order_changer&) = delete; - class mapped_file : std::istream { - public: - mapped_file() = default; - mapped_file(const std::string& path); + private: + data_streamer* _data_streamer {nullptr}; + byte_order _saved_byte_order {byte_order::undefined}; + }; - mapped_file(const mapped_file&) = delete; - mapped_file& operator=(const mapped_file&) = delete; + class mapped_file : public std::istream { + public: + mapped_file(); + mapped_file(const std::string& path); - mapped_file(mapped_file&& other); - mapped_file& operator=(mapped_file&& other); + // no copying + mapped_file(const mapped_file&) = delete; + mapped_file& operator=(const mapped_file&) = delete; - ~mapped_file(); + // moving allowed + mapped_file(mapped_file&& other); + mapped_file& operator=(mapped_file&& other); - void open(const std::string& path); + ~mapped_file(); - size_t size() const { return _length; } + // it's an error to open an already opened mapped_file + void open(const std::string& path); - private: - int _fd {-1}; - char* _mapping {nullptr}; - size_t _length {0}; - std::stringbuf _membuf; - }; + // direct (read-only) access to mapped memory + const char* mapping() const { return _mapping; } + size_t size() const { return _length; } - } + private: + int _fd {-1}; + char* _mapping {nullptr}; + size_t _length {0}; + std::stringbuf _membuf; + }; + + } } diff --git a/mapped_file.cpp b/mapped_file.cpp index 88b9a0e..a5c8d8b 100644 --- a/mapped_file.cpp +++ b/mapped_file.cpp @@ -18,6 +18,8 @@ using namespace sc::io; +mapped_file::mapped_file() : std::istream {&_membuf} {} + mapped_file::mapped_file(const std::string& path) : std::istream {&_membuf} { open(path); } @@ -47,12 +49,15 @@ mapped_file::mapped_file(mapped_file&& other) { } mapped_file& mapped_file::operator=(mapped_file &&other) { - mapped_file mf {std::move(other)}; - std::swap(mf, *this); + if (&other != this) { + mapped_file mf {std::move(other)}; + std::swap(mf, *this); + } return *this; } void mapped_file::open(const std::string& path) { + if (_fd != -1) throw std::runtime_error("already open"); _fd = ::open(path.c_str(), O_RDONLY); throw_if_min1_msg(_fd, "could not open file"); struct stat st;