nlib
InputStream.h
Go to the documentation of this file.
1 
2 #pragma once
3 #ifndef INCLUDE_NN_NLIB_INPUTSTREAM_H_
4 #define INCLUDE_NN_NLIB_INPUTSTREAM_H_
5 
6 #include "nn/nlib/Config.h"
7 
8 NLIB_NAMESPACE_BEGIN
9 
10 // code snippets:
11 // InputStream& stream = 'stream that inherits InputStream';
12 // if (!stream.Read(dataptr, nbyte)) { error = stream.GetErrorValue(); ..... }
13 // while ((c = stream.Read()) >= 0) { c is [0x00 - 0xFF] }
14 // if (!stream) { error = stream.GetErrorValue(); ..... }
16  public:
18  m_Cur(0),
19  m_End(0),
20  m_Buf(NULL),
21  m_BufSize(0),
22  m_ErrorId(0) {}
24  // NOTE:
25  // cannot call Close_() from this destructor.
26  // the destructor of the derived class has to call Close_() if needed.
27  }
28  // returns true if there has been no errors
29  // you can also write the codes such that 'if (!!stream) { ... }'
30  bool IsOk() const NLIB_NOEXCEPT { return m_ErrorId == 0; }
31  errno_t GetErrorValue() const NLIB_NOEXCEPT { return m_ErrorId; }
32  // use Pos64() if you need a 64bit value on 32bit arch
33  size_t Pos() const NLIB_NOEXCEPT { return static_cast<size_t>(Pos64()); }
34  uint64_t Pos64() const NLIB_NOEXCEPT { return m_Pos + m_Cur; }
36  if (this->IsOk() && m_Cur == m_End) {
37  CheckBuffer();
38  return this->IsOk() && m_Cur == m_End;
39  }
40  return false;
41  }
42  // < 0 if EOS or error, otherwise returns a byte and ++pos
44  if (NLIB_UNLIKELY(m_Cur == m_End)) {
45  CheckBuffer();
46  if (NLIB_UNLIKELY(m_Cur == m_End)) return -1;
47  }
48  return m_Buf[m_Cur++];
49  }
50  // < 0 if EOS or error, otherwise returns a byte and pos is unchanged
52  if (NLIB_UNLIKELY(m_Cur == m_End)) {
53  CheckBuffer();
54  if (NLIB_UNLIKELY(m_Cur == m_End)) return -1;
55  }
56  return m_Buf[m_Cur];
57  }
58  // returns skipped number of bytes
59  size_t Skip(size_t nBytes) NLIB_NOEXCEPT;
60  size_t Read(void* ptr, size_t nBytes) NLIB_NOEXCEPT NLIB_NONNULL {
61 #ifndef NLIB_NONNULL_ENABLED
62  if (!ptr) {
63  this->SetError(EINVAL);
64  return 0;
65  }
66 #endif
67  if (nBytes > RSIZE_MAX) { // INT01-C
68  this->SetError(EINVAL);
69  return 0;
70  }
71  if (m_Cur + nBytes <= m_End) {
72  nlib_memcpy(ptr, nBytes, &m_Buf[m_Cur], nBytes);
73  m_Cur += nBytes;
74  return nBytes;
75  }
76  return this->Read_(ptr, nBytes);
77  }
78  bool Close() NLIB_NOEXCEPT;
80 
81  protected:
82  void ResetBuffer(void* p, size_t nBytes) NLIB_NOEXCEPT {
83  m_Buf = reinterpret_cast<unsigned char*>(p);
84  m_BufSize = static_cast<int>(nBytes);
85  }
86  void SetError(errno_t e) const NLIB_NOEXCEPT {
87  if (m_ErrorId == 0) m_ErrorId = e;
88  }
89 
90  private:
91  virtual size_t FillBuffer_(void* p, size_t nBytes) NLIB_NOEXCEPT = 0;
92  virtual bool Close_() NLIB_NOEXCEPT = 0;
93  virtual void* GetWorkBuffer_(size_t* nBytes) NLIB_NOEXCEPT;
94  size_t Read_(void* ptr, size_t nBytes) NLIB_NOEXCEPT;
95 
96  // By default, Skip_() reads data on m_Buf.
97  // you can override it if you can implement more efficient code.
98  virtual size_t Skip_(size_t nBytes) NLIB_NOEXCEPT;
99 
100  private:
101  void CheckBuffer() NLIB_NOEXCEPT;
102  bool GetWorkBuffer() NLIB_NOEXCEPT;
103 
104  private:
105  uint64_t m_Pos;
106  size_t m_Cur;
107  size_t m_End;
108  unsigned char* m_Buf;
109  size_t m_BufSize;
110  mutable errno_t m_ErrorId;
111  // m_ErrorId is changed only from derived classes.
112  // FillBuffer_() or Close_() changes m_ErrorId in other words.
113 
115 };
116 
117 class NLIB_VIS_PUBLIC NullInputStream NLIB_FINAL : public InputStream {
118  public:
120  virtual ~NullInputStream() NLIB_NOEXCEPT {}
121 
122  private:
123  char m_DummyBuf[256];
124  virtual size_t FillBuffer_(void* p, size_t nBytes) NLIB_NOEXCEPT NLIB_OVERRIDE;
125  virtual bool Close_() NLIB_NOEXCEPT NLIB_OVERRIDE { return true; }
126  virtual size_t Skip_(size_t nBytes) NLIB_NOEXCEPT NLIB_OVERRIDE;
127 };
128 
129 NLIB_NAMESPACE_END
130 
131 #endif // INCLUDE_NN_NLIB_INPUTSTREAM_H_
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Definition: Platform.h:2151
#define NLIB_UNLIKELY(x)
Indicates to the compiler that condition x is likely to be false.
Definition: Platform_unix.h:62
uint64_t Pos64() const noexcept
Returns the current position in the stream as a 64-bit value.
Definition: InputStream.h:34
#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 IsEos() noexcept
Returns true if the stream is finished being read through to the end. If the stream has not been read...
Definition: InputStream.h:35
#define NLIB_OVERRIDE
Defines override if it is available for use. If not, holds an empty string.
int Read() noexcept
Reads one byte of data from the stream.
Definition: InputStream.h:43
size_t Read(void *ptr, size_t nBytes) noexcept
Reads the number of bytes of data specified by nBytes into the memory region specified by ptr...
Definition: InputStream.h:60
size_t Pos() const noexcept
Returns the current position in the stream.
Definition: InputStream.h:33
void SetError(errno_t e) const noexcept
Sets an error to InputStream.
Definition: InputStream.h:86
errno_t GetErrorValue() const noexcept
Gets the error value.
Definition: InputStream.h:31
#define RSIZE_MAX
Defines a value somewhat smaller than the maximum value of size_t.
Definition: Platform.h:295
bool IsOk() const noexcept
Checks that no error has occurred.
Definition: InputStream.h:30
#define NLIB_CEXPR
Defines constexpr if it is available for use. If not, holds an empty string.
virtual ~InputStream() noexcept
Destructor. This function is called from the derived class.
Definition: InputStream.h:23
constexpr InputStream() noexcept
Instantiates the object. This function is called from the derived class.
Definition: InputStream.h:17
The base class for input streams. This class cannot be instantiated.
Definition: InputStream.h:15
NLIB_CHECK_RESULT int Peek() noexcept
Reads the next byte without consuming the stream.
Definition: InputStream.h:51
A file that contains the configuration information for each development environment.
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:51
The class for streams that always load 0.
Definition: InputStream.h:117
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
#define NLIB_CHECK_RESULT
Indicates that the caller of the function must check the returned value.
Definition: Platform_unix.h:64
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:24