MPD  0.20.15
DynamicFifoBuffer.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2015 Max Kellermann <max.kellermann@gmail.com>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the
14  * distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20  * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27  * OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef DYNAMIC_FIFO_BUFFER_HXX
31 #define DYNAMIC_FIFO_BUFFER_HXX
32 
33 #include "ForeignFifoBuffer.hxx"
34 
40 template<typename T>
41 class DynamicFifoBuffer : protected ForeignFifoBuffer<T> {
42 public:
47 
48  explicit DynamicFifoBuffer(size_type _capacity)
49  :ForeignFifoBuffer<T>(new T[_capacity], _capacity) {}
51  delete[] GetBuffer();
52  }
53 
54  DynamicFifoBuffer(const DynamicFifoBuffer &) = delete;
55 
65 
66  void Grow(size_type new_capacity) {
67  assert(new_capacity > GetCapacity());
68 
69  T *old_data = GetBuffer();
70  T *new_data = new T[new_capacity];
71  ForeignFifoBuffer<T>::MoveBuffer(new_data, new_capacity);
72  delete[] old_data;
73  }
74 
75  void WantWrite(size_type n) {
77  /* we already have enough space */
78  return;
79 
80  const size_type in_use = GetAvailable();
81  const size_type required_capacity = in_use + n;
82  size_type new_capacity = GetCapacity();
83  do {
84  new_capacity <<= 1;
85  } while (new_capacity < required_capacity);
86 
87  Grow(new_capacity);
88  }
89 
95  WantWrite(n);
96  return Write().data;
97  }
98 
103  std::copy_n(p, n, Write(n));
104  Append(n);
105  }
106 
107 protected:
109 };
110 
111 #endif
DynamicFifoBuffer(size_type _capacity)
void MoveBuffer(T *new_data, size_type new_capacity)
Range::pointer_type pointer_type
A reference to a memory area that is writable.
Definition: Silence.hxx:27
constexpr size_type GetCapacity() const
ForeignFifoBuffer< T >::Range Range
Range::const_pointer_type const_pointer_type
Range Write()
Prepares writing.
A first-in-first-out buffer: you can append data at the end, and read data from the beginning...
pointer_type data
ForeignFifoBuffer< T >::const_pointer_type const_pointer_type
pointer_type Write(size_type n)
Write data to the buffer, growing it as needed.
constexpr size_type GetAvailable() const
ForeignFifoBuffer< T >::size_type size_type
ForeignFifoBuffer< T >::pointer_type pointer_type
A first-in-first-out buffer: you can append data at the end, and read data from the beginning...
void Grow(size_type new_capacity)
void WantWrite(size_type n)
void Append(const_pointer_type p, size_type n)
Append data to the buffer, growing it as needed.