Skip to content
Snippets Groups Projects
Select Git revision
  • 8915359b0308d608cfa96c0292df0b822c7f813e
  • master default protected
  • ia2
  • adql2.1-ia2
  • private_rows
5 results

TAPFileManager.java

Blame
  • PacketStream.cpp 14.18 KiB
    /***************************************************************************
                              PacketStream.cpp  -  description
                                 -------------------
        begin                : Thu Nov 29 2001
        copyright            : (C) 2001, 2013 by Andrea Bulgarelli
        email                : bulgarelli@iasfbo.inaf.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                  *
     *                                                                         *
     ***************************************************************************/
     
    #include "PacketStream.h"
    #include "ConfigurationFile.h"
    #include "PacketExceptionFileFormat.h"
    #include "PacketExceptionIO.h"
    #include "PacketNotRecognized.h"
    #include "PacketLibDemo.h"
    #include <sstream>
    
    using namespace PacketLib;
    
    PacketStream::PacketStream(string fileNameConfig)
    {
    	filenameConfig = realpath(fileNameConfig.c_str(), NULL);
        numberOfPacketType = 0;
        headerReference = 0;
        //TODO
        packetType = new Packet* [255];
        //TODO
        memset(packetType, 0, sizeof(Packet*)*255);
        pathFileNameConfig = 0;
    	dimHeader = 0;
    	std::cout << "Loading config file " << filenameConfig << " ..." << std::endl;
    	createStreamStructure();
    	std::cout << "Load complete." << std::endl;
    }
    
    PacketStream::PacketStream()
    	: filenameConfig("")
    {
        numberOfPacketType = 0;
        headerReference = 0;
        //TODO
        packetType =  new Packet* [255];
        //TODO
        memset(packetType, 0, sizeof(Packet*)*255);
        pathFileNameConfig = 0;
    	dimHeader = 0;
    }
    
    
    
    PacketStream::~PacketStream()
    {
        for(int i=0; i< numberOfPacketType; i++)
            delete packetType[i];
        delete[] packetType;
        delete headerReference;
        free(pathFileNameConfig);
    }
    
    dword PacketStream::getPacketDimension(ByteStreamPtr stream) {
    	dword dimPre = 0;
    	if(prefix)
    		dimPre += dimPrefix;
    	//ByteStreamPtr prefix = new ByteStream(stream, dimPre, bigendian);
    	
    	dword dim = 0;
    	dword dimHeader = headerReference->size();
    	dim += dimHeader;
    	ByteStreamPtr tempHeader = ByteStreamPtr(new ByteStream());
    	tempHeader->setStream(stream->stream+dimPre, dimHeader, bigendian);
    	headerReference->setByteStream(tempHeader);
    	dim += headerReference->getPacketLength();
    	return dim;
    }
    
    
    int PacketStream::detPacketType(ByteStreamPtr prefix, ByteStreamPtr packetHeader, ByteStreamPtr packetDataField)
    {
        ///  Iterate through list and output each element.
        ///  The packetType 0 is the packet not recognized
        for (int i = 1; i<numberOfPacketType; i++)
        {
            Packet* p = getPacketType(i);
    		p->decode(prefix, packetHeader, packetDataField);
            if(p->verify())
                return i;
        }
        return 0;
    }
    
    int PacketStream::detPacketType(ByteStreamPtr prefix, ByteStreamPtr packet)
    {
        /// Iterate through list and output each element.
        /// The packetType 0 is the packet not recognized
        for (dword i = 1; i<numberOfPacketType; i++)
        {
            Packet* p = getPacketType(i);
    		p->decode(prefix, packet);
            if(p->verify())
                return i;
        }
        return 0;
    }
    
    
    int PacketStream::detPacketType(ByteStreamPtr packet)
    {
        /// Iterate through list and output each element.
        /// The packetType 0 is the packet not recognized
        for (dword i = 1; i<numberOfPacketType; i++)
        {
            Packet* p = getPacketType(i);
    		p->decode(packet);
            if(p->verify())
                return i;
        }
        return 0;
    }
    
    
    
    Packet* PacketStream::getPacket(ByteStreamPtr stream) throw(PacketException*){
    	
    	int index = detPacketType(stream);
    	if(index > 0) {
    		Packet* p = getPacketType(index);
    		
    		if(!p->decode(stream)) //gli stream diventano del packet
    			throw new PacketExceptionIO("it is impossible to resolve the packet.");
    		
    		return p;
    		
    	}
    	else
    		return 0;
    	
    }
    
    const std::string fixed32[] = { "uint32", "int32", "float" };
    const std::string fixed64[] = { "uint64", "int64", "double" };
    
    void PacketStream::cachePhysicalIndexes(pugi::xml_node node, std::map<pugi::xml_node, int>& physicalIndex)
    {
    	int index = 0;
    	for(pugi::xml_node_iterator it=node.begin(); it != node.end(); ++it)
    	{
    		if(string(it->name()).compare("field") != 0)
    			continue;
    #ifdef DEBUG
    		std::cout << "Physical index of " << it->attribute("name").value() << " is " << index << std::endl;
    #endif
    		physicalIndex[*it] = index;
    
    		// if 32bits fields
    		string typeStr = it->attribute("type").value();
    		bool found = false;
    		for(unsigned int i=0; i<3; i++)
    		{
    			if(typeStr.compare(fixed32[i]) == 0)
    			{
    				index+=2;
    				found = true;
    				break;
    			}
    		}
    		if(found)
    			continue;
    
    		// if 64bits fields
    		for(unsigned int i=0; i<3; i++)
    		{
    			if(typeStr.compare(fixed64[i]) == 0)
    			{
    				index+=4;
    				found = true;
    				break;
    			}
    		}
    		if(found)
    			continue;
    
    		// else (<= 16bits fields)
    		index++;
    	}
    }
    
    void PacketStream::createStreamStructureXml()
    {
    	std::map<pugi::xml_node, int> physicalIndex;
    
    	pugi::xml_document doc;
    
    	// open the config file
    	if (!doc.load_file(filenameConfig.c_str()))
    	{
    		std::stringstream ss;
    		ss << "Cannot open " << filenameConfig;
    		throw new PacketExceptionFileFormat(ss.str().c_str());
    	}
    
    	// cache all the field physical indexes
    	pugi::xpath_node_set fieldParents = doc.select_nodes("//*[field]");
    	for(pugi::xpath_node_set::const_iterator it = fieldParents.begin(); it != fieldParents.end(); ++it)
    		cachePhysicalIndexes(it->node(), physicalIndex);
    
    	// get the stream node
    	pugi::xml_node sNode = doc.child("stream");
    	if(!sNode) throw new PacketExceptionFileFormat("<stream> not found.");
    
    	if(pathFileNameConfig) free(pathFileNameConfig);
    	pathFileNameConfig = getcwd(NULL, 512L);
    
    	bigendian = false;
    	pugi::xml_attribute beAttr = sNode.attribute("bigendian");
    	if(beAttr && strcmp(beAttr.value(), "true") == 0)
    		bigendian = true;
    #ifdef DEBUG
    	std::cout << "big endian? " << beAttr.value() << std::endl;
    #endif
    
    	dimPrefix = 0;
    	prefix = false;
    	pugi::xml_attribute preAttr = sNode.attribute("prefixSize");
    	if(preAttr)
    	{
    		prefix = true;
    		dimPrefix = atoi(preAttr.value());
    	}
    #ifdef DEBUG
    	std::cout << "prefix size: " << dimPrefix << std::endl;
    #endif
    
    	// get the header node
    	pugi::xml_node hNode = sNode.child("header");
    	if(!hNode) throw new PacketExceptionFileFormat("<header> not found.");
    
    	// get the packet length physical index
    	std::string query = std::string("//field[@id=\"") + hNode.attribute("idref").value()+"\"]";
    	pugi::xml_node plNode = hNode.select_nodes(query.c_str())[0].node();
    	int plIndex = physicalIndex[plNode];
    
    	// get the packet length bit width
    	std::string typeStr = plNode.attribute("type").value();
    	std::string::size_type spos = typeStr.find_first_of("0123456789");
    	std::string::size_type epos = typeStr.find_last_of("0123456789");
    	int nbits = atoi(typeStr.substr(spos, epos+1).c_str());
    
    	// load the header
    	delete headerReference;
    	headerReference = new PacketHeader();
    	headerReference->loadHeader(hNode, plIndex, nbits);
    	dimHeader = headerReference->size();
    
    	// load the packet not recognized
    	PacketNotRecognized* p = new PacketNotRecognized(bigendian);
    	p->createPacketType(hNode, prefix, dimPrefix);
    
    	packetType[numberOfPacketType] = p;
    	numberOfPacketType++;
    
    	// load packet types
    	pugi::xml_node pNode = sNode.child("packet");
    	while(pNode) {
    		if(pNode.attribute("name") != 0)
    		{
    			Packet* p = new Packet(bigendian);
    			p->createPacketType(doc, hNode, plIndex, nbits, pNode, prefix, dimPrefix, physicalIndex);
    			packetType[numberOfPacketType] = p;
    			p->setPacketID(numberOfPacketType);
    			numberOfPacketType++;
    		}
    		pNode = pNode.next_sibling();
    	}
    }
    
    bool PacketStream::createStreamStructure() throw(PacketException*)
    {
    	if(filenameConfig.find(".xml") != std::string::npos)
    	{
    		createStreamStructureXml();
    		return true;
    	}
    
        ConfigurationFile config;
        char* line;
        char **argv = new char* [1];
        argv[0] = (char*) filenameConfig.c_str();
        //cout << "@@@@@@@@@@OPEN " << filenameConfig << endl;
        try
        {
            if(config.open(argv))
            {
                //delete[] argv;
                if(pathFileNameConfig) free(pathFileNameConfig);
                pathFileNameConfig = getcwd(NULL, 512L);
                /// prefix
                config.setpos(0);
                line = config.getLine();
                if(strcmp(line, "[Configuration]") == 0)
                {
                    //delete[] line;
                    line = config.getLine();
                    if(strcmp(line, "false") == 0)
                        prefix = false;
                    else
                    {
                        if(strcmp(line, "true") == 0)
                            prefix = true;
                        else
                        {
                            //delete[] line;
                            throw new PacketExceptionFileFormat("Prefix selector format not correct. It's possible only true or false value.");
                            return false;
                        }
                    }
                    //delete[] line;
                    /// bigendian
                    line = config.getLine();
                    if(strcmp(line, "false") == 0)
                        bigendian = false;
                    else
                    {
                        if(strcmp(line, "true") == 0)
                            bigendian = true;
                        else
                        {
                            throw new PacketExceptionFileFormat("Bigendian selector format not correct. It's possible only true or false value.");
                            return false;
                        }
                    }
                    /// dimensione of prefix
                    //delete[] line;
                    line = config.getLine();
    				if(prefix == false)
    					dimPrefix = 0;
    				else
    					dimPrefix = atoi(line);
                }
                else
                    throw new PacketExceptionFileFormat("No [Configuration] section found.");
                /// [Header Format] section
                //delete[] line;
                line = config.getLine();
                if(strcmp(line, "[Header Format]") == 0)
                {
                    //delete[] line;
                    ///  Create headerReference of PacketHeader type. The method reads the structure of header from configuration file (named in filenameConfig)
                    line = config.getLine();
                    delete headerReference;
                    headerReference = (PacketHeader*) new PacketHeader();
                    if(!headerReference->loadHeader(line))
                    {
                        //delete[] line;
                        throw new PacketExceptionFileFormat("No parameters in file header format");
                        return false;
                    }
    				dimHeader = headerReference->size();
                    /// It creates the PACKET NOT RECOGNIZED
                    PacketNotRecognized* p = new PacketNotRecognized(bigendian);
                    if(!p->createPacketType(line, prefix, dimPrefix))
                    {
                        //delete[] line;
                        throw new PacketExceptionFileFormat("Packet Not Recognized not created.");
                    }
                    else
                    {
                        packetType[numberOfPacketType] = p;
                        numberOfPacketType++;
                    }
                    //delete[] line;
                }
                else
                {
                    throw new PacketExceptionFileFormat("No [Header format] section");
                    return false;
                }
                /// [Packet Format]
                line = config.getLine();
                if(strcmp(line, "[Packet Format]") == 0)
                {
                    char* packetFileName = config.getLine();
                    while(strlen(packetFileName) != 0)
                    {
                        Packet* p;
                        p = new Packet(bigendian);
                        p->createPacketType(packetFileName, prefix, dimPrefix);
                        packetType[numberOfPacketType] = p;
                        p->setPacketID(numberOfPacketType);
                        numberOfPacketType++;
                        //delete[] packetFileName;
                        packetFileName = config.getLine();
                    }
                }
                else
                {
                    throw new PacketExceptionFileFormat("No [Packet Format] section");
                    return false;
                }
                config.close();
            }
            else
                throw new PacketExceptionFileFormat("Header file configuration not found.");
    
            return true;
        }
        catch(PacketExceptionIO* e)
        {
            e->add(" - ");
            e->add(filenameConfig.c_str());
            e->add("Configuration file: ");
            throw e;
        }
        catch(PacketExceptionFileFormat* e)
        {
            e->add(" - ");
            e->add(filenameConfig.c_str());
            e->add("Configuration file: ");
            throw e;
        }
    }
    
    word PacketStream::getPrefixDimension() const
    {
        if(prefix)
            return dimPrefix;
        else
            return 0;
    }
    
    
    word PacketStream::getHeaderDimension() const
    {
    	return dimHeader;
    }
    
    
    word PacketStream::getNumberOfPacketType()
    {
        return numberOfPacketType;
    }
    
    
    Packet* PacketStream::getPacketType(int index)
    {
        return packetType[index];
    }
    
    Packet* PacketStream::getPacketType(string name) {
    	for(int i=1; i<numberOfPacketType; i++) {
    		string pname = packetType[i]->getName();
    		if(pname.compare(name) == 0)
    			return packetType[i];
    	}
    	throw new PacketException("Packet type not found in the PacketStream");
    }
    
    bool PacketStream::isBigEndian()
    {
        return (bool) this->bigendian;
    }
    
    
    void PacketStream::setFileNameConfig(const char* f)
    {
        this->filenameConfig = (char*) f;
        //this->pathFileNameConfig = Utility::extractPath(filenameConfig);
    }
    
    
    bool PacketStream::thereIsPrefix()
    {
        return prefix;
    }