1/*****************************************************************************/
2// Copyright 2006-2007 Adobe Systems Incorporated
3// All Rights Reserved.
4//
5// NOTICE:  Adobe permits you to use, modify, and distribute this file in
6// accordance with the terms of the Adobe license agreement accompanying it.
7/*****************************************************************************/
8
9/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_ref_counted_block.h#2 $ */
10/* $DateTime: 2012/07/31 22:04:34 $ */
11/* $Change: 840853 $ */
12/* $Author: tknoll $ */
13
14/** Support for a refcounted block, with optional copy-on-write
15 */
16
17/*****************************************************************************/
18
19#ifndef __dng_ref_counted_block__
20#define __dng_ref_counted_block__
21
22/*****************************************************************************/
23
24#include "dng_types.h"
25#include "dng_mutex.h"
26
27/*****************************************************************************/
28
29/// \brief Class to provide resource acquisition is instantiation discipline
30/// for small memory allocations.
31///
32/// This class does not use dng_memory_allocator for memory allocation.
33
34class dng_ref_counted_block
35	{
36
37	private:
38
39		struct header
40			{
41
42			dng_mutex fMutex;
43
44			uint32 fRefCount;
45
46			uint32 fSize;
47
48			header (uint32 size)
49				: fMutex ("dng_ref_counted_block")
50				, fRefCount (1)
51				, fSize (size)
52				{
53				}
54
55			~header ()
56				{
57				}
58
59			};
60
61		void *fBuffer;
62
63	public:
64
65
66		/// Construct an empty memory buffer using malloc.
67		/// \exception dng_memory_full with fErrorCode equal to dng_error_memory.
68
69		dng_ref_counted_block ();
70
71		/// Construct memory buffer of size bytes using malloc.
72		/// \param size Number of bytes of memory needed.
73		/// \exception dng_memory_full with fErrorCode equal to dng_error_memory.
74
75		dng_ref_counted_block (uint32 size);
76
77		/// Release memory buffer using free.
78
79		~dng_ref_counted_block ();
80
81		/// Copy constructore, which takes a reference to data and does not copy the block.
82
83		dng_ref_counted_block (const dng_ref_counted_block &data);
84
85		/// Assignment operatore takes a reference to right hand side and does not copy the data.
86
87		dng_ref_counted_block & operator= (const dng_ref_counted_block &data);
88
89		/// Clear existing memory buffer and allocate new memory of size bytes.
90		/// \param size Number of bytes of memory needed.
91		/// \exception dng_memory_full with fErrorCode equal to dng_error_memory.
92
93		void Allocate (uint32 size);
94
95		/// Release any allocated memory using free. Object is still valid and
96		/// Allocate can be called again.
97
98		void Clear ();
99
100		/// If there is only one reference, do nothing, otherwise copy the data into a new block and return an object with that block as the data.
101
102		void EnsureWriteable ();
103
104		/// Return pointer to allocated memory as a void *..
105		/// \retval void * valid for as many bytes as were allocated.
106
107		uint32 LogicalSize ()
108			{
109			return ((header *)fBuffer)->fSize;
110			}
111
112		void * Buffer ()
113			{
114			return (void *)((char *)fBuffer + sizeof (header));
115			}
116
117		/// Return pointer to allocated memory as a const void *.
118		/// \retval const void * valid for as many bytes as were allocated.
119
120		const void * Buffer () const
121			{
122			return (const void *)((char *)fBuffer + sizeof (header));
123			}
124
125		/// Return pointer to allocated memory as a char *.
126		/// \retval char * valid for as many bytes as were allocated.
127
128		char * Buffer_char ()
129			{
130			return (char *) Buffer ();
131			}
132
133		/// Return pointer to allocated memory as a const char *.
134		/// \retval const char * valid for as many bytes as were allocated.
135
136		const char * Buffer_char () const
137			{
138			return (const char *) Buffer ();
139			}
140
141		/// Return pointer to allocated memory as a uint8 *.
142		/// \retval uint8 * valid for as many bytes as were allocated.
143
144		uint8 * Buffer_uint8 ()
145			{
146			return (uint8 *) Buffer ();
147			}
148
149		/// Return pointer to allocated memory as a const uint8 *.
150		/// \retval const uint8 * valid for as many bytes as were allocated.
151
152		const uint8 * Buffer_uint8 () const
153			{
154			return (const uint8 *) Buffer ();
155			}
156
157		/// Return pointer to allocated memory as a uint16 *.
158		/// \retval uint16 * valid for as many bytes as were allocated.
159
160		uint16 * Buffer_uint16 ()
161			{
162			return (uint16 *) Buffer ();
163			}
164
165		/// Return pointer to allocated memory as a const uint16 *.
166		/// \retval const uint16 * valid for as many bytes as were allocated.
167
168		const uint16 * Buffer_uint16 () const
169			{
170			return (const uint16 *) Buffer ();
171			}
172
173		/// Return pointer to allocated memory as a int16 *.
174		/// \retval int16 * valid for as many bytes as were allocated.
175
176		int16 * Buffer_int16 ()
177			{
178			return (int16 *) Buffer ();
179			}
180
181		/// Return pointer to allocated memory as a const int16 *.
182		/// \retval const int16 * valid for as many bytes as were allocated.
183
184		const int16 * Buffer_int16 () const
185			{
186			return (const int16 *) Buffer ();
187			}
188
189		/// Return pointer to allocated memory as a uint32 *.
190		/// \retval uint32 * valid for as many bytes as were allocated.
191
192		uint32 * Buffer_uint32 ()
193			{
194			return (uint32 *) Buffer ();
195			}
196
197		/// Return pointer to allocated memory as a uint32 *.
198		/// \retval uint32 * valid for as many bytes as were allocated.
199
200		const uint32 * Buffer_uint32 () const
201			{
202			return (const uint32 *) Buffer ();
203			}
204
205		/// Return pointer to allocated memory as a const int32 *.
206		/// \retval const int32 * valid for as many bytes as were allocated.
207
208		int32 * Buffer_int32 ()
209			{
210			return (int32 *) Buffer ();
211			}
212
213		/// Return pointer to allocated memory as a const int32 *.
214		/// \retval const int32 * valid for as many bytes as were allocated.
215
216		const int32 * Buffer_int32 () const
217			{
218			return (const int32 *) Buffer ();
219			}
220
221		/// Return pointer to allocated memory as a uint64 *.
222		/// \retval uint64 * valid for as many bytes as were allocated.
223
224		uint64 * Buffer_uint64 ()
225			{
226			return (uint64 *) Buffer ();
227			}
228
229		/// Return pointer to allocated memory as a uint64 *.
230		/// \retval uint64 * valid for as many bytes as were allocated.
231
232		const uint64 * Buffer_uint64 () const
233			{
234			return (const uint64 *) Buffer ();
235			}
236
237		/// Return pointer to allocated memory as a const int64 *.
238		/// \retval const int64 * valid for as many bytes as were allocated.
239
240		int64 * Buffer_int64 ()
241			{
242			return (int64 *) Buffer ();
243			}
244
245		/// Return pointer to allocated memory as a const int64 *.
246		/// \retval const int64 * valid for as many bytes as were allocated.
247
248		const int64 * Buffer_int64 () const
249			{
250			return (const int64 *) Buffer ();
251			}
252
253		/// Return pointer to allocated memory as a real32 *.
254		/// \retval real32 * valid for as many bytes as were allocated.
255
256		real32 * Buffer_real32 ()
257			{
258			return (real32 *) Buffer ();
259			}
260
261		/// Return pointer to allocated memory as a const real32 *.
262		/// \retval const real32 * valid for as many bytes as were allocated.
263
264		const real32 * Buffer_real32 () const
265			{
266			return (const real32 *) Buffer ();
267			}
268
269		/// Return pointer to allocated memory as a real64 *.
270		/// \retval real64 * valid for as many bytes as were allocated.
271
272		real64 * Buffer_real64 ()
273			{
274			return (real64 *) Buffer ();
275			}
276
277		/// Return pointer to allocated memory as a const real64 *.
278		/// \retval const real64 * valid for as many bytes as were allocated.
279
280		const real64 * Buffer_real64 () const
281			{
282			return (const real64 *) Buffer ();
283			}
284
285	};
286
287/*****************************************************************************/
288
289#endif
290
291/*****************************************************************************/
292