Open Lighting Architecture
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MemoryBlock.h
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  *
16  * MemoryBlock.h
17  * A block of memory.
18  * Copyright (C) 2013 Simon Newton
19  */
20 
21 #ifndef INCLUDE_OLA_IO_MEMORYBLOCK_H_
22 #define INCLUDE_OLA_IO_MEMORYBLOCK_H_
23 
24 #include <stdint.h>
25 #include <string.h>
26 #include <algorithm>
27 
28 namespace ola {
29 namespace io {
30 
35 class MemoryBlock {
36  public:
37  // Ownership of the data is transferred.
38  MemoryBlock(uint8_t *data, unsigned int size)
39  : m_data(data),
40  m_data_end(data + size),
41  m_capacity(size),
42  m_first(data),
43  m_last(data) {
44  }
45 
46  ~MemoryBlock() {
47  delete[] m_data;
48  }
49 
50  // Move the insertion point to the end of the block. This is useful if you
51  // want to use the block in pre-pend mode
52  void SeekBack() {
53  m_first = m_data_end;
54  m_last = m_first;
55  }
56 
57  // The amount of memory space in this block.
58  unsigned int Capacity() const { return m_capacity; }
59 
60  // The amount of data in this block.
61  unsigned int Size() const {
62  return static_cast<unsigned int>(m_last - m_first);
63  }
64 
65  bool Empty() const {
66  return m_last == m_first;
67  }
68 
69  // Pointer to the first byte of valid data in this block.
70  uint8_t *Data() const { return m_first; }
71 
72  // Attempt to append the data to this block. returns the number of bytes
73  // written, which will be less than length if the block is now full.
74  unsigned int Append(const uint8_t *data, unsigned int length) {
75  unsigned int bytes_to_write = std::min(
76  length, static_cast<unsigned int>(m_data_end - m_last));
77  memcpy(m_last, data, bytes_to_write);
78  m_last += bytes_to_write;
79  return bytes_to_write;
80  }
81 
82  // Attempt to prepend the data to this block. returns the number of bytes
83  // written (from the end of data), which will be less than length if the
84  // block is now full.
85  unsigned int Prepend(const uint8_t *data, unsigned int length) {
86  unsigned int bytes_to_write = std::min(
87  length, static_cast<unsigned int>(m_first - m_data));
88  memcpy(m_first - bytes_to_write, data + length - bytes_to_write,
89  bytes_to_write);
90  m_first -= bytes_to_write;
91  return bytes_to_write;
92  }
93 
94  // Copy at most length bytes of data into the location data. This does not
95  // change the data in any way.
96  unsigned int Copy(uint8_t *data, unsigned int length) const {
97  unsigned int bytes_to_read = std::min(
98  length, static_cast<unsigned int>(m_last - m_first));
99  memcpy(data, m_first, bytes_to_read);
100  return bytes_to_read;
101  }
102 
103  // Remove at most length bytes from the front of this block.
104  unsigned int PopFront(unsigned int length) {
105  unsigned int bytes_to_pop = std::min(
106  length, static_cast<unsigned int>(m_last - m_first));
107  m_first += bytes_to_pop;
108  return bytes_to_pop;
109  }
110 
111  private:
112  uint8_t* const m_data;
113  uint8_t* const m_data_end;
114  unsigned int m_capacity;
115  // Points to the valid data in the block.
116  uint8_t *m_first;
117  uint8_t *m_last; // points to one after last
118 };
119 } // namespace io
120 } // namespace ola
121 #endif // INCLUDE_OLA_IO_MEMORYBLOCK_H_