]> git.tdb.fi Git - libs/core.git/blobdiff - source/io/base.h
Add move semantics to Variant
[libs/core.git] / source / io / base.h
index 774d03467b57f73b5af04217dcf8e3cae70046d1..92c860d266f1923d275c6f568ef99c4a0e715863 100644 (file)
@@ -1,26 +1,35 @@
 #ifndef MSP_IO_BASE_H_
 #define MSP_IO_BASE_H_
 
+#include <cstddef>
 #include <sigc++/sigc++.h>
+#include <msp/core/mspcore_api.h>
+#include <msp/core/mutex.h>
+#include <msp/core/noncopyable.h>
+#include "handle.h"
 #include "mode.h"
 #include "poll.h"
-#include "types.h"
 
 namespace Msp {
 namespace IO {
 
 /**
 Common interface for all I/O objects.
-
-A derived class must call set_events(P_NONE) before it is destroyed to avoid
-leaving stale pointers in an EventDispatcher.
 */
-class Base
+class MSPCORE_API Base: private NonCopyable
 {
 public:
-       /** Emitted when there is data available for reading.  If all data is not
-       read, the signal is emitted again immediately. */
-       sigc::signal<void> signal_data_available;
+       /** RAII synchronization primitive.  Prevents concurrent access to the
+       target object during the lifetime of the Synchronize object. */
+       class Synchronize
+       {
+       private:
+               Base &io;
+
+       public:
+               Synchronize(Base &);
+               ~Synchronize();
+       };
 
        /** Emitted when there is no more data to be read. */
        sigc::signal<void> signal_end_of_file;
@@ -29,26 +38,16 @@ public:
        seeked) and any data buffered by upper layers needs to be flushed. */
        sigc::signal<void> signal_flush_required;
 
-       /** Emitted when the I/O object has closed. */
-       sigc::signal<void> signal_closed;
-
-       /** Emitted when the mask of interesting events changes.  Mainly for use by
-       EventDispatcher. */
-       sigc::signal<void, PollEvent> signal_events_changed;
-
        /** Emitted when the object is deleted.  Mainly for use by
        EventDispatcher. */
        sigc::signal<void> signal_deleted;
 
 protected:
-       Mode mode;
-       PollEvent events;
-       bool eof_flag;
+       Mode mode = M_READ;
+       bool eof_flag = false;
+       Mutex *mutex = nullptr;
 
        Base();
-private:
-       Base(const Base &);
-       Base &operator=(const Base &);
 public:
        virtual ~Base();
 
@@ -58,31 +57,39 @@ public:
        was done.
 
        Blocking is enabled by default. */
-       virtual void set_block(bool) { }
+       virtual void set_block(bool) = 0;
+
+       /** Sets inheritance mode.  When inheritance is enabled, the file descriptor
+       will persist through Process::execute.
+
+       Inheritance is disabled by default. */
+       virtual void set_inherit(bool) = 0;
 
        /** Returns the current mode flags. */
        Mode get_mode() const { return mode; }
 
 protected:
-       virtual unsigned do_write(const char *, unsigned) =0;
-       virtual unsigned do_read(char *, unsigned) =0;
+       void check_access(Mode) const;
+
+       virtual std::size_t do_write(const char *, std::size_t) = 0;
+       virtual std::size_t do_read(char *, std::size_t) = 0;
 
 public:
        /** Writes data from a buffer.  Subject to blocking.  Returns the number of
        bytes written, which may be zero for a non-blockin operation. */
-       unsigned write(const char *b, unsigned c) { return do_write(b, c); }
+       std::size_t write(const char *b, std::size_t c) { return do_write(b, c); }
 
        /** Writes a string.  This is identical to calling
        write(s.data(), s.size()). */
-       unsigned write(const std::string &s) { return do_write(s.data(), s.size()); }
+       std::size_t write(const std::string &s) { return do_write(s.data(), s.size()); }
 
        /** Writes a single character.  This is identical to calling
        write(&c, 1). */
-       virtual unsigned put(char c) { return do_write(&c, 1); }
+       virtual std::size_t put(char c) { return do_write(&c, 1); }
 
        /** Reads data into a buffer.  Subject to blocking.  Returns the number of
        bytes read, which may be zero for a non-blocking operation. */
-       unsigned read(char *b, unsigned c) { return do_read(b, c); }
+       std::size_t read(char *b, std::size_t c) { return do_read(b, c); }
 
        /** Reads characters up to the next linefeed or end-of-file.  The linefeed
        is not included in the line.  Returns true if a line was successfully read,
@@ -93,26 +100,18 @@ public:
        to end-of-file or non-blocking operation. */
        virtual int get();
 
-       /** Returns the end-of-file flag. */
-       bool eof() const { return eof_flag; }
-
 protected:
-       void set_events(PollEvent);
+       void set_eof();
 
 public:
-       /** Returns a mask of the currently interesting events.  Used by
-       EventDispatcher. */
-       PollEvent get_events() const { return events; }
-
-       /** Returns a handle for polling.  Should throw if the object does not have
-       an event handle. */
-       virtual Handle get_event_handle() =0;
-
-       /** Notifies the object of an event.  Used by EventDispatcher. */
-       void event(PollEvent);
+       /** Returns the end-of-file flag.  Note that some types of objects won't
+       indicate end-of-file until you try to read at least one byte past the actual
+       end, while others indicate it when you've read the last byte. */
+       bool eof() const { return eof_flag; }
 
-protected:
-       virtual void on_event(PollEvent) { }
+       /** Returns the system-level handle for the object.  Used by Console to
+       perform redirections. */
+       virtual const Handle &get_handle(Mode) = 0;
 };
 
 } // namespace IO