All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ArrayBuffer.h
1 // Copyright eeGeo Ltd (2012-2015), All Rights Reserved
2 
3 #pragma once
4 
5 #include "Types.h"
6 
7 #include <cstring>
8 #include <streambuf>
9 #include <cstring>
10 
11 namespace Eegeo
12 {
13  template<typename T>
14  class ArrayBuffer : public std::streambuf
15  {
16  typedef T type;
17  public:
18  ArrayBuffer(const type *begin, const type *end) :
19  m_pBegin(begin),
20  m_pEnd(end),
21  m_pCurrent(m_pBegin)
22  {
23  Eegeo_ASSERT(std::less_equal<const type *>()(m_pBegin, m_pEnd), "The end pointer is less than the begin pointer");
24  }
25 
26  explicit ArrayBuffer(const type *str) :
27  m_pBegin(str),
28  m_pEnd(m_pBegin + std::strlen(str)),
29  m_pCurrent(m_pBegin)
30  {
31  }
32 
33  private:
34  int_type underflow()
35  {
36  if (m_pCurrent == m_pEnd)
37  return traits_type::eof();
38 
39  return traits_type::to_int_type(*m_pCurrent);
40  }
41 
42  int_type uflow()
43  {
44  if (m_pCurrent == m_pEnd)
45  return traits_type::eof();
46 
47  return traits_type::to_int_type(*m_pCurrent++);
48  }
49 
50  int_type pbackfail(int_type ch)
51  {
52  if (m_pCurrent == m_pBegin || (ch != traits_type::eof() && ch != m_pCurrent[-1]))
53  return traits_type::eof();
54 
55  return traits_type::to_int_type(*--m_pCurrent);
56  }
57 
58  std::streamsize showmanyc()
59  {
60  Eegeo_ASSERT(std::less_equal<const type *>()(m_pCurrent, m_pEnd), "The end pointer is less than the begin pointer")
61  return m_pEnd - m_pCurrent;
62  }
63 
64  pos_type seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out)
65  {
66  if (way == std::ios_base::beg)
67  {
68  m_pCurrent = m_pBegin + off;
69  }
70  else if (way == std::ios_base::cur)
71  {
72  m_pCurrent += off;
73  }
74  else if (way == std::ios_base::end)
75  {
76  m_pCurrent = m_pEnd + off;
77  }
78 
79  if (m_pCurrent < m_pBegin || m_pCurrent > m_pEnd)
80  {
81  return static_cast<pos_type>(-1);
82  }
83 
84  return static_cast<pos_type>(m_pCurrent - m_pBegin);
85  }
86 
87  pos_type seekpos(pos_type sp, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out)
88  {
89  m_pCurrent = m_pBegin + sp;
90 
91  if (m_pCurrent < m_pBegin || m_pCurrent > m_pEnd)
92  {
93  return static_cast<pos_type>(-1);
94  }
95 
96  return static_cast<pos_type>(m_pCurrent - m_pBegin);
97  }
98 
99  private:
100  const type * const m_pBegin;
101  const type * const m_pEnd;
102  const type * m_pCurrent;
103  };
104 }