コード例 #1
0
ファイル: CAAFDictionaryTest.cpp プロジェクト: mcanthony/aaf
static HRESULT CreateAAFFile(
    aafWChar * pFileName,
    aafUID_constref fileKind,
    testRawStorageType_t rawStorageType,
    aafProductIdentification_constref productID)
{
  IAAFFileSP       pFile;
  IAAFHeaderSP     pHeader;
  IAAFDictionarySP pDictionary;
  IAAFMobSP        pMob;
  IAAFTimelineMobSlotSP    pMobSlot;
  IAAFSequenceSP   pSequence;
  IAAFSegmentSP    pSegment;
  IAAFComponentSP  pComponent;
  int              i;
  HRESULT          hr = S_OK;
	
	
  try
	{  
	  // Remove the previous test file if any.
	  RemoveTestFile(pFileName);
		
	  // Create the AAF file
	  checkResult(CreateTestFile( pFileName, fileKind, rawStorageType, productID, &pFile ));

	  // Get the AAF file header.
	  checkResult(pFile->GetHeader(&pHeader));

	  // Get the AAF Dictionary so that we can create valid AAF objects.
	  checkResult(pHeader->GetDictionary(&pDictionary));
		
	  // Create a new class, and register it in the dictionary.
	  RegisterNewClass (pDictionary);
	  CAAFBuiltinDefs defs (pDictionary);

	  // Create a Composition Mob
	  checkResult(defs.cdCompositionMob()->
				  CreateInstance(IID_IAAFMob, 
								 (IUnknown **)&pMob));
		
	  checkResult(pMob->SetMobID(TEST_MobID));
	  checkResult(pMob->SetName(L"AAFDictionaryTest"));
		
	  // Add mob slot w/ Sequence
	  checkResult(defs.cdSequence()->
				  CreateInstance(IID_IAAFSequence, 
								 (IUnknown **)&pSequence));		

	  checkResult(pSequence->Initialize(defs.ddkAAFPicture()));
		
	  //
	  //	Add some segments.  Need to test failure conditions
	  //	(i.e. starting/ending w/ transition, two trans back
	  //	to back).
	  //
	  for(i = 0; i < kNumComponents; i++)
		{
		  aafLength_t		len = 10;
			
		  // For the first component, make it our extended filler.
		  if(i == 0)
			{
			  IAAFClassDefSP pNewFillClassDef;
			  checkResult(pDictionary->LookupClassDef(kClassAUID_NewFill,
													  &pNewFillClassDef));
			  checkResult
				(pNewFillClassDef->CreateInstance(IID_IAAFComponent, 
												  (IUnknown**)&pComponent));
			  checkResult(pComponent->SetDataDef(defs.ddkAAFPictureWithMatte()));
			}
		  else
			{
			  checkResult
				(defs.cdFiller()->CreateInstance(IID_IAAFComponent, 
												 (IUnknown**)&pComponent));

			  checkResult(pComponent->SetDataDef(defs.ddkAAFPicture()));
			}

		  checkResult(pComponent->SetLength(len));
		  checkResult(pSequence->AppendComponent(pComponent));
			
		  // For our first component, set the 'odor' value.  Must be
		  // done after the component has been inserted in sequence.
		  if (i == 0)
			{
			  // Set the odor value.
			  //
			  // 1) Get type def for uint32
			  IAAFTypeDefSP ptd;
			  checkResult (pDictionary->LookupTypeDef (kAAFTypeID_UInt32,
													   &ptd));
			  assert (ptd);
			  IAAFTypeDefIntSP pTDUint32;
			  checkResult(ptd->QueryInterface (IID_IAAFTypeDefInt,
											   (void **)&pTDUint32));
			  assert (pTDUint32);

			  // 2) Create a property value for the odor property, and
			  //    set it to 42.
			  IAAFPropertyValueSP pVal;
			  const aafUInt32 odorValue = 42;
			  checkResult (pTDUint32->CreateValue ((aafMemPtr_t) &odorValue,
												   sizeof (odorValue),
												   &pVal));

			  // 3) Look up the property def for the odor property in
			  //    the new fill class.
			  IAAFClassDefSP pNewFillClass;
			  checkResult (pDictionary->LookupClassDef (kClassAUID_NewFill,
														&pNewFillClass));
			  IAAFPropertyDefSP pPropDef;
			  checkResult (pNewFillClass->LookupPropertyDef (kPropAUID_NewFill_Odor,
															 &pPropDef));

			  // 4) Get IAAFObject interface for new fill object, and
			  //    set the odor property.
			  IAAFObjectSP pObj;
			  checkResult(pComponent->QueryInterface (IID_IAAFObject,
													  (void **)&pObj));
			  checkResult (pObj->SetPropertyValue (pPropDef, pVal));
			}
		}

	  checkResult(pSequence->QueryInterface (IID_IAAFSegment, (void **)&pSegment));
		
	  aafRational_t editRate = { 0, 1};
	  checkResult(pMob->AppendNewTimelineSlot(editRate,
											  pSegment,
											  1,
											  L"AAF Test Sequence",
											  0,
											  &pMobSlot));
		
	  // Add the master mob to the file and cleanup
	  pHeader->AddMob(pMob);

	  checkResult (RegisterDefs (pDictionary));

	  testKLVDataDefinitions(pDictionary, pMob);
	  testTaggedDefinitions(pDictionary, pMob);

	}
  catch (HRESULT& rResult)
	{
	  hr = rResult;
	}
	
  // Cleanup and return
  if (pFile)
	{
	  pFile->Save();
	  pFile->Close();
	}
  return hr;
}
コード例 #2
0
static HRESULT WriteRecord (
    const aafWChar * pFileName,
    aafUID_constref fileKind,
    testRawStorageType_t rawStorageType,
    aafProductIdentification_constref productID)
{
  HRESULT hr = E_FAIL;
  IAAFFileSP   pFile;

  try 
	{
	  HRESULT temphr;

	  // Remove the previous test file if any.
	  RemoveTestFile(pFileName);

	  // Create the file and get the new file's header.
	  checkResult(CreateTestFile( pFileName, fileKind, rawStorageType, productID, &pFile ));
	  IAAFHeaderSP pHeader;
  	  checkResult(pFile->GetHeader(&pHeader));
	  IAAFDictionarySP pDict;
	  checkResult (pHeader->GetDictionary(&pDict));
	  CAAFBuiltinDefs defs(pDict);

	  // get the SDK version against which we are testing
      aafProductVersion_t			testVer;
      checkResult(pHeader->GetRefImplVersion(&testVer));

	  // Create, initialize, and register the Rational16 type, to
	  // consist of an Int16 numerator and a UInt16 denominator.
	  IAAFTypeDef* tdr16MemberTypes[] =
	  {defs.tdInt16(),
	   defs.tdUInt16()};
	  aafWChar numerator[] = L"Numerator";
	  aafWChar denominator[] = L"Denominator";
	  aafString_t tdr16MemberNames[] =
	  {numerator,
	   denominator};
	  IAAFTypeDefRecordSP ptdr16;
	  checkResult (pDict->
				   CreateMetaInstance (kAAFClassID_TypeDefRecord,
									   IID_IAAFTypeDefRecord,
									   (IUnknown**) &ptdr16));

	  checkResult (ptdr16->Initialize (sTypeId_Rational16,
									  tdr16MemberTypes,
									  tdr16MemberNames,
									  2,
									  L"Rational16"));

	  // check for duplicate initialization
	  temphr = ptdr16->Initialize (sTypeId_Rational16,
								  tdr16MemberTypes,
								  tdr16MemberNames,
								  2,
								  L"Rational16");
	  checkExpression (AAFRESULT_ALREADY_INITIALIZED == temphr,
					   AAFRESULT_TEST_FAILED);

	  IAAFTypeDefSP ptd;
	  checkResult (ptdr16->QueryInterface (IID_IAAFTypeDef, (void**) &ptd));
	  checkResult (pDict->RegisterTypeDef (ptd));

	  // Create, initialize, and register the Rational16Position type,
	  // to consist of a Rational16 X and Rational16 Y coordinates.

	  IAAFTypeDefRecordSP ptdr16p;
	  //checkResult (defs.cdTypeDefRecord()->
	  // CreateInstance (IID_IAAFTypeDefRecord,
	  // (IUnknown**)&ptdr16p));
	  checkResult (pDict->
				   CreateMetaInstance (kAAFClassID_TypeDefRecord,
									   IID_IAAFTypeDefRecord,
									   (IUnknown**) &ptdr16p));

	  IAAFTypeDef * pTempTd = 0;
	  checkResult (ptdr16->QueryInterface (IID_IAAFTypeDef,
										  (void**) &pTempTd));	  
	  IAAFTypeDef* tdr16pMemberTypes[] =
	  {pTempTd,
	   pTempTd};
	  aafWChar xpos[] = L"X Position";
	  aafWChar ypos[] = L"Y Position";
	  aafString_t tdr16pMemberNames[] =
	  {xpos,
	   ypos};
	  checkResult (ptdr16p->Initialize (sTypeId_Rational16_pair,
									   tdr16pMemberTypes,
									   tdr16pMemberNames,
									   2,
									   L"Rational16Pair"));
	  // check for duplicate initialization
	  temphr = ptdr16p->Initialize (sTypeId_Rational16,
								   tdr16pMemberTypes,
								   tdr16pMemberNames,
								   2,
								   L"Rational16Pair");
	  checkExpression (AAFRESULT_ALREADY_INITIALIZED == temphr,
					   AAFRESULT_TEST_FAILED);

	  pTempTd->Release ();
	  pTempTd = 0;
	  checkResult (ptdr16p->QueryInterface (IID_IAAFTypeDef, (void**) &ptd));
	  checkResult (pDict->RegisterTypeDef (ptd));

	  // Now attempt to register offsets of Rational16_pair.  This
	  // should fail, because offsets of its members (of type
	  // Rational16) have not yet been registered.
	  temphr = RegisterRational16PairOffsets (ptdr16p);
	  checkExpression (temphr == AAFRESULT_NOT_REGISTERED,
					   AAFRESULT_TEST_FAILED);

	  // Now let's attempt registration the right way.
	  checkResult (RegisterRational16Offsets (ptdr16));
	  checkResult (RegisterRational16PairOffsets (ptdr16p));

	  // register variable array of Rational16Pair records
	  IAAFTypeDefVariableArraySP ptdvaarpr;
	  IAAFTypeDefSP ptdarpr;
	  // perform this part only for specified versions
	  if( versionUInt(testVer) >= versionUInt(1,1,1,0) )
	  {
		//Create a Variable Array
		checkResult(pDict->CreateMetaInstance (AUID_AAFTypeDefVariableArray, IID_IAAFTypeDefVariableArray, (IUnknown **) &ptdvaarpr));
		
		//IAAFTypeDefVariableArray::Initialize
		checkResult(ptdvaarpr->Initialize(sTypeId_Rational16_array, ptd, L"Rational16PairArray"));
		
		//  Register our new VA type def :
		checkResult(ptdvaarpr->QueryInterface(IID_IAAFTypeDef, (void**)&ptdarpr));
		checkResult(pDict->RegisterTypeDef(ptdarpr));
	  }

	  // Create a new property on Composition mob (called Position)
	  // whose type is Rational16_pair.
	  checkResult (ptdr16p->QueryInterface (IID_IAAFTypeDef,
										   (void**) &ptd));
	  IAAFPropertyDefSP pPropDefPosA;
	  IAAFPropertyDefSP pPropDefPosB;
	  IAAFPropertyDefSP pPropDefPosC;
	  checkResult (defs.cdCompositionMob()->RegisterOptionalPropertyDef
				   (sPropertyId_positionA,
					L"PositionA",
					ptd,
					&pPropDefPosA));
	  checkResult (defs.cdCompositionMob()->RegisterOptionalPropertyDef
				   (sPropertyId_positionB,
					L"PositionB",
					ptd,
					&pPropDefPosB));
	  checkResult (defs.cdCompositionMob()->RegisterOptionalPropertyDef
				   (sPropertyId_positionC,
					L"PositionC",
					ptd,
					&pPropDefPosC));

	  // register property of type variable array of Rational16Pair records
	  IAAFPropertyDefSP pPropDefPosN;
	  // perform this part only for specified versions
	  if( versionUInt(testVer) >= versionUInt(1,1,1,0) )
	  {
		checkResult (defs.cdCompositionMob()->RegisterOptionalPropertyDef
					(sPropertyId_positionN,
						L"PositionN",
						ptdarpr,
						&pPropDefPosN));
	  }


	  // Register the Mixed_t type
	  IAAFTypeDef* tdMixedMemberTypes[] = {defs.tdInt8(), defs.tdUInt32()};
	  aafWChar str_angle[] = L"Angle";
	  aafWChar str_speed[] = L"Speed";
	  aafString_t tdMixedMemberNames[] = {str_angle, str_speed};
	  IAAFTypeDefRecordSP ptdrmixed;
	  checkResult(pDict->CreateMetaInstance(kAAFClassID_TypeDefRecord, IID_IAAFTypeDefRecord, (IUnknown**) &ptdrmixed));
	  checkResult(ptdrmixed->Initialize(sTypeId_Mixed, tdMixedMemberTypes, tdMixedMemberNames, 2, L"Mixed"));
	  //  Register Mixed type def
	  IAAFTypeDefSP ptdmixed;
	  checkResult(ptdrmixed->QueryInterface(IID_IAAFTypeDef, (void**)&ptdmixed));
	  checkResult(pDict->RegisterTypeDef(ptdmixed));
	  checkResult(RegisterMixedOffsets(ptdrmixed));
	  // Added Velocity property to Composition Mob
	  IAAFPropertyDefSP pPropDefVelocity;
	  checkResult (defs.cdCompositionMob()->RegisterOptionalPropertyDef
				   (sPropertyId_velocity,
					L"Velocity",
					ptdmixed,
					&pPropDefVelocity));


	  // Create one of our new CompositionMobs, and add a values for
	  // the Position property.
	  IAAFCompositionMobSP pcm;
	  checkResult (defs.cdCompositionMob()->
				   CreateInstance (IID_IAAFCompositionMob,
								   (IUnknown**)&pcm));

	  // Add property value for PositionA using CreateValueFromValues
	  // methods.  The constituent property values will be created
	  // from CreateValueFromStruct, and from SetValueFromStruct.

	  const Rational16_t v_12 = {1, 2};
	  const Rational16_t v_34 = {3, 4};
	  IAAFPropertyValue * pValRat[2] = { 0 };

	  checkResult (ptdr16->
				   CreateValueFromStruct ((aafMemPtr_t) &v_12,
										  sizeof (v_12),
										  &pValRat[0]));
	  // create it with wrong data, and use SetStruct to give it right
	  // data
	  checkResult (ptdr16->
				   CreateValueFromStruct ((aafMemPtr_t) &v_12,
										  sizeof (v_12),
										  &pValRat[1]));
	  checkResult (ptdr16->
				   SetStruct (pValRat[1],
							  (aafMemPtr_t) &v_34,
							  sizeof (v_34)));

	  // Create the Rational16_pair property value from the
	  // Rational16 property values.
	  IAAFPropertyValueSP pRat16PairVal_1234;
	  temphr = ptdr16p->CreateValueFromValues (0,
											  2,
											  &pRat16PairVal_1234);
	  checkExpression (AAFRESULT_NULL_PARAM == temphr,
					   AAFRESULT_TEST_FAILED);
	  temphr = ptdr16p->CreateValueFromValues (pValRat,
											  1,
											  &pRat16PairVal_1234);
	  checkExpression (AAFRESULT_ILLEGAL_VALUE == temphr,
					   AAFRESULT_TEST_FAILED);
	  checkResult (ptdr16p->CreateValueFromValues (pValRat,
												  2,
												  &pRat16PairVal_1234));
	  pValRat[0]->Release ();
	  pValRat[0] = 0;
	  pValRat[1]->Release ();
	  pValRat[1] = 0;

	  IAAFObjectSP pObj;
	  checkResult (pcm->QueryInterface (IID_IAAFObject,
										(void**) &pObj));
	  checkResult (pObj->SetPropertyValue (pPropDefPosA,
										   pRat16PairVal_1234));


	  // Add property value for PositionB using CreateValueFromStruct
	  // methods.
	  const Rational16_t r16_56 = {5, 6};
	  const Rational16_t r16_78 = {7, 8};
	  Rational16pair_t r16p_5678;
	  r16p_5678.X_Position = r16_56;
	  r16p_5678.Y_Position = r16_78;
	  IAAFPropertyValueSP pRat16PairVal_5678;
	  temphr = ptdr16p->
		CreateValueFromStruct (0,
							   sizeof (r16p_5678),
							   &pRat16PairVal_5678);
	  checkExpression (AAFRESULT_NULL_PARAM == temphr,
					   AAFRESULT_TEST_FAILED);
	  temphr = ptdr16p->
		CreateValueFromStruct ((aafMemPtr_t) &r16p_5678,
							   sizeof (r16p_5678),
							   0);
	  checkExpression (AAFRESULT_NULL_PARAM == temphr,
					   AAFRESULT_TEST_FAILED);
	  temphr = ptdr16p->
		CreateValueFromStruct ((aafMemPtr_t) &r16p_5678,
							   sizeof (r16p_5678)+1,
							   &pRat16PairVal_5678);
	  checkExpression (AAFRESULT_ILLEGAL_VALUE == temphr,
					   AAFRESULT_TEST_FAILED);
	  checkResult (ptdr16p->
				   CreateValueFromStruct ((aafMemPtr_t) &r16p_5678,
										  sizeof (r16p_5678),
										  &pRat16PairVal_5678));
	  checkResult (pObj->SetPropertyValue (pPropDefPosB,
										   pRat16PairVal_5678));

	  // Add property value for PositionC using CreateValueFromStruct
	  // methods, and then use SetStruct to set the value.
	  const Rational16_t r16_9a = {9, 10};
	  const Rational16_t r16_bc = {11, 12};
	  Rational16pair_t r16p_9abc;
	  r16p_9abc.X_Position = r16_9a;
	  r16p_9abc.Y_Position = r16_bc;
	  IAAFPropertyValueSP pRat16PairVal_9abc;
	  checkResult (ptdr16p->
				   CreateValueFromStruct ((aafMemPtr_t) &r16p_5678,
										  sizeof (r16p_5678),
										  &pRat16PairVal_9abc));
	  temphr = ptdr16p->SetStruct (0,
								  (aafMemPtr_t) &r16p_9abc,
								  sizeof (r16p_9abc));
	  checkExpression (AAFRESULT_NULL_PARAM == temphr,
					   AAFRESULT_TEST_FAILED);
	  temphr = ptdr16p->SetStruct (pRat16PairVal_9abc,
								  0,
								  sizeof (r16p_9abc));
	  checkExpression (AAFRESULT_NULL_PARAM == temphr,
					   AAFRESULT_TEST_FAILED);
	  temphr = ptdr16p->SetStruct (pRat16PairVal_9abc,
								  (aafMemPtr_t) &r16p_9abc,
								  sizeof (r16p_9abc)-1);
	  checkExpression (AAFRESULT_ILLEGAL_VALUE == temphr,
					   AAFRESULT_TEST_FAILED);
	  checkResult (ptdr16p->SetStruct (pRat16PairVal_9abc,
									  (aafMemPtr_t) &r16p_9abc,
										  sizeof (r16p_9abc)));
	  checkResult (pObj->SetPropertyValue (pPropDefPosC,
										   pRat16PairVal_9abc));

	  // add a value of PropertyN
	  IAAFPropertyValueSP spArrayPropertyValue;
	  // perform this part only for specified versions
	  if( versionUInt(testVer) >= versionUInt(1,1,1,0) )
	  {
	    // Create an empty array and then fill it by appending elements...
  		checkResult( ptdvaarpr->CreateEmptyValue (&spArrayPropertyValue) );
		
	    // intentionally in permuted order
		checkResult( ptdvaarpr->AppendElement(spArrayPropertyValue, pRat16PairVal_5678) );

		checkResult( ptdvaarpr->AppendElement(spArrayPropertyValue, pRat16PairVal_9abc) );

		checkResult( ptdvaarpr->AppendElement(spArrayPropertyValue, pRat16PairVal_1234) );

		// set PropertyN
		checkResult ( pObj->SetPropertyValue( pPropDefPosN, spArrayPropertyValue ) );
	  }

	  // Set the value on the new Velocity property (of Mixed_t type)
	  const Mixed_t velocty = {15, 2001};
	  IAAFPropertyValueSP pVelocity;
	  checkResult (ptdrmixed->CreateValueFromStruct((aafMemPtr_t) &velocty, sizeof(velocty), &pVelocity));
	  checkResult (pObj->SetPropertyValue(pPropDefVelocity, pVelocity));


	  //Put the modified comp mob into the file.
	  IAAFMobSP pMob;
	  checkResult (pcm->QueryInterface (IID_IAAFMob,
										(void**) &pMob));
	  checkResult (pHeader->AddMob(pMob));

	  // Attempt to save the file.
	  checkResult(pFile->Save());
		
	  // Attempt to close the file.
	  checkResult(pFile->Close());
	  IAAFFileSP nullFile;
	  pFile = nullFile;  // zeros the pFile, and releases it.

	  hr = AAFRESULT_SUCCESS;
	}
  catch (HRESULT& rResult)
	{
	  hr = rResult;
	}
	
  // cleanup
  if (pFile)
	{
	  pFile->Save();
	  pFile->Close();
	}
	
  return hr;
}
コード例 #3
0
// Create the test file.
void CAAFTypeDefWeakObjRef_create (
    aafCharacter_constptr pFileName,
    aafUID_constref fileKind,
    testRawStorageType_t rawStorageType,
    aafProductIdentification_constref productID)
{
  // Remove the previous test file is one exists
  RemoveTestFile (pFileName);

  // Create the file.
  IAAFFileSP pFile;
  checkResult (CreateTestFile( pFileName, fileKind, rawStorageType, productID, &pFile ));
  
  try
  {
    IAAFHeaderSP pHeader;
    checkResult (pFile->GetHeader (&pHeader));
    
    aafProductVersion_t toolkitVersion;
    checkResult(GetAAFVersions(pHeader, &toolkitVersion, NULL));
    bool weakReferencesSupported = WeakReferencesSupported(toolkitVersion);
    
    IAAFDictionarySP pDictionary;
    checkResult (pHeader->GetDictionary (&pDictionary));
    
    CAAFBuiltinDefs defs (pDictionary);
   
    if (weakReferencesSupported)
    {
      // Create a Weak reference to a type definition.
      IAAFTypeDefWeakObjRefSP pWeakObjRef;
      checkResult(pDictionary->CreateMetaInstance(AUID_AAFTypeDefWeakObjRef,
                                                  IID_IAAFTypeDefWeakObjRef,
                                                  (IUnknown **)&pWeakObjRef));
      
      // Find the class definition for all type definitions.
      IAAFClassDefSP pClassDef;
      checkResult(pDictionary->LookupClassDef(AUID_AAFTypeDef, &pClassDef));
      

  	  aafUID_t targetSet[2];
      targetSet[0] = kAAFPropID_Root_MetaDictionary;
      targetSet[1] = kAAFPropID_MetaDictionary_TypeDefinitions;
      checkResult(pWeakObjRef->Initialize(kAAFTypeID_TestWeakReferenceToType,
                                          pClassDef,
                                          kMyWeakReferenceToTypeDefinitionName,
                                          sizeof(targetSet)/sizeof(aafUID_t),
                                          targetSet));

      // Validate that we make the correct "type" by inspecting the type category.
      IAAFTypeDefSP pTypeDef;
      checkResult(pWeakObjRef->QueryInterface(IID_IAAFTypeDef, (void **)&pTypeDef));

      eAAFTypeCategory_t category;
      checkResult(pTypeDef->GetTypeCategory(&category));
      checkExpression(kAAFTypeCatWeakObjRef == category, AAFRESULT_TEST_FAILED);


    	// Add the new type to the dictionary.
    	checkResult(pDictionary->RegisterTypeDef(pTypeDef));
    	
    	
    	// Now add a new optional weak reference property to an existing class.
    	IAAFClassDefSP pFillerClass;
      IAAFPropertyDefSP pWeakRefPropertyDef;  	
      checkResult(pDictionary->LookupClassDef(AUID_AAFComponent, &pFillerClass));   
      checkResult(pFillerClass->RegisterOptionalPropertyDef(
        kAAFPropID_TestWeakReferenceToType,
        kMyWeakReferenceToTypeDefinitionPropertyName,
        pTypeDef,
        &pWeakRefPropertyDef));      
    }
  

#ifndef NO_REFERENCE_TO_MOB_TEST
    if (weakReferencesSupported)
    {
      // Create a Weak reference to a mob.
      IAAFTypeDefWeakObjRefSP pWeakObjRef;
      checkResult(pDictionary->CreateMetaInstance(AUID_AAFTypeDefWeakObjRef,
                                                  IID_IAAFTypeDefWeakObjRef,
                                                  (IUnknown **)&pWeakObjRef));

      // Find the class definition for all mobs.
      IAAFClassDefSP pClassDef;
      checkResult(pDictionary->LookupClassDef(AUID_AAFMob, &pClassDef));


      aafUID_t targetSet[3];
      targetSet[0] = kAAFPropID_Root_Header;
      targetSet[1] = kAAFPropID_Header_Content;
      targetSet[2] = kAAFPropID_ContentStorage_Mobs;
      checkResult(pWeakObjRef->Initialize(kAAFTypeID_TestWeakReferenceToMob,
                                          pClassDef,
                                          kMyWeakReferenceToMobName,
                                          sizeof(targetSet)/sizeof(aafUID_t),
                                          targetSet));

      // Validate that we make the correct "type" by inspecting the type category.
      IAAFTypeDefSP pTypeDef;
      checkResult(pWeakObjRef->QueryInterface(IID_IAAFTypeDef, (void **)&pTypeDef));

      eAAFTypeCategory_t category;
      checkResult(pTypeDef->GetTypeCategory(&category));
      checkExpression(kAAFTypeCatWeakObjRef == category, AAFRESULT_TEST_FAILED);


      // Add the new type to the dictionary.
      checkResult(pDictionary->RegisterTypeDef(pTypeDef));


      // Now add a new optional weak reference property to an existing class.
      IAAFClassDefSP pFillerClass;
      IAAFPropertyDefSP pWeakRefPropertyDef;
      checkResult(pDictionary->LookupClassDef(AUID_AAFComponent, &pFillerClass));
      checkResult(pFillerClass->RegisterOptionalPropertyDef(
        kAAFPropID_TestWeakReferenceToMob,
        kMyWeakReferenceToMobPropertyName,
        pTypeDef,
        &pWeakRefPropertyDef));
    }
#endif
  


  
    //
	  // Create a Composition Mob
	  //
	  IAAFMobSP pMob;
	  checkResult(defs.cdCompositionMob()->CreateInstance(IID_IAAFMob, (IUnknown **)&pMob));
	  checkResult(pMob->SetMobID(TEST_MobID));
	  checkResult(pMob->SetName(L"TestCompMob"));
	  
	  //
	  // Create a sequence to hold our test fillers components.
	  //
	  IAAFSequenceSP pSequence;
	  checkResult (defs.cdSequence()->CreateInstance(IID_IAAFSequence, (IUnknown **)&pSequence));
	  checkResult (pSequence->Initialize (defs.ddkAAFPicture()));

	  
	  IAAFFillerSP pFiller1;
	  checkResult (defs.cdFiller()->CreateInstance(IID_IAAFFiller, (IUnknown **)&pFiller1));
	  checkResult (pFiller1->Initialize (defs.ddkAAFPicture(), 16));
	
		IAAFFillerSP pFiller2;
	  checkResult (defs.cdFiller()->CreateInstance(IID_IAAFFiller, (IUnknown **)&pFiller2));
	  checkResult (pFiller2->Initialize (defs.ddkAAFPicture(), 32));


    if (weakReferencesSupported)
    {
      // Try adding a weak reference before filler is attached to the file.
      CreateWeakReference(pFiller1, defs.tdInt64());
      CheckWeakReference(pFiller1, defs.tdInt64());
      
      ChangeWeakReference(pFiller1, defs.tdString());
      CreateWeakReference(pFiller2, defs.tdInt32()); 	
    }


    //
    // Add the initialized fillers to the sequence.
    //
    IAAFComponentSP pComp1;
  	checkResult(pFiller1->QueryInterface(IID_IAAFComponent, (void **)&pComp1));
  	checkResult(pSequence->AppendComponent(pComp1));

    IAAFComponentSP pComp2;
  	checkResult(pFiller2->QueryInterface(IID_IAAFComponent, (void **)&pComp2));	
  	checkResult(pSequence->AppendComponent(pComp2));
  	
  	//
  	// Append the sequence as the segment in a new timeline mob slot.
  	//
  	IAAFSegmentSP pSegment;
  	checkResult(pSequence->QueryInterface(IID_IAAFSegment, (void **)&pSegment));
   	aafRational_t  editRate = {30000, 1001};
   	aafCharacter_constptr pSlotName = L"Slot 1";
   	aafPosition_t  origin = 0;
   	IAAFTimelineMobSlotSP pNewSlot;
   	checkResult(pMob->AppendNewTimelineSlot(editRate, pSegment, TEST_SlotID, pSlotName, origin, &pNewSlot));

    //
    // Add to the set of mobs in the file.
    //
    checkResult(pHeader->AddMob(pMob));

#ifndef NO_REFERENCE_TO_MOB_TEST
    if (weakReferencesSupported)
    {
      // The referenced object needs to be attached to the file.
      CreateWeakReference(pFiller1, pMob);
      CheckWeakReference(pFiller1, pMob);
    }
#endif
//    if (weakReferencesSupported)
//    {
//      // Try adding a weak reference after filler is attached to the file.
//      CreateWeakReference(pFiller2, defs.tdInt32());  	
//    }

    // Verify the data before the save.
    CAAFTypeDefWeakObjRef_verify (pHeader);

    checkResult(pFile->Save());
    checkResult(pFile->Close());
  }
  catch (HRESULT& rhr)
  {
    if (pFile) // only save & close the file if it was actually opened
    {
      pFile->Save();  // This may not be safe???
      pFile->Close();
    }
    throw rhr;
  }
  catch (...)
  {
    if (pFile) // only close the file if it was actually opened
      pFile->Close();  
    throw;
  }
}