/*+MHDR*/
/*
# clearcase: (not checkedin)  Tau4.2
+------------------------------------------------------------------------------+
|  Modulname    : MCODFNC.CPP                                                  |
|  Date         : 01.04.1996                                                   |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description  :                                                              |
|  This Modul contains all decode- end encode functions for messages going     |
|  across the Postmaster within a C++ class                                    |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-MHDR*/

/*
+------------------------------------------------------------------------------+
|                                                                              |
|  Copyright by Telelogic AB 1993 - 1999                                       |
|                                                                              |
|  This Program is owned by Telelogic and is protected by national             |
|  copyright laws and international copyright treaties. Telelogic              |
|  grants you the right to use this Program on one computer or in              |
|  one local computer network at any one time.                                 |
|  Under this License you may only modify the source code for the purpose      |
|  of adapting it to your environment. You must reproduce and include          |
|  any copyright and trademark notices on all copies of the source code.       |
|  You may not use, copy, merge, modify or transfer the Program except as      |
|  provided in this License.                                                   |
|  Telelogic does not warrant that the Program will meet your                  |
|  requirements or that the operation of the Program will be                   |
|  uninterrupted and error free. You are solely responsible that the           |
|  selection of the Program and the modification of the source code            |
|  will achieve your intended results and that the results are actually        |
|  obtained.                                                                   |
|                                                                              |
+------------------------------------------------------------------------------+
*/

#ifndef __MCODFNC_CPP_
#define __MCODFNC_CPP_

/*+IMPORT*/
/*====================  I M P O R T  =========================================*/
#include "string.h"
#include "malloc.h"

#ifdef HOSTSIM
  #define SDTGATE
#endif

#ifndef SDTGATE
  #include "mt_ll.h"
#endif

#include "mcodlib.hpp"
#include "mcodfnc.hpp"

#include <stdio.h>

#ifdef DEBUG
#include <stream.h>
#endif

/*============================================================================*/
/*-IMPORT*/


/*+MGG*/
/*====================  M O D U L G L O B A L E   G R O E S S E N  ===========*/

/*--------------------  Konstanten, Macros  ----------------------------------*/

/*--------------------  Typdefinitionen     ----------------------------------*/

/*--------------------  Funktionen   -----------------------------------------*/

/*--------------------  Variablen    -----------------------------------------*/

/*============================================================================*/
/*-MGG*/

//
// Encoding method for all the messages
//
/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : StartEncode                                                  |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function initializies class local variables which are used by all the  |
|  other encode functions. This function is to be called before the first      |
|  encoding.                                                                   |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
void ClassHostMessage::StartEncode ( char * Buffer, int MaxLength )
/*-FDEF S*/
{
  #ifdef DEBUG
    cout << "Encode,Start\n";
  #endif
  BufferBegin          = Buffer;
  CurrentBufferAddress = Buffer;
  CurrentOffset        = 0;
  BufferLength         = MaxLength;
  return;
}

/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : Encode_CSTRING                                               |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function is used to encode a C string into the transmitter buffer      |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
int ClassHostMessage::Encode_CSTRING ( char * src )
/*-FDEF S*/
{
  int tmp_len;

  #ifdef DEBUG
    cout << "Encode,CSTRING\n";
  #endif

  tmp_len = strlen (src);

  memcpy ((void*) &BufferBegin [CurrentOffset], (void*) &tmp_len, sizeof (tmp_len) );
  CurrentOffset += sizeof (tmp_len) ;

  memcpy ((void*) &BufferBegin [CurrentOffset], (void*)src, tmp_len );
  CurrentOffset += tmp_len ;

  return (ENC_OKAY);
}

#ifndef SDTGATE
/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : Encode_CLIST                                                 |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function is used to encode a linked list into the transmitter buffer   |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
int ClassHostMessage::Encode_CLIST ( xmk_T_LINKED_LIST * src )
/*-FDEF S*/
{
  xmk_T_LINKED_LIST * p;
  int               Counter = 0;

  #ifdef DEBUG
    cout << "Encode,CLIST\n";
  #endif
  //
  // First encode the counter / amount of elements in list
  //
  p = src;
  while( p != NULL )
  {
    Counter++;
    p = p->next;
  }
  memcpy ((void*) &BufferBegin [CurrentOffset], (void*) &Counter, 4/*sizeof (int)*/ );
  CurrentOffset += 4/*sizeof (int)*/ ;


  //
  // then encode the elements
  //
  p = src;
  for( ;Counter > 0; Counter-- )
  {
    p->element_len = strlen (p->element);

    memcpy ((void*) &BufferBegin [CurrentOffset], (void*) &(p->element_len), sizeof (p->element_len) );
    CurrentOffset += sizeof (p->element_len) ;

    memcpy ((void*) &BufferBegin [CurrentOffset], (void*) p->element, p->element_len );
    CurrentOffset += p->element_len ;

    p = p->next;
  }

  return (ENC_OKAY);
}
#endif /* ... SDTGATE */

/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : Encode_CINT                                                  |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function is used to encode a C integer value.                          |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
int ClassHostMessage::Encode_CINT ( int src )
/*-FDEF S*/
{
  #ifdef DEBUG
    cout << "Encode,CINT\n";
  #endif
  memcpy ((void*) &BufferBegin [CurrentOffset], (void*) &src, 4/*sizeof (int)*/ );
  CurrentOffset += 4/*sizeof (int)*/ ;

  return (ENC_OKAY);
}

/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : Encode_CRAWBUFFER                                            |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function is used to encode a not specified data buffer (e.g.           |
|  xmk_LineStatus into the transmitter buffer                                  |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
int ClassHostMessage::Encode_CRAWBUFFER ( int srclen, char * src )
/*-FDEF S*/
{
  #ifdef DEBUG
    cout << "Encode,CRAWBUFFER\n";
  #endif
  memcpy((void*) &BufferBegin [CurrentOffset], (void*) &srclen, 4/*sizeof (int)*/);
  CurrentOffset += 4/*sizeof (int)*/;

  memcpy((void*) &BufferBegin [CurrentOffset], (void*) src, srclen);
  CurrentOffset += srclen;
  return (ENC_OKAY);
}

/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : EndEncode                                                    |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function is used to finish the encoding                                |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
int ClassHostMessage::EndEncode ( void )
/*-FDEF S*/
{
  #ifdef DEBUG
    cout << "Encode,End\n";
  #endif
  return (ENC_OKAY);
}


/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : EncodedLength                                                |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function delivers the encoded message length.                          |
|  Remark: 'CurrentOffset' is private                                          |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
int ClassHostMessage::EncodedLength ( void )
/*-FDEF S*/
{
  return( CurrentOffset );
}


//
// Decoding method for all the messages
//
/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : StartDecode                                                  |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function initializies class local variables which are used by all the  |
|  other decode functions. This function is to be called before the first      |
|  decoding.                                                                   |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
void ClassHostMessage::StartDecode ( char * Buffer, int MaxLength )
/*-FDEF S*/
{
  #ifdef DEBUG
    cout << "Decode,Start\n";
  #endif
  BufferBegin          = Buffer;
  CurrentBufferAddress = Buffer;
  CurrentOffset        = 0;
  BufferLength         = MaxLength;
  return;
}

/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : Decode_CSTRING                                               |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function is used to decode a C string out of the receiver buffer       |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
int ClassHostMessage::Decode_CSTRING ( char ** dest )
/*-FDEF S*/
{
  int tmp_len;

  #ifdef DEBUG
    cout << "Decode,CSTRING\n";
  #endif
  memcpy ((void*) &tmp_len, (void *) &BufferBegin [CurrentOffset], 4/*sizeof (int)*/);
  CurrentOffset += 4/*sizeof (int)*/;
  *dest = (char*) XMALLOC (tmp_len+1);
  if ( (void*) *dest == (void*) NULL)
    return (DEC_NO_MEMORY);
  memset ((void*) *dest, 0, tmp_len+1);

  memcpy ( (void*) *dest, (void *) &BufferBegin [CurrentOffset], tmp_len);
  CurrentOffset += tmp_len;
  return (DEC_OKAY);
}

#ifndef SDTGATE
/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : Decode_CLIST                                                 |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function is used to decode a linked list out of the receiver buffer    |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
int ClassHostMessage::Decode_CLIST ( xmk_T_LINKED_LIST ** dest )
/*-FDEF S*/
{
  xmk_T_LINKED_LIST * p;
  int               Counter;

  #ifdef DEBUG
    cout << "Decode,CLIST\n";
  #endif
  //
  // First decode the counter / amount of elements in list
  //
  memcpy ( (void*) &Counter, (void *) &BufferBegin [CurrentOffset], 4/*sizeof (int)*/ );
  CurrentOffset += 4/*sizeof (int)*/ ;

  if(Counter == 0)
  {
    *dest = NULL;
    return(DEC_OKAY);
  }
  //
  // then decode the elements
  //
  p = NULL;
  for( ; Counter > 0; Counter-- )
  {
    if( (void*)p == (void*)NULL )
    {
      p = (xmk_T_LINKED_LIST*) XMALLOC( sizeof(xmk_T_LINKED_LIST));
      *dest = p;
    }
    else
    {
      p->next = (xmk_T_LINKED_LIST*) XMALLOC( sizeof(xmk_T_LINKED_LIST));
      p = p->next;
    }

    if ( (void*) p == (void*) NULL)
      return (DEC_NO_MEMORY);

    memcpy ((void*) &p->element_len, (void *) &BufferBegin [CurrentOffset], 4/*sizeof (int)*/);
    CurrentOffset += 4/*sizeof (int)*/;
    p->element = (char*) XMALLOC (p->element_len+1);
    if ( (void*) p->element == (void*) NULL)
      return (DEC_NO_MEMORY);
    memset ((void*) p->element, 0, p->element_len+1);
    memcpy ((void*) p->element, (void*) &BufferBegin [CurrentOffset], p->element_len);
    CurrentOffset += p->element_len;
  }
  p->next = NULL;
  return (DEC_OKAY);
}
#endif /* ... SDTGATE */

/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : Decode_CINT                                                  |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function is used to decode a C integer value out of the receiver buffer|
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
int ClassHostMessage::Decode_CINT ( int * dest )
/*-FDEF E*/
{
  #ifdef DEBUG
    cout << "Decode,CINT\n";
  #endif
  memcpy ( (void*) dest, (void *) &BufferBegin [CurrentOffset], 4/*sizeof (int)*/ );
  CurrentOffset +=4/*sizeof (int)*/ ;
  return (DEC_OKAY);
}

/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : Decode_CRAWBUFFER                                            |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function is used to decode a not specified data set out of the receiver|
|  buffer                                                                      |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
int ClassHostMessage::Decode_CRAWBUFFER ( int *destlen, char ** dest )
/*-FDEF S*/
{
  #ifdef DEBUG
    cout << "Decode,CRAWBUFFER\n";
  #endif
  memcpy ((void*) destlen, (void*) &BufferBegin [CurrentOffset], 4/*sizeof (int)*/ );
  CurrentOffset += 4/*sizeof (int)*/ ;
  *dest = (char*) XMALLOC (*destlen+1);
  if ( (void*) *dest == (void*) NULL)
    return (DEC_NO_MEMORY);
  memset ((void*) *dest, 0, *destlen+1);

  memcpy ((void*) *dest, (void*) &BufferBegin [CurrentOffset], *destlen );
  CurrentOffset += *destlen ;

  return (DEC_OKAY);
}
/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : EndDecode                                                    |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function is used to finish the decoding                                |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
int ClassHostMessage::EndDecode ( void )
/*-FDEF S*/
{
  #ifdef DEBUG
    cout << "Decode,End\n";
  #endif
  if( BufferLength != CurrentOffset)
  {
    #ifndef XMK_WIN
      fprintf (stderr, "**ERR:Message Decoder : Expected BufferLength=%d, Got Length=%d\n", 
               CurrentOffset, BufferLength);
    #endif
    return( DEC_ERR_IN_MSG_LENGTH );
  }
  else
    return (DEC_OKAY);
}

#ifndef SDTGATE
/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : FreeCLIST                                                    |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  This function frees the in Decode_CLIST() allocated memory                  |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
xmk_T_LINKED_LIST * ClassHostMessage::FreeCList ( xmk_T_LINKED_LIST * dest)
/*-FDEF S*/
{
  xmk_T_LINKED_LIST * p;

  #ifdef DEBUG
    cout << "FreeCList\n";
  #endif

  p = dest;

  while( (void*)dest != (void*) NULL )
  {
    if( (void*)p->element != (void*)NULL )
      XFREE( p->element );

    p = dest->next;
    XFREE( dest );
    dest = p;
  }

  return (NULL);
}
#endif /* ... SDTGATE */

/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : FreeCRAWBuffer                                               |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|  Here the memory allocated in Decode_CRAWBUFFER() is freed.                  |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/

/*+FDEF E*/
char * ClassHostMessage::FreeCRAWBuffer ( char * dest)
/*-FDEF E*/
{
  #ifdef DEBUG
    cout << "FreeCRAWBuffer\n";
  #endif
  if( (void*) dest != (void*) NULL )
    XFREE( dest );

  return (NULL);
}


//
// end members of class HostMessage */
//
#endif /*...  __MCODFNC_CPP_ */

