• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*****************************************************************************/
2 // Copyright 2006 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.cpp#1 $ */
10 /* $DateTime: 2012/05/30 13:28:51 $ */
11 /* $Change: 832332 $ */
12 /* $Author: tknoll $ */
13 
14 /*****************************************************************************/
15 
16 #include <new>
17 
18 #include "dng_ref_counted_block.h"
19 
20 #include "dng_exceptions.h"
21 
22 /*****************************************************************************/
23 
dng_ref_counted_block()24 dng_ref_counted_block::dng_ref_counted_block ()
25 
26 	:	fBuffer (NULL)
27 
28 	{
29 
30 	}
31 
32 /*****************************************************************************/
33 
dng_ref_counted_block(uint32 size)34 dng_ref_counted_block::dng_ref_counted_block (uint32 size)
35 
36 	:	fBuffer (NULL)
37 
38 	{
39 
40 	Allocate (size);
41 
42 	}
43 
44 /*****************************************************************************/
45 
~dng_ref_counted_block()46 dng_ref_counted_block::~dng_ref_counted_block ()
47 	{
48 
49 	Clear ();
50 
51 	}
52 
53 /*****************************************************************************/
54 
Allocate(uint32 size)55 void dng_ref_counted_block::Allocate (uint32 size)
56 	{
57 
58 	Clear ();
59 
60 	if (size)
61 		{
62 
63 		fBuffer = malloc (size + sizeof (header));
64 
65 		if (!fBuffer)
66 			{
67 
68 			ThrowMemoryFull ();
69 
70 			}
71 
72 		new (fBuffer) header (size);
73 
74 		}
75 
76 	}
77 
78 /*****************************************************************************/
79 
Clear()80 void dng_ref_counted_block::Clear ()
81 	{
82 
83 	if (fBuffer)
84 		{
85 
86 
87 		bool doFree = false;
88 
89 		header *blockHeader = (struct header *)fBuffer;
90 
91 			{
92 
93 			dng_lock_mutex lock (&blockHeader->fMutex);
94 
95 			if (--blockHeader->fRefCount == 0)
96 				doFree = true;
97 			}
98 
99 		if (doFree)
100 			{
101 
102 			blockHeader->~header ();
103 
104 			free (fBuffer);
105 
106 			}
107 
108 		fBuffer = NULL;
109 
110 		}
111 
112 	}
113 
114 /*****************************************************************************/
115 
dng_ref_counted_block(const dng_ref_counted_block & data)116 dng_ref_counted_block::dng_ref_counted_block (const dng_ref_counted_block &data)
117 	: fBuffer (NULL)
118 	{
119 
120 	header *blockHeader = (struct header *)data.fBuffer;
121 
122 	dng_lock_mutex lock (&blockHeader->fMutex);
123 
124 	blockHeader->fRefCount++;
125 
126 	fBuffer = blockHeader;
127 
128 	}
129 
130 /*****************************************************************************/
131 
operator =(const dng_ref_counted_block & data)132 dng_ref_counted_block & dng_ref_counted_block::operator= (const dng_ref_counted_block &data)
133 	{
134 
135 	if (this != &data)
136 		{
137 		Clear ();
138 
139 		header *blockHeader = (struct header *)data.fBuffer;
140 
141 		dng_lock_mutex lock (&blockHeader->fMutex);
142 
143 		blockHeader->fRefCount++;
144 
145 		fBuffer = blockHeader;
146 
147 		}
148 
149 	return *this;
150 
151 	}
152 
153 /*****************************************************************************/
154 
EnsureWriteable()155 void dng_ref_counted_block::EnsureWriteable ()
156 	{
157 
158 	if (fBuffer)
159 		{
160 
161 		header *possiblySharedHeader = (header *)fBuffer;
162 
163 			{
164 
165 			dng_lock_mutex lock (&possiblySharedHeader->fMutex);
166 
167 			if (possiblySharedHeader->fRefCount > 1)
168 				{
169 
170 				fBuffer = NULL;
171 
172 				Allocate ((uint32)possiblySharedHeader->fSize);
173 
174 				memcpy (Buffer (),
175 					((char *)possiblySharedHeader) + sizeof (struct header), // could just do + 1 w/o cast, but this makes the type mixing more explicit
176 					possiblySharedHeader->fSize);
177 
178 				possiblySharedHeader->fRefCount--;
179 
180 				}
181 
182 			}
183 
184 		}
185 	}
186 
187 /*****************************************************************************/
188