/***************************************************************************
                          PartOfPacket.h  -  description
                             -------------------
    begin                : Thu Dec 6 2001
    copyright            : (C) 2001 by Andrea Bulgarelli
    email                : bulgarelli@bo.iasf.cnr.it
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software for non commercial purpose              *
 *   and for public research institutes; you can redistribute it and/or    *
 *   modify it under the terms of the GNU General Public License.          *             
 *   For commercial purpose see appropriate license terms                  *
 *                                                                         *
 ***************************************************************************/

#ifndef PARTOFPACKET_H
#define PARTOFPACKET_H

#include "InputText.h"
#include "Field.h"
#include "PacketLibDefinition.h"
#include "Utility.h"
#include "ByteStream.h"
#include "PacketException.h"
#include "MemoryBuffer.h"

namespace PacketLib {

extern word pattern[17];

//##ModelId=3C0F6C190370
//##Documentation
//##	This class represent a subset of the packet. This class has been created for grouping
//##	the common behaviours of PacketHeader, DataFieldHeader and SourceDataField
//##	$Date: 2012/06/08 15:14:29 $
//##	$Header: /home/repository/cvs/gtb/PacketLib/include/PartOfPacket.h,v 1.8 2012/06/08 15:14:29 bulgarelli Exp $
//##	$Id: PartOfPacket.h,v 1.8 2012/06/08 15:14:29 bulgarelli Exp $
//##	$Revision: 1.8 $
//##	\brief Single part of packet.
class PartOfPacket
{
    public:

        //##ModelId=3C0F6C1A0223
        //##Documentation
        //## Constructor
        PartOfPacket(const char* popName = 0);

        //##ModelId=3C35860301F9
        //##Documentation
        //## Virtual destructor
        virtual ~PartOfPacket();

        //##ModelId=3CAEAC8B0280
        //##Documentation
        //## Prints the structure of this part of packet.
        virtual string* printStructure();

        //##ModelId=3CAEAC8B02FD
        //##Documentation
        //## Prints the value of each field of this part of packet.
        virtual char** printValue(const char* addString = "");

        //##ModelId=3C0F6C1A0228
        //##Documentation
        //## This method loads the field present into the InputText (passed with the
        //## parameter).
        //## The InputText must be open and the internal pointer of the file must
        //## be in the first line that describes the fields.
        virtual bool loadFields(InputText& fp) throw(PacketException*);

        //##ModelId=3EADC13B032C
        //##Documentation
        //## This method loads the field present into the MemoryBuffer (passed with the
        //## parameter).
        virtual bool loadFields(MemoryBuffer* mb) throw(PacketException*);

        //##ModelId=3EADC13C029C
        virtual MemoryBuffer* loadFieldsInBuffer(InputText & fp);

        //##ModelId=3C358603027B
        //##Documentation
        //## Returns the dimension (in byte) of this part of packet.
        virtual  inline word getDimension() {
          return fieldsDimension / 8;
        };

        //##ModelId=3C187751015F
        //##Documentation
        //## Returns a pointer of a field in the list of fields of this part of packet.
        //## \param index Represent the index in the list.
        virtual  inline  Field* getFields(word index) {
          if(index < numberOfFields)
            return fields[index];
          else 
              return 0;            
        };

        //##ModelId=3EADC13D0294
        //##Documentation
        //## Returns the value of a field in the list of fields of this part of packet.
        //## \param index Represent the index in the list.
        virtual  inline word getFieldValue(word index) {
          if(index < numberOfFields)
            return fields[index]->value;
          else
            return 0;
        };
	
	//##Documentation
	//## Returns the value of a field in the list of fields of this part of packet. 
	//## The value returned is interpreted as a real single precision (IEEE 754).
	//## The index of the argument is the first 16 bit field of the 2 fields that compound
	//## the 32 bit real single precision. The layout foreseen is the following:
	//##	---------------------------------
	//##	-	float last 16 bits	-	the index passed as argument
	//##	---------------------------------
	//##	-	float first 16 bits	-	the index + 1
	//##	---------------------------------	
	//## This corresponds with the PTC=5, PFC = 1.
	//## \param index Represent the index of the field.
	virtual float getFieldValue_5_1(word index);
	
	//##Documentation
	//## Set the value of a field. The value is interpreted as a real single
	//## precision (IEEE 754). 
	//## The index of the argument is the first 16 bit field of the 2 fields that compound
	//## the 32 bit real single precision. The layout foreseen is the following:
	//##	---------------------------------
	//##	-	float last 16 bits	-	the index passed as argument
	//##	---------------------------------
	//##	-	float first 16 bits	-	the index + 1
	//##	---------------------------------	
	//## This corresponds with the PTC=5, PFC = 1.
	//## See setFieldValue(word index, word value) for general considerations.
	//## \param index Represent the index of the field.
	//## \param value The real single precision value	
	virtual void setFieldValue_5_1(word index, float value);
	
	//##Documentation
	//## Returns the value of a field in the list of fields of this part of packet. 
	//## The value returned is interpreted as a 32 bit signed integer.
	//## The index of the argument is the first 16 bit field of the 2 fields that compound
	//## the 32 bit signed integer. The layout foreseen is the following:
	//##	---------------------------------
	//##	-	32 bit int MSB 16 bits	- the index passed as argument
	//##	---------------------------------
	//##	-	32 bit int LSB 16 bits	- the index + 1
	//##	---------------------------------	
	//## This corresponds with the PTC=4, PFC = 14.
	//## \param index Represent the index of the field.
	virtual signed long getFieldValue_4_14(word index);

	//##Documentation
	//## Sets the value of a field. The value is interpreted as a 32 bit signed integer.
	//## The index of the argument is the first 16 bit field of the 2 fields that compound
	//## the 32 bit signed integer. The layout foreseen is the following:
	//##	---------------------------------
	//##	-	32 bit int MSB 16 bits	- 	the index passed as argument
	//##	---------------------------------
	//##	-	32 bit int LSB 16 bits	- 	the index + 1
	//##	---------------------------------	
	//## This corresponds with the PTC=4, PFC = 14.
	//## See setFieldValue(word index, word value) for general considerations.
	//## \param index Represent the index of the field.
	//## \param value The 32 bit signed integer value.		
	virtual void setFieldValue_4_14(word index, signed long value);
	
	//##Documentation
	//## Returns the value of a field in the list of fields of this part of packet. 
	//## The value returned is interpreted as a 24 bit signed integer.
	//## The index of the argument is the first 16 bit field of the 2 fields that compound
	//## the 24 bit signed integer. The layout foreseen is the following:
	//##	---------------------------------
	//##	-	24 bit int MSB 16 bits	-	the index passed as argument
	//##	---------------------------------
	//##	-	24 bit int LSB 8 bits	-	the index + 1
	//##	---------------------------------	
	//## This corresponds with the PTC=4, PFC = 13.
	//## \param index Represent the index of the field.
	//## \return the 24 bit signed data converted in a long 32 bit
	virtual signed long getFieldValue_4_13(word index);

	//##Documentation
	//## Sets the value of a field. The value is interpreted as a 24 bit signed integer.
	//## The index of the argument is the first 16 bit field of the 2 fields that compound
	//## the 24 bit signed integer. The layout foreseen is the following:
	//##	---------------------------------
	//##	-	24 bit int MSB 16 bits	-	the index passed as argument
	//##	---------------------------------
	//##	-	24 bit int LSB 8 bits	-	the index + 1
	//##	---------------------------------	
	//## This corresponds with the PTC=4, PFC = 13.
	//## See setFieldValue(word index, word value) for general considerations.
	//## \param index Represent the index of the field.
	//## \param value The 24 bit signed integer value. The long value is converted in a
	//## 24 bit data format (bit0 with the sign became 24 bit)
	virtual void setFieldValue_4_13(word index, signed long value) throw(PacketException*);	
	
	//##Documentation
	//## Returns the value of a field in the list of fields of this part of packet. 
	//## The value returned is interpreted as a 32 bit unsigned integer.
	//## The index of the argument is the first 16 bit field of the 2 fields that compound
	//## the 32 bit unsigned long. The layout foreseen is the following:
	//##	---------------------------------
	//##	-	32 bit int MSB 16 bits	- the index passed as argument
	//##	---------------------------------
	//##	-	32 bit int LSB 16 bits	- the index + 1
	//##	---------------------------------	
	//## This corresponds with the PTC=3, PFC = 14.
	//## \param index Represent the index of the field.
	virtual unsigned long getFieldValue_3_14(word index);

	//##Documentation
	//## Sets the value of a field. The value is interpreted as a 32 bit unsigned integer.
	//## The index of the argument is the first 16 bit field of the 2 fields that compound
	//## the 32 bit unsigned long. The layout foreseen is the following:
	//##	---------------------------------
	//##	-	32 bit int MSB 16 bits	- 	the index passed as argument
	//##	---------------------------------
	//##	-	32 bit int LSB 16 bits	- 	the index + 1
	//##	---------------------------------	
	//## This corresponds with the PTC=3, PFC = 14.
	//## See setFieldValue(word index, word value) for general considerations.
	//## \param index Represent the index of the field.
	//## \param value The 32 bit unsigned integer value.		
	virtual void setFieldValue_3_14(word index, unsigned long value);
	
	//##Documentation
	//## Returns the value of a field in the list of fields of this part of packet. 
	//## The value returned is interpreted as a 24 bit unsigned integer.
	//## The index of the argument is the first 16 bit field of the 2 fields that compound
	//## the 24 bit unsigned long. The layout foreseen is the following:
	//##	---------------------------------
	//##	-	24 bit int MSB 16 bits	- the index passed as argument
	//##	---------------------------------
	//##	-	24 bit int LSB 8 bits	- the index + 1
	//##	---------------------------------	
	//## This corresponds with the PTC=3, PFC = 13.
	//## \param index Represent the index of the field.
	virtual unsigned long getFieldValue_3_13(word index);

	//##Documentation
	//## Sets the value of a field. The value is interpreted as a 24 bit unsigned integer.
	//## The index of the argument is the first 16 bit field of the 2 fields that compound
	//## the 24 bit unsigned long. The layout foreseen is the following:
	//##	---------------------------------
	//##	-	24 bit int MSB 16 bits	- 	the index passed as argument
	//##	---------------------------------
	//##	-	24 bit int LSB 8 bits	- 	the index + 1
	//##	---------------------------------	
	//## This corresponds with the PTC=3, PFC = 13.
	//## See setFieldValue(word index, word value) for general considerations.
	//## \param index Represent the index of the field.
	//## \param value The 24 bit unsigned integer value.		
	virtual void setFieldValue_3_13(word index, unsigned long value) throw(PacketException*);		

        //##ModelId=3EADC13E0246
        //##Documentation
        //## Sets the value of a field in the list of fields of this part of packet. Remember that
	//## if a predefined value is specified in the .stream, this method has not effect and the 
	//## value contained in the .stream is used.
        //## \param index Represent the index in the list.
        //## \param value The value must be setted.
        virtual void setFieldValue(word index, word value);

        //##ModelId=3C187751018C
        //##Documentation
        //## Returns the number of fields.
        virtual  inline word getNumberOfFields() {
          return numberOfFields;
        };

        //##ModelId=3C18AB2E037F
        //##Documentation
        //## Sets the stream of byte. This method assigns the value of stream for each field of part of packet
        virtual bool setByteStream(ByteStream* s);

        //##Documentation
        //## Represent current stream reads from input.
        ByteStream* stream;

	      //##ModelId=3EADC13B024B
        //##Documentation
        //## Represent current stream writes to output.
        ByteStream* outputstream;

        //##ModelId=3EADC1400007
        //##Documentation
        //## Generates the stream.
        virtual ByteStream* generateStream(bool bigendian);

        //##ModelId=3EADC14003CC
        //##Documentation
        //## Creates the outputstream ByteStream for the generation of the output stream
        virtual bool setOutputStream(ByteStream* os, word first);

        //##Documentation
        //## In a recoursive structure, the PartOfPacket that contains this PartOfPacket
        PartOfPacket* previous;

        char* popName;     

    protected:

        //##Documentation
        //## List of field of part of packet.
        Field** fields;

        //##Documentation
        //## Dimension in bit of fields.
        word fieldsDimension;

	//##ModelId=3EADC13B0295
        //##Documentation
        //## Number of fields.
        word numberOfFields;

    private:

        //##ModelId=3EADC14201B1
        void deleteFields();
};


}
#endif
