//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include "Precompiled.h"
#include "SharedIncludes.h"

namespace CommonHelpers {
//==================================================================================================

void* SysHelpers_PAccess::InterlockedExchangePtr( [HIn][HOut][HInterlockedAccess]
                                                  void** volatile pPointerOperand,
                                                  void* substutionPointerValue )
{
   return Unmanaged::InterlockedExchangePtr( pPointerOperand, substutionPointerValue );
}

//--------------------------------------------------------------------------------------------------

void* SysHelpers_PAccess::ClearMemoryBlock( [HOut] void* pDestinationBlock,
                                            UIntPtr length )
{
   ::ZeroMemory( pDestinationBlock, ($SIZE)length );
   return pDestinationBlock;
}

void* SysHelpers_PAccess::CopyMemoryBlock( [HIn] void* pSourceBlock,
                                           [HOut] void* pDestinationBlock,
                                           UIntPtr length )
{
   ::CopyMemory( pDestinationBlock, pSourceBlock, ($SIZE)length );
   return pDestinationBlock;
}

//--------------------------------------------------------------------------------------------------

generic<typename T>
array<T>^ SysHelpers_PAccess::CopyBufferToArray( [HIn] void* pSourceElements,
                                                 array<T>^ destinationElements )
{
   pin_ptr<T> pDestinationElements = &destinationElements[ 0 ];
   int count = destinationElements->Length;
   if ( count )
      ::CopyMemory( pDestinationElements, pSourceElements,
         ($SIZE)HCheckedInt::Multiply( count, sizeof(T) ) );
   return destinationElements;
}

generic<typename T>
void* SysHelpers_PAccess::CopyArrayToBuffer( array<T>^ sourceElements,
                                             [HOut] void* pDestinationElements )
{
   pin_ptr<T> pSourceElements = &sourceElements[ 0 ];
   int count = sourceElements->Length;
   if ( count )
      ::CopyMemory( pDestinationElements, pSourceElements,
         ($SIZE)HCheckedInt::Multiply( count, sizeof(T) ) );
   return pDestinationElements;
}

//--------------------------------------------------------------------------------------------------

void SysHelpers_PAccess::ReleaseIUnknown([HIn][HOut] void* pIUnknown)
{
   ((IUnknown*)pIUnknown) -> Release();
}

//==================================================================================================

static SysHelpers_PAccess::SysHelpers_PAccess()
{
   SystemLib::Access();
}

//==================================================================================================
} // CommonHelpers
