minor improvements
This commit is contained in:
		
							
								
								
									
										455
									
								
								libscio.hpp
									
									
									
									
									
								
							
							
						
						
									
										455
									
								
								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<char*>(val);
 | 
			
		||||
					for (size_t i = 0; i < n / 2; ++i) {
 | 
			
		||||
						std::swap(p[i], p[n - 1 - i]);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				template<class T>
 | 
			
		||||
				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<T*>(buf);
 | 
			
		||||
				}
 | 
			
		||||
				template<class T>
 | 
			
		||||
				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<char*>(&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<char*>(val);
 | 
			
		||||
                    for (size_t i = 0; i < n / 2; ++i) {
 | 
			
		||||
                        std::swap(p[i], p[n - 1 - i]);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                template<class T>
 | 
			
		||||
                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<T*>(buf);
 | 
			
		||||
                }
 | 
			
		||||
                template<class T>
 | 
			
		||||
                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<char*>(&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<uint8_t>(file.get()); }
 | 
			
		||||
				int8_t getsi8(std::istream& file) const { return file.get(); }
 | 
			
		||||
				uint16_t getui16(std::istream& file) const { return get<uint16_t>(file); }
 | 
			
		||||
				int16_t getsi16(std::istream& file) const { return get<int16_t>(file); }
 | 
			
		||||
				uint32_t getui24(std::istream& file) const;
 | 
			
		||||
				int32_t getsi24(std::istream& file) const;
 | 
			
		||||
				uint32_t getui32(std::istream& file) const { return get<uint32_t>(file); }
 | 
			
		||||
				int32_t getsi32(std::istream& file) const { return get<int32_t>(file); }
 | 
			
		||||
				uint64_t getui64(std::istream& file) const { return get<uint64_t>(file); }
 | 
			
		||||
				int64_t getsi64(std::istream& file) const { return get<int64_t>(file); }
 | 
			
		||||
                std::string get4chars(std::istream& file) const;
 | 
			
		||||
 | 
			
		||||
				float getf32(std::istream& file) const { return get<float>(file); }
 | 
			
		||||
				double getf64(std::istream& file) const { return get<double>(file); }
 | 
			
		||||
				double getf80(std::istream& file) const;
 | 
			
		||||
                uint8_t getui8(std::istream& file) const { return static_cast<uint8_t>(file.get()); }
 | 
			
		||||
                int8_t getsi8(std::istream& file) const { return file.get(); }
 | 
			
		||||
                uint16_t getui16(std::istream& file) const { return get<uint16_t>(file); }
 | 
			
		||||
                int16_t getsi16(std::istream& file) const { return get<int16_t>(file); }
 | 
			
		||||
                uint32_t getui24(std::istream& file) const;
 | 
			
		||||
                int32_t getsi24(std::istream& file) const;
 | 
			
		||||
                uint32_t getui32(std::istream& file) const { return get<uint32_t>(file); }
 | 
			
		||||
                int32_t getsi32(std::istream& file) const { return get<int32_t>(file); }
 | 
			
		||||
                uint64_t getui64(std::istream& file) const { return get<uint64_t>(file); }
 | 
			
		||||
                int64_t getsi64(std::istream& file) const { return get<int64_t>(file); }
 | 
			
		||||
 | 
			
		||||
				void put4chars(const std::string& s, std::ostream& file) const;
 | 
			
		||||
                float getf32(std::istream& file) const { return get<float>(file); }
 | 
			
		||||
                double getf64(std::istream& file) const { return get<double>(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<uint16_t>(val, file); }
 | 
			
		||||
				void putsi16(int16_t val, std::ostream& file) const { put<int16_t>(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<uint32_t>(val, file); }
 | 
			
		||||
				void putsi32(int32_t val, std::ostream& file) const { put<int32_t>(val, file); }
 | 
			
		||||
				void putui64(uint64_t val, std::ostream& file) const { put<uint64_t>(val, file); }
 | 
			
		||||
				void putsi64(int64_t val, std::ostream& file) const { put<int64_t>(val, file); }
 | 
			
		||||
                void put4chars(const std::string& s, std::ostream& file) const;
 | 
			
		||||
 | 
			
		||||
				void putf32(float val, std::ostream& file) const { put<float>(val, file); }
 | 
			
		||||
				void putf64(double val, std::ostream& file) const { put<double>(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<uint16_t>(val, file); }
 | 
			
		||||
                void putsi16(int16_t val, std::ostream& file) const { put<int16_t>(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<uint32_t>(val, file); }
 | 
			
		||||
                void putsi32(int32_t val, std::ostream& file) const { put<int32_t>(val, file); }
 | 
			
		||||
                void putui64(uint64_t val, std::ostream& file) const { put<uint64_t>(val, file); }
 | 
			
		||||
                void putsi64(int64_t val, std::ostream& file) const { put<int64_t>(val, file); }
 | 
			
		||||
 | 
			
		||||
			private:
 | 
			
		||||
				byte_order _target_byte_order {cur_byte_order()};
 | 
			
		||||
		};
 | 
			
		||||
                void putf32(float val, std::ostream& file) const { put<float>(val, file); }
 | 
			
		||||
                void putf64(double val, std::ostream& file) const { put<double>(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;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user