//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / ie
//
//File: iecoder.h
//
//Version: $Revision: 1.11 $
//
//State: $State: Exp $
//
//Date: $Date: 1999/03/09 12:51:46 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
// 
//Author:
//      Timo Kokkonen
//      Sami Raatikainen
//
//Description:
//      Base class for encoding and decoding information elements.
//      Offers usage of extension bits and bit-by-bit handling.
//      When decoding with bit-handling is needed, frame has to be 
//      converted to the bitString first using bitStringToFrame-method!
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//
//
//History:
//

#ifndef __SIG_IECODER_H__
#define __SIG_IECODER_H__

#include <typeinfo>
#include <string>
#include <autoptr.h>
#include "pf/types.h"
#include "pf/bytes.h"
#include "pf/bitstring.h"
#include "pf/ie.h"
#include "pf/frame.h"
#include "pf/messenge.h"

class IECoder
{
    public:
        virtual ~IECoder(void);
        IECoder(const string &IEname_,
                const pfByte &IEtype_,
                bool isMandatory_);
        
        virtual void decode(pfFrame &frame_, pfMessenger *msg_);
        virtual void encode(pfFrame &frame_, pfMessenger *msg_);
        
        // Pure virtual methods have to be implemented in derived classes
        virtual void decodeIE(pfFrame &frame_, pfMessenger *msg_) = 0;
        virtual void encodeIE(pfFrame &frame_, pfMessenger *msg_) = 0;
        
        // Methods that may be used with pdu coding
        pfByte getType(void) const;
        virtual void setMaxTimeExist(pfUlong newMax_);
        virtual bool isDecodedOK(void) const;
        
    protected:
        virtual void setHeaderMinLength(pfUlong length_);
        virtual void setContentLength(pfUlong min_, pfUlong max_ = 40);
        virtual void checkHeaderMinLength(pfUlong length_) const;
        virtual void checkContentLength(pfUlong length_) const;
        
        enum ActionInd
        {
            notSpecified,
            clearCall,
            discardMessageAndReport,
            discardMessage,
            discardIEAndReport,
            discardIE
        };
        virtual void setContentErrorAction(IECoder::ActionInd action_);
        virtual void throwContentError(void) const;

        virtual void setIEtoMsg(pfMessenger *msg_, auto_ptr<pfIE> &ie_) const;

        // --------------------
        // Specific methods for detailed encoding/decoding using bits.
        void frameToBitString(pfFrame &frame_, pfUlong length_);
        void bitStringToFrame(pfFrame &frame_);
        
        pfUlong getLength(void) const;
        void putBits(pfUlong value_, pfUlong length_);
        pfUlong getBits(pfUlong length_);
  
        pfUlong getExtension(void);
        void putExtension(pfUlong value_);
        pfUlong endExtension(void);

        void putSpare(pfUlong amount_, pfUlong value_ = 0);
        void skip(pfUlong amount_);
        
        string decodeBCD(pfUlong odd_, pfUlong length_);
        pfUlong encodeBCD(const string &address_);
        char ulongToChar(pfUlong value_);
        
        string decodeIA5(pfLong &ieLength_);
        pfUlong encodeIA5(string &digits_);

        // --------------------


        // IE/PDU specific variables
        string _IEname;
        bool _isMandatory;
        pfUlong _maxTimeExist;

    private:
        pfByte _IEtype;
        
        void checkBitUsage(void);
        bool isGetExtOK(void) const;
        
        pfUlong _IE_HEADER_MIN_LENGTH;
        pfUlong _IE_CONTENT_MIN_LENGTH;
        pfUlong _IE_CONTENT_MAX_LENGTH;

        pfBitString _bitString;
        bool _bitsUsageAllowed;
        
        bool _extensionBit;
        bool _isExtensionEnded;
        bool _isDataReadable;  // data in _bitString valid/invalid
        
        ActionInd _actionInd;
};

#endif //__SIG_IECODER_H__
