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
7 months ago
|
/*****************************************************************************/
|
||
|
// 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--;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************/
|