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