converted by lore's source converter


//////////////////////////////////////////////////////////////////////////////
//
// MTypes.cpp: Implementation of the basic type classes
//
//////////////////////////////////////////////////////////////////////////////
//
// author:     Eckhard Kantz
// website:    http://wegalink.eu
//
//////////////////////////////////////////////////////////////////////////////
/* 
This is FREE software  

Permission is hereby granted, free of charge,  to any person obtaining  a copy 
of this software and associated documentation files (the "Software"),  to deal 
in the Software without restriction, including without limitation  the  rights 
to use,  copy,  modify,  merge,  publish,  distribute, sublicense, and/or sell 
copies  of  the  Software,   and  to  permit  persons  to  whom  the  Software 
is furnished to do so, subject to the following conditions: 

There are no conditions imposed on the use of this software. 

THE SOFTWARE IS PROVIDED "AS IS",  WITHOUT  WARRANTY  OF ANY KIND,  EXPRESS OR 
IMPLIED,  INCLUDING  BUT  NOT  LIMITED  TO  THE  WARRANTIES OF MERCHANTABILITY, 
FITNESS  FOR  A  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY CLAIM,  DAMAGES OR OTHER 
LIABILITY,  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, 
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN  THE 
SOFTWARE. 
*/

#include "MTypes.h"

//////////////////////////////////////////////////////////////////////
// MString Class
//////////////////////////////////////////////////////////////////////

MString::MString()
{
  //Reset text array and length
   pText   = NULL;
   uLength = 0;
}

MString::MString(const int8* _text)
{
  //Initialize text array
   pText = NULL;
   setText(_text);
}

MString::MString(const MString & _String)
{
  //Initialize text array
   pText = NULL;
   setText(_String.getText());
}


MString::MString(uint32 _uLength)
{
  //Generate empty text array
   uLength = _uLength;
   pText   = new int8[uLength + 1];
   memset(pText,0,uLength+1);
}

MString::~MString()
{
  //Remove text array from heap
   delete[] pText;
}

const int8* MString::getText() const
{
  //Return text array or empty string
   if(NULL != pText){
      return pText;
   }else{
      return (int8*)"";
   }
}

int8* MString::getBuffer() const
{
    // Check length and return text array
   if (uLength>0){
      return pText;
   }else{
      return "";
   }
}

uint32 MString::getLength() const
{
  //Return text length
   return uLength;
}

int8* MString::setText(const int8* _pText)
{
  //Replace existing text array with a new string
   uLength = (uint32)strlen(_pText);
   delete[] pText;
   pText = new int8[uLength+1];
  if (uLength>0){
     memcpy(pText,_pText,uLength);
  }
  pText[uLength] = 0;
   return pText;
}

void MString::setText(const MString & _String)
{
  //Replace existing text array with the content of a given MString object
   setText(_String.getText());
}

int8* MString::setText(const int8* pFirst, const int8* pLast)
{
  //Replace existing text array with a given substring
  if (pFirst<=pLast){
   uLength = (uint32)(pLast-pFirst+1);
  }else{
    uLength = 0;
  }
   delete[] pText;
   pText = new int8[uLength+1];
  if (uLength>0){
     memcpy(pText, pFirst, uLength);
  }
   pText[uLength] = 0;
   return pText;
}

void MString::setLength(uint32 _uLength)
{
  //Reallocate the text array with a new size
   uLength = _uLength;
   delete[] pText;
   pText = new int8[uLength+1];
   *(pText+uLength) = 0;
}

void MString::setAt(uint32 _uPos, uint32 _uChar)
{
  //Replace a single character in the text array
   if(_uPos < uLength){
      pText[_uPos] = (int8)_uChar;
   }
}

uint32 MString::operator[](uint32 _uPos) const
{
  //Return single character at a given position in the text array
   if(_uPos >= uLength){
      return 0;
   }else{
      return pText[_uPos];
   }
}

void MString::operator += (MString& mString)
{
   operator += (mString.getBuffer());
}

void MString::operator += (int8* pString)
{
   //Preserve existing text array
   int8*  pOldText   = pText;
   uint32 uOldLength = uLength;

   //Add existing and new string into the new text array
   uint32 uStringLength = (uint32)strlen(pString);
   uLength += uStringLength;
   pText = new int8[uLength+1];
   pText[uLength]=0;
   if (uOldLength>0){
      memcpy(pText,pOldText,uOldLength);
   }
   if (uLength>uOldLength){
      memcpy(pText+uOldLength,pString,uStringLength);
   }
   delete[] pOldText;
}

void MString::operator += (uint32 uNum)
{
   MString mString;
   mString = uNum;
   operator += (mString.getBuffer());
}

void MString::operator += (uint64 u64Num)
{
   MString mString;
   mString = u64Num;
   operator += (mString.getBuffer());
}

void MString::operator = (const MString& _mString)
{
  //Take over content from a given MString object
   setText(_mString.getText());
}

void MString::operator = (const int8* szString)
{
  //Take over content from a given MString object
   setText(szString);
}

void MString::operator=(const uint32 uNum)
{
   char achNum[20];
   sprintf(achNum,"%u",uNum);
   setText(achNum);
}

void MString::operator=(const uint64 u64Num)
{
#define NUM_BILLION 1000000000
   char achNum[40];
   if (u64Num/NUM_BILLION >= NUM_BILLION){
      sprintf(achNum,"%u%u%u",
         (uint32)((u64Num/NUM_BILLION)/NUM_BILLION),
         (uint32)((u64Num/NUM_BILLION)%NUM_BILLION),
         (uint32)(u64Num%NUM_BILLION));
   }else if(u64Num >= NUM_BILLION){
      sprintf(achNum,"%u%u",
         (uint32)(u64Num/NUM_BILLION),
         (uint32)(u64Num%NUM_BILLION));
   }else{
      sprintf(achNum,"%u",(uint32)u64Num);
   }
   setText(achNum);
}

bool MString::operator==(const MString& mTxt)
{
  //Compare the text content of two MString objects
   if (mTxt.getLength()!=uLength){
      return false;
   }else{
      if (0==strcmp(mTxt.getBuffer(),pText)){
         return true;
      }else{
         return false;
      }
   }
}

bool MString::operator==(int8* achTxt)
{
  //Compare the text array with a given string
   if (strlen(achTxt)!=uLength){
      return false;
   }else{
      if (0==strcmp(achTxt,pText)){
         return true;
      }else{
         return false;
      }
   }
}

bool MString::operator!=(const MString& mTxt)
{
  //Compare the text content of two MString objects
   if (mTxt.getLength()!=uLength){
      return true;
   }else{
      if (0!=strcmp(mTxt.getBuffer(),pText)){
         return true;
      }else{
         return false;
      }
   }
}

bool MString::operator!=(int8* achTxt)
{
  //Compare the text array with a given string
   if (strlen(achTxt)!=uLength){
      return true;
   }else{
      if (0!=strcmp(achTxt,pText)){
         return true;
      }else{
         return false;
      }
   }
}

int MString::compareHeader(const int8* _header)
{
  //Compare the first characters in the text array with a given header string
   return strncmp(pText, _header, strlen(_header));
}

unsigned int MString::Match(MLString** ppLMatch, int8 const* pPattern)
{
   int8* pFirst    = pText; //first matching character
   int8* pSrcText  = pText; //current text position
   int8  chMatch = ' ';  //single character to be found
   int8* szMatch = NULL;    //group of alternative characters
   uint32 nSkip;         //skip any character
   uint32 nMatch;         //current match number
   uint32 nMatchMin;     //minimal match number
   uint32 nMatchMax;     //maximal match number
   uint32 nLMatch = 0;       //number of valid result list members

   for(;;){

      //Evaluate next pattern element
      nSkip   = 0;
      szMatch = NULL;
      switch(*pPattern){
      case 0:
         return nLMatch;
      case '(':
         pFirst = pSrcText;
         pPattern++;
         continue;
      case ')':
         if(NULL == *ppLMatch){
            *ppLMatch = new MLString;
         }
         (*ppLMatch)->setText(pFirst, pSrcText-1);
         ppLMatch = (*ppLMatch)->getAdrNext();
         nLMatch++;
         pPattern++;
         continue;
      case '.':
         pPattern++;
         //Determine modifiers
         switch(*pPattern){
         case'*':
            nSkip = MAX_UINT32;
            pPattern++;
            break;
         case '+':
            nSkip = MAX_UINT32;
            pSrcText++;
            pPattern++;
         default:
            nSkip = 1;
            break;
         }
         break;
      case '\\':
         pPattern++;
         switch(*pPattern){
         case 's':   //white spaces
            szMatch = " \t\r\n";
            break;
         case 'd':   //digits
            szMatch = "0123456789";
            break;
         case 'w':   //word characters
            szMatch = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            break;
         default:
            chMatch = *pPattern;
            break;
         }
         pPattern++;
         break;
      default:
         chMatch = *pPattern++;
         break;
      }

      //Determine possible modifiers
      switch(*pPattern){
      case '*':
         nMatchMin = 0;
         nMatchMax = MAX_UINT32;
         pPattern++;
         break;
      case '+':
         nMatchMin = 1;
         nMatchMax = MAX_UINT32;
         pPattern++;
         break;
      case '?':
         nMatchMin = 0;
         nMatchMax = 1;
         pPattern++;
         break;
      default:
         nMatchMin = 1;
         nMatchMax = 1;
         break;
      }

      //Step over matching character(s)
      for(nMatch=0;;){
         if(NULL == szMatch){
            while(nMatch < nMatchMax && chMatch == *pSrcText){
               nMatch++;
               pSrcText++;
            }
         }else{
            while(nMatch < nMatchMax && NULL != strchr(szMatch, (int32)*pSrcText)){
               nMatch++;
               pSrcText++;
            }
         }
         if(nMatch < nMatchMin){
            if(nSkip > nMatch){
               nSkip -= nMatch + 1;
               pSrcText++;
               nMatch = 0;
               continue;
            }
            return nLMatch;
         }
         break;
      }
   }
}

// Conversion function
uint32 MString::getNum()
{
   uint32 uNum = 0;
   for (uint32 i=0;i<getLength();i++){
      uNum *= 10;
      uNum += *(pText+i)-'0';
   }
   return uNum;
}

//Backup and restore
const int8* MString::read(const int8* pFilename)
{
   FILE*   pFile;
   struct  stat buf;
   int32   fh;
   uint32  uFileSize = 0;

   //Determine file size
   if (-1!=(fh = open(pFilename,O_RDONLY))){
      if (0==fstat(fh,&buf)){
         uFileSize = buf.st_size;
      }else{
         throw MException("File status not accessible.");
      }
      close( fh );
   }else{
      throw MException("Data file not found.");
   }

   pFile = fopen(pFilename,"rb");
   if(NULL==pFile){
      throw MException("Data file can not be opened.");
   }else{
      try{
         setLength(uFileSize);
         fread(pText,1,uFileSize,pFile);
         fclose(pFile);
      }catch(...){
         fclose(pFile);
         throw MException("Data file not readable.");
      }
   }
   return pText;
}

void MString::write(const int8* pFilename)
{
   FILE*   pFile;
   if (NULL!=(pFile = fopen(pFilename,"wb"))){
      fwrite(pText,uLength,1,pFile);
   }
   fclose(pFile);
}


//////////////////////////////////////////////////////////////////////
// MLString Class
//////////////////////////////////////////////////////////////////////
MLString::MLString()
{
   pNext = NULL;
}

MLString::~MLString()
{

}

MLString* MLString::getNext()
{
   return pNext;
}

MString* MLString::setNext(MLString* _Next)
{
   return(pNext = _Next);
}

MLString** MLString::getAdrNext()
{
   return &pNext;
}



//////////////////////////////////////////////////////////////////////
// MMString Class
//////////////////////////////////////////////////////////////////////
MMString::MMString(const MString& _mSourceString,const int8* _pszDelimiters)
:mSourceString(_mSourceString)
{
   uCurrentPosition = 0;
   mSetOfDelimiters.setText(_pszDelimiters);
}

MMString::~MMString()
{
}

int8* MMString::getNextDelimitedString()
{
   uint32 uSubStringLength = 0;
   bool   fDelimiterFound  = false;

   //Current position must not be greater than the string length
   if(uCurrentPosition >= mSourceString.uLength){
      return NULL;
   }
   for(;uCurrentPosition<mSourceString.uLength;uCurrentPosition++){
      for(uint32 k=0;k<mSetOfDelimiters.getLength();k++){
         if((uint32)*(mSourceString.getText()+uCurrentPosition) == mSetOfDelimiters[k]){
            fDelimiterFound = true;
            break;
         }
      }
      if(true==fDelimiterFound){
         if(uSubStringLength>0){
            break;
         }
         fDelimiterFound = false;
      }else{
         uSubStringLength++;
      }
   }
   //Transfer substring
   setLength(uSubStringLength);
   for(uint32 m=0;m<uSubStringLength;m++){
      setAt(m, (uint32)*(mSourceString.getText()+uCurrentPosition-uSubStringLength+m));
   }

   return pText;
}

void MMString::operator=(const MMString&)
{
}


int8* MMString::setDelimiters(int8* pszDelimiters)
{
   return mSetOfDelimiters.setText(pszDelimiters);
}

void MMString::resetPosition()
{
   uCurrentPosition = 0;
}

//////////////////////////////////////////////////////////////////////
// MDateTime class
//////////////////////////////////////////////////////////////////////
MDateTime::MDateTime()
{

}

MDateTime::~MDateTime()
{

}

// Systime access function (nanoseconds)
int64 MDateTime::getSysClockNanoSec()
{
#ifndef WIN32
   struct timeval  stTimeValue;
   struct timezone stTimeZone;
    gettimeofday(&stTimeValue,&stTimeZone);
   return (((int64)1000000000*stTimeValue.tv_sec)+(int64)1000*stTimeValue.tv_usec);
#else
   struct timeb timebuffer;
   ftime( &timebuffer );
   return (int64)1000000*((int64)1000*timebuffer.time+timebuffer.millitm);
#endif
}

// Time conversion
uint64 MDateTime::getNanoSec(const char* szDateTime)
{
#define TIMEZONE 60*60
   MString  mDateTime(szDateTime);
   MMString mNum(mDateTime," -:.cdehilmnostu");

   // Date/time components
   time_t     nTime;
   int32     nMilliSeconds;
   struct tm stDateTime;
   stDateTime.tm_isdst = 0;
   // Year
   mNum.resetPosition();
   if (NULL==mNum.getNextDelimitedString()){
      throw MException("Invalid year");
   }
   stDateTime.tm_year = mNum.getNum() - 1900;
   // Month
   if (NULL==mNum.getNextDelimitedString()){
      throw MException("Invalid month");
   }
   stDateTime.tm_mon = mNum.getNum() - 1;
   // Day
   if (NULL==mNum.getNextDelimitedString()){
      throw MException("Invalid day");
   }
   stDateTime.tm_mday = mNum.getNum();
   // Hour
   if (NULL==mNum.getNextDelimitedString()){
      throw MException("Invalid hour");
   }
   stDateTime.tm_hour = mNum.getNum();
   // Minute
   if (NULL==mNum.getNextDelimitedString()){
      throw MException("Invalid minute");
   }
   stDateTime.tm_min = mNum.getNum();
   // Second
   if (NULL==mNum.getNextDelimitedString()){
      throw MException("Invalid second");
   }
   stDateTime.tm_sec = mNum.getNum();
   // Millisecond
   if (NULL==mNum.getNextDelimitedString()){
      nMilliSeconds = 0;
   }else{
      nMilliSeconds = mNum.getNum();
   }
   // Convert  
   if (-1==(nTime=mktime(&stDateTime))){
      throw MException("Time not recognized",szDateTime);
   }
   return (((uint64)(nTime + TIMEZONE) * 1000) + nMilliSeconds) * 1000000;
}

MString MDateTime::getTimeUTC(uint32 uDateTime)
{
   if (0==uDateTime){
      uDateTime = time(NULL);
   }
   struct tm* pDateTime = gmtime((time_t*)&uDateTime);
   char achUTC[20];
   sprintf(achUTC,"%4u-%02u-%02u %02u:%02u:%02u",
      pDateTime->tm_year + 1900,
      pDateTime->tm_mon + 1,
      pDateTime->tm_mday,
      pDateTime->tm_hour,
      pDateTime->tm_min,
      pDateTime->tm_sec);

   return MString(achUTC);
}

//////////////////////////////////////////////////////////////////////
// MBenchmark class
//////////////////////////////////////////////////////////////////////
#define TOLERANCE   150
#define PRECISION   10L
#define RANGE_MILLI   1000000L
#define RANGE_MICRO   1000L
#define RANGE_MIN     100L
#define RANGE_MAX     1000000L

MBenchmark::MBenchmark(int32 _nLoops, int32 _nTrialPeriodMilliSec, int32 _nTrials)
{
   nLoops          = _nLoops > 0 ? _nLoops : 1;
   nTrials         = _nTrials > 0 ? _nTrials : 1;
   n64TrialPeriod  = _nTrialPeriodMilliSec > 0 ? _nTrialPeriodMilliSec : 0;
   n64TrialPeriod  *= 1000000; //convert to nanoseconds
   // Set start condition
   nCurLoop  = 0;
   nCurTrial = 0;
}
MBenchmark::~MBenchmark()
{

}
bool MBenchmark::run()
{
   // Check loop status
   if(--nCurLoop > 0){
      return true;
   }
   // Check for start condition
   if(0==nCurTrial){
      // Initiate new run
      nCycles          = 1;
      nCurLoop         = nLoops;
      nCurTrial        = nTrials;
      n64DurationMin   = MAX_INT64;
      n64ZeroOffsetMin = MAX_INT64;
      n64TrialEnd      = mDateTime.getSysClockNanoSec() + n64TrialPeriod;
      return true;
   }
   // Check for trial end
    if(n64TrialEnd > (n64CurTime = mDateTime.getSysClockNanoSec())){
      nCycles++;
      nCurLoop = nLoops;
      return true;
   }else{
      // Evaluate trial results
      if(nCycles * nLoops != 0){
         n64Duration = (n64TrialPeriod + n64CurTime - n64TrialEnd)* PRECISION / (nCycles * nLoops);
         // Evaluate empty loop (zero offset)
         nCurLoop   = nLoops;
         nCurCycle  = nCycles;
         n64CurTime = mDateTime.getSysClockNanoSec();
         while(dummy());
         n64TrialEnd   = mDateTime.getSysClockNanoSec();
         n64ZeroOffset = (n64TrialEnd - n64CurTime)* PRECISION / (nCycles * nLoops);
      }else{
         n64Duration = -1;
      }
      if(n64Duration > 0 && n64Duration < n64DurationMin){
         n64DurationMin = n64Duration;
      }
      if(n64ZeroOffset >= 0 && n64ZeroOffset < n64ZeroOffsetMin){
         n64ZeroOffsetMin = n64ZeroOffset;
      }
      if(--nCurTrial > 0){
         nCycles          = 1;
         nCurLoop         = nLoops;
         n64DurationMin   = MAX_INT64;
         n64ZeroOffsetMin = MAX_INT64;
         n64TrialEnd      = mDateTime.getSysClockNanoSec() + n64TrialPeriod;
         return true;
      }
      return false;
   }
}
bool MBenchmark::dummy()
{
   if(nCurLoop-- > 0){
      return true;
   }
   if(nCurCycle-- > 0){
      nCurLoop = nLoops;
      return true;
   }
   return false;
}
MString MBenchmark::info(int64 n64Reference,int64 n64Divisor)
{
   int8 achInfo[1000];
   int8 achFlag[1000];

   if(n64Divisor > 1){
      n64DurationMin = (n64DurationMin -n64ZeroOffsetMin) /n64Divisor;
   }else{
      n64DurationMin = n64DurationMin -n64ZeroOffsetMin;
   }
   if((int32)n64DurationMin < (int32)n64Reference){
      sprintf(achFlag,"--");
   }else if(100*(int32)n64DurationMin > TOLERANCE*(int32)n64Reference){
      sprintf(achFlag,"++");
   }else{
      sprintf(achFlag," ");
   }
   if((int32)n64DurationMin <= 0){
    // Invalid
      sprintf(achInfo,"       n.a.         ");
   }else if((int32)(n64DurationMin/(PRECISION*RANGE_MILLI)) > RANGE_MAX){
    // Range exceeded
      sprintf(achInfo,"    - out of range -");
   }else if((int32)(n64DurationMin/(PRECISION*RANGE_MILLI)) >= RANGE_MIN &&
      (int32)(n64DurationMin/RANGE_MILLI) >= 0){
       // Millisecond range
      sprintf(achInfo,"%6u ms ref:%6u %s",
         (int32)(n64DurationMin/(PRECISION*RANGE_MILLI)),
         (int32)(n64Reference/(PRECISION*RANGE_MILLI)),
         achFlag);
   }else if((int32)(n64DurationMin/(PRECISION*RANGE_MICRO)) >= RANGE_MIN &&
      (int32)(n64DurationMin/(RANGE_MICRO*RANGE_MIN)) >= 0){
       // Microsecond range
      sprintf(achInfo,"%6u us ref:%6u %s",
         (int32)(n64DurationMin/(PRECISION*RANGE_MICRO)),
         (int32)(n64Reference/(PRECISION*RANGE_MICRO)),
         achFlag);
   }else if((int32)(n64DurationMin/PRECISION) >= RANGE_MIN){
       // Nanosecond range
      sprintf(achInfo,"%6u ns ref:%6u %s",
         (int32)(n64DurationMin/PRECISION),
         (int32)(n64Reference/PRECISION),
         achFlag);
   }else{
       // Sub-nanosecond range
      sprintf(achInfo,"%6.1f ns ref:%6.1f %s",(float)n64DurationMin/PRECISION,(float)n64Reference/PRECISION,achFlag);
   }
   return MString(achInfo);
}


//////////////////////////////////////////////////////////////////////
// MException Class
//////////////////////////////////////////////////////////////////////
MException::MException()
{
   pData  = NULL;
   putMessage("General exception encountered");
   putContext("");
}

MException::MException(void* _pData)
{
   pData = _pData;
   putMessage("Exception with data encountered");
   putContext("");
}

MException::MException(MString& mMessage)
{
   pData = NULL;
   putMessage(mMessage.getText());
   putContext("");
}

MException::MException(const int8* _pMessage)
{
   pData = NULL;
   putMessage(_pMessage);
   putContext("");
}

MException::MException(MString& mMessage,int32 _nParameter)
{
   pData = NULL;
   putMessage(mMessage.getText());
   MString mParameter(_nParameter);
   putContext(mParameter.getText());
}

MException::MException(const int8* _pMessage,int32 _nParameter)
{
   pData = NULL;
   putMessage(_pMessage);
   MString mParameter(_nParameter);
   putContext(mParameter.getText());
}

MException::MException(MString& mMessage,MString& mContext)
{
   pData = NULL;
   putMessage(mMessage.getText());
   putContext(mContext.getText());
}

MException::MException(const int8* _pMessage,MString& mContext)
{
   pData = NULL;
   putMessage(_pMessage);
   putContext(mContext.getText());
}

MException::MException(const int8* _pMessage,const int8* _pContext)
{
   pData = NULL;
   putMessage(_pMessage);
   putContext(_pContext);
}

MException::MException(void* _pData,MString& mMessage)
{
   pData = _pData;
   putMessage(mMessage.getText());
   putContext("");
}

MException::MException(void* _pData,const int8* _pMessage)
{
   pData = _pData;
   putMessage(_pMessage);
   putContext("");
}

MException::MException(void* _pData,MString& mMessage,MString& mContext)
{
   pData = _pData;
   putMessage(mMessage.getText());
   putContext(mContext.getText());
}

MException::MException(void* _pData,const int8* _pMessage,MString& mContext)
{
   pData = _pData;
   putMessage(_pMessage);
   putContext(mContext.getText());
}

MException::MException(void* _pData,const int8* _pMessage,const int8* _pContext)
{
   pData = _pData;
   putMessage(_pMessage);
   putContext(_pContext);
}

MException::MException( const MException &E)
{
   pData = E.pData;
   putMessage(E.pMessage);
   putContext(E.pContext);
}

MException::~MException()
{
   delete pMessage;
   delete pContext;
}

void MException::putMessage(const int8* _pMessage)
{
   pMessage = new int8[strlen(_pMessage)+1];
   strcpy(pMessage,_pMessage);
}

void MException::putContext(const int8* _pContext)
{
   pContext = new int8[strlen(_pContext)+1];
   strcpy(pContext,_pContext);
}

void* MException::getData()
{
   return pData;
}

int8* MException::getMessage()
{
   return pMessage;
}

int8* MException::getContext()
{
   return pContext;
}