Beispiel #1
0
void MpCodecFactory::freeAllLoadedLibsAndCodec()
{
   OsSharedLibMgrBase* pShrMgr = OsSharedLibMgr::getOsSharedLibMgr();

   UtlHashBagIterator iter(mCodecsInfo);
   MpCodecSubInfo* pinfo;

   UtlHashBag libLoaded;
   UtlString* libName;

   while ((pinfo = (MpCodecSubInfo*)iter()))
   {  
      if ((!pinfo->getCodecCall()->isStatic()) && 
         (!libLoaded.find(&pinfo->getCodecCall()->getModuleName()))) {
         libLoaded.insert(const_cast<UtlString*>(&pinfo->getCodecCall()->getModuleName()));
      }    
   }

   UtlHashBagIterator iter2(libLoaded);
   while ((libName = (UtlString*)iter2()))
   {
      pShrMgr->unloadSharedLib(libName->data());
   }

   iter.reset();
   while ((pinfo = (MpCodecSubInfo*)iter()))
   {  
      if (!pinfo->getCodecCall()->isStatic()) {
         mCodecsInfo.remove(pinfo);
         delete pinfo;         
      }
   }

   mCodecInfoCacheValid = FALSE;
}
Beispiel #2
0
int MpTopologyGraph::addVirtualOutputs(MpResourceTopology& resourceTopology,
                                       UtlHashBag& newResources,
                                       UtlBoolean replaceNumInName,
                                       int resourceNum)
{
   int portsAdded = 0;
   MpResourceTopology::VirtualPortIterator portIter;
   UtlString realResourceName;
   int realPortIdx;
   UtlString virtualResourceName;
   int virtualPortIdx;

   resourceTopology.initVirtualOutputIterator(portIter);
   while (resourceTopology.getNextVirtualOutput(portIter,
                                                realResourceName, realPortIdx,
                                                virtualResourceName, virtualPortIdx)
          == OS_SUCCESS)
   {
      if(replaceNumInName)
      {
         MpResourceTopology::replaceNumInName(realResourceName, resourceNum);
         MpResourceTopology::replaceNumInName(virtualResourceName, resourceNum);
      }

      // Lookup real resource.
      MpResource *pResource = (MpResource*)newResources.find(&realResourceName);
      assert(pResource);
      if (!pResource)
      {
         continue;
      }

      // Check port index correctness. Note, that this check gracefully
      // handles case with realPortIdx equal -1.
      if (realPortIdx >= pResource->maxOutputs())
      {
         assert(!"Trying to map virtual port to non existing real port!");
         continue;
      }

      // Add entry to virtual ports map.
      // We need to create UtlVoidPtr wrapper for pResource, or it will be
      // destroyed on pair deletion.
      UtlContainablePair *pRealPort = new UtlContainablePair(new UtlVoidPtr(pResource),
                                                             new UtlInt(realPortIdx));
      UtlContainablePair *pVirtPort = new UtlContainablePair(new UtlString(virtualResourceName),
                                                             new UtlInt(virtualPortIdx));
      mVirtualOutputs.insertKeyAndValue(pVirtPort, pRealPort);
      portsAdded++;
   }
   resourceTopology.freeVirtualOutputIterator(portIter);

   return portsAdded;
}
Beispiel #3
0
   void testRemoveReference()
      {
         // the following two entries collide if the initial bucket size is 16
         UtlInt int1(1);
         UtlInt int16(16);

         UtlInt int2a(2);
         UtlInt int2b(2);
         UtlInt int3(3);

         UtlHashBag bag;

         CPPUNIT_ASSERT( bag.numberOfBuckets() == 16 ); // check assumption of collision

         // Load all the test objects
         CPPUNIT_ASSERT( bag.insert(&int1) == &int1 );
         CPPUNIT_ASSERT( bag.insert(&int16) == &int16 );
         CPPUNIT_ASSERT( bag.insert(&int2a) == &int2a );
         CPPUNIT_ASSERT( bag.insert(&int2b) == &int2b );
         CPPUNIT_ASSERT( bag.insert(&int3) == &int3 );

         // Check that everything is there
         CPPUNIT_ASSERT( bag.entries() == 5 );
         CPPUNIT_ASSERT( bag.contains(&int1) );
         CPPUNIT_ASSERT( bag.contains(&int16) );
         CPPUNIT_ASSERT( bag.contains(&int2a) ); // cannot test for 2a and 2b independently
         CPPUNIT_ASSERT( bag.contains(&int3) );

         // Take entry 1 out (might collide w/ 16)
         CPPUNIT_ASSERT( bag.removeReference(&int1) == &int1 );

         // Check that everything except entry 1 is still there, and that 1 is gone
         CPPUNIT_ASSERT( bag.entries() == 4 );
         CPPUNIT_ASSERT( ! bag.contains(&int1) );
         CPPUNIT_ASSERT( bag.contains(&int16) );
         CPPUNIT_ASSERT( bag.contains(&int2a) );// cannot test for 2a and 2b independently
         CPPUNIT_ASSERT( bag.contains(&int3) );

         // Put entry 1 back in (so that 16 will collide w/ it again)
         CPPUNIT_ASSERT( bag.insert(&int1) == &int1 );

         // Check that everything is there
         CPPUNIT_ASSERT( bag.entries() == 5 );
         CPPUNIT_ASSERT( bag.contains(&int1) );
         CPPUNIT_ASSERT( bag.contains(&int16) );
         CPPUNIT_ASSERT( bag.contains(&int2a) );
         CPPUNIT_ASSERT( bag.contains(&int3) );

         // Take entry 16 out (might collide w/ 1)
         CPPUNIT_ASSERT( bag.removeReference(&int16) == &int16 );

         // Check that everything except entry 16 is still there, and that 16 is gone
         CPPUNIT_ASSERT( bag.entries() == 4 );
         CPPUNIT_ASSERT( bag.contains(&int1) );
         CPPUNIT_ASSERT( ! bag.contains(&int16) );
         CPPUNIT_ASSERT( bag.contains(&int2a) );// cannot test for 2a and 2b independently
         CPPUNIT_ASSERT( bag.contains(&int3) );

         // remove 2a (and ensure that you don't get back 2b)
         CPPUNIT_ASSERT( bag.removeReference(&int2a) == &int2a );

         // Check that everything that should be is still there
         CPPUNIT_ASSERT( bag.entries() == 3 );
         CPPUNIT_ASSERT( bag.contains(&int1) );
         CPPUNIT_ASSERT( ! bag.contains(&int16) );
         CPPUNIT_ASSERT( bag.find(&int2a) == &int2b ); // equal values, but now there's only one
         CPPUNIT_ASSERT( bag.contains(&int3) );

         // remove 3 (no collision for this one)
         CPPUNIT_ASSERT( bag.removeReference(&int3) == &int3 );

         // Check that everything that should be is still there
         CPPUNIT_ASSERT( bag.entries() == 2 );
         CPPUNIT_ASSERT( bag.contains(&int1) );
         CPPUNIT_ASSERT( ! bag.contains(&int16) );
         CPPUNIT_ASSERT( bag.find(&int2a) == &int2b ); // equal values, but now there's only one
         CPPUNIT_ASSERT( ! bag.contains(&int3) );

         // remove 3 again - should fail this time
         CPPUNIT_ASSERT( bag.removeReference(&int3) == NULL );

         // Check that everything that should be is still there
         CPPUNIT_ASSERT( bag.entries() == 2 );
         CPPUNIT_ASSERT( bag.contains(&int1) );
         CPPUNIT_ASSERT( ! bag.contains(&int16) );
         CPPUNIT_ASSERT( bag.find(&int2a) == &int2b ); // equal values, but now there's only one
         CPPUNIT_ASSERT( ! bag.contains(&int3) );

      }
Beispiel #4
0
    /*!a Test case to test the destroy()
    *    method.
    */
    void testRemoveAndDestroy()
    {
        const char* prefix  = "test the destroy() method " ;

        // The ContainableTestStub has been implemented such that a static
        // counter is incremented everytime an instance is created and
        // the counter is decremented everytime an instance is destroyed.
        UtlContainableTestStub* uStub = new UtlContainableTestStub(0) ;
        UtlContainableTestStub* uStubPtr = new UtlContainableTestStub(101) ;
        commonList.insert(uStub) ;
        commonList.insert(uStubPtr) ;

        string msg ;
        int cCountBefore = UtlContainableTestStub :: getCount() ;
        UtlBoolean retValue = commonList.destroy(uStubPtr) ;
        int cCountAfter  ;
        uStubPtr = NULL ;
        TestUtilities::createMessage(2, &msg, prefix, ":- Verify the return value") ;
        CPPUNIT_ASSERT_MESSAGE(msg.data(), retValue) ;

        // To verify that the object was destroyed, check to see if the static count has been
        // decremented. If yes, it means that the destructor was called.
        cCountAfter = UtlContainableTestStub :: getCount() ;
        TestUtilities::createMessage(2, &msg, prefix, ":- Verify that the object was deleted") ;
        CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.data(), cCountBefore -1, cCountAfter) ;

        // THe way to verify if the object has been removed is to
        // create a new stub such that it has the same value as
        // the removed stub. Try to find the new stub
        UtlContainableTestStub uStubNew(101) ;
        UtlContainable* uSearch = commonList.find(&uStubNew) ;
        TestUtilities::createMessage(2, &msg, prefix, ":- Verify that the entry is removed") ;
        CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.data(), (void*)NULL, (void*)uSearch) ;

        // Now test the case when you have added multiple deletable keys
        // and the first key inserted is deleted first.
        UtlContainableTestStub* uStubPtr2 = new UtlContainableTestStub(201) ;
        UtlContainableTestStub* uStubPtr3 = new UtlContainableTestStub(201) ;
        commonList.insert(uStubPtr2) ;
        commonList.insert(uStubPtr3) ;
        UtlInt uTestInt(2031) ;
        commonList.insert(&uTestInt) ;
        // after destroying, either uStubPtr or uStubPtr3 might have gotten deleted and
        // we have no way to find out which one. So create a new ContainableTestStub
        // and use that for search
        UtlContainableTestStub uStubTemp(201) ;


        cCountBefore = UtlContainableTestStub :: getCount() ;
        commonList.destroy(&uStubTemp) ;
        cCountAfter = UtlContainableTestStub :: getCount() ;

        uSearch = commonList.find(&uStubTemp) ;
        const char*  msgTemp = "Verify that doing a removeAndDestroy on " \
             "an item that has multiple matches removes only one entry " ;
        TestUtilities::createMessage(2, &msg, msgTemp, " :- Verify value is still found") ;
        CPPUNIT_ASSERT_MESSAGE("Verify that doing a removeAndDestroy on " \
             "an item that has multiple matches removes only one entry", \
             uSearch == uStubPtr2 || uSearch == uStubPtr3) ;
        TestUtilities::createMessage(2, &msg, msgTemp, " :- Verify value *was* destroyed") ;
        CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.data(), cCountBefore -1, cCountAfter) ;

        msgTemp = "Verify that the remaining entry can also be deleted" ;
        cCountBefore = UtlContainableTestStub :: getCount() ;
        commonList.destroy(&uStubTemp) ;
        cCountAfter = UtlContainableTestStub :: getCount() ;
        TestUtilities::createMessage(2, &msg, msgTemp, " :- Verify value *was* destroyed") ;
        CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.data(), cCountBefore -1, cCountAfter) ;

        // In all the above tests, a total of 5 entries were added
       // and 3 were removed.
        int finalCount = commonEntriesCount + 2 ;
        msgTemp = "Verify that the HashTable stil has the other entries" ;
        CPPUNIT_ASSERT_EQUAL_MESSAGE(msgTemp, finalCount, (int)commonList.entries()) ;
    }
Beispiel #5
0
    void utlTestFind_And_Contains(FindOrContains type)
    {
        const int testCount = 7 ;
        const char* prefixFind = "Test the find() method when the match " ;
        const char* prefixContains = "Test the contains() method when the match " ;
        const char* Msgs[] = { \
               "is the first element ", \
               "is the last element ", \
               "is a mid element (unique match) ", \
               "has two value matches but a single ref match ", \
               "has two ref matches", \
               "has a value match but no ref match", \
               "has no match at all" \
        } ;

       // insert two elements to satisfy (d) and (e)
       commonList.insert( commonContainables_Clone[4]) ;
       commonList.insert( commonContainables[3]) ;

       UtlString noExist("This cannot and should not exist!!!") ;

       UtlContainable* searchValues[] = { \
                 commonContainables[0], commonContainables[5], commonContainables[2], \
                 commonContainables[4], commonContainables[3], \
                 commonContainables_Clone[2], &noExist \
       } ;

       bool expectedValues_Contains[]    = {true, true, true, true, true, true, false } ;

       UtlContainable* searchValuesForFind[] = { \
                 commonContainables[0], commonContainables[5], commonContainables[2], \
                 commonContainables[4], commonContainables[3], \
                 commonContainables_Clone[1], &noExist \
       } ;

       // In case of the hashtable, searching for a key can return *ANY* of the values
       // that matches and we dont care about which one. so we need two set of expected values
       UtlContainable* expValues_Find[][2] = { \
                 {commonContainables[0], commonContainables[0]}, \
                 {commonContainables[5], commonContainables[2]}, \
                 {commonContainables[2], commonContainables[2]}, \
                 {commonContainables_Clone[4], commonContainables[4]}, \
                 {commonContainables[3], commonContainables[3]}, \
                 {commonContainables[1], commonContainables[1]}, \
                 {NULL, NULL} \
       } ;

       for (int i = 0 ; i < testCount ; i++)
       {
           string msg ;
           if (type == TEST_FIND)
           {
               bool isFound = false ;
               UtlContainable* act = commonList.find(searchValuesForFind[i]) ;
               // If we are expecting either 'A' or 'B' for the search
               isFound = (act == expValues_Find[i][0]) || (act == expValues_Find[i][1]) ;
               TestUtilities::createMessage(2, &msg, prefixFind, Msgs[i]) ;
               CPPUNIT_ASSERT_MESSAGE(msg.data(), isFound) ;
           }
           else if (type == TEST_CONTAINS)
           {
               UtlBoolean act = commonList.contains(searchValues[i]) ;
               UtlBoolean exp = (UtlBoolean)expectedValues_Contains[i] ;
               TestUtilities::createMessage(2, &msg, prefixContains, Msgs[i]) ;
               CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.data(), exp, act) ;
           }
       }

    }//utlTestIndex
Beispiel #6
0
    /*a! Test the insert method for a list that is not empty. Add both unique and non-unique entries.
    *
    *    The test data for this test is :-
    *      a) Add a new UtlInt
    *      b) Add a new UtlString
    *      c) Add a new UtlVoidPtr
    *      d) Add a new Containable such that a similar one (value match) exists already
    *      e) Add a new Containable such that the same one (reference match) exists already
    */
    void testInsert()
    {
        struct testInsertStructure
        {
            const char* testDescription ;
            UtlContainable* itemToAdd ;
            UtlContainable* expectedReturnValue ;
            // In case of the hashtable, searching for a key can return *ANY* of the values
            // that matches and we dont care about which one. so we need two set of expected values
            UtlContainable* expectedFoundValue ;
            UtlContainable* altExpectedFoundValue ;
        } ;
        const char* prefix = "Test the insert(UtlContainable*) method for a non empty HashTable " ;
        const char* suffix1 = " :- Verify return value" ;
        const char* suffix2 = " :- Verify that the value is inserted" ;
        const char* suffix3 = " :- Verify that the number of entries is incremented by one" ;

        UtlInt uInt = UtlInt(1234) ;
        UtlString uString = UtlString("Test String") ;
        UtlVoidPtr uVoidPtr((char*)"Hello world") ;

        testInsertStructure testData[] = { \
            { "Add a new UtlInt ", &uInt, &uInt, &uInt, &uInt}, \
            { "Add a new UtlString ", &uString, &uString, &uString, &uString}, \
            { "Add a new UtlVoidPtr ", &uVoidPtr, &uVoidPtr, &uVoidPtr, &uVoidPtr}, \
            { "Add a Containable such that an identical one(value match) " \
              "exists in the table ", commonContainables_Clone[3], commonContainables_Clone[3], \
              commonContainables[3], commonContainables_Clone[3] }, \
            { "Add a Containable such that an exact duplicate " \
              "(including reference match) exists in the table ", commonContainables[4],
              commonContainables[4], commonContainables[4] } \
        } ;

        int expCount  = commonEntriesCount;

        string msg ;
        UtlContainable* uAct ;
        UtlContainable* uReturn ;
        /* :TODO: this part of the test is in error.
         *    when there is more than one of the same value in the bage,
         *    the find() method may return any of the objects with that value.
         */
        int testCount = sizeof(testData)/sizeof(testData[0]) ;
        for (int i = 0 ; i < testCount ; i++)
        {
            uReturn = commonList.insert(testData[i].itemToAdd) ;
            expCount++ ;
            uAct = commonList.find(testData[i].itemToAdd) ;
            TestUtilities::createMessage(3, &msg, prefix, \
                 testData[i].testDescription, suffix1) ;
            CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.data(), \
                testData[i].expectedReturnValue, uReturn) ;

            // when there is more than one of the same value in the bag,
            // the find() method may return any of the objects with that value.
            bool isFound = (uAct == testData[i].expectedFoundValue) || \
                 (uAct == testData[i].altExpectedFoundValue) ;
            TestUtilities::createMessage(3, &msg, prefix, \
                testData[i].testDescription, suffix2) ;
            CPPUNIT_ASSERT_MESSAGE(msg.data(), isFound) ;
            TestUtilities::createMessage(3, &msg, prefix, \
                testData[i].testDescription, suffix3) ;
            CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.data(), expCount, (int)commonList.entries()) ;
        }
    } //testInsert
Beispiel #7
0
int MpTopologyGraph::linkTopologyResources(MpResourceTopology& resourceTopology,
                                           UtlHashBag& newResources,
                                           UtlBoolean replaceNumInName,
                                           int resourceNum)
{
    // Link the resources
    int connectionIndex = 0;
    UtlString outputResourceName;
    UtlString inputResourceName;
    int outputResourcePortIndex;
    int inputResourcePortIndex;
    MpResource* outputResource = NULL;
    MpResource* inputResource = NULL;
    OsStatus result;
    UtlHashMap newConnectionIds;

#ifdef TEST_PRINT
    osPrintf("%d new resources in the list\n", newResources.entries());
    UtlHashBagIterator iterator(newResources);
    MpResource* containerResource = NULL;
    while(containerResource = (MpResource*) iterator())
    {
        osPrintf("found list resource: \"%s\" value: \"%s\"\n",
                 containerResource->getName().data(), containerResource->data());
    }
#endif

    while(resourceTopology.getConnection(connectionIndex,
                                         outputResourceName,
                                         outputResourcePortIndex,
                                         inputResourceName,
                                         inputResourcePortIndex) == OS_SUCCESS)
    {
        if(replaceNumInName)
        {
            resourceTopology.replaceNumInName(outputResourceName, resourceNum);
            resourceTopology.replaceNumInName(inputResourceName, resourceNum);
        }

        // Look in the container of new resources first as this is more 
        // efficient and new resources are not added immediately to a running
        // flowgraph
        outputResource = (MpResource*) newResources.find(&outputResourceName);
        if(outputResource == NULL)
        {
            result = lookupResource(outputResourceName, outputResource);
            if(result != OS_SUCCESS)
            {
                int virtPortIdx = outputResourcePortIndex>=0?outputResourcePortIndex:-1;
                int realPortIdx;
                result = lookupVirtualOutput(outputResourceName, virtPortIdx,
                                             outputResource, realPortIdx);
                if (result == OS_SUCCESS && outputResourcePortIndex>=0)
                {
                   outputResourcePortIndex = realPortIdx;
                }
            }
            assert(result == OS_SUCCESS);
        }
        inputResource = (MpResource*) newResources.find(&inputResourceName);
        if(inputResource == NULL)
        {
            result = lookupResource(inputResourceName, inputResource);
            if(result != OS_SUCCESS)
            {
                int virtPortIdx = inputResourcePortIndex>=0?inputResourcePortIndex:-1;
                int realPortIdx;
                result = lookupVirtualInput(inputResourceName, virtPortIdx,
                                            inputResource, realPortIdx);
                if (result == OS_SUCCESS && inputResourcePortIndex>=0)
                {
                   inputResourcePortIndex = realPortIdx;
                }
            }
            assert(result == OS_SUCCESS);
        }
        assert(outputResource);
        assert(inputResource);

        if(outputResource && inputResource)
        {
            if(outputResourcePortIndex == MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT)
            {
                outputResourcePortIndex = outputResource->reserveFirstUnconnectedOutput();
                assert(outputResourcePortIndex >= 0);
            }
            else if(outputResourcePortIndex < MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT)
            {
                // First see if a real port is already in the dictionary
                UtlInt searchKey(outputResourcePortIndex);
                UtlInt* foundValue = NULL;
                if((foundValue = (UtlInt*) newConnectionIds.findValue(&searchKey)))
                {
                    // Use the mapped index
                    outputResourcePortIndex = foundValue->getValue();
                }
                else
                {
                    // Find an available port and add it to the map
                    int realPortNum = outputResource->reserveFirstUnconnectedOutput();
                    assert(realPortNum >= 0);
                    UtlInt* portKey = new UtlInt(outputResourcePortIndex);
                    UtlInt* portValue = new UtlInt(realPortNum);
                    newConnectionIds.insertKeyAndValue(portKey, portValue);
                    outputResourcePortIndex = realPortNum;
                }
            }

            if(inputResourcePortIndex == MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT)
            {
                inputResourcePortIndex = inputResource->reserveFirstUnconnectedInput();
                assert(inputResourcePortIndex >= 0);
            }
            else if(inputResourcePortIndex < MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT)
            {
                // First see if a real port is already in the dictionary
                UtlInt searchKey(inputResourcePortIndex);
                UtlInt* foundValue = NULL;
                if((foundValue = (UtlInt*) newConnectionIds.findValue(&searchKey)))
                {
                    // Use the mapped index
                    inputResourcePortIndex = foundValue->getValue();
                }
                else
                {
                    // Find an available port and add it to the map
                    int realPortNum = inputResource->reserveFirstUnconnectedInput();
                    assert(realPortNum >= 0);
                    UtlInt* portKey = new UtlInt(inputResourcePortIndex);
                    UtlInt* portValue = new UtlInt(realPortNum);
                    newConnectionIds.insertKeyAndValue(portKey, portValue);
                    inputResourcePortIndex = realPortNum;
                }
            }


            result = addLink(*outputResource, outputResourcePortIndex, *inputResource, inputResourcePortIndex);
            assert(result == OS_SUCCESS);
        }
        connectionIndex++;
    }

    newConnectionIds.destroyAll();
    return(connectionIndex);
}
void SipPublishContentMgr::getPublished(const char* resourceId,
                                        const char* eventTypeKey,
                                        UtlBoolean fullState,
                                        int& numContentTypes,
                                        HttpBody**& eventContent,
                                        SipPublishContentMgrDefaultConstructor**
                                        pDefaultConstructor)
{
    // Construct the key to look up.
    UtlString key;
    key.append(resourceId);
    key.append(CONTENT_KEY_SEPARATOR);
    key.append(eventTypeKey);

    lock();

    // Look up the key in the specific or default entries, as appropriate.
    UtlHashBag* bag = 
       resourceId ?
       (fullState ? &mContentEntries : &mPartialContentEntries) :
       (fullState ? &mDefaultContentEntries : &mDefaultPartialContentEntries);
    PublishContentContainer* container =
       dynamic_cast <PublishContentContainer*> (bag->find(&key));

    // If not found, return zero versions.
    if (container == NULL)
    {
       numContentTypes = 0;
       eventContent = new HttpBody*[0];
    }
    // Content for this event type exists.
    else
    {
        int num = container->mEventContent.entries();
        numContentTypes = num;

        HttpBody** contentCopies = new HttpBody*[num];
        eventContent = contentCopies;

        // Copy the contents into the array.
        for (int index = 0; index < num; index++)
        {
           eventContent[index] =
              new HttpBody(*dynamic_cast <HttpBody*>
                            (container->mEventContent.at(index)));
        }
    }

    // Return the default constructor, if any.
    if (pDefaultConstructor && !resourceId)
    {
       UtlContainable* defaultConstructor =
          (fullState ?
           mDefaultContentConstructors :
           mDefaultPartialContentConstructors).findValue(&key);
       *pDefaultConstructor =
          // Is there a default constructor?
          defaultConstructor ?
          // If so, make a copy of the constructor and return pointer to it.
          (dynamic_cast <SipPublishContentMgrDefaultConstructor*>
           (defaultConstructor))->copy() :
          // Otherwise, return NULL.
          NULL;
    }

    unlock();

    return;
}
UtlBoolean SipPublishContentMgr::getContent(const char* resourceId,
                                            const char* eventTypeKey,
                                            const char* eventType,
                                            UtlBoolean fullState,
                                            const UtlString& acceptHeaderValue,
                                            HttpBody*& content,
                                            UtlBoolean& isDefaultContent,
                                            UtlString* availableMediaTypes)
{
    UtlBoolean foundContent = FALSE;
    PublishContentContainer* container = NULL;
    isDefaultContent = FALSE;

    UtlString key;
    key.append(resourceId);
    key.append(CONTENT_KEY_SEPARATOR);
    key.append(eventTypeKey);

    lock();

    UtlHashBag* pContent;
    if (fullState)
    {
       // Full content (this is the usual case)
       pContent = &mContentEntries;
    }
    else
    {
       // Partial content (used for partial dialog events)
       pContent = &mPartialContentEntries;
    }

    // See if resource-specific content exists
    container =
        dynamic_cast <PublishContentContainer*> (pContent->find(&key));

    // There is no resource-specific content.  Check if the default
    // constructor exists.
    if (container == NULL)
    {
       // Construct the key for the default data.
       UtlString default_key;
       default_key.append(CONTENT_KEY_SEPARATOR);
       default_key.append(eventTypeKey);

       // Look up the constructor.

       UtlHashMap* pDefaultConstructors;
       if (fullState)
       {
          // Full content (this is the usual case)
          pDefaultConstructors = &mDefaultContentConstructors;
       }
       else
       {
          // Partial content (used for partial dialog events)
          pDefaultConstructors = &mDefaultPartialContentConstructors;
       }
       SipPublishContentMgrDefaultConstructor* constructor =
          dynamic_cast <SipPublishContentMgrDefaultConstructor*>
          (pDefaultConstructors->findValue(&default_key));
       // If it exists, call it to publish content for this resource/event.
       if (constructor)
       {
          constructor->generateDefaultContent(this, resourceId,
                                              eventTypeKey, eventType);
       }

       // See if resource-specific content exists now.
       container =
          dynamic_cast <PublishContentContainer*> (pContent->find(&key));

       // If content was found, still mark it as default content.
       if (container)
       {
               isDefaultContent = TRUE;
       }
       // If still no content was found, check if (fixed) default content exists.
       else
       {
           container =
              dynamic_cast <PublishContentContainer*>
              (mDefaultContentEntries.find(&default_key));
           if(container)
           {
               isDefaultContent = TRUE;
           }
       }
    }

    // Within the container, choose the correct content.
    if (container)
    {
        if (acceptHeaderValue.compareTo(acceptAllTypes) != 0)
        {
           // Search for the first content in the container whose
           // MIME type is in the acceptable list.
           UtlSListIterator contentIterator(container->mEventContent);
           HttpBody* bodyPtr;
           while (!foundContent &&
                  (bodyPtr = dynamic_cast <HttpBody*> (contentIterator())))
           {
              // Trim any parameters off the body content type.
              UtlString* content_type = bodyPtr;
              UtlString base_content_type(*content_type);
              ssize_t i = base_content_type.index(';');
              if (i != UTL_NOT_FOUND)
              {
                 base_content_type.remove(i);
              }
              
              // See if base_content_type is in acceptHeaderValue.
              if (acceptHeaderValue.findToken(base_content_type.data(), ",", ";"))
              {
                 // If base_content_type is "multipart/related", extract
                 // the 'type' parameter value, which is the type of the
                 // root component, and check whether it is in acceptHeaderValue.
                 ssize_t j;
                 if (base_content_type.compareTo("multipart/related",
                                                 UtlString::ignoreCase) == 0)
                 {
                    // Search for the 'type' parameter.
                    i = content_type->index(";type=", UtlString::ignoreCase);
                    if (i != UTL_NOT_FOUND)
                    {
                       // Advance i to point to the value.
                       i += sizeof (";type=") - 1;
                       if ((*content_type)(i) == '\"')
                       {
                          // Value is quoted.
                          // Advance i to point to the value proper.
                          i++;
                          // Find the closing double-quote.
                          j = content_type->index('\"', i);
                          if (j == UTL_NOT_FOUND)
                          {
                             // This shouldn't happen.
                             Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                                           "SipPublishContentMgr::getContent "
                                           "No closing double-quote found for 'type' parameter in body MIME type '%s'",
                                           content_type->data());
                             // j == UTL_NOT_FOUND indicates failure.
                          }
                       }
                       else
                       {
                          // Value is not quoted.
                          // Find the end of the parameter.
                          j = content_type->index(';', i);
                          if (j == UTL_NOT_FOUND)
                          {
                             j = content_type->length();
                          }
                       }
                       if (j != UTL_NOT_FOUND)
                       {
                          // Characters from i to j are the type parameter value.
                          UtlString base_root_type;
                          base_root_type.append(*content_type, i, j - i);
                          // Remove parameters from base_root_type.
                          ssize_t k = base_content_type.index(';');
                          if (k != UTL_NOT_FOUND)
                          {
                             base_content_type.remove(k);
                          }
                          // See if base_root_type is in acceptHeaderValue.
                          if (acceptHeaderValue.findToken(base_root_type.data(), ",", ";"))
                          {
                             // Having passed all the tests, this content is OK.
                             foundContent = true;
                          }
                       }              
                    }
                    else
                    {
                       Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                                     "SipPublishContentMgr::getContent "
                                     "No 'type' parameter in body MIME type '%s'",
                                     content_type->data());
                    }
                 }
                 else
                 {
                    // If base_content_type is not multipart/related,
                    // we can accept the content with no further tests.
                    foundContent = true;
                 }

                 // If this content is acceptable, copy it into 'content'.
                 // Because foundContent is true, the loop will exit.
                 if (foundContent)
                 {
                    content = bodyPtr->copy();
                 }
              }
           }
           if (!foundContent)
           {
              // No content was found that matched the allowed MIME types.
              Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                            "SipPublishContentMgr::getContent no acceptable content found for key '%s', acceptHeaderValue '%s', resourceId '%s', eventTypeKey ='%s', eventType '%s'",
                            key.data(),
                            acceptHeaderValue.data(),
                            resourceId ? resourceId : "[none]",
                            eventTypeKey, eventType);
              if (availableMediaTypes)
              {
                 // Construct the list of available MIME types.
                 availableMediaTypes->remove(0);
                 contentIterator.reset();
                 while ((bodyPtr = dynamic_cast <HttpBody*> (contentIterator())))
                 {
                    if (!availableMediaTypes->isNull())
                    {
                       availableMediaTypes->append(',');
                    }
                    availableMediaTypes->append(static_cast <UtlString&> (*bodyPtr));
                 }
              }
           }
        }
        else
        {
           // No MIME types were specified, take the first content in the list.
           // (which should exist)
           HttpBody* bodyPtr =
              dynamic_cast <HttpBody*> (container->mEventContent.first());
           if (bodyPtr)
           {
              content = bodyPtr->copy();
              foundContent = TRUE;
           }
           else
           {
              // No content was found (at all).
              // Set *availableMediaTypes.
              if (availableMediaTypes)
              {
                 availableMediaTypes->remove(0);
              }
              Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                            "SipPublishContentMgr::getContent no content found for key '%s', resourceId '%s', eventTypeKey ='%s', eventType '%s' - publish() must have been called with numContentTypes==0",
                            key.data(),
                            resourceId ? resourceId : "[none]",
                            eventTypeKey, eventType);
           }
        }
    }
    else
    {
       // No container found for this resource and event.
       // Set *availableMediaTypes.
       if (availableMediaTypes)
       {
          availableMediaTypes->remove(0);
       }
       Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                     "SipPublishContentMgr::getContent no container found for key '%s', acceptHeaderValue '%s', resourceId '%s', eventTypeKey ='%s', eventType '%s', fullState = %d",
                     key.data(),
                     acceptHeaderValue.data(),
                     resourceId ? resourceId : "[none]",
                     eventTypeKey, eventType,
                     fullState);
    }

    unlock();

    return foundContent;
}
void SipPublishContentMgr::publish(const char* resourceId,
                                   const char* eventTypeKey,
                                   const char* eventType,
                                   int numContentTypes,
                                   HttpBody* eventContent[],
                                   UtlBoolean fullState,
                                   UtlBoolean noNotify)
{
    Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                  "SipPublishContentMgr::publish resourceId '%s', eventTypeKey '%s', eventType '%s', numContentTypes %d, noNotify %d, fullState %d",
                  resourceId ? resourceId : "(null)",
                  eventTypeKey, eventType, numContentTypes, noNotify, fullState);

    if (numContentTypes < 1)
    {
       Os::Logger::instance().log(FAC_SIP, PRI_ERR,
                     "SipPublishContentMgr::publish "
                     "No content bodies supplied for resourceId '%s', "
                     "eventTypeKey '%s', fullState %d",
                     resourceId? resourceId : "(null)",
                     eventTypeKey, fullState);
       
    }

    // Construct the key to look up.
    UtlString key;
    key.append(resourceId);
    key.append(CONTENT_KEY_SEPARATOR);
    key.append(eventTypeKey);

    lock();

    // Determine the storage we will be using.
    UtlHashBag* pContent;
    // resourceId can be NULL if we are called from ::publishDefault()
    if (resourceId)
    {
       if (fullState)
       {
          // Full dialog events
          pContent = &mContentEntries;
       }
       else
       {
          // Partial dialog events
          pContent = &mPartialContentEntries;
       }
    }
    else
    {
       // Default dialog events
       if (fullState)
       {
          pContent = &mDefaultContentEntries;
       }
       else
       {
          pContent = &mDefaultPartialContentEntries;
       }
    }

    // Look up the key in the specific or default entries, as appropriate.
    PublishContentContainer* container =
       dynamic_cast <PublishContentContainer*> (pContent->find(&key));

    // If not found, create a container.
    if (container == NULL)
    {
        container = new PublishContentContainer(key);
	// Save the container in the appropriate hash.
        pContent->insert(container);
    }
    // The content for this event type already existed
    else
    {
        // Remove the old content
        container->mEventContent.destroyAll();
    }

    // Add the new content
    for (int index = 0; index < numContentTypes; index++)
    {
        Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
            "SipPublishContentMgr::publish eventContent[%d] = %p, key = '%s', content type = '%s', getBytes() = %p '%s'",
                      index,
                      eventContent[index],
                      key.data(),
                      eventContent[index]->data(),
                      eventContent[index]->getBytes(),
                      eventContent[index]->getBytes());
        container->mEventContent.append(eventContent[index]);
    }

    // Don't call the observers if noNotify is set or if this is default content.
    if (!noNotify && resourceId)
    {
       // Call the observer for the content change, if any.
       UtlString eventTypeString(eventType);
       PublishCallbackContainer* callbackContainer =
          dynamic_cast <PublishCallbackContainer*>
          (mEventContentCallbacks.find(&eventTypeString));
       if (callbackContainer)
       {
          (callbackContainer->mpCallback)(callbackContainer->mpApplicationData,
                                          resourceId,
                                          eventTypeKey,
                                          eventTypeString,
                                          NULL);
       }
    }

    unlock();
}
Beispiel #11
0
UtlBoolean SipPublishContentMgr::getContent(const char* resourceId,
        const char* eventTypeKey,
        const char* eventType,
        const char* acceptHeaderValue,
        HttpBody*& content,
        int& version,
        UtlBoolean& isDefaultContent,
        UtlBoolean fullState)
{
    UtlBoolean foundContent = FALSE;
    UtlString key(resourceId);

    key.append(eventTypeKey);
    PublishContentContainer* container = NULL;
    isDefaultContent = FALSE;

    // Turn acceptHeaderValue into a HashBag of its components.
    // acceptedTypesGiven = FALSE if there are no components.
    UtlHashBag contentTypes;
    UtlBoolean acceptedTypesGiven =
        buildContentTypesContainer(acceptHeaderValue, contentTypes);

    lock();

    UtlHashBag* pContent;
    if (fullState)
    {
        // Full content (this is the usual case)
        pContent = &mContentEntries;
    }
    else
    {
        // Partial content (used for partial dialog events)
        pContent = &mPartialContentEntries;
    }

    // See if resource-specific content exists
    container =
        dynamic_cast <PublishContentContainer*> (pContent->find(&key));

    // There is no resource-specific content.  Check if the default
    // constructor exists.
    if (container == NULL)
    {
        // Construct the key for the default data.
        UtlString default_key(eventTypeKey);

        // Look up the constructor.

        SipPublishContentMgrDefaultConstructor* constructor =
            dynamic_cast <SipPublishContentMgrDefaultConstructor*>
            (mDefaultContentConstructors.findValue(&default_key));
        // If it exists, call it to publish content for this resource/event.
        if (constructor)
        {
            constructor->generateDefaultContent(this, resourceId,
                                                eventTypeKey, eventType);
        }

        // See if resource specific content exists now.
        container =
            dynamic_cast <PublishContentContainer*> (pContent->find(&key));

        // If content was found, still mark it as default content.
        if (container)
        {
            isDefaultContent = TRUE;
        }
        // If still no content was found, check if the default exists.
        else
        {
            container =
                dynamic_cast <PublishContentContainer*>
                (mDefaultContentEntries.find(&default_key));
            if(container)
            {
                isDefaultContent = TRUE;
            }
        }
    }

    // Within the container, find the content of the right MIME type.
    if (container)
    {
        if (acceptedTypesGiven)
        {
            UtlString base_mime_type;

            // Search for the first content in the container whose
            // MIME type is in the acceptable list.
            UtlSListIterator contentIterator(container->mEventContent);
            HttpBody* bodyPtr;
            UtlSListIterator versionIterator(container->mEventVersion);
            UtlInt* versionPtr;
            while (!foundContent &&
                    (bodyPtr = dynamic_cast <HttpBody*> (contentIterator())) &&
                    (versionPtr = dynamic_cast <UtlInt*> (versionIterator())))
            {
                // Test if ';' is present in *bodyPtr's MIME type.
                // (Remember that an HttpBody considered as a UtlString has
                // the value of its content type.)
                ssize_t i = bodyPtr->index(';');

                // The 'if expression' is TRUE if the MIME type of *bodyPtr
                // is found in in contentTypes.  This is messy, because
                // *bodyPtr's MIME type may have parameters, which have
                // to be removed before searching contentTypes.
                if (contentTypes.find(i == UTL_NOT_FOUND ?
                                      bodyPtr :
                                      ( base_mime_type.remove(0),
                                        base_mime_type.append(*bodyPtr, 0, i),
                                        &base_mime_type)))
                {
                    content = bodyPtr->copy();
                    version = versionPtr->getValue();
                    foundContent = TRUE;
                }
            }
            if (!foundContent)
            {
                // No content was found that matched the required MIME types.
                OsSysLog::add(FAC_SIP, PRI_WARNING,
                              "SipPublishContentMgr::getContent no content found for key '%s', acceptHeaderValue '%s', resourceId '%s', eventTypeKey ='%s', eventType '%s'",
                              key.data(),
                              acceptHeaderValue ? acceptHeaderValue : "[none]",
                              resourceId ? resourceId : "[none]",
                              eventTypeKey, eventType);
            }
        }
        else
        {
            // No MIME types were specified, take the first content in the list.
            HttpBody* bodyPtr =
                dynamic_cast <HttpBody*> (container->mEventContent.first());
            UtlInt* versionPtr =
                dynamic_cast <UtlInt*> (container->mEventVersion.first());
            if (bodyPtr)
            {
                content = bodyPtr->copy();
                version = versionPtr->getValue();
                foundContent = TRUE;
            }
            else
            {
                // No content was found (at all).
                OsSysLog::add(FAC_SIP, PRI_WARNING,
                              "SipPublishContentMgr::getContent no content found for key '%s', acceptHeaderValue '%s', resourceId '%s', eventTypeKey ='%s', eventType '%s'",
                              key.data(),
                              acceptHeaderValue ? acceptHeaderValue : "[none]",
                              resourceId ? resourceId : "[none]",
                              eventTypeKey, eventType);
            }
        }
    }
    else
    {
        // No container found for this resource and event.
        OsSysLog::add(FAC_SIP, PRI_WARNING,
                      "SipPublishContentMgr::getContent no container found for key '%s', acceptHeaderValue '%s', resourceId '%s', eventTypeKey ='%s', eventType '%s', fullState = %d",
                      key.data(),
                      acceptHeaderValue ? acceptHeaderValue : "[none]",
                      resourceId ? resourceId : "[none]",
                      eventTypeKey, eventType,
                      fullState);
    }

    unlock();

    contentTypes.destroyAll();
    return (foundContent);
}
Beispiel #12
0
void SipPublishContentMgr::publish(const char* resourceId,
                                   const char* eventTypeKey,
                                   const char* eventType,
                                   int numContentTypes,
                                   HttpBody* eventContent[],
                                   const int eventVersion[],
                                   UtlBoolean noNotify,
                                   UtlBoolean fullState)
{
    OsSysLog::add(FAC_SIP, PRI_DEBUG,
                  "SipPublishContentMgr::publish resourceId '%s', eventTypeKey '%s', eventType '%s', numContentTypes %d, noNotify %d, fullState %d",
                  resourceId, eventTypeKey, eventType, numContentTypes,
                  noNotify, fullState);

    UtlBoolean resourceIdProvided = resourceId && *resourceId;

    // Construct the key to look up.
    UtlString key;
    if(resourceIdProvided)
    {
        key = resourceId;
    }

    if(eventTypeKey)
    {
        key.append(eventTypeKey);
    }

    lock();

    // Determine the type of storage we will be using
    UtlHashBag* pContent;
    if (resourceIdProvided)
    {
        if (fullState)
        {
            // Full dialog events
            pContent = &mContentEntries;
        }
        else
        {
            // Partial dialog events
            pContent = &mPartialContentEntries;
        }
    }
    else
    {
        // Default dialog events
        pContent = &mDefaultContentEntries;
    }

    // Look up the key in the specific or default entries, as appropriate.
    PublishContentContainer* container =
        dynamic_cast <PublishContentContainer*> (pContent->find(&key));

    // If not found, create a container.
    if(container == NULL)
    {
        container = new PublishContentContainer();
        *((UtlString*) container) = key;
        // Save the container in the appropriate hash.
        pContent->insert(container);
    }

    // The content for this event type already existed
    else
    {
        // Remove the old content
        container->mEventContent.destroyAll();
        container->mEventVersion.destroyAll();
    }

    // Add the new content
    for (int index = 0; index < numContentTypes; index++)
    {
        OsSysLog::add(FAC_SIP, PRI_DEBUG,
                      "SipPublishContentMgr::publish eventContent[%d] = %p, key = '%s', content type = '%s', version = %d, getBytes() = %p '%s'",
                      index,
                      eventContent[index],
                      key.data(),
                      eventContent[index]->data(),
                      eventVersion[index],
                      eventContent[index]->getBytes(),
                      eventContent[index]->getBytes());
        container->mEventContent.append(eventContent[index]);
        container->mEventVersion.append(new UtlInt(eventVersion[index]));
    }

    // Don't call the observers if noNotify is set or if this is default content.
    if (!noNotify && resourceIdProvided)
    {
        // Call the observer for the content change, if any.
        UtlString eventTypeString(eventType);
        PublishCallbackContainer* callbackContainer =
            dynamic_cast <PublishCallbackContainer*>
            (mEventContentCallbacks.find(&eventTypeString));
        if(callbackContainer && callbackContainer->mpCallback)
        {
            (callbackContainer->mpCallback)(callbackContainer->mpApplicationData,
                                            resourceId,
                                            eventTypeKey,
                                            eventTypeString);
        }
    }

    unlock();
}