//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / testing/testadapter/adapter
//
//File: pducoderbase.h
//
//Version: $Revision: 1.16 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/11/25 13:13:52 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author:
//      Timo Kokkonen
//      Jussi Turunen
//
//Description:
//      Base class used for coding methods in testing.
//      Encoding is done simply by moving data from received 
//      SerializedMessage to pfFrame. Decode is an abstract method
//      since decoding is PDU-specific. 
//      Individual en/decode methods are implemented in this class
//      (bit-, octet, hex- and IA5string and Beg/EndOfElement).
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//
//
//History:
//

#ifndef __ADAPTER_PDUCODERBASE_H__
#define __ADAPTER_PDUCODERBASE_H__

#include <typeinfo>
#include <string>

#include <OB/CORBA.h>

#include "pf/frame.h"
#include "pf/bitstring.h"
#include "testing/testadapter/adapter/msg.h"

class pduCoderBase
{
    public:
        virtual ~pduCoderBase(void);

        static const string UNKNOWN_PDUStr; //("UNKNOWN_PDU");
        static const string UNKNOWN_FIELDStr; //("UNKNOWN_FIELD");

        static const int OCTETSIZE = 8; // one octet is 8 bits
        static const int HEXSIZE = 4; // one hex is 4 bits

        virtual pfFrame encode
          (const otMessage::SerializedMessage &message_);
        virtual otMessage::SerializedMessage decode
          (const pfFrame &frame_) = 0;

        string getPDUname(void);

    protected:
        pduCoderBase(void);
        
        void decodeBitString(const string &name_,
                             pfUlong length_);   // length_ bits
        void decodeOctetString(const string &name_,
                               pfUlong length_); // length_ octets
        void decodeHexString(const string &name_,
                             pfUlong length_);   // length_/2 octets
        void decodeIA5String(const string &name_,
                             pfUlong length_);   // length_ chars

        void decodeBegOfElement(const string &name_);
        void decodeEndOfElement(const string &name_);

        void encodeBitString(const string &value_);
        void encodeOctetString(const string &value_);
        void encodeIA5String(const string &value_);

        // called by decodeXXString methods
        void insertToMessage(const string &name_,
                             const string &value_,
                             otMessage::ElementKind kind_);
        // Methods to ensure that non-blockSize_-aligned bitfields go
        // to method bitStringToOctetString
        pfBitString alignLength(pfUlong &length_,
                                const pfUlong blockSize_);
        void forceToBlockSize(pfBitString &bitString_, 
                              const pfUlong blockSize_);

        // Methods for adding bitstring to and removing it from a frame
        void frameToDataBuffer(pfFrame frame_);
        pfFrame dataBufferToFrame(void);
        void clearDataBuffer(void);

        // Method to get non-octet-aligned fields from _databuffer
        // Thsi is used only in SSCOP at the moment.
        string getBitField(const pfUlong length_);

        // Methods for conversion from one type to another
        static pfBitString octetStringToBitString(const string &value_);
        static string bitStringToOctetString(pfBitString value_);
        static void addUlongToString(string &name_, pfUlong value_);
        static string ulongToString(pfUlong value_);

        // Stores the PDU's name in _identifier
        void storePDUname(const string &pduName_);

        // method for removing data from _dataBuffer
        void removeData(pfUlong bits_);

        // method to store unknown data
        void storeUnknownField(pfUlong length_);

        // methods to print error and warning messages
        static void printWarningMsg(const string &warningMsg_);
        static void printErrorMsg(const string &errorMsg_);

        // _databuffer.length and _message used in derived classes
        pfBitString _dataBuffer;
        otMessage::SerializedMessage _message; 

    private:
        string _identifier;
        pfUlong _index;
};

#endif // __ADAPTER_PDUCODERBASE_H__
