You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
3.4 KiB
188 lines
3.4 KiB
/*****************************************************************************/
|
|
// Copyright 2006 Adobe Systems Incorporated
|
|
// All Rights Reserved.
|
|
//
|
|
// NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
// accordance with the terms of the Adobe license agreement accompanying it.
|
|
/*****************************************************************************/
|
|
|
|
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_ref_counted_block.cpp#1 $ */
|
|
/* $DateTime: 2012/05/30 13:28:51 $ */
|
|
/* $Change: 832332 $ */
|
|
/* $Author: tknoll $ */
|
|
|
|
/*****************************************************************************/
|
|
|
|
#include <new>
|
|
|
|
#include "dng_ref_counted_block.h"
|
|
|
|
#include "dng_exceptions.h"
|
|
|
|
/*****************************************************************************/
|
|
|
|
dng_ref_counted_block::dng_ref_counted_block ()
|
|
|
|
: fBuffer (NULL)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
dng_ref_counted_block::dng_ref_counted_block (uint32 size)
|
|
|
|
: fBuffer (NULL)
|
|
|
|
{
|
|
|
|
Allocate (size);
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
dng_ref_counted_block::~dng_ref_counted_block ()
|
|
{
|
|
|
|
Clear ();
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void dng_ref_counted_block::Allocate (uint32 size)
|
|
{
|
|
|
|
Clear ();
|
|
|
|
if (size)
|
|
{
|
|
|
|
fBuffer = malloc (size + sizeof (header));
|
|
|
|
if (!fBuffer)
|
|
{
|
|
|
|
ThrowMemoryFull ();
|
|
|
|
}
|
|
|
|
new (fBuffer) header (size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void dng_ref_counted_block::Clear ()
|
|
{
|
|
|
|
if (fBuffer)
|
|
{
|
|
|
|
|
|
bool doFree = false;
|
|
|
|
header *blockHeader = (struct header *)fBuffer;
|
|
|
|
{
|
|
|
|
dng_lock_mutex lock (&blockHeader->fMutex);
|
|
|
|
if (--blockHeader->fRefCount == 0)
|
|
doFree = true;
|
|
}
|
|
|
|
if (doFree)
|
|
{
|
|
|
|
blockHeader->~header ();
|
|
|
|
free (fBuffer);
|
|
|
|
}
|
|
|
|
fBuffer = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
dng_ref_counted_block::dng_ref_counted_block (const dng_ref_counted_block &data)
|
|
: fBuffer (NULL)
|
|
{
|
|
|
|
header *blockHeader = (struct header *)data.fBuffer;
|
|
|
|
dng_lock_mutex lock (&blockHeader->fMutex);
|
|
|
|
blockHeader->fRefCount++;
|
|
|
|
fBuffer = blockHeader;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
dng_ref_counted_block & dng_ref_counted_block::operator= (const dng_ref_counted_block &data)
|
|
{
|
|
|
|
if (this != &data)
|
|
{
|
|
Clear ();
|
|
|
|
header *blockHeader = (struct header *)data.fBuffer;
|
|
|
|
dng_lock_mutex lock (&blockHeader->fMutex);
|
|
|
|
blockHeader->fRefCount++;
|
|
|
|
fBuffer = blockHeader;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void dng_ref_counted_block::EnsureWriteable ()
|
|
{
|
|
|
|
if (fBuffer)
|
|
{
|
|
|
|
header *possiblySharedHeader = (header *)fBuffer;
|
|
|
|
{
|
|
|
|
dng_lock_mutex lock (&possiblySharedHeader->fMutex);
|
|
|
|
if (possiblySharedHeader->fRefCount > 1)
|
|
{
|
|
|
|
fBuffer = NULL;
|
|
|
|
Allocate ((uint32)possiblySharedHeader->fSize);
|
|
|
|
memcpy (Buffer (),
|
|
((char *)possiblySharedHeader) + sizeof (struct header), // could just do + 1 w/o cast, but this makes the type mixing more explicit
|
|
possiblySharedHeader->fSize);
|
|
|
|
possiblySharedHeader->fRefCount--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|