objectclass.cc~

来自「certi-SHM-3.0.tar 不错的开源的分布式方针软件 大家多多支持 他」· CC~ 代码 · 共 1,185 行 · 第 1/3 页

CC~
1,185
字号
// -*- mode:C++ ; tab-width:4 ; c-basic-offset:4 ; indent-tabs-mode:nil -*-// ----------------------------------------------------------------------------// CERTI - HLA RunTime Infrastructure// Copyright (C) 2002, 2003  ONERA//// This file is part of CERTI-libCERTI//// CERTI-libCERTI is free software ; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public License// as published by the Free Software Foundation ; either version 2 of// the License, or (at your option) any later version.//// CERTI-libCERTI is distributed in the hope that it will be useful, but// WITHOUT ANY WARRANTY ; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this program ; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307// USA//// $Id: ObjectClass.cc,v 3.12 2003/03/04 09:47:04 breholee Exp $// ----------------------------------------------------------------------------#include "ObjectClass.hh"namespace certi {static pdCDebug D("OBJECTCLASS", "(ObjClass) - ");// ----------------------------------------------------------------------------//! To be used only by CRead, it returns the new Attribute's Handle.AttributeHandleObjectClass::addAttribute(ObjectClassAttribute *theAttribute,                          Boolean is_inherited){    if (theAttribute == NULL)        throw RTIinternalError("Tried to add NULL attribute.");    theAttribute->setHandle(attributeSet.size() + 1);    theAttribute->server = server ;    // If the attribute is inherited, it keeps its security level.    // If not, it takes the default security level of the class.    if (is_inherited != RTI_TRUE)        theAttribute->LevelID = LevelID ;    attributeSet.push_front(theAttribute);    D.Out(pdProtocol, "ObjectClass %u has a new attribute %u.",          handle, theAttribute->getHandle());    return theAttribute->getHandle();}// ----------------------------------------------------------------------------//! Add the class' attributes to the 'Child' Class.voidObjectClass::addAttributesToChild(ObjectClass *the_child){    // The Attribute List is read backwards to respect the same attribute order    // for the child(Attributes are inserted at the beginning of the list).    ObjectClassAttribute *childAttribute = NULL ;    list<ObjectClassAttribute *>::reverse_iterator a ;    for (a = attributeSet.rbegin(); a != attributeSet.rend(); a++) {        assert((*a) != NULL);        childAttribute = new ObjectClassAttribute(*a);        assert(childAttribute != NULL);        D.Out(pdProtocol,              "ObjectClass %u adding new attribute %d to child class %u.",              handle, (*a)->getHandle(), the_child->getHandle());        the_child->addAttribute(childAttribute);        if (childAttribute->getHandle() != (*a)->getHandle())            throw RTIinternalError("Error while copying child's attributes.");    }}// ----------------------------------------------------------------------------/*! Take a Broadcast List and continue to send messages. You should  take a look at ObjectClassSet::RegisterObject to understand  what is going on...*/voidObjectClass::broadcastClassMessage(ObjectClassBroadcastList *ocbList){    // 1. Set ObjectHandle to local class Handle.    ocbList->message->objectClass = handle ;    // 2. Update message attribute list by removing child's attributes.    if ((ocbList->message->type == m_REFLECT_ATTRIBUTE_VALUES) ||        (ocbList->message->type == m_REQUEST_ATTRIBUTE_OWNERSHIP_ASSUMPTION)) {        int attr = 0 ;        while (attr < ocbList->message->handleArraySize) {            // If the attribute is not in that class, remove it from            // the message.            try {                getAttributeWithHandle(ocbList->message->handleArray[attr]);                attr++ ;            }            catch (AttributeNotDefined &e) {                ocbList->message->removeAttribute(attr);            }        }    }    // 3. Add class/attributes subscribers to the list.    switch(ocbList->message->type) {    case m_DISCOVER_OBJECT:    case m_REMOVE_OBJECT: {        // For each federate, add it to list if at least one attribute has        // been subscribed.        FederateHandle federate = 0 ;        for (federate = 1 ; federate <= MaxSubscriberHandle ; federate++) {            if (isFederateSubscriber(federate) == RTI_TRUE) {                ocbList->addFederate(federate);            }        }    }        break ;    case m_REFLECT_ATTRIBUTE_VALUES:    case m_REQUEST_ATTRIBUTE_OWNERSHIP_ASSUMPTION: {        // For each class attribute, update the list be adding federates who        // subscribed to the attribute.        list<ObjectClassAttribute *>::const_iterator a ;        for (a = attributeSet.begin(); a != attributeSet.end(); a++) {            (*a)->updateBroadcastList(ocbList);        }    }        break ;    default:        throw RTIinternalError("BroadcastClassMsg: Unknown type.");    }    // 4. Send pending messages.    ocbList->sendPendingMessage(server);}// ----------------------------------------------------------------------------//! sendToFederate.voidObjectClass::sendToFederate(NetworkMessage *msg, FederateHandle theFederate){    // Send the message 'msg' to the Federate which Handle is theFederate.    Socket *socket = NULL ;    printf("avant getSocketLink dans sendToFederate\n");    try {#ifdef HLA_USES_UDP        socket = server->getSocketLink(theFederate, BEST_EFFORT);#else        socket = server->getSocketLink(theFederate);#endif        msg->write(socket);    }    catch (RTIinternalError &e) {        D.Out(pdExcept,              "Reference to a killed Federate while broadcasting.");    }    catch (NetworkError &e) {        D.Out(pdExcept, "Network error while broadcasting, ignoring.");    }    // BUG: If except = 0, could use Multicast.}// ----------------------------------------------------------------------------//! sendToOwners.voidObjectClass::sendToOwners(CDiffusion *diffusionList,                          ObjectHandle theObjectHandle,                          FederateHandle theFederate,                          const char *theTag,                          TypeNetworkMessage type){    int nbAttributes = diffusionList->size ;    FederateHandle toFederate ;    for (int i = 0 ; i < nbAttributes ; i++) {        toFederate = diffusionList->DiffArray[i].federate ;        if (toFederate != 0) {            NetworkMessage *answer = new NetworkMessage ;            answer->type = type ;            answer->federation = server->federation();            answer->federate = theFederate ;            answer->exception = e_NO_EXCEPTION ;            answer->object = theObjectHandle ;            strcpy(answer->label, theTag);            int index = 0 ;            for (int j = i ; j < nbAttributes ; j++) {                if (diffusionList->DiffArray[j].federate == toFederate) {                    D.Out(pdDebug, "handle : %u",                          diffusionList->DiffArray[j].attribute);                    diffusionList->DiffArray[j].federate = 0 ;                    answer->handleArray[index] = diffusionList                        ->DiffArray[j].attribute ;                    index++ ;                }            }            answer->handleArraySize = index ;            D.Out(pdDebug, "Envoi message type %u ", type);            sendToFederate(answer, toFederate);        }    }}// ----------------------------------------------------------------------------/*! Throw SecurityError if the Federate is not allowed to access the  Object Class, and print an Audit message containing reason.*/voidObjectClass::checkFederateAccess(FederateHandle the_federate,                                 const char *reason)    throw (SecurityError){    D.Out(pdInit, "Beginning of CheckFederateAccess for the federate %d",          the_federate);    // BUG: Should at least but a line in Audit    if (server == NULL)        return ;    Boolean result = server->canFederateAccessData(the_federate, LevelID);    // BUG: Should use Audit.    if (result != RTI_TRUE) {        cout << "Object Class " << handle << " : SecurityError for federate "             << the_federate << '(' << reason << ")." << endl ;        throw SecurityError("Federate should not access Object Class.");    }}// ----------------------------------------------------------------------------//! ObjectClass constructor (only one).ObjectClass::ObjectClass(void)    : handle(0), Father(0), server(NULL), Depth(0),      Name(NULL), LevelID(PublicLevelID), MaxSubscriberHandle(0){}// ----------------------------------------------------------------------------//! ObjectClass destructor (frees allocated memory).ObjectClass::~ObjectClass(void){    if (Name != NULL) {        free(Name);        Name = NULL ;    }    // Deleting instances    if (!objectSet.empty())        D.Out(pdError,              "ObjectClass %d : Instances remaining while exiting...", handle);    while (!objectSet.empty()) {        delete objectSet.front();        objectSet.pop_front();    }    // Deleting Class Attributes    while (!attributeSet.empty()) {        delete attributeSet.front();        attributeSet.pop_front();    }    // Deleting Sons    while (!sonSet.empty()) {        sonSet.pop_front();    }}// ----------------------------------------------------------------------------/*! Delete the object instance 'theObjectHandle', and starts to  broadcast the RemoveObject message. Return a BroadcastList of  Federates, in order to allow our ObjectClassSet to go on with  the message broadcasting, by giving the list to our parent  class.*/ObjectClassBroadcastList *ObjectClass::deleteInstance(FederateHandle theFederateHandle,                            ObjectHandle theObjectHandle,                            const char *theUserTag)    throw (DeletePrivilegeNotHeld,           ObjectNotKnown,           RTIinternalError){    // 1. Pre-conditions checking(may throw ObjectNotKnown)    Object *object = getInstanceWithID(theObjectHandle);    // Is the Federate really the Object Owner?(Checked only on RTIG)    if ((server != NULL) && (object->Owner != theFederateHandle)) {        D.Out(pdExcept, "Delete Object %d: Federate %d not owner.",              theObjectHandle, theFederateHandle);        throw DeletePrivilegeNotHeld();    }    // 2. Remove Instance    list<Object *>::iterator o ;    list<Object *>::iterator tmp ;    for (o = objectSet.begin(); o != objectSet.end(); o++) {        if ((*o)->getHandle() == theObjectHandle) {            tmp = o ;            tmp-- ;            delete (*o);            objectSet.erase(o); // i is dereferenced.            o = tmp ; // loop will increment o            // A break may be enough ?!        }    }    // 3. Prepare and broadcast message.    ObjectClassBroadcastList *ocbList = NULL ;    if (server != NULL) {        D.Out(pdRegister,              "Object %u deleted in class %u, now broadcasting...",              theObjectHandle, handle);        NetworkMessage *answer = new NetworkMessage ;        answer->type = m_REMOVE_OBJECT ;        answer->federation = server->federation();        answer->federate = theFederateHandle ;        answer->exception = e_NO_EXCEPTION ;        answer->objectClass = handle ; // Class Handle        answer->object = theObjectHandle ;        strcpy(answer->label, theUserTag);        ocbList = new ObjectClassBroadcastList(answer, 0);        broadcastClassMessage(ocbList);    }    else {        D.Out(pdRegister,              "Object %u deleted in class %u, no broadcast to do.",              theObjectHandle, handle);    }    // Return the BroadcastList in case it had to be passed to the parent    // class.    return ocbList ;}// ----------------------------------------------------------------------------//! Print the ObjectClasses tree to the standard output.void ObjectClass::display(void) const{    cout << " ObjectClass #" << handle << " \"" << Name << "\":" << endl ;    // Display inheritance    cout << " Parent Class Handle: " << Father << endl ;    cout << " Security Level: " << LevelID << endl ;    cout << " " << sonSet.size() << " Child(s):" << endl ;    list<ObjectClassHandle>::const_iterator s = sonSet.begin();    for (int i = 1 ; s != sonSet.end(); s++, i++) {        cout << " Son " << i << " handle: "<< (*s) << endl ;    }    // Display Attributes    cout << " " << attributeSet.size() << " Attribute(s):" << endl ;    list<ObjectClassAttribute *>::const_iterator a ;    for (a = attributeSet.begin(); a != attributeSet.end(); a++) {        (*a)->display();    }    // Display Instances    cout << " " << objectSet.size() << " Instances(s):" << endl ;    list<Object *>::const_iterator o ;    for (o = objectSet.begin(); o != objectSet.end(); o++) {        (*o)->display();    }}// ----------------------------------------------------------------------------//! getAttributeHandle.AttributeHandleObjectClass::getAttributeHandle(const char *the_name) const    throw (AttributeNotDefined,           RTIinternalError){    list<ObjectClassAttribute *>::const_iterator a ;    for (a = attributeSet.begin(); a != attributeSet.end(); a++) {        if (strcmp((*a)->getName(), the_name) == 0)            return (*a)->getHandle();    }    D.Out(pdExcept, "ObjectClass %u: Attribute \"%s\" not defined.",          handle, the_name);    throw AttributeNotDefined();}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?