ROSE  0.9.9.139
StaticBuffer.h
1 // WARNING: Changes to this file must be contributed back to Sawyer or else they will
2 // be clobbered by the next update from Sawyer. The Sawyer repository is at
3 // https://github.com/matzke1/sawyer.
4 
5 
6 
7 
8 #ifndef Sawyer_StaticBuffer_H
9 #define Sawyer_StaticBuffer_H
10 
11 #include <Sawyer/AllocatingBuffer.h>
12 #include <Sawyer/Assert.h>
13 #include <Sawyer/Buffer.h>
14 #include <Sawyer/Sawyer.h>
15 
16 #include <boost/serialization/access.hpp>
17 #include <boost/serialization/array.hpp>
18 #include <boost/serialization/base_object.hpp>
19 #include <boost/serialization/nvp.hpp>
20 #include <boost/serialization/split_member.hpp>
21 
22 namespace Sawyer {
23 namespace Container {
24 
29 template<class A, class T>
30 class StaticBuffer: public Buffer<A, T> {
31 public:
32  typedef A Address;
33  typedef T Value;
34  typedef Buffer<A, T> Super;
36 private:
37  Value *values_;
38  Address size_;
39  bool rdonly_;
40 
41 private:
42  friend class boost::serialization::access;
43 
44  template<class S>
45  void save(S &s, const unsigned version) const {
46  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
47  s & BOOST_SERIALIZATION_NVP(size_);
48  s & BOOST_SERIALIZATION_NVP(rdonly_);
49  s & boost::serialization::make_nvp("values", boost::serialization::make_array(values_, size_));
50  }
51 
52  template<class S>
53  void load(S &s, const unsigned version) {
54  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
55  s & BOOST_SERIALIZATION_NVP(size_);
56  s & BOOST_SERIALIZATION_NVP(rdonly_);
57  values_ = new Value[size_];
58  s & boost::serialization::make_nvp("values", boost::serialization::make_array(values_, size_));
59  }
60 
61  BOOST_SERIALIZATION_SPLIT_MEMBER();
62 
63 private:
64  // For serialization only
65  StaticBuffer()
66  : values_(NULL), size_(0), rdonly_(false) {}
67 
68 protected:
69  StaticBuffer(Value *values, Address size)
70  : Super(".StaticBuffer"), values_(values), size_(size), rdonly_(false) {
71  ASSERT_require(size==0 || values!=NULL);
72  }
73  StaticBuffer(const Value *values, Address size)
74  : Super(".StaticBuffer"), values_(const_cast<Value*>(values)), size_(size), rdonly_(true) {
75  ASSERT_require(size==0 || values!=NULL);
76  }
77 
78 public:
85  static typename Buffer<A, T>::Ptr instance(Value *values, Address size) {
86  return typename Buffer<A, T>::Ptr(new StaticBuffer(values, size));
87  }
88  static typename Buffer<A, T>::Ptr instance(const Value *values, Address size) {
89  return typename Buffer<A, T>::Ptr(new StaticBuffer(values, size));
90  }
93  // It doesn't make sense to exactly copy a static buffer because the point is to create a new buffer that points to data
94  // that is independent of the source buffer. Therefore we create an allocating buffer instead.
95  typename Buffer<A, T>::Ptr copy() const /*override*/ {
96  typename Buffer<A, T>::Ptr newBuffer = AllocatingBuffer<A, T>::instance(size_);
97  Address nWritten = newBuffer->write(values_, 0, size_);
98  if (nWritten != size_) {
99  throw std::runtime_error("StaticBuffer::copy() failed after copying " +
100  boost::lexical_cast<std::string>(nWritten) + " of " +
101  boost::lexical_cast<std::string>(size_) +
102  (1==size_?" value":" values"));
103  }
104  return newBuffer;
105  }
106 
107  Address available(Address start) const /*override*/ {
108  return start < size_ ? size_-start : 0;
109  }
110 
111  void resize(Address newSize) /*override*/ {
112  if (newSize != size_)
113  throw std::runtime_error("unable to resize StaticBuffer");
114  }
115 
116  Address read(Value *buf, Address address, Address n) const /*override*/ {
117  n = std::min(n, available(address));
118  if (buf)
119  memcpy(buf, values_+address, n*sizeof(values_[0]));
120  return n;
121  }
122 
123  Address write(const Value *buf, Address address, Address n) /*override*/ {
124  if (rdonly_)
125  return 0;
126  n = std::min(n, available(address));
127  if (buf)
128  memcpy(values_+address, buf, n*sizeof(values_[0]));
129  return n;
130  }
131 
132  const Value* data() const /*override*/ {
133  return values_;
134  }
135 };
136 
137 } // namespace
138 } // namespace
139 
140 #endif
A Address
Type of addresses.
Definition: StaticBuffer.h:32
Points to static data.
Definition: StaticBuffer.h:30
static Buffer< A, T >::Ptr instance(Address size)
Allocating constructor.
Buffer< A, T >::Ptr copy() const
Create a new copy of buffer data.
Definition: StaticBuffer.h:95
Reference-counting smart pointer.
Definition: SharedPointer.h:34
Name space for the entire library.
Definition: Access.h:11
virtual Address size() const
Size of buffer.
Definition: Buffer.h:76
static Buffer< A, T >::Ptr instance(Value *values, Address size)
Construct from caller-supplied data.
Definition: StaticBuffer.h:85
SharedPointer< Buffer > Ptr
Reference counting smart pointer.
Definition: Buffer.h:45
Base class for all buffers.
Definition: Buffer.h:25
Address read(Value *buf, Address address, Address n) const
Reads data from a buffer.
Definition: StaticBuffer.h:116
void resize(Address newSize)
Change the size of the buffer.
Definition: StaticBuffer.h:111
Buffer< A, T > Super
Type of base class.
Definition: StaticBuffer.h:34
Address available(Address start) const
Distance to end of buffer.
Definition: StaticBuffer.h:107
static Buffer< A, T >::Ptr instance(const Value *values, Address size)
Construct from caller-supplied data.
Definition: StaticBuffer.h:88
const Value * data() const
Data for the buffer.
Definition: StaticBuffer.h:132
Address write(const Value *buf, Address address, Address n)
Writes data to a buffer.
Definition: StaticBuffer.h:123