/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
/* -*-C++-*-
****************************************************************************
*
* File:         IpcMessageObj.cpp (previously under /common)
* Description:
*
* Created:      5/6/98
* Language:     C++
*
*
*
****************************************************************************
*/

#include "Platform.h"


#include "NAStdlib.h"
#include "Ipc.h"

#include "IpcMessageObj.h"
#include "str.h"
#include "ComDefs.h"  // to get ROUND8
#include <byteswap.h>
// -----------------------------------------------------------------------
// Methods for class IpcMessageObj
// -----------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////////////
// general constructor, creates both unpacked, packed objects 
IpcMessageObj::IpcMessageObj(IpcMessageObjType msgType,
			     IpcMessageObjVersion version)
  {
  s_.objType_ = (short) msgType;
  s_.objVersion_ = version;
  s_.refCount_ = 1; // an object comes with an initial refcount of 1
  s_.objLength_ = 0;
  s_.next_ = NULL;
  s_.endianness_  = IpcMyEndianness;
  s_.spare1_ = 0;
  s_.spare2_ = 0;
  s_.vPtrPad_ = NULL;
  }

///////////////////////////////////////////////////////////////////////////////  
// constructor used to perform copyless receive, maps packed objects in place.
IpcMessageObj::IpcMessageObj(IpcBufferedMsgStream* msgStream)
  { 
  // IpcBufferedMsgStream parm used to differentiate from default constructor
  if (s_.endianness_ != IpcMyEndianness)
    {
    swapFourBytes(s_.objType_);
    swapFourBytes(s_.objVersion_);
    swapFourBytes(s_.objLength_);
    assert(0); // didn't implement
    s_.refCount_ = 1; // an object comes with an initial refcount of 1
    s_.endianness_ = IpcMyEndianness;
    }
  }

IpcMessageObj::~IpcMessageObj()
{
  if (s_.refCount_ != 1)
    {
      // something went wrong!!!!!!!!!!!!!!!
      //
      // Take the two cases:
      // a) the variable is allocated in static memory or in the stack
      // b) the variable was allocated from the heap, using operator new
      //
      // For case a), the user isn't supposed to perform any increments
      // or decrements of the ref count. One possibility is that he did.
      // The other possibility is that there are still outstanding I/Os
      // or other processes that share the object and therefore we
      // shouldn't destroy it.
      //
      // For case b) it is similar. Either the user hasn't used increment
      // and decrement refcount and then he can delete the object or
      // get rid of it by decrementing the refcount (preferred method).
      // Again, either the user forgot to decrement the refcount or
      // the object is still shared by other components.

      // Complain about the abuse
      ABORT("trying to destroy a message object that is still in use");
    }
}

///////////////////////////////////////////////////////////////////////////////
// used to allocate a packed send object.
void* IpcMessageObj::operator new(size_t size,
                                  IpcBufferedMsgStream& msgStream,
                                  IpcMessageObjSize appendDataLen)
{
  IpcMessageObjSize appendStart = (IpcMessageObjSize) size;
  
  alignSizeForNextObj(appendStart);
  return (msgStream.sendMsgObj(appendStart + appendDataLen));
}

IpcMessageObjSize IpcMessageObj::packObjIntoMessage(
               IpcMessageBufferPtr buffer)
{
  return packObjIntoMessage(buffer, FALSE);
}

IpcMessageObjSize IpcMessageObj::packObjIntoMessage(IpcMessageBufferPtr buffer,
                            NABoolean swapBytes)
{
  // copy the base class (IpcMessageObj) data members and calculate how
  // many more bytes beyond the base class remain to be copied
  IpcMessageObjSize derivedObjLen =
    packedLength() - packBaseClassIntoMessage(buffer, swapBytes);

  // ---------------------------------------------------------------------
  // copy derivedObjLen bytes to the message buffer, assuming that
  // the packed and unpacked representations of the object are the same,
  // that whoever derived from this class did correctly override
  // the packedLength() virtual function, and that the derived data is
  // stored directly following the base class data (this may not be the
  // case if multiple inheritance is used!!!!).
  // ---------------------------------------------------------------------
  str_cpy_all(buffer, (const char *) &this[1], derivedObjLen);

  return derivedObjLen + sizeof(IpcMessageObj);
}

IpcMessageObjSize IpcMessageObj::packObjIntoMessage32(
               IpcMessageBufferPtr buffer)
{
  return packObjIntoMessage32(buffer, FALSE);
}

IpcMessageObjSize IpcMessageObj::packObjIntoMessage32(IpcMessageBufferPtr buffer,
                            NABoolean swapBytes)
{
  // copy the base class (IpcMessageObj) data members and calculate how
  // many more bytes beyond the base class remain to be copied
  IpcMessageObjSize derivedObjLen =
    packedLength32() - packBaseClassIntoMessage32(buffer, swapBytes);

  // ---------------------------------------------------------------------
  // copy derivedObjLen bytes to the message buffer, assuming that
  // the packed and unpacked representations of the object are the same,
  // that whoever derived from this class did correctly override
  // the packedLength() virtual function, and that the derived data is
  // stored directly following the base class data (this may not be the
  // case if multiple inheritance is used!!!!).
  // ---------------------------------------------------------------------
  str_cpy_all(buffer, (const char *) &this[1], derivedObjLen);

  return derivedObjLen + sizeof(IpcMessageObj);
}

void IpcMessageObj::unpackObj(IpcMessageObjType /*objType*/,
			      IpcMessageObjVersion /*objVersion*/,
			      NABoolean /*sameEndianness*/,
			      IpcMessageObjSize objSize,
			      IpcConstMessageBufferPtr buffer)
{
  assert(objSize >= sizeof(IpcMessageObj));

  // unpack the first sizeof(IpcMessageObj) bytes and fixup the virtual
  // function pointer of the base class
  unpackBaseClass(buffer);

  // copy the rest into the memory following the IpcMessageObj data members
  // (should we allow such a dangerous default implementation?)
  str_cpy_all((char *) &this[1], buffer, objSize - sizeof(IpcMessageObj));
  // - Change the offset in the next ptr to zero
  //
  s_.next_ = NULL;
}

void IpcMessageObj::unpackObj32(IpcMessageObjType /*objType*/,
			        IpcMessageObjVersion /*objVersion*/,
			        NABoolean /*sameEndianness*/,
			        IpcMessageObjSize objSize,
			        IpcConstMessageBufferPtr buffer)
{
  assert(objSize >= SQL_32BIT_IPC_MESSAGE_OBJ_SIZE);

  // unpack the first sizeof(IpcMessageObj) bytes and fixup the virtual
  // function pointer of the base class
  unpackBaseClass32(buffer);

  // copy the rest into the memory following the IpcMessageObj data members
  // (should we allow such a dangerous default implementation?)
  str_cpy_all((char *) &this[1], buffer, objSize - SQL_32BIT_IPC_MESSAGE_OBJ_SIZE);
  // - Change the offset in the next ptr to zero
  //
  s_.next_ = NULL;
}

NABoolean IpcMessageObj::checkObj(IpcMessageObjType t,
                                  IpcMessageObjVersion v,
                                  NABoolean sameEndianness,
                                  IpcMessageObjSize size,
                                  IpcConstMessageBufferPtr buffer) const
{
  return checkBaseClass(t, v, sameEndianness, size, buffer);
}

NABoolean IpcMessageObj::checkBaseClass(IpcMessageObjType t,
                                        IpcMessageObjVersion v,
                                        NABoolean sameEndianness,
                                        IpcMessageObjSize size,
                                        IpcConstMessageBufferPtr &buffer) const
{
  NABoolean result = TRUE;
  const IpcConstMessageBufferPtr lastByte = buffer + size - 1;
  if (!checkBuffer(buffer, sizeof(IpcMessageObj), lastByte) ||
      s_.objType_ != t ||
      s_.objVersion_ != v)
  {
    result = FALSE;
    ipcIntegrityCheckEpilogue(result);
  }
  return result;
}

IpcMessageRefCount IpcMessageObj::incrRefCount()
{
  return ++s_.refCount_;
}

IpcMessageRefCount IpcMessageObj::decrRefCount()
{
  // delete this object if the result falls down to 0
  // NOTE: users who allocate an IpcMessageObj on the stack should
  // never call incrRefCount() or decrRefCount() on that object.
  if (s_.refCount_ == 1)
    {
      // don't decrement the refcount; the destructor performs a
      // consistency check that an object can only be destroyed
      // when it has a refcount of 1
      delete this;
      return 0;
    }
  else
    {
      assert(s_.refCount_ > 1);
      return --s_.refCount_;
    }
}
IpcMessageObjSize IpcMessageObj::packBaseClassIntoMessage(
     IpcMessageBufferPtr &buffer)
{
   return packBaseClassIntoMessage(buffer, FALSE);
}

IpcMessageObjSize IpcMessageObj::packBaseClassIntoMessage(
     IpcMessageBufferPtr &buffer, NABoolean swapBytes)
{
  // the default implementation performs a byte-wise copy
  IpcMessageObjSize copyLen = sizeof(IpcMessageObj);
  char *savedVPtr = getMyVPtr();

  assert(copyLen == 48 AND
	 sizeof(s_) == 40 AND
	 (char *) this == ((char *) &s_ - sizeof(char *)));

  // wipe out the virtual function pointer before moving data
  // (makes sure that the copied object doesn't have a stray pointer in it)
  setMyVPtr(NULL);

  // ---------------------------------------------------------------------
  // Copy packedLength() bytes to the message buffer, assuming that
  // the packed and unpacked representations of the object are the same
  // and that whoever derived from this class did correctly override
  // the packedLength() virtual function. No copy necessary if this
  // is packing in-place.
  // ---------------------------------------------------------------------
  if (buffer == (IpcMessageBufferPtr) this)
    {
      // now that we're sending we won't allow anybody else to reference
      // the object in the message buffer
      assert(s_.refCount_ == 1);
    }
  else
    {
      // save the current refcount and set it to 1, since the copied object
      // is in a new space and therefore should have a refcount of 1
      IpcMessageRefCount saveRefCount = s_.refCount_;
      IpcMessageObjVersion saveObjVersion = 0;
      IpcMessageObjType    saveObjType = IPC_MSG_SQLCAT_FIRST;
      IpcMessageObjSize    saveObjLength = 0;
      char                 saveEndianness = 0;
      s_.refCount_ = 1;
      if (swapBytes)
      {
         saveObjType = s_.objType_;
         saveObjVersion = s_.objVersion_;
         saveEndianness = s_.endianness_;
         saveObjLength = s_.objLength_;
         
         s_.objType_ = bswap_32(s_.objType_); 
         s_.objVersion_ = bswap_32(s_.objVersion_);
         // Switch the Endian since we are swapping the bytes
#ifdef NA_LITTLE_ENDIAN
         s_.endianness_ = IpcBigEndian;
#else
         s_.endianness_ = IpcLittleEndian;
#endif
         s_.objLength_ = bswap_32(s_.objLength_); 
         s_.refCount_ = bswap_32(s_.refCount_);
      }
      str_cpy_all(buffer,(const char *)this,copyLen);

      if (swapBytes)
      {
         s_.objType_ = saveObjType;
         s_.objVersion_ = saveObjVersion;
         s_.endianness_ = saveEndianness;
         s_.objLength_ = saveObjLength;
      }
      // restore virtual function pointer and refCount_ for the in-memory copy
      s_.refCount_ = saveRefCount;
      setMyVPtr(savedVPtr);
    }

  buffer += copyLen;
  return copyLen;
}

// pack the base class to be read by 32-bit BDR client
IpcMessageObjSize IpcMessageObj::packBaseClassIntoMessage32(
     IpcMessageBufferPtr &buffer, NABoolean swapBytes)
{
  // a hard-coded 32-bit IpcMessageObj class size
  IpcMessageObjSize copyLen = SQL_32BIT_IPC_MESSAGE_OBJ_SIZE;

  // cleanup buffer first
  memset(buffer, 0, copyLen);

  // ---------------------------------------------------------------------
  // a 32 byte layout of this object:
  //
  //    +---------------------------------+     \
  //  0 | _vptr (NT) or padding (NSK)     |      |
  //    +---------------------------------+      |
  //  4 | objType_  _  (copy)             |      |
  //    +---------------------------------+      |
  //  8 | objVersion_  (copy)             |      |
  //    +---------------------------------+      |
  // 12 | refCount_    (copy)             |      |
  //    +---------------------------------+      |
  // 16 | objLength_   (copy)             |      >  IpcMessageObjStruct
  //    +---------------------------------+      |
  // 20 | next_                           |      |
  //    +---------------------------------+      |
  // 24 | endianness_  (copy)             |      |
  //    +---------------------------------+      |
  // 25 | spare1_                         |      |
  //    +---------------------------------+      |
  // 26 | spare2_                         |      |
  //    +---------------------------------+      |
  // 28 | _vptr (NSK) or padding (NT)     |      |
  //    +---------------------------------+     /
  //
  // need to copy only marked fields
  // ---------------------------------------------------------------------

  if (buffer == (IpcMessageBufferPtr) this)
    {
      // now that we're sending we won't allow anybody else to reference
      // the object in the message buffer
      assert(s_.refCount_ == 1);
    }
  else
    {
      // set refcount to 1, since the copied object
      // is in a new space and therefore should have a refcount of 1
      IpcMessageRefCount   tempRefCount = 1;
      IpcMessageObjVersion tempObjVersion = s_.objVersion_;
      IpcMessageObjType    tempObjType = s_.objType_;
      IpcMessageObjSize    tempObjLength = s_.objLength_;;
      char                 tempEndianness = s_.endianness_;

      if (swapBytes)
      {
         tempObjType = bswap_32(tempObjType); 
         tempObjVersion = bswap_32(tempObjVersion);
         // Switch the Endian since we are swapping the bytes
#ifdef NA_LITTLE_ENDIAN
         tempEndianness = IpcBigEndian;
#else
         tempEndianness = IpcLittleEndian;
#endif
         tempObjLength = bswap_32(tempObjLength); 
         tempRefCount = bswap_32(tempRefCount);
      }
      // move only needed fields, see above
      memcpy((char*)buffer + 4, (char*)&tempObjType, 4);
      memcpy((char*)buffer + 8, (char*)&tempObjVersion, 4);
      memcpy((char*)buffer +12, (char*)&tempRefCount, 4);
      memcpy((char*)buffer +16, (char*)&tempObjLength, 4);
      memcpy((char*)buffer +24, (char*)&tempEndianness, 1);
    }

  buffer += copyLen;
  return copyLen;
}

void IpcMessageObj::alignBufferForNextObj(IpcConstMessageBufferPtr &buffer)
{
  buffer = (IpcConstMessageBufferPtr) ROUND8((Long)buffer);
}

void IpcMessageObj::alignBufferForNextObj(IpcMessageBufferPtr &buffer)
{
  buffer = (IpcMessageBufferPtr) ROUND8((Long)buffer);
}

void IpcMessageObj::alignSizeForNextObj(IpcMessageObjSize &size)
{
  ULng32 s = (ULng32) size; // just for safety

  // clear the last 3 bits of the size to round it down to
  // the next size that is divisible by 8
  ULng32 roundedDown = s LAND 0xFFFFFFF8;

  // if that didn't change anything we're done, the size was
  // a multiple of 8 already
  if (s != roundedDown)
    {
      // else we have to round up and add the filler
      size = (IpcMessageObjSize) roundedDown + 8;
    }
}

void IpcMessageObj::unpackBaseClass(IpcConstMessageBufferPtr &buffer)
{
  // save the virtual function pointer (it is already set to the correct value)
  char *savedVPtr = getMyVPtr();
  
  // copy objSize bytes into the memory that this object occupies
  // this header (should we allow such a dangerous default implementation?)
  str_cpy_all((char *) this,buffer,sizeof(IpcMessageObj));

  // restore the previously saved virtual function pointer, since it got
  // overwritten with a NULL value by the copy operation above
  // NOTE: this of course assumes that derived classes don't need their
  // own virtual function pointers!!!
  setMyVPtr(savedVPtr);
  // - Change the offset in the next ptr to zero
  //
  s_.next_ = NULL;
  buffer += sizeof(IpcMessageObj);
}

// unpack base class got from 32-bit server
void IpcMessageObj::unpackBaseClass32(IpcConstMessageBufferPtr &buffer)
{
  // copy only selected fields from the buffer
  memcpy((char*)&(s_.objType_), (char*)buffer + 4, 4);
  memcpy((char*)&(s_.objVersion_), (char*)buffer + 8, 4);
  memcpy((char*)&(s_.refCount_), (char*)buffer +12, 4);
  memcpy((char*)&(s_.objLength_), (char*)buffer +16, 4);
  memcpy((char*)&(s_.endianness_), (char*)buffer +24, 1);
  
  s_.next_ = NULL;
  buffer += SQL_32BIT_IPC_MESSAGE_OBJ_SIZE;
}

IpcMessageObjSize IpcMessageObj::packDependentObjIntoMessage(
     IpcMessageBufferPtr buffer)
{
  return packDependentObjIntoMessage(buffer, FALSE);
}

IpcMessageObjSize IpcMessageObj::packDependentObjIntoMessage(
     IpcMessageBufferPtr buffer, NABoolean swapBytes)
{
  IpcMessageBufferPtr alignedBuffer = buffer;
  alignBufferForNextObj(alignedBuffer);

  // pack the object and compute the length
  IpcMessageObjSize result = packObjIntoMessage(alignedBuffer, swapBytes);

  // finish the object that is now inside the buffer, similarly to what
  // IpcMessageStream::send() does
  IpcMessageObj *bufObj = (IpcMessageObj *) alignedBuffer;

  bufObj->setMyVPtr(NULL);
  bufObj->s_.objLength_ = result;
  bufObj->s_.refCount_ = 1;
  bufObj->s_.next_ = NULL;
  
  if (swapBytes)
  {
     bufObj->s_.objLength_ = bswap_32(bufObj->s_.objLength_);
     bufObj->s_.refCount_ = bswap_32(bufObj->s_.refCount_);
  }

  // add the filler space that had to be added to the returned result
  result += (alignedBuffer - buffer);

  return result;
}

IpcMessageObjSize IpcMessageObj::packDependentObjIntoMessage32(
     IpcMessageBufferPtr buffer)
{
  return packDependentObjIntoMessage32(buffer, FALSE);
}

IpcMessageObjSize IpcMessageObj::packDependentObjIntoMessage32(
     IpcMessageBufferPtr buffer, NABoolean swapBytes)
{
  IpcMessageBufferPtr alignedBuffer = buffer;
  alignBufferForNextObj(alignedBuffer);

  // pack the object and compute the length
  IpcMessageObjSize result = packObjIntoMessage32(alignedBuffer, swapBytes);
  IpcMessageObjSize sResult = result; // swapped result if does

  Int32 refCount = 1;

  Int32 firstField = 0; // assume Linux where vPtrPad_ is at the end
  if (swapBytes)
  {
    // send to NSK where vPtrPad_ is at the beginning of the structure.
    firstField = 4;
    refCount = bswap_32(refCount);
    sResult = bswap_32(sResult);
  }

  // finish the object that is now inside the buffer by move only needed fields
  memset((char*)alignedBuffer, 0, 4);                     // vPtrPad_
  memcpy((char*)alignedBuffer + 12, (char*)&refCount, 4); // refCount_
  memcpy((char*)alignedBuffer + 16, (char*)&sResult, 4);  // objLength_
  memset((char*)alignedBuffer + 20, 0, 4);                // next_
  memset((char*)alignedBuffer + 28, 0, 4);                // vPtrPad_

  // add the filler space that had to be added to the returned result
  result += (alignedBuffer - buffer);

  return result;
}

void IpcMessageObj::unpackDependentObjFromBuffer(
     IpcConstMessageBufferPtr &buffer,
     NABoolean sameEndianness)
{
  alignBufferForNextObj(buffer);

  IpcMessageObj       *objInBuffer = (IpcMessageObj       *) buffer;
  IpcMessageObjSize   objLength    = objInBuffer->s_.objLength_;

  unpackObj(objInBuffer->s_.objType_,
	    objInBuffer->s_.objVersion_,
	    sameEndianness,
	    objLength,
	    buffer);

  buffer += objLength;
}

void IpcMessageObj::unpackDependentObjFromBuffer32(
     IpcConstMessageBufferPtr &buffer,
     NABoolean sameEndianness)
{
  alignBufferForNextObj(buffer);

  // NEEDS PORT
  //   The problem here is that IpcMessageObjStruct does not contain
  //   the 4 bytes allocated for the virtual function table pointer and
  //   on NT the vftptr is BEFORE the structure and on unix/NSK it is after.
  IpcMessageObjType    objType    = *(Int32 *)((char *)buffer + 4);  // objType_
  IpcMessageObjVersion objVersion = *(Int32 *)((char *)buffer + 8);  // objVersion_
  IpcMessageObjSize    objLength  = *(Int32 *)((char *)buffer + 16); // objLength_
   

  unpackObj32(objType,
	      objVersion,
	      sameEndianness,
	      objLength,
	      buffer);
  buffer += objLength;

}

NABoolean IpcMessageObj::checkDependentObj(IpcConstMessageBufferPtr &buffer,
                                           NABoolean sameEndianness) const
{
  alignBufferForNextObj(buffer);
  IpcMessageObj *objInBuffer = (IpcMessageObj *) buffer;
  IpcMessageObjSize objLength = objInBuffer->s_.objLength_;

  if (!checkObj(objInBuffer->s_.objType_,
                objInBuffer->s_.objVersion_,
                sameEndianness,
                objLength,
                buffer))
  {
    return FALSE;
  }

  buffer += objLength;
  return TRUE;
}

void IpcMessageObj::turnByteOrder()
{
	// NEEDS PORT (2/26/97)
	//  the code to handle endianness is not quite right. as a temporary
	//  measure for the demo, turn this code off.
	return;
}

///////////////////////////////////////////////////////////////////////////////
// merge next packed message object in IpcMessageBuffer with this object
void IpcMessageObj::mergeNextPackedObj()
  {
  IpcMessageObj* nextObj = getNextFromOffset();
  if (nextObj)
    {
    if (nextObj->s_.next_)
      {
      IpcMessageObj * offset = (IpcMessageObj*) (
                               (Long)(s_.next_) + (char *)(nextObj->s_.next_));
      s_.next_ = (IpcMessageObj*)offset;
      }
    else
      s_.next_ = NULL;
    }
  return;
  }

IpcMessageObj *IpcMessageObj::getNextFromOffset()
{
  if (s_.next_ == NULL)
    return NULL;
  else
    // add the "this" pointer to the offset
    return (IpcMessageObj *) ((char*) this + (Long) s_.next_);
}

void IpcMessageObj::convertNextToOffset()
{
  // subtract the "this" pointer from the address to make it an offset
  if (s_.next_ != NULL)
    s_.next_ = (IpcMessageObj *) ((char*) s_.next_ - (char*) this);
}

IpcMessageObjSize packCharStarIntoBuffer(IpcMessageBufferPtr &buffer,
                                 char* strPtr, NABoolean swapBytes)
{
  Lng32 length;

  if (strPtr==NULL)
     length=0;
  else
     length=str_len(strPtr)+1; // 1 is for the null-terminator char
   // NOT a recursive call.
  IpcMessageObjSize result = packIntoBuffer(buffer,length, swapBytes);         

  if (strPtr!=NULL)
     str_cpy_all((char*)buffer,strPtr,length);
  buffer += length;
  return result+length; 
}

// UR2 
IpcMessageObjSize packCharStarIntoBuffer(IpcMessageBufferPtr &buffer, 
                                 NAWchar* strPtr, NABoolean swapBytes)
{
  Lng32 length;

  if (strPtr==NULL)
     length=0;
  else
     length=na_wcslen(strPtr)+1; // 1 is for the null-terminator char
  length *= sizeof(NAWchar);

   // NOT a recursive call.
  IpcMessageObjSize result = packIntoBuffer(buffer,length, swapBytes);         

  if (strPtr!=NULL)
     na_wcscpy((NAWchar*)buffer,strPtr);
  buffer += length;
  return result+length; 
}

void unpackBuffer(IpcConstMessageBufferPtr &buffer, 
                  char* &strPtr, 
                  CollHeap* collHeapPtr)
{
  if (collHeapPtr != NULL)
    collHeapPtr->deallocateMemory(strPtr);
  else
    delete strPtr;

  Lng32 length;
   // NOT a recursive call.
  unpackBuffer(buffer,length);  // already has +1 for null terminating char
  if (length==0)
     strPtr = NULL;
  else {
     if (collHeapPtr != NULL) {
        strPtr = (char*) (collHeapPtr->allocateMemory(length)); 
        assert(strPtr!=NULL);
     }
     else {
        strPtr = new char[length];  
        assert(strPtr!=NULL);
     }

     str_cpy_all(strPtr,(char*) buffer, length);
     buffer += length;
  }
}

void skipCharStarInBuffer(IpcConstMessageBufferPtr &buffer)
{
  Lng32 length;
  // NOT a recursive call.
  unpackBuffer(buffer,length);  // already has +1 for null terminating char
  buffer += length;
}

// Verify that the next field in a message buffer does not extend
// beyond lastByte.
NABoolean checkBuffer (
    /* INOUT */ IpcConstMessageBufferPtr &buffer,
    /* IN    */ ULng32 dataLength,
    /* IN    */ IpcConstMessageBufferPtr lastByte )
{
  NABoolean result = TRUE;
  IpcConstMessageBufferPtr endOfData = buffer + dataLength - 1;
  if (endOfData > lastByte)
  {
    result = FALSE;
    ipcIntegrityCheckEpilogue(result);
  }
  else
  {
    buffer += dataLength;
  }
  return result;
}

// Verify that the next field in a message buffer does not extend
// beyond lastByte, and if it does then copy the field into dataPtr.
NABoolean checkAndUnpackBuffer (
    /* INOUT */ IpcConstMessageBufferPtr &buffer,
    /* IN    */ ULng32 dataLength,
    /* OUT   */ char *dataPtr,
    /* IN    */ IpcConstMessageBufferPtr lastByte )
{
  NABoolean result = TRUE;
  IpcConstMessageBufferPtr endOfData = buffer + dataLength - 1;
  if (endOfData > lastByte)
  {
    result = FALSE;
    ipcIntegrityCheckEpilogue(result);
  }
  else
  {
    str_cpy_all(dataPtr, (char *) buffer, dataLength);
    buffer += dataLength;
  }
  return result;
}

// Verify that the next string field in a message buffer does not
// extend beyond lastByte. Note that the packed format for a string
// includes a 4-byte length field as a prefix.
NABoolean checkCharStarInBuffer (
    /* INOUT */ IpcConstMessageBufferPtr &buffer,
    /* IN    */ NABoolean sameEndianness,
    /* IN    */ IpcConstMessageBufferPtr lastByte )
{
  NABoolean result = TRUE;
  Int32  dataLength = 0;
  if (!checkAndUnpackBuffer(buffer, sizeof(dataLength),
                            (char *) &dataLength, lastByte))
  {
    result = FALSE;
    ipcIntegrityCheckEpilogue(result);
  }
  else
  {
    if (!sameEndianness)
    {
      swapFourBytes(dataLength);
    }
    if (!checkBuffer(buffer, dataLength, lastByte))
    {
      result = FALSE;
      ipcIntegrityCheckEpilogue(result);
    }
  }
  return result;
}

// IpcMessageObj::checkObj() implementations all call this function
// immediately when they detect a failure. Setting a breakpoint here
// can help you quickly track down the cause of a checkObj()
// failure. Right now this function is just a wrapper around
// NAError_stub_for_breakpoints() but in the future we may decide it
// should also do some bookeeping or error reporting of its own.
void ipcIntegrityCheckEpilogue(NABoolean status)
{
  if (!status)
  {
    NAError_stub_for_breakpoints();
  }
}
