nlib
OutputStream.h
[詳解]
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
環境に合わせてnoexcept 又は同等の定義がされます。
Definition: Platform.h:2151
bool Flush() noexcept
ストリームをフラッシュします。
Definition: OutputStream.h:85
#define NLIB_UNLIKELY(x)
条件xが偽になる傾向が高いことをコンパイラに示します。
Definition: Platform_unix.h:62
#define NLIB_FINAL
利用可能であればfinalが定義されます。そうでない場合は空文字列です。
#define NLIB_NONNULL
全ての引数にNULLを指定することができないことを示します。
Definition: Platform_unix.h:66
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
Definition: Config.h:126
#define NLIB_SAFE_BOOL(class_name, exp)
クラス内に安全なoperator bool()を定義します。 可能であればC++11のexplicit boolを利用します。 ...
Definition: Config.h:141
bool IsOk() const noexcept
エラーが発生していないかどうかを調べます。
Definition: OutputStream.h:90
#define NLIB_OVERRIDE
利用可能であればoverrideが定義されます。そうでない場合は空文字列です。
BufferingMode GetBufferingMode() const noexcept
バッファリングモードを取得します。
Definition: OutputStream.h:91
uint64_t Pos64() const noexcept
ストリーム上の現在位置を64bit整数で返します。
Definition: OutputStream.h:39
constexpr OutputStream() noexcept
デフォルトコンストラクタです。
Definition: OutputStream.h:26
実際の書き込み動作を行わないOutputStreamです。
Definition: OutputStream.h:133
bool Write(int b) noexcept
ストリームに1バイトのデータを書き込みます。
Definition: OutputStream.h:40
#define RSIZE_MAX
size_tの最大値よりいくらか小さい値が定義されています。
Definition: Platform.h:295
#define NLIB_CEXPR
利用可能であればconstexprが定義されます。そうでない場合は空文字列です。
size_t Pos() const noexcept
ストリーム上の現在位置を返します。
Definition: OutputStream.h:38
void SetError(errno_t e) const noexcept
OutputStreamにエラーを設定します。
Definition: OutputStream.h:99
virtual ~OutputStream() noexcept
デストラクタです。何もしません。
Definition: OutputStream.h:32
開発環境別の設定が書かれるファイルです。
出力をラインバッファします。コンソールに出力する場合に設定されます。
Definition: OutputStream.h:21
#define NLIB_VIS_PUBLIC
関数やクラス等のシンボルをライブラリの外部に公開します。
Definition: Platform_unix.h:51
bool Write(const void *p, size_t n) noexcept
ストリームにn バイトのデータを書き込みます。
Definition: OutputStream.h:54
BufferingMode
OutputStreamのバッファリングモードです。
Definition: OutputStream.h:19
errno_t nlib_memcpy(void *s1, size_t s1max, const void *s2, size_t n)
N1078のmemcpy_sに相当する実装です。
Definition: Platform.h:2095
出力ストリームの基底クラスです。このクラスを実体化することはできません。
Definition: OutputStream.h:17
bool WriteGather(const nlib_fd_iovec *iov, int iovcnt) noexcept
複数の非連続のバッファからデータをストリームに書き出します。
Definition: OutputStream.h:72
int errno_t
intのtypedefで、戻り値としてPOSIXのエラー値を返すことを示します。
Definition: NMalloc.h:24