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 
34 class 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 
headerheader48 			header (uint32 size)
49 				: fMutex ("dng_ref_counted_block")
50 				, fRefCount (1)
51 				, fSize (size)
52 				{
53 				}
54 
~headerheader55 			~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 
LogicalSize()107 		uint32 LogicalSize ()
108 			{
109 			return ((header *)fBuffer)->fSize;
110 			}
111 
Buffer()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 
Buffer()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 
Buffer_char()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 
Buffer_char()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 
Buffer_uint8()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 
Buffer_uint8()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 
Buffer_uint16()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 
Buffer_uint16()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 
Buffer_int16()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 
Buffer_int16()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 
Buffer_uint32()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 
Buffer_uint32()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 
Buffer_int32()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 
Buffer_int32()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 
Buffer_uint64()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 
Buffer_uint64()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 
Buffer_int64()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 
Buffer_int64()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 
Buffer_real32()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 
Buffer_real32()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 
Buffer_real64()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 
Buffer_real64()280 		const real64 * Buffer_real64 () const
281 			{
282 			return (const real64 *) Buffer ();
283 			}
284 
285 	};
286 
287 /*****************************************************************************/
288 
289 #endif
290 
291 /*****************************************************************************/
292