nlib
OutputStream.h
Go to the documentation of this file.
1 
2 #pragma once
3 #ifndef INCLUDE_NN_NLIB_OUTPUTSTREAM_H_
4 #define INCLUDE_NN_NLIB_OUTPUTSTREAM_H_
5 
6 #include "nn/nlib/Config.h"
7 
8 NLIB_NAMESPACE_BEGIN
9 
10 // code snippets:
11 // OutputStream& stream = 'stream that inherits OutputStream';
12 // if (!stream.Write(dataptr, nbyte)) { error = stream.GetErrorValue(); .... }
13 // for (.....) { if (!stream.Write(byte)) { error = stream.GetErrorValue(); .... } }
14 // # you should Flush() and Close() explicitly
15 // if (!stream.Flush()) { error = stream.GetErrorValue(); .... } }
16 // if (!stream.Close()) { error = stream.GetErrorValue(); .... } }
18  public:
20  BUFFERINGMODE_BLOCKBUFFERED = 0, // default
21  BUFFERINGMODE_LINEBUFFERED, // if console output
22  BUFFERINGMODE_UNBUFFERED
23  };
24 
25  public:
27  m_Cur(0),
28  m_Buf(NULL),
29  m_BufSize(0),
30  m_ErrorId(0),
31  m_BufferingMode(BUFFERINGMODE_BLOCKBUFFERED) {}
33  // NOTE:
34  // cannot call Close_() from this destructor.
35  // the destructor of the derived class has to call Close_() if needed.
36  }
37  // use Pos64() if you need a 64bit value on 32bit arch
38  size_t Pos() const NLIB_NOEXCEPT { return static_cast<size_t>(Pos64()); }
39  uint64_t Pos64() const NLIB_NOEXCEPT { return m_Pos + m_Cur; }
40  bool Write(int b) NLIB_NOEXCEPT {
41  // NOTE:
42  // if the stream is closed,
43  // Write() will succeed before the internal buffer becomes full.
44  if (NLIB_UNLIKELY(m_Cur == m_BufSize)) {
45  if (NLIB_UNLIKELY(!this->Flush_(false))) return false;
46  if (NLIB_UNLIKELY(m_BufSize == 0)) {
47  this->SetError(EIO);
48  return false;
49  }
50  }
51  m_Buf[m_Cur++] = static_cast<unsigned char>(b & 0xff);
52  return true;
53  }
54  bool Write(const void* p, size_t n) NLIB_NOEXCEPT NLIB_NONNULL {
55 #ifndef NLIB_NONNULL_ENABLED
56  if (!p) {
57  this->SetError(EINVAL);
58  return false;
59  }
60 #endif
61  if (n > RSIZE_MAX) {
62  this->SetError(EINVAL);
63  return false;
64  }
65  if (m_Cur + n <= m_BufSize) {
66  nlib_memcpy(&m_Buf[m_Cur], n, p, n);
67  m_Cur += n;
68  return true;
69  }
70  return this->Write_(p, n);
71  }
72  bool WriteGather(const nlib_fd_iovec* iov, int iovcnt) NLIB_NOEXCEPT NLIB_NONNULL {
73 #ifndef NLIB_NONNULL_ENABLED
74  if (!iov) {
75  this->SetError(EINVAL);
76  return false;
77  }
78 #endif
79  if (iovcnt < 0) {
80  this->SetError(EINVAL);
81  return false;
82  }
83  return this->WriteGather_(iov, iovcnt);
84  }
85  bool Flush() NLIB_NOEXCEPT { return Flush_(true); }
86  bool Close() NLIB_NOEXCEPT;
87  errno_t GetErrorValue() const NLIB_NOEXCEPT { return m_ErrorId; }
88  // returns true if there has been no errors
89  // you can also write the codes such that 'if (!!stream) { ... }'
90  bool IsOk() const NLIB_NOEXCEPT { return m_ErrorId == 0; }
91  BufferingMode GetBufferingMode() const NLIB_NOEXCEPT { return m_BufferingMode; }
93 
94  protected:
95  void ResetBuffer(void* p, size_t nBytes) NLIB_NOEXCEPT {
96  m_Buf = reinterpret_cast<unsigned char*>(p);
97  m_BufSize = static_cast<int>(nBytes);
98  }
99  void SetError(errno_t e) const NLIB_NOEXCEPT {
100  if (m_ErrorId == 0) m_ErrorId = e;
101  }
102 
103  private:
104  virtual bool PushBuffer_(const void* p, size_t nBytes, bool doFlush) NLIB_NOEXCEPT = 0;
105  virtual bool Close_() NLIB_NOEXCEPT = 0;
106  virtual void* GetWorkBuffer_(size_t* nBytes) NLIB_NOEXCEPT;
107  virtual bool WriteGather_(const nlib_fd_iovec* iov, int iovcnt) NLIB_NOEXCEPT;
108  bool Write_(const void* p, size_t n) NLIB_NOEXCEPT;
109 
110  private:
111  bool Flush_(bool flushDevice) NLIB_NOEXCEPT;
112  bool GetWorkBuffer_() NLIB_NOEXCEPT;
113 
114  private:
115  uint64_t m_Pos;
116  size_t m_Cur;
117  unsigned char* m_Buf;
118  size_t m_BufSize;
119  mutable errno_t m_ErrorId;
120 
121  protected:
122  // NOTE:
123  // BufferingMode is for the codes which use OutputStream.
124  // OutputStream only shows the buffering mode which the user specified.
125  // for example, TextWriter (the user of OutputStream) has to decide
126  // when to call Flush() looking at GetBufferingMode().
127  BufferingMode m_BufferingMode;
128 
129  private:
131 };
132 
133 class NLIB_VIS_PUBLIC NullOutputStream NLIB_FINAL : public OutputStream {
134  public:
136  virtual ~NullOutputStream() NLIB_NOEXCEPT NLIB_OVERRIDE {}
137 
138  private:
139  unsigned char m_DummyBuf[256];
140  virtual bool PushBuffer_(const void* p, size_t, bool doFlush) NLIB_NOEXCEPT NLIB_OVERRIDE;
141  virtual bool Close_() NLIB_NOEXCEPT NLIB_OVERRIDE { return true; }
142 };
143 
144 NLIB_NAMESPACE_END
145 
146 #endif // INCLUDE_NN_NLIB_OUTPUTSTREAM_H_
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Definition: Platform.h:2151
bool Flush() noexcept
Flushes the stream.
Definition: OutputStream.h:85
#define NLIB_UNLIKELY(x)
Indicates to the compiler that condition x is likely to be false.
Definition: Platform_unix.h:62
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
#define NLIB_NONNULL
Indicates that you cannot specify NULL for all arguments.
Definition: Platform_unix.h:66
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
Definition: Config.h:126
#define NLIB_SAFE_BOOL(class_name, exp)
Defines a safe operator bool function in the class. Uses the C++11 explicit bool if it is available f...
Definition: Config.h:141
bool IsOk() const noexcept
Checks that no error has occurred.
Definition: OutputStream.h:90
#define NLIB_OVERRIDE
Defines override if it is available for use. If not, holds an empty string.
BufferingMode GetBufferingMode() const noexcept
Gets the buffering mode.
Definition: OutputStream.h:91
uint64_t Pos64() const noexcept
Returns the current position in the stream as a 64-bit integer.
Definition: OutputStream.h:39
constexpr OutputStream() noexcept
Instantiates the object with default parameters (default constructor).
Definition: OutputStream.h:26
The class for OutputStream objects for which no actual writing takes place.
Definition: OutputStream.h:133
bool Write(int b) noexcept
Writes one byte of data to the stream.
Definition: OutputStream.h:40
#define RSIZE_MAX
Defines a value somewhat smaller than the maximum value of size_t.
Definition: Platform.h:295
#define NLIB_CEXPR
Defines constexpr if it is available for use. If not, holds an empty string.
size_t Pos() const noexcept
Returns the current position in the stream.
Definition: OutputStream.h:38
void SetError(errno_t e) const noexcept
Sets an error to OutputStream.
Definition: OutputStream.h:99
virtual ~OutputStream() noexcept
Destructor. Does not do anything.
Definition: OutputStream.h:32
A file that contains the configuration information for each development environment.
The output is line buffered. This mode is set when data is output to the console. ...
Definition: OutputStream.h:21
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:51
bool Write(const void *p, size_t n) noexcept
Writes n bytes of data to the stream.
Definition: OutputStream.h:54
BufferingMode
The buffering mode for OutputStream.
Definition: OutputStream.h:19
errno_t nlib_memcpy(void *s1, size_t s1max, const void *s2, size_t n)
An implementation corresponding to N1078 memcpy_s.
Definition: Platform.h:2095
The base class for output streams. This class cannot be instantiated.
Definition: OutputStream.h:17
bool WriteGather(const nlib_fd_iovec *iov, int iovcnt) noexcept
Writes data from multiple non-continuous buffers to a stream.
Definition: OutputStream.h:72
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:24