ROSE  0.11.145.0
AllocatingBuffer.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_AllocatingBuffer_H
9 #define Sawyer_AllocatingBuffer_H
10 
11 #include <Sawyer/Buffer.h>
12 #include <Sawyer/Sawyer.h>
13 
14 #include <boost/lexical_cast.hpp>
15 #include <boost/serialization/access.hpp>
16 #include <boost/serialization/base_object.hpp>
17 #include <boost/serialization/nvp.hpp>
18 #include <boost/serialization/vector.hpp>
19 #include <cstring> // memcpy
20 #include <string>
21 
22 namespace Sawyer {
23 namespace Container {
24 
29 template<class A, class T>
30 class AllocatingBuffer: public Buffer<A, T> {
31 public:
32  typedef A Address;
33  typedef T Value;
34  typedef Buffer<A, T> Super;
36 private:
37  std::vector<Value> values_;
38 
39 private:
40  friend class boost::serialization::access;
41 
42  // Users: You'll need to register the subclass once you know its type, such as
43  // BOOST_CLASS_REGISTER(Sawyer::Container::AllocatingBuffer<size_t,uint8_t>);
44  template<class S>
45  void serialize(S &s, const unsigned /*version*/) {
46  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
47  s & BOOST_SERIALIZATION_NVP(values_);
48  }
49 
50 protected:
51  explicit AllocatingBuffer(Address size = 0): Super(".AllocatingBuffer"), values_(size) {}
52 
53 public:
58  static typename Buffer<A, T>::Ptr instance(Address size) {
59  return typename Buffer<A, T>::Ptr(new AllocatingBuffer(size));
60  }
61 
65  static typename Buffer<A, T>::Ptr instance(const std::string &s) {
66  typename Buffer<A, T>::Ptr retval(new AllocatingBuffer(s.size()));
67  retval->write(s.c_str(), 0, s.size());
68  return retval;
69  }
70 
71  typename Buffer<A, T>::Ptr copy() const /*override*/ {
72  typename Buffer<A, T>::Ptr newBuffer = instance(this->size());
73  Address nWritten = newBuffer->write(&values_[0], 0, this->size());
74  if (nWritten != this->size()) {
75  throw std::runtime_error("AllocatingBuffer::copy() failed after copying " +
76  boost::lexical_cast<std::string>(nWritten) + " of " +
77  boost::lexical_cast<std::string>(this->size()) +
78  (1==this->size()?" value":" values"));
79  }
80  return newBuffer;
81  }
82 
83  Address available(Address start) const /*override*/ {
84  return start < values_.size() ? values_.size() - start : 0;
85  }
86 
87  void resize(Address newSize) /*override*/ {
88  values_.resize(newSize);
89  }
90 
91  Address read(Value *buf, Address address, Address n) const /*override*/ {
92  n = std::min(n, available(address));
93  if (buf && n>0)
94  memcpy(buf, &values_[address], n*sizeof(values_[0]));
95  return n;
96  }
97 
98  Address write(const Value *buf, Address address, Address n) /*override*/ {
99  n = std::min(n, available(address));
100  if (buf && n>0)
101  memcpy(&values_[address], buf, n*sizeof(values_[0]));
102  return n;
103  }
104 
105  const Value* data() const /*override*/ {
106  return values_.size() > 0 ? &values_[0] : NULL;
107  }
108 };
109 
110 } // namespace
111 } // namespace
112 
113 #endif
const Value * data() const
Data for the buffer.
T Value
Type of data that is stored.
Buffer< A, T >::Ptr copy() const
Create a new copy of buffer data.
A Address
Type of addresses used to index the stored data.
Address read(Value *buf, Address address, Address n) const
Reads data from a buffer.
static Buffer< A, T >::Ptr instance(Address size)
Allocating constructor.
Reference-counting intrusive smart pointer.
Definition: SharedPointer.h:68
Name space for the entire library.
Definition: FeasiblePath.h:767
Allocates memory as needed.
virtual Address size() const
Size of buffer.
Definition: Buffer.h:76
Address available(Address start) const
Distance to end of buffer.
Address write(const Value *buf, Address address, Address n)
Writes data to a buffer.
SharedPointer< Buffer > Ptr
Reference counting smart pointer.
Definition: Buffer.h:45
static Buffer< A, T >::Ptr instance(const std::string &s)
Allocating constructor.
Base class for all buffers.
Definition: Buffer.h:25
Buffer< A, T > Super
Type of base class.
void resize(Address newSize)
Change the size of the buffer.