Skip to content
Snippets Groups Projects
Select Git revision
  • 693818189b6968132d844c0dcae0352acec3dd36
  • master default protected
  • v4.5.2
  • v4.5.1
  • v4.5.0
  • v4.4.0
  • v4.3.3
  • v4.3.2
  • v4.3.1
  • v4.3.0
  • v4.2.0
  • v4.1.0
  • v4.0.2
  • v4.0.1
  • v4.0.0
  • v3.4.0
  • v3.3.0
  • v3.2.0
  • v3.1.1
  • v3.1.0
  • v3.0.1
  • v3.0.0
22 results

PartOfPacket.cpp

Blame
  • PartOfPacket.cpp 16.32 KiB
    /***************************************************************************
                              PartOfPacket.cpp  -  description
                                 -------------------
        begin                : Thu Dec 6 2001
        copyright            : (C) 2001, 2013 by Andrea Bulgarelli
        email                : bulgarelli@iasfbo.inaf.it
     ***************************************************************************/
    
    /***************************************************************************
     *                                                                         *
     *   This program is free software; you can redistribute it and/or modify  *
     *   it under the terms of the GNU General Public License as published by  *
     *   the Free Software Foundation; either version 2 of the License, or     *
     *   (at your option) any later version.                                   *
     *                                                                         *
     ***************************************************************************/
    
    #include "PartOfPacket.h"
    
    using namespace PacketLib;
    
    word PacketLib::pattern[] = {0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535};
    
    
    PartOfPacket::PartOfPacket(const char* popName)
    {
        fieldsDimension = 0;
        stream = ByteStreamPtr(new ByteStream());
        numberOfFields = 0;
        fields = 0;
        outputstream = 0;
        this->popName = (char*) popName;
    }
    
    
    PartOfPacket::~PartOfPacket()
    {
        deleteFields();
        /// delete stream;
        /// Don't deletes the extern ByteStream. The responsibility of this isn't of Packet class;
        /// But deletes the internal ByteStream
    //     if(stream !=0) AB27Aug2005
    //         if(!stream->getMemAllocation()) {
    //             delete stream; stream = 0;
    // 	}
    }
    
    
    
    string* PartOfPacket::printStructure()
    {
        bool first = true;
        char *s;
    
        for(unsigned i=0; i< numberOfFields; i++)
        {
            Field* f = fields[i];
            if(first)
            {
                sprintf(s, "Prog: %d - Name - %s\n", f->getProgressiv(), f->getName() );
                first = false;
            }
            else
                sprintf(s, "%sProg: %d - Name - %s\n", s, f->getProgressiv(), f->getName() );
        }
        string* sr = new string(s);
        return sr;
    }
    
    /*
    // OLD VERSION
    bool PartOfPacket::loadFields(InputText& fp) throw(PacketException*)
    {
        bool ret;
        MemoryBuffer* buffer = loadFieldsInBuffer(fp);
        if(buffer==0)
            return false;
        ret = loadFields(buffer);
        //buffer->freebuffer(); TODO
        //delete buffer; TODO
        return ret;
    }
    */
    
    bool PartOfPacket::loadFields(InputText& fp) throw(PacketException*)
    {
        char* name, *dimension, *value;
        /// It calls the function that releases the memory
        deleteFields();
        int count = 0;
        /// count the number of fields
        long pos = fp.getpos();
        do {
            name = fp.getLine();
            count++;
            if(name[0] == '[')
            {
                count--;
                break;
            }
        } while(strlen(name) !=  0);
        fp.setpos(pos);
        fields = new Field* [count/3];
    
        name = fp.getLine();
        if(strlen(name) == 0)
        {
            return false;
        }
    
        while(strlen(name) != 0)
        {
    
            dimension = fp.getLine();
            value = fp.getLine();
            Field* f = new Field(name, dimension, value, numberOfFields);
            fieldsDimension += f->getDimension();
            fields[numberOfFields] = f;
            numberOfFields++;
            name = fp.getLine();
            /// It reads until the buffer ends
            if(name[0] == '[')
            {
                break;
            }
        }
        return true;
    }
    
    
    
    bool PartOfPacket::loadFields(MemoryBuffer* buffer) throw(PacketException*)
    {
        char* name;
        char* dimension;
        char* value;
        int count = 0;
    
        /// It calls the function to release the memory
        deleteFields();
        count = buffer->getBufferDimension();
        /// It allocates the field memory
        fields = new Field* [count/3];
    
        /// Begin of the packet creation
        name = buffer->getbuffer();
        if(name == 0)
        {
            return false;
        }
        while(name != 0)
        {
            dimension = buffer->getbuffer();
            value = buffer->getbuffer();
            Field* f = new Field(name, dimension, value, numberOfFields);
            fieldsDimension += f->getDimension();
            fields[numberOfFields] = f;
            numberOfFields++;
            name = buffer->getbuffer();
            /// It reads until the buffer ends
            if(name == 0)
            {
                return true;
            }
        }
        return true;
    }
    
    
    
    MemoryBuffer* PartOfPacket::loadFieldsInBuffer(InputText & fp)
    {
        char* name, *dimension, *value;
        MemoryBuffer* buffer = 0;
        int count = 0;
        name = fp.getLine();
        if(strlen(name) == 0)
        {
            return buffer;
        }
    
        buffer = new MemoryBuffer();
    
        while(strlen(name) != 0)
        {
            buffer->setbuffer(name);
            dimension = fp.getLine();
            buffer->setbuffer(dimension);
            value = fp.getLine();
            buffer->setbuffer(value);
            count++;
            name = fp.getLine();
            /// It reads until it reaches [
            if(name[0] == '[')
            {
                //delete[] name;
                break;
            }
        }
        return buffer;
    }
    
    
    bool PartOfPacket::setByteStream(ByteStreamPtr s)
    {
        Field* ftemp;
    
        /// If NULL is passed it exits
        if(s == NULL) return true;
    
        if(getDimension() > s->getDimension())
            return false;
    
    
        if(!s->getMemAllocation())
            stream->setStream(s->stream, s->getDimension(), s->isBigendian());
    
        /// The stream is assigned
        this->stream = s;
        //this->stream->setStream(s, 0, s->getDimension() - 1);
        /// The pointer is converted from byte to void. The reading from file allows the correct data interpretation
        /// for big or little endian machines
        byte* stream = (byte*) s->stream;
        /// It indicates the position inside the word:
        byte posbit = 0;
        /// It indicates the word to be analyzed inside the stream
        word posword = 0;
        /// Dimension nof the current field
        byte dimbit = 0;
    
        /// number of shift for elaboration
        short numberOfShift = 0;
        /// number of fields
        //unsigned nof = getNumberOfFields();
        word nof = numberOfFields;
        for(word i=0; i<nof; i++)
        {
            ftemp =  fields[i];
            dimbit = ftemp->getDimension();
            /// Temporary word to be modified for the elaboration
            byte bh = *(stream + posword);
            byte bl = *(stream + posword + 1);
            //word wordtemp = *(stream + posword);
            word wordtemp;
            if (s->isBigendian())
                wordtemp = bh * 256 + bl;
            else
                wordtemp = bl * 256 + bh;
            numberOfShift = 16 - (posbit + dimbit);
            //parte nuova
            /// \remarks if the condition is not fulfilled, the code is equal to the versions older than PacketLib 1.3.3
            if(numberOfShift < 0)   
            {
                short currentDimBit = dimbit + numberOfShift;
                dimbit = abs(numberOfShift);
                ftemp->value = (wordtemp & pattern[currentDimBit] ) << dimbit;
                posbit = 0;
                posword += 2;
                bh = *(stream + posword);
                bl = *(stream + posword + 1);
                if (s->isBigendian())
                    wordtemp = bh * 256 + bl;
                else
                    wordtemp = bl * 256 + bh;
    
                numberOfShift = 16 - (posbit + dimbit);
                wordtemp = wordtemp >> numberOfShift;
                /*		cout << i << ": " << ftemp->value << endl;
                		cout << i << ": " << (ftemp->value << currentDimBit) << endl;
                		cout << i << ": " << wordtemp << endl;*/
                ftemp->value = (ftemp->value) | wordtemp & pattern[dimbit];
                /*		cout << i << ": " << ftemp->value << endl;
                		cout << i << ": " << (wordtemp & pattern[dimbit]) << endl;*/
            }
            else
            {
                //questa fa parte della parte vecchia
                wordtemp = wordtemp >> numberOfShift;
                ftemp->value = wordtemp & pattern[dimbit];
            }
            /// Upgrade of pobit and posword
            posbit += dimbit;
            if(posbit >=16)
            {
                posword+=2;
                posbit =0;
            }
        }
        return true;
    }
    
    
    
    char** PartOfPacket::printValue(const char* addString)
    {
        //bool first = true;
        string s1, s2, s3;
        char *s = new char[1];       //importante, altrimenti non funziona
        char *t;
        char **c;
        long index;
        //c = (char**) malloc(sizeof(char*) * (numberOfFields + 1));
        c = new char* [numberOfFields + 1];
        s3 = "";
        if(!stream) return NULL;
        // Create constant iterator for list.
    
        //list<Field>::iterator iter;
        /// Iterate through list and output each element.
        index = 0;
        //for (iter=fields.begin(); iter != fields.end(); iter++)
        for(unsigned i=0; i<numberOfFields; i++)
        {
            //Field* f = (Field*) &(*iter);
            Field* f = fields[i];
            //sprintf(s, "Name: %s Value: %d\n", f->name.c_str(), f->value);
            //cout << "@ " << f->value << endl;
            sprintf(s, "%d", f->value);
            //s1 = "Name: ";
            s1 = "";
            s2 = f->getName();
            s2 += " (";
            s2 += Utility::integerToString(f->getDimension());
            s2 +=  ") - ";
            s2 += "Value: ";
            s2 += s;
            s2 += " (0x";
            s2 += Utility::stringToHexadecimal((byte*) &f->value, 2, false, false);
            s2 += ")";
            //		s2 += //+ "@";
            s3 = s1 + s2 + addString;
            //		s3 += '\n';
            c[index] = new char[s3.size() + 1];
            t = (char*) s3.c_str();
            for(unsigned j=0; j<= s3.size(); j++)
                c[index][j] = t[j];
            //c[index][i] = '\0';
            //printf("%p\n", c[index]);
            //cout << c[index] << endl;
            index ++;
        }
        c[index] = 0;
        return c;
    }
    
    void PartOfPacket::printValueStdout()
    {
        //bool first = true;
        string s1, s2, s3;
        char *s = new char[1];       //importante, altrimenti non funziona
        if(!stream) return;
        for(unsigned i=0; i<numberOfFields; i++)
        {
            //Field* f = (Field*) &(*iter);
            Field* f = fields[i];
            //sprintf(s, "Name: %s Value: %d\n", f->name.c_str(), f->value);
            sprintf(s, "%d", f->value);
            //s1 = "Name: ";
            s1 = "";
            s2 = f->getName();
            s2 += " (";
            s2 += Utility::integerToString(f->getDimension());
            s2 +=  ") - ";
            s2 += "Value: ";
            s2 += s;
            s2 += " (0x";
            s2 += Utility::stringToHexadecimal((byte*) &f->value, 2, false, false);
            s2 += ")";
            s3 = s1 + s2;
            cout << s3 << endl;
        }
        /* if(stream)
             	cout << stream->printStreamInHexadecimal() << endl;
         if(outputstream)
             	cout << stream->printStreamInHexadecimal() << endl;*/
    }
    
    
    void PartOfPacket::deleteFields()
    {
        for(unsigned i = 0; i < numberOfFields; i++)
            delete fields[i];
        delete[] fields;
    }
    
    
    ByteStreamPtr PartOfPacket::generateStream(bool bigendian)
    {
        word w = 0, wtemp = 0;
        int posbit = 0;
        word posword = 0;
        short shift;
        /// Dimension of the current field
        byte dimbit = 0;
        if(outputstream == 0)
            outputstream = ByteStreamPtr(new ByteStream(getDimension(), bigendian));
        for(unsigned i = 0; i<numberOfFields; i++)
        {
            if(!fields[i]->thereIsPredefinedValue())
                wtemp = fields[i]->value;
            else
                wtemp = fields[i]->value =  fields[i]->getPredefinedValue();
            dimbit = fields[i]->getDimension();
            shift = 16 - dimbit - posbit;
            if(shift < 0)
            {
                byte nbitshigh = abs(shift);
                //word wh = wtemp >> (16 - nbitshigh);
                word wh = wtemp >> (nbitshigh);
                w = w | wh;
                if(outputstream->setWord(posword, w))
                    posword+=2;
                else
                    return 0;
                w = 0;
                posbit = nbitshigh;
                w = (wtemp & pattern[nbitshigh]) << (16-posbit);
    
            }
            else
            {
                wtemp = (wtemp << shift);
                w = w | wtemp;
                //cout << (Utility::wordToBinary(w, 16))->c_str() << endl;
                posbit += fields[i]->getDimension();
            }
            if(posbit == 16)
            {
                posbit = 0;
                if(outputstream->setWord(posword, w))
                    posword+=2;
                else
                    return 0;
                w = 0;
    
            }
            else
            {
                if(posbit > 16)
                    return 0;
            }
        }
        if(posbit < 16)
            outputstream->setWord(posword, w);
        return outputstream;
    };
    
    
    bool PartOfPacket::setOutputStream(ByteStreamPtr os, dword first)
    {
        outputstream = ByteStreamPtr(new ByteStream((os->stream + first), getDimension(), os->isBigendian()));
        return true;
    }
    
    void PartOfPacket::setFieldValue(word index, word value)
    {
        if(index < numberOfFields)
            fields[index]->value = (value & pattern[fields[index]->getDimension()]);
    }
    
    float PartOfPacket::getFieldValue_5_1(word index)
    {
        union u_tag
        {
        	/// 32 bit
            unsigned long i;
            /// 32 bit single precision
            float f;	
        } u;
        u.i = (getFieldValue(index) << 16) | getFieldValue(index + 1);
        return u.f;
    }
    
    void PartOfPacket::setFieldValue_5_1(word index, float value)
    {
        union u_tag
        {
        	/// 32 bit
            unsigned long i;
            /// 32 bit single precision
            float f;	
        } u;
        word w;
        u.f = value;
        w = (word)(u.i >> 16);
        setFieldValue(index, w);
        w = (word)(0xFFFF & u.i);
        setFieldValue(index + 1, w);
    }
    
    signed long PartOfPacket::getFieldValue_4_14(word index)
    {
        long l;
        l = (long)(getFieldValue(index) << 16) | (long)getFieldValue(index + 1);
        return l;
    }
    
    void PartOfPacket::setFieldValue_4_14(word index, signed long value)
    {
        word w;
        w = (word)(value >> 16);
        setFieldValue(index, w);
        w = (word) (0xFFFF & value);
        setFieldValue(index + 1, w);
    }
    
    unsigned long PartOfPacket::getFieldValue_3_14(word index)
    {
        dword l;
        l = (dword)(getFieldValue(index) << 16) | (dword)getFieldValue(index + 1);
        return l;
    }
    
    void PartOfPacket::setFieldValue_3_14(word index, unsigned long value)
    {
        word w;
        w = (word)(value >> 16);
        setFieldValue(index, w);
        w = (word) (0xFFFF & value);
        setFieldValue(index + 1, w);
    }
    
    unsigned long PartOfPacket::getFieldValue_3_13(word index)
    {
        word wh, wl;
        wh = getFieldValue(index);
        wl = getFieldValue(index + 1);
        return (dword)(wh << 8) | (dword)(wl & 0xFF);
    }
    
    void PartOfPacket::setFieldValue_3_13(word index, unsigned long value) throw(PacketException*)
    {
        word w;
        if(value > U24BITINTGEGERUNSIGNED_MAX)
            throw new PacketException("setFieldValue_3_13(): the max value of 24 bit unsigned integer should be 16777215");
        w = (word)(value >> 8);
        setFieldValue(index, w);
        w = (word) (0xFF & value);
        setFieldValue(index + 1, w);
    }
    
    signed long PartOfPacket::getFieldValue_4_13(word index)
    {
        union u_tag
        {
        	/// 32 bit
            unsigned long u;		
            signed long s;
        } us;
        us.u = getFieldValue_3_14(index);
        /// get the sign
        unsigned long sign = (us.u  >> 23); 
        unsigned long wh = us.u & 0x007FFFFF;
        /// get a long 32 bit
        if(sign == 1)
            us.u = 0x7F800000 + wh + (sign << 31);
        else
            us.u = wh + (sign << 31);
        return us.s;
    }
    
    
    void PartOfPacket::setFieldValue_4_13(word index, signed long value) throw(PacketException*)
    {
        union u_tag
        {
        	/// 32 bit
            unsigned long u;		
            signed long s;
        } us;
        if(value > U24BITINTGEGERSIGNED_MAX)
            throw new PacketException("setFieldValue_4_13(): the max value of 24 bit signed integer should be 8388607");
        if(value < U24BITINTGEGERSIGNED_MIN)
            throw new PacketException("setFieldValue_4_13(): the min value of 24 bit signed integer should be -8388607");
        us.s = value;
        unsigned long sign = (us.u >> 31);
        /// 23 bit
        unsigned long wh = us.u & 0x007FFFFF;
        unsigned long value2 = 0;
        value2 = wh + (sign << 23);
        setFieldValue_3_14(index, value2);
    }
    
    void PacketLib::PartOfPacket::memByteStream(ByteStreamPtr stream) {
    	this->stream = stream;
    }