1 /*
2  * Copyright (C) 2002 - David W. Durham
3  *
4  * This file is part of ReZound, an audio editing application.
5  *
6  * ReZound is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published
8  * by the Free Software Foundation; either version 2 of the License,
9  * or (at your option) any later version.
10  *
11  * ReZound is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
19  */
20 #ifndef __TAutoBuffer_H__
21 #define __TAutoBuffer_H__
22 #pragma once
23 
24 #include "../../config/common.h"
25 
26 // I suppose these headers would be available on all posix platforms
27 #include <stddef.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <errno.h>
31 
32 #include <stdexcept>
33 #include <string>
34 
35 #ifndef __func__
36 	#ifdef _MSC_VER
37 		// Microsoft compiler specific
38 		#define __func__	__FUNCTION__
39 	#endif
40 #endif
41 
42 /*
43 	This template class is used to allocate an buffer of memory that will automatically deallocate the
44 	memory when this object goes out of scope.
45 
46 	The type used to instantiate the template must have a default constructor
47 */
48 
49 template <class type> class TAutoBuffer
50 {
51 public:
52 	// size is in elements, not bytes
53 	TAutoBuffer(size_t _size=0,bool zeroContents=false) :
54 		size(0),
55 		buffer(NULL)
56 	{
57 		setSize(_size,zeroContents);
58 		/*
59 		if(_size>0)
60 		{
61 			buffer=(type *)malloc(_size*sizeof(type));
62 			if(buffer==NULL)
63 				throw runtime_error(string(__func__)+" -- error allocating memory -- "+strerror(errno));
64 			if(zeroContents)
65 				memset(buffer,0,_size*sizeof(type));
66 		}
67 		size=_size;
68 		*/
69 	}
70 
~TAutoBuffer()71 	virtual ~TAutoBuffer()
72 	{
73 		if(buffer)
74 			free(buffer);
75 	}
76 
77 
78 	// cast to type *
79 	operator type * ()
80 	{
81 		return buffer;
82 	}
83 
84 	operator const type * () const
85 	{
86 		return buffer;
87 	}
88 
89 	// get at internal buffer
data()90 	type *data()
91 	{
92 		return buffer;
93 	}
94 
data()95 	const type *data() const
96 	{
97 		return buffer;
98 	}
99 
100 	type *operator+(int offset)
101 	{
102 		return buffer+offset;
103 	}
104 
105 	const type *operator+(int offset) const
106 	{
107 		return buffer+offset;
108 	}
109 
110 #if 0 // I don't know why these cause so many warnings, but it should still be automatically castable to void* thru the type* operators
111 	// cast to void *
112 	operator void * const ()
113 	{
114 		return buffer;
115 	}
116 
117 	operator const void * const () const
118 	{
119 		return buffer;
120 	}
121 #endif
122 
123 
124 	/* for some reason this causes ambiguities in gcc 3.2 .. so I guess it will choose to cast to pointer then subscript if I don't define this but do subscript an object of this class
125 	type &operator[](size_t i) const
126 	{
127 		return buffer[i];
128 	}
129 	*/
130 
getSize()131 	size_t getSize() const
132 	{
133 		return size;
134 	}
135 
136 	void setSize(size_t newSize,bool zeroAllContents=false) // newSize is in elements not bytes
137 	{
138 		if(newSize>0)
139 		{
140 			type *temp=(type *)realloc(buffer,newSize*sizeof(type));
141 			if(temp==NULL)
142 				throw std::runtime_error(std::string(__func__)+" -- error reallocating memory");
143 			buffer=temp;
144 			size=newSize;
145 			if(zeroAllContents)
146 				memset(buffer,0,size*sizeof(type));
147 		}
148 		else
149 		{
150 			if(buffer)
151 				free(buffer);
152 			buffer=NULL;
153 			size=0;
154 		}
155 	}
156 
copyFrom(const TAutoBuffer<type> & source,size_t amount)157 	void copyFrom(const TAutoBuffer<type> &source,size_t amount)
158 	{
159 		if(amount>source.getSize())
160 			amount=source.getSize();
161 
162 		if(getSize()<amount)
163 			setSize(amount);
164 
165 		memcpy(buffer,source.buffer,amount);
166 	}
167 
168 private:
169 
170 	size_t size;
171 	type *buffer;
172 };
173 
174 #endif
175