/*

This software module was originally developed by 

Mike Guzewicz (E-mu Systems)


in the course of development of the MPEG-4 Audio (ISO/IEC 14496-3) standard. 
This software module is an implementation of a part of one or more 
MPEG-4 Audio (ISO/IEC 14496-3) tools as specified by the MPEG-4 Audio 
(ISO/IEC 14496-3). ISO/IEC gives users of the MPEG-4 Audio (ISO/IEC 14496-3) 
free license to this software module or modifications thereof for use 
in hardware or software products claiming conformance to the MPEG-4 Audio 
(ISO/IEC 14496-3). Those intending to use this software module in hardware 
or software products are advised that its use may infringe existing patents. 
The original developer of this software module and his/her company, the 
subsequent editors and their companies, and ISO/IEC have no liability for 
use of this software module or modifications thereof in an implementation. 
Copyright is not released for non MPEG-4 Audio (ISO/IEC 14496-3) conforming 
products. E-mu Systems retains full right to use the code for his/her own 
purpose, assign or donate the code to a third party and to inhibit third 
parties from using the code for non MPEG-4 Audio (ISO/IEC 14496-3) 
conforming products. This copyright notice must be included in all copies 
or derivative works. 

Copyright (C) 1997 E-mu Systems, Inc.

*/
     /*********************************************************************
     
     sfe_win_mem.cpp
     *********************************************************************/
  
#include <string.h>
#include "sfe_datatype.h"
#include "sfe_win_mem.h"


/////////////////////////////
//      Definitions        //
/////////////////////////////


///////////////////////////////////////////////////////
// Take note that these functions are only applicable
// when complied under Windows.
///////////////////////////////////////////////////////

#if defined(WINDOWS_MEMORY)

//////////////////////////
// Allocate your memory
//////////////////////////
VOIDPTR Alloc(DWORD dwSize)
{
  DWORD      dwAllocated;
  HANDLE     hMem;
  void huge* pMem;

  ///////////////////////////////////////////////////
  // Obtain a handle to the allocated memory.  Also
  // be aware that the we are allocating shorts, not
  // bytes.  Therefore, the number of bytes needed
  // will be twice the number of samples indicated.
  ///////////////////////////////////////////////////
  hMem = GlobalAlloc(GHND, (DWORD)(dwSize));

  //// Did we manage to get any memory allocated? ////
  if (hMem != NULL)
  {
    dwAllocated = GlobalSize(hMem);

    //// Was enough memory allocated? ////
    if (dwSize <= dwAllocated)
    {
      //// Lock it in place ////
      pMem = (VOIDPTR)GlobalLock(hMem);

      if (pMem != NULL)
      {
	return (pMem);
      }
    }

    //// Free up the allocated memory since you didn't pass your tests ////
    GlobalFree(hMem);
  }

  return (NULL);
}


////////////////////////////////////////
// Initialize your memory to some value
////////////////////////////////////////
VOIDPTR Memset(VOIDPTR pMem, WORD wValue, DWORD dwSize)
{
  if (pMem != NULL)
  {
    BYTEPTR pByte = (BYTEPTR) pMem;

    if (dwSize != 0)
    {
      //// Decrement for zero-based indexing ////
      dwSize--;

      while (dwSize > 0)
      {
	pByte[dwSize] = wValue;
	dwSize--;
      }

      //// Pick up the last byte ////
      pByte[0] = wValue;
    }
  }
  return (pMem);
}


//////////////////////////
// Deallocate your memory
//////////////////////////
void Dealloc(VOIDPTR pMem)
{
  HANDLE hMem;

  ///////////////////////////////
  // Memory debugging code
  ///////////////////////////////

  if (pMem != NULL)
  {
    hMem = GlobalHandle(SELECTOROF(pMem));

    if (hMem != NULL)
    {
      GlobalUnlock(hMem);
      GlobalFree(hMem);

      pMem = NULL;
    }
  }
}


///////////////////////////////////////////////
// Copy your memory to another memory location
///////////////////////////////////////////////
VOIDPTR HFMemCopy(VOIDPTR pDest, VOIDPTR pSrc, DWORD dwNBytes)
{
  //// A Windows 3.1 specific call... ////
  hmemcpy(pDest, pSrc, (LONG) dwNBytes);

  /////////////////////////////////////////////////
  // Here's how one might code the above function:
  /////////////////////////////////////////////////
  /*
  DWORD   dwBytesLeft;
  BYTEPTR pTempSrc    = (BYTEPTR) pSrc;
  BYTEPTR pTempDest   = (BYTEPTR) pDest;


  if (dwNBytes != 0)
  {
    //// Decrement for zero-based indexing ////
    dwNBytes--;

    while (dwNBytes > 0)
    {
      pTempDest[dwNBytes] = pTempSrc[dwNBytes];
      dwNBytes--;
    }

    //// Pick up the last byte ////
    pTempDest[0] = pTempSrc[0];
  }
  */

  return ((VOIDPTR) pDest);
}


////////////////////////////////////////////////////////////////
// The following is normal memory management using new/delete
////////////////////////////////////////////////////////////////
#elif defined(CPP_MEMORY)

VOIDPTR Alloc(DWORD dwSize)
{
  return ((VOIDPTR) new BYTE[(size_t) dwSize]);
}


VOIDPTR Memset(VOIDPTR pMem, WORD wValue, DWORD dwSize)
{
  return (memset(pMem, wValue, dwSize));
}


void Dealloc(VOIDPTR pMem)
{
  delete [] pMem;
  pMem = 0;
}


VOIDPTR HFMemCopy(VOIDPTR pDest, VOIDPTR pSrc, DWORD dwNBytes)
{
  return (memcpy(pDest, pSrc, (size_t)dwNBytes));
}

////////////////////////////////////////////////////////////////
// The following is DOS memory management using far... functions
////////////////////////////////////////////////////////////////
#elif defined(DOS_MEMORY)

VOIDPTR Alloc(DWORD dwSize)
{
  return ((VOIDPTR)farmalloc(dwSize));
}


VOIDPTR Memset(VOIDPTR pMem, WORD wValue, DWORD dwSize)
{
  VOIDPTR theReturn = pMem;
  BYTEPTR pByte = (BYTEPTR) pMem;
  WORD count = 0;
  size_t theMemSetSize;
  while (dwSize != 0)
  {
   if (dwSize > 0xFFFF)
     theMemSetSize = 0xFFFF;
   else
     theMemSetSize = (size_t)dwSize;
   if (_fmemset(&pByte[count*0x10000], wValue, theMemSetSize) == NULL)
     return NULL;
   dwSize -= theMemSetSize;
   count++;
  }
  return theReturn;
}


void Dealloc(VOIDPTR pMem)
{
  farfree(pMem);
  pMem = 0;
}


VOIDPTR HFMemCopy(VOIDPTR pDest, VOIDPTR pSrc, DWORD dwNBytes)
{
  BYTEPTR pByteDest;
  BYTEPTR pByteSrc;

  pByteDest = (BYTEPTR)pDest;
  pByteSrc =  (BYTEPTR)pSrc;

  VOIDPTR theReturn = (VOIDPTR)(pByteDest[dwNBytes]);
  DWORD count = 0;
  size_t theMemCpySize;
  while (dwNBytes != 0)
  {
   if (dwNBytes > 0xFFFF)
     theMemCpySize = 0xFFFF;
   else
     theMemCpySize = (size_t)dwNBytes;
   if (_fmemcpy(&pByteDest[count*0x10000], &pByteSrc[count*0x10000], theMemCpySize) == NULL)
     return NULL;
   dwNBytes -= theMemCpySize;
   count++;
  }
  return theReturn;

}

#endif

//////////////////////// End of WIN_MEM.CPP /////////////////////////
