btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / cortex / addons / common / RawBuffer.cpp
blob0686ade91c6fb07421c819ad9e65a6db49593296
1 /*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 // RawBuffer.cpp
33 // e.moon 31mar99
35 #include "RawBuffer.h"
37 #include <RealtimeAlloc.h>
38 #include <Debug.h>
39 #include <cstring>
41 // -------------------------------------------------------- //
42 // ctor/dtor/accessors
43 // -------------------------------------------------------- //
45 // allocate buffer (if frames > 0)
46 RawBuffer::RawBuffer(
47 uint32 frameSize,
48 uint32 frames,
49 bool bCircular,
50 rtm_pool* pFromPool) :
52 m_pData(0),
53 m_pPool(pFromPool),
54 m_frameSize(frameSize),
55 m_frames(frames),
56 m_allocatedSize(0),
57 m_bCircular(bCircular),
58 m_bOwnData(true)
61 if(m_frames)
62 resize(m_frames);
65 // point to given data (does NOT take responsibility for
66 // deleting it; use adopt() for that.)
67 RawBuffer::RawBuffer(
68 void* pData,
69 uint32 frameSize,
70 uint32 frames,
71 bool bCircular,
72 rtm_pool* pFromPool) :
74 m_pData(pData),
75 m_pPool(pFromPool),
76 m_frameSize(frameSize),
77 m_frames(frames),
78 m_allocatedSize(0),
79 m_bCircular(bCircular),
80 m_bOwnData(false)
83 RawBuffer::RawBuffer(const RawBuffer& clone) {
84 operator=(clone);
87 // generate a reference to the buffer
88 RawBuffer& RawBuffer::operator=(const RawBuffer& clone) {
89 m_pData = clone.m_pData;
90 m_allocatedSize = clone.m_allocatedSize;
91 m_frameSize = clone.m_frameSize;
92 m_frames = clone.m_frames;
93 m_bCircular = clone.m_bCircular;
94 m_pPool = clone.m_pPool;
95 m_bOwnData = false;
97 return *this;
100 // deallocate if I own the data
101 RawBuffer::~RawBuffer() {
102 free();
105 char* RawBuffer::data() const { return (char*)m_pData; }
106 // returns pointer to given frame
107 char* RawBuffer::frame(uint32 frame) const {
108 return data() + (frame * frameSize());
110 uint32 RawBuffer::frameSize() const { return m_frameSize; }
111 uint32 RawBuffer::frames() const { return m_frames; }
112 uint32 RawBuffer::size() const { return m_frames * m_frameSize; }
114 bool RawBuffer::isCircular() const { return m_bCircular; }
115 bool RawBuffer::ownsBuffer() const { return m_bOwnData; }
117 rtm_pool* RawBuffer::pool() const { return m_pPool; }
119 // resize buffer, re-allocating if necessary to contain
120 // designated number of frames.
121 // Does not preserve buffer contents.
123 void RawBuffer::resize(uint32 frames) {
124 uint32 sizeRequired = frames * m_frameSize;
126 // already have enough storage?
127 if(sizeRequired < m_allocatedSize &&
128 m_bOwnData) {
129 m_frames = frames;
130 return;
133 // free existing storage
134 free();
136 // allocate
137 m_pData = (m_pPool) ?
138 rtm_alloc(m_pPool, sizeRequired) :
139 new int8[sizeRequired];
141 m_bOwnData = true;
142 m_allocatedSize = sizeRequired;
143 m_frames = frames;
147 // take ownership of buffer from target
148 // (deletes current buffer data, if any owned)
150 void RawBuffer::adopt(
151 void* pData,
152 uint32 frameSize,
153 uint32 frames,
154 bool bCircular,
155 rtm_pool* pPool) {
157 // clean up myself first
158 free();
160 // reference
161 operator=(RawBuffer(pData, frameSize, frames, bCircular, pPool));
163 // mark ownership
164 m_bOwnData = true;
167 // returns false if the target doesn't own the data, but references it
168 // one way or the other
170 bool RawBuffer::adopt(RawBuffer& target) {
172 // reference
173 operator=(target);
175 // take ownership if possible
177 if(!target.m_bOwnData) {
178 m_bOwnData = false;
179 return false;
182 target.m_bOwnData = false;
183 m_bOwnData = true;
184 return true;
187 // adopt currently ref'd data (if any; returns false if no buffer data or
188 // already owned)
190 bool RawBuffer::adopt() {
191 if(!m_pData || m_bOwnData)
192 return false;
194 m_bOwnData = true;
195 return true;
198 // -------------------------------------------------------- //
199 // operations
200 // -------------------------------------------------------- //
202 // fill the buffer with zeroes
204 void RawBuffer::zero() {
205 if(!m_pData || !m_frames)
206 return;
208 memset(m_pData, 0, m_frames * m_frameSize);
211 // raw copy to destination buffer, returning the number of
212 // frames written, and adjusting both offsets accordingly.
214 // no frames will be written if the buffers' frame sizes
215 // differ.
217 uint32 RawBuffer::rawCopyTo(
218 RawBuffer& target,
219 uint32* pioFromFrame,
220 uint32* pioTargetFrame,
221 uint32 frames) const {
223 if(m_frameSize != target.m_frameSize)
224 return 0;
226 ASSERT(m_pData);
227 ASSERT(m_frames);
228 ASSERT(target.m_pData);
230 // convert frame counts to byte offsets
231 uint32 fromOffset = *pioFromFrame * m_frameSize;
232 uint32 targetOffset = *pioTargetFrame * m_frameSize;
234 // figure buffer sizes in bytes
235 uint32 size = m_frames * m_frameSize;
236 uint32 targetSize = target.m_frames * target.m_frameSize;
238 // figure amount to write
239 uint32 toCopy = frames * m_frameSize;
240 if(target.m_bCircular) {
241 if(toCopy > targetSize)
242 toCopy = targetSize;
243 } else {
244 if(toCopy > (targetSize-targetOffset))
245 toCopy = (targetSize-targetOffset);
247 uint32 remaining = toCopy;
249 // do it
250 while(remaining) {
252 // figure a contiguous area to fill
253 uint32 targetChunk = targetSize - targetOffset;
255 if(targetChunk > remaining)
256 targetChunk = remaining;
258 // fill it (from one or more source areas)
259 while(targetChunk > 0) {
261 // figure a contiguous source area
262 uint32 sourceChunk = size - fromOffset;
263 if(sourceChunk > targetChunk)
264 sourceChunk = targetChunk;
266 // copy it
267 memcpy(
268 (int8*)target.m_pData + targetOffset,
269 (int8*)m_pData + fromOffset,
270 sourceChunk);
272 // advance offsets
273 targetOffset += sourceChunk;
274 if(targetOffset == targetSize)
275 targetOffset = 0;
277 fromOffset += sourceChunk;
278 if(fromOffset == size)
279 fromOffset = 0;
281 // figure remaining portion of target area to fill
282 targetChunk -= sourceChunk;
283 remaining -= sourceChunk;
287 // write new offsets
288 *pioFromFrame = fromOffset / m_frameSize;
289 *pioTargetFrame = targetOffset / m_frameSize;
291 return toCopy;
294 // more convenient version of above if you don't care
295 // how the offsets change.
297 uint32 RawBuffer::rawCopyTo(
298 RawBuffer& target,
299 uint32 fromOffset,
300 uint32 targetOffset,
301 uint32 frames) const {
303 return rawCopyTo(target, &fromOffset, &targetOffset, frames);
306 // -------------------------------------------------------- //
307 // internal operations
308 // -------------------------------------------------------- //
310 // free owned data, if any
311 // [16jun99] uses proper rtm_free() call if needed
312 void RawBuffer::free() {
313 if(!(m_bOwnData && m_pData))
314 return;
316 if(m_pPool)
317 rtm_free(m_pData);
318 else
319 delete [] (int8 *)m_pData;
321 m_pData = 0;
325 // END -- RawBuffer.cpp --