// now need the reading functionality static HRESULT ReadAAFFile(aafWChar * pFileName) { IAAFFile * pFile = NULL; // printing file open time clock_t start = clock(); clock_t finish; double duration; check(AAFFileOpenExistingRead ( pFileName, 0, &pFile)); finish = clock(); duration = ((double) (finish - start) / CLOCKS_PER_SEC); pFile->Close(); pFile->Release(); pFile=NULL; #if 0 printf("Open time = %f seconds\n", duration); #endif cleanup: if (pFile) { pFile->Close(); pFile->Release(); } return AAFRESULT_SUCCESS; }
extern int main(int argc, char *argv[]) { if (argc < 2) { printUsage(argv[0]); return 1; } aafWChar Filename[FILENAME_MAX]; size_t status = mbstowcs(Filename, argv[1], sizeof(Filename)); if (status == (size_t)-1) { fprintf(stderr, "mbstowcs failed for \"%s\"\n", argv[1]); return 1; } IAAFFile *pFile = NULL; int mode = 0; HRESULT res_open; // Perform the simplest possible use of the AAF SDK to open an // existing AAF file. This is enough to cause a memory leak in // AAF SDK v1.1.2 and up to at least CVS snapshot 2008-05-12. res_open = AAFFileOpenExistingRead(Filename, mode, &pFile); if (AAFRESULT_FAILED(res_open)) { aafCharacter buf[100] = L""; AAFResultToText(res_open, buf, sizeof(buf)); fprintf(stderr, "AAFFileOpenExistingRead() failed, result=0x%08x %ls\n", res_open, buf); return 1; } pFile->Close(); pFile->Release(); return 0; }
static HRESULT ReadAAFFile(const aafWChar * pFileName, testType_t testType) { IAAFFile * pFile = NULL; IAAFHeader * pHeader = NULL; IAAFDictionary* pDictionary = NULL; IAAFEssenceAccess* pEssenceAccess = NULL; IAAFEssenceMultiAccess* pMultiEssence = NULL; IAAFEssenceFormat *fmtTemplate = NULL; IEnumAAFMobs* pMobIter = NULL; IAAFMob* pMob = NULL; IAAFMasterMob* pMasterMob = NULL; IAAFEssenceFormat* pFormat = NULL; aafNumSlots_t numMobs, numSlots; aafSearchCrit_t criteria; aafRational_t readSampleRate; aafMobID_t mobID; aafWChar namebuf[1204]; unsigned char AAFDataBuf[4096]; aafUInt32 AAFBytesRead, samplesRead; FILE* pWavFile = NULL; unsigned char WAVDataBuf[4096], *dataPtr; size_t WAVBytesRead; aafUInt32 dataOffset, dataLen; aafUInt16 bitsPerSample, numCh; check(AAFFileOpenExistingRead ( pFileName, 0, &pFile)); check(pFile->GetHeader(&pHeader)); // Get the AAF Dictionary so that we can create valid AAF objects. check(pHeader->GetDictionary(&pDictionary)); // Here we check on the number of mobs in the file. // Get the number of master mobs in the file (should be one) check(pHeader->CountMobs(kAAFMasterMob, &numMobs)); // ** causes leak if (1 == numMobs ) { printf("Found %d Master Mobs\n", numMobs); criteria.searchTag = kAAFByMobKind; criteria.tags.mobKind = kAAFMasterMob; check(pHeader->GetMobs(&criteria, &pMobIter)); while(AAFRESULT_SUCCESS == pMobIter->NextOne(&pMob)) { char mobIDstr[256]; char mobName[256]; check(pMob->GetMobID (&mobID)); check(pMob->GetName (namebuf, sizeof(namebuf))); convert(mobName, sizeof(mobName), namebuf); MobIDtoString(mobID, mobIDstr); printf(" MasterMob Name = '%s'\n", mobName); printf(" (mobID %s)\n", mobIDstr); // Make sure we have two slots check(pMob->CountSlots(&numSlots)); if (2 == numSlots) { // The essence data is in SlotID 1 // Get a Master Mob interface check(pMob->QueryInterface(IID_IAAFMasterMob, (void **)&pMasterMob)); // Open the Essence Data check(pMasterMob->OpenEssence( 1, // SlotID 1 NULL, // mediaCriteria (Don't care) kAAFMediaOpenReadOnly, // Open mode kAAFCompressionDisable,// Compress disabled &pEssenceAccess)); // Open and read the Wave file (for comparison) pWavFile = fopen("Laser.wav", "r"); if (pWavFile) { // read in the essence data WAVBytesRead = fread(WAVDataBuf, sizeof(unsigned char), sizeof(WAVDataBuf), pWavFile); fclose(pWavFile); pWavFile = NULL; check(loadWAVEHeader(WAVDataBuf, &bitsPerSample, &numCh, &readSampleRate, &dataOffset, &dataLen)); dataPtr = WAVDataBuf + dataOffset; aafUInt32 sampleBits; aafInt32 bytesRead; check(pEssenceAccess->GetEmptyFileFormat (&fmtTemplate)); check(fmtTemplate->AddFormatSpecifier (kAAFAudioSampleBits, 0, NULL)); check(pEssenceAccess->GetFileFormat (fmtTemplate, &pFormat)); fmtTemplate->Release(); fmtTemplate = NULL; check(pFormat->GetFormatSpecifier (kAAFAudioSampleBits, sizeof(sampleBits), (aafDataBuffer_t)&sampleBits, &bytesRead)); pFormat->Release(); pFormat = NULL; if(sampleBits != bitsPerSample) { printf("***Wrong sample size read ( was %d , should be %d)\n", sampleBits, bitsPerSample); } // Read the Data from the AAF file if(testType == testStandardCalls) { check(pEssenceAccess->ReadSamples( dataLen, //!!! Hardcoded // Number of Samples sizeof(AAFDataBuf), // Maximum buffer size AAFDataBuf, // Buffer for the data &samplesRead, // Actual number of samples read &AAFBytesRead)); // Actual number of bytes read } else if(testType == testMultiCalls) { aafmMultiXfer_t xfer; aafmMultiResult_t result; check(pEssenceAccess->QueryInterface(IID_IAAFEssenceMultiAccess, (void **)&pMultiEssence)); xfer.numSamples = dataLen; //!!! Hardcoded // Number of Samples xfer.buflen = sizeof(AAFDataBuf); xfer.buffer = AAFDataBuf; result.bytesXfered = 0; check(pMultiEssence->ReadMultiSamples(1, &xfer, &result)); samplesRead = result.samplesXfered; AAFBytesRead = result.bytesXfered; pMultiEssence->Release(); pMultiEssence = NULL; } // Now compare the data read from the AAF file to the actual WAV file if (dataLen != AAFBytesRead) { printf("***Wrong number of bytes read (was %u , should be %zu)\n", AAFBytesRead, WAVBytesRead); } if (memcmp( dataPtr, AAFDataBuf, dataLen) != 0) { printf("*** Data Read is different than the data in the WAV file ***\n"); } } else { printf("***Failed to open Wave file Laser.wav for comparison\n"); } } else { printf("***Wrong number of slots in the Master Mob (was %d should be %d)\n", numSlots, 2); } if (pMasterMob) { pMasterMob->Release(); pMasterMob = NULL; } pMob->Release(); pMob = NULL; if (pEssenceAccess) { pEssenceAccess->Release(); pEssenceAccess = NULL; } } // while pMobIter->NextOne pMobIter->Release(); pMobIter = NULL; } else { printf("***Wrong number of Master mobs in the file (was %d should be %d)\n", numMobs, 1); } printf("--------\n"); cleanup: // Cleanup and return if (pWavFile) fclose(pWavFile); if (pMultiEssence) pMultiEssence->Release(); pMultiEssence=NULL; if(fmtTemplate) { fmtTemplate->Release(); fmtTemplate = NULL; } if (pEssenceAccess) { pEssenceAccess->Release(); pEssenceAccess = NULL; } if (pDictionary) pDictionary->Release(); pDictionary=NULL; if (pHeader) pHeader->Release(); pHeader=NULL; if (pMobIter) pMobIter->Release(); pMobIter=NULL; if (pFormat) pFormat->Release(); pFormat=NULL; if (pFile) { pFile->Close(); pFile->Release(); pFile=NULL; } return moduleErrorTmp; }
static void ReadAAFFile(aafWChar * pFileName) { HRESULT hr = S_OK; IAAFFile * pFile = NULL; hr = AAFFileOpenExistingRead (pFileName, AAF_FILE_MODE_LAZY_LOADING, &pFile); if (SUCCEEDED(hr)) { IAAFHeader * pHeader = NULL; hr = pFile->GetHeader(&pHeader); check(hr); // display error message if (SUCCEEDED(hr)) { IAAFIdentification * pIdent = NULL; hr = pHeader->GetLastIdentification(&pIdent); check(hr); // display error message if (SUCCEEDED(hr)) { printIdentification(pIdent); pIdent->Release(); pIdent = NULL; // count Mobs aafNumSlots_t n; hr = pHeader->CountMobs(kAAFAllMob, &n); check(hr); printf("\nNumber of Mobs = %d\n", n); // Header::Version, Header::ObjectModelVersion aafVersionType_t version = {0}; check(pHeader->GetFileRevision (&version) ); printf("\nHeader::Version = %d.%d\n", version.major, version.minor); aafFileRev_t fileVersion = kAAFRev1; check(pFile->GetRevision (&fileVersion) ); printf("\nHeader::ObjectModelVersion = %d", fileVersion); if (fileVersion == kAAFRev1) printf(" (recognized as kAAFRev1)\n"); else if (fileVersion == kAAFRev2) printf(" (recognized as kAAFRev2)\n"); else printf("\n"); // Show datadefs, with version IEnumAAFDataDefsSP pEnumDataDef; IAAFDictionarySP pDictionary; check(pHeader->GetDictionary(&pDictionary)); check(pDictionary->GetDataDefs(&pEnumDataDef)); IAAFDataDef* pDataDef; printf("\nDatadefs = "); while (SUCCEEDED(pEnumDataDef->NextOne(&pDataDef))) { IAAFDefObjectSP pDefObject; check(pDataDef->QueryInterface(IID_IAAFDefObject, (void**)&pDefObject)); pDataDef->Release(); pDataDef = NULL; aafUID_t id = {0}; check(pDefObject->GetAUID(&id)); aafWChar wchName[500]; char chName[1000]; check( pDefObject->GetName(wchName, sizeof (wchName)) ); convert(chName, sizeof(chName), wchName); if (memcmp( &id, &kAAFDataDef_LegacyPicture, sizeof(id)) == 0) printf("\"%s\" (recognized as legacy Picture)\n", chName); else if (memcmp( &id, &kAAFDataDef_Picture, sizeof(id)) == 0) printf("\"%s\" (recognized as Picture)\n", chName); else if (memcmp( &id, &kAAFDataDef_LegacySound, sizeof(id)) == 0) printf("\"%s\" (recognized as legacy Sound)\n", chName); else if (memcmp( &id, &kAAFDataDef_Sound, sizeof(id)) == 0) printf("\"%s\" (recognized as Sound)\n", chName); else if (memcmp( &id, &kAAFDataDef_LegacyTimecode, sizeof(id)) == 0) printf("\"%s\" (recognized as legacy Timecode)\n", chName); else if (memcmp( &id, &kAAFDataDef_Timecode, sizeof(id)) == 0) printf("\"%s\" (recognized as Timecode)\n", chName); else if (memcmp( &id, &kAAFDataDef_PictureWithMatte, sizeof(id)) == 0) printf("\"%s\" (recognized as PictureWithMatte)\n", chName); else if (memcmp( &id, &kAAFDataDef_Edgecode, sizeof(id)) == 0) printf("\"%s\" (recognized as Edgecode)\n", chName); else if (memcmp( &id, &kAAFDataDef_Auxiliary, sizeof(id)) == 0) printf("\"%s\" (recognized as Auxiliary)\n", chName); else if (memcmp( &id, &kAAFDataDef_DescriptiveMetadata, sizeof(id)) == 0) printf("\"%s\" (recognized as DescriptiveMetadata)\n", chName); else if (memcmp( &id, &kAAFDataDef_Matte, sizeof(id)) == 0) printf("\"%s\" (recognized as Matte)\n", chName); else printf("\"%s\"\n", chName); printf(" "); } // Check if file contains TypeDefs known to cause a v1.0 reader to assert. // Known instances of this are UInt32Set and AUIDSet added to the v1.1 SDK. // Cannot use Dictionary::LookupTypeDef to check for them, because this // has the side effect of registering the typedef we are checking for // from the built-in model. Instead, iterate through typedefs (in file) // and check for the known instances. printf("\nTypes incompatible with SDK v1.0.x ="); IEnumAAFTypeDefsSP pEnumTypeDef; check(pDictionary->GetTypeDefs(&pEnumTypeDef)); IAAFTypeDef* pTypeDef; bool foundToxic = false; while (SUCCEEDED(pEnumTypeDef->NextOne(&pTypeDef))) { IAAFMetaDefinitionSP pMetaDef; check(pTypeDef->QueryInterface(IID_IAAFMetaDefinition, (void**)&pMetaDef)); pTypeDef->Release(); pTypeDef = NULL; aafUID_t typeUID; check(pMetaDef->GetAUID(&typeUID)); aafWChar wchName[500]; char chName[1000]; check( pMetaDef->GetName(wchName, sizeof (wchName)) ); convert(chName, sizeof(chName), wchName); if ((memcmp( &typeUID, &kAAFTypeID_AUIDSet, sizeof(typeUID)) == 0) || (memcmp( &typeUID, &kAAFTypeID_UInt32Set, sizeof(typeUID)) == 0)) { printf(" %s", chName); foundToxic = true; } } if (!foundToxic) printf(" (none)"); printf("\n\n"); } pHeader->Release(); pHeader = NULL; } hr = pFile->Close(); check(hr); pFile->Release(); pFile = NULL; // Get file kind. // Since AAF SDK v1.0.2, the file kind actually identifies the implementation // of the file kind, from which the file kind is inferred. aafUID_t fileKind = {0}; aafBool isAAFFile = kAAFFalse; check(AAFFileIsAAFFile(pFileName, &fileKind, &isAAFFile)); if (isAAFFile) { if (memcmp( &fileKind, &kAAFFileKind_AafM512Binary, sizeof(fileKind)) == 0) printf("Filekind = 512-byte SS (reading with Microsoft)\n"); else if (memcmp( &fileKind, &kAAFFileKind_AafS512Binary, sizeof(fileKind)) == 0) printf("Filekind = 512-byte SS (reading with Schemasoft)\n"); else if (memcmp( &fileKind, &kAAFFileKind_AafG512Binary, sizeof(fileKind)) == 0) printf("Filekind = 512-byte SS (reading with GSF)\n"); else if (memcmp( &fileKind, &kAAFFileKind_Aaf512Binary, sizeof(fileKind)) == 0) printf("Filekind = 512-byte SS (reading with default implementation)\n"); else if (memcmp( &fileKind, &kAAFFileKind_AafM4KBinary, sizeof(fileKind)) == 0) printf("Filekind = 4096-byte SS (reading with Microsoft)\n"); else if (memcmp( &fileKind, &kAAFFileKind_AafS4KBinary, sizeof(fileKind)) == 0) printf("Filekind = 4096-byte SS (reading with Schemasoft)\n"); else if (memcmp( &fileKind, &kAAFFileKind_AafG4KBinary, sizeof(fileKind)) == 0) printf("Filekind = 4096-byte SS (reading with GSF)\n"); else if (memcmp( &fileKind, &kAAFFileKind_Aaf4KBinary, sizeof(fileKind)) == 0) printf("Filekind = 4096-byte SS (reading with default implementation)\n"); else printf("Filekind = Recognized by SDK but unknown to AAFInfo\n"); } } else { fprintf(stderr, "Error : Failed to open file (result = %0x).\n", hr); exit(1); } }
int main(int argc, char *argv[]) { if (argc != 4 || (strcmp(argv[1], "-xml") != 0 && strcmp(argv[1], "-ss") != 0)) { Usage(argc, argv); exit(1); } aafCharacter *inFileName = new aafCharacter[strlen(argv[2]) + 1]; aafCharacter *outFileName = new aafCharacter[strlen(argv[3]) + 1]; size_t status = mbstowcs(inFileName, argv[2], strlen(argv[2])); if (status == (size_t)-1) { fprintf(stderr, "\nError: Failed to convert filename '%s' to a wide string.", argv[2]); exit(1); } status = mbstowcs(outFileName, argv[3], strlen(argv[3])); if (status == (size_t)-1) { fprintf(stderr, "\nError: Failed to convert filename '%s' to a wide string.", argv[3]); exit(1); } inFileName[strlen(argv[2])] = 0; outFileName[strlen(argv[3])] = 0; // remove the output file if it already exists remove(argv[3]); CAAFInitialize aafInit; IAAFFile* inFile = 0; IAAFFile* outFile = 0; check(AAFFileOpenExistingRead(inFileName, 0, &inFile)); aafProductVersion_t v; v.major = 0; v.minor = 1; v.tertiary = 0; v.patchLevel = 0; v.type = kAAFVersionUnknown; const aafUID_t productUID = {0x97e04c67, 0xdbe6, 0x4d11, {0xbc, 0xd7, 0x3a, 0x90, 0x42, 0x53, 0xa2, 0xef}}; aafProductIdentification_t productInfo; aafWChar companyName[] = L"AMW Association"; aafWChar productName[] = L"aaffmtconv"; productInfo.companyName = companyName; productInfo.productName = productName; productInfo.productVersion = &v; productInfo.productVersionString = 0; productInfo.productID = productUID; productInfo.platform = 0; // create output file based on choice of stored format if (strcmp(argv[1], "-xml") == 0) { check(AAFFileOpenNewModifyEx(outFileName, &kAAFFileKind_AafXmlText, 0, &productInfo, &outFile)); } else { check(AAFFileOpenNewModify(outFileName, 0, &productInfo, &outFile)); } // save copy using the selected stored format check(inFile->SaveCopyAs(outFile)); check(outFile->Close()); check(inFile->Close()); outFile->Release(); outFile = 0; inFile->Release(); inFile = 0; delete [] inFileName; delete [] outFileName; return 0; }
extern int main(int argc, char *argv[]) { const char *filename_cstr = "test.aaf"; #ifndef _MSC_VER setlocale (LC_ALL, "en_US.UTF-8"); #endif if (argc >= 2) { filename_cstr = argv[1]; } // convert C str to wide string aafWChar filename[FILENAME_MAX]; size_t status = mbstowcs(filename, filename_cstr, sizeof(filename)); if (status == (size_t)-1) { fprintf(stderr, "mbstowcs failed for \"%s\"\n", filename_cstr); return 1; } remove(filename_cstr); IAAFFile *pFile = NULL; int mode = 0; aafProductIdentification_t productID; aafProductVersion_t TestVersion = {1, 1, 0, 0, kAAFVersionUnknown}; productID.companyName = (aafCharacter*)L"HSC"; productID.productName = (aafCharacter*)L"String Tester"; productID.productVersion = &TestVersion; productID.productVersionString = NULL; productID.productID = TestProductID; productID.platform = (aafCharacter*)L"Linux"; // Create new AAF file check(AAFFileOpenNewModify(filename, mode, &productID, &pFile)); // Create a simple Mob IAAFClassDef *classDef = NULL; IAAFMob *pMob = NULL; IAAFHeader *pHeader = NULL; IAAFDictionary *pDictionary = NULL; check(pFile->GetHeader(&pHeader)); check(pHeader->GetDictionary(&pDictionary)); check(pDictionary->LookupClassDef(AUID_AAFMasterMob, &classDef)); check(classDef->CreateInstance(IID_IAAFMob, (IUnknown **)&pMob)); classDef->Release(); check(pMob->SetMobID(TEST_MobID)); // UTF-8 for codepoint U+1D11E (musical G Clef): 0xf0,0x9d,0x84,0x9e // UTF-8 for codepoint U+1D122 (musical F Clef): 0xf0,0x9d,0x84,0xa2 // http://unicode.org/charts/PDF/U1D100.pdf // http://en.wikipedia.org/wiki/UTF-8 aafCharacter *mobname; const unsigned char inputStr[] = { 0xf0,0x9d,0x84,0x9e, // U+1D11E 0xf0,0x9d,0x84,0xa2, // U+1D122 0x4d, 0x6f, 0x62, // 'M' 'o' 'b' 0x0 }; // Convert UTF-8 inputStr to native wchar_t representation (UTF-32 Unix, UTF-16 Windows) int wlen = 0, n; #ifndef _MSC_VER int ret; char *p = (char *)inputStr; while ((ret = mblen(p, 4)) > 0) { ++wlen; p+=ret; } mobname = new aafCharacter[wlen+1]; n = mbstowcs(mobname, (const char *)inputStr, wlen+1); if (n == -1) { fprintf (stderr, "mbstowcs returned -1. Invalid multibyte string\n"); exit(1); } #else // Under Windows we must use MultiByteToWideChar() to get correct UTF-8 conversion to UTF-16 // since mbstowcs() is broken for UTF-8. wlen = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, (LPCSTR)inputStr, -1, NULL, 0); if (wlen == 0) { fprintf (stderr, "MultiByteToWideChar returned 0. Invalid multibyte string\n"); exit(1); } mobname = new aafCharacter[wlen]; n = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, (LPCSTR)inputStr, -1, mobname, wlen); if (n == 0) { fprintf (stderr, "MultiByteToWideChar returned 0. Invalid multibyte string\n"); exit(1); } #endif // SetName() calls OMSimpleProperty::set() which does a memcpy of the mobname string // to an OMByte* variable 'bits()' at OMProperty.cpp:399 // Found by setting an rwatch on mobname address. check(pMob->SetName(mobname)); aafUInt32 size_before = 0; check(pMob->GetNameBufLen(&size_before)); check(pHeader->AddMob(pMob)); pMob->Release(); pHeader->Release(); pDictionary->Release(); // All the work of storing to disk happens during Save() // The bits() variable is next read in OMType::contract() at OMType.cpp:137 // which is called by ImplAAFTypeDefCharacter::externalize() at ImplAAFTypeDefCharacter.cpp:307 // which is called by ImplAAFTypeDefString::externalize() at ImplAAFTypeDefString.cpp:584 // which is called by OMSSStoredObject::save() at OMSSStoredObject.cpp:382 check(pFile->Save()); check(pFile->Close()); pFile->Release(); // OMCharacterStringProperty<CharacterType>::stringLength() at OMVariableSizePropertyT.h:80 // calculates string length of AAF string properties // Read AAF file back in check(AAFFileOpenExistingRead(filename, mode, &pFile)); // Get the Mob check(pFile->GetHeader(&pHeader)); check(pHeader->LookupMob(TEST_MobID, &pMob)); aafUInt32 size_after = 0; check(pMob->GetNameBufLen(&size_after)); aafCharacter *mobname_after = new aafCharacter[size_after]; check(pMob->GetName(mobname_after, size_after)); // Compare Mob name before storing to disk with Mob name read back from disk int test_result = 0; if (size_before != size_after) { printf("size_before=%d != size_after=%d\n", size_before, size_after); test_result = 1; } else { if (memcmp(mobname, mobname_after, size_before) != 0) { printf("wchar_t* mobname and wchar_t* mobname_after differ:\n"); printf(" %s\n", hexDump(mobname, size_before)); printf(" %s\n", hexDump(mobname_after, size_after)); test_result = 1; } } // Check if the multibyte (UTF-8) versions of mobname and mobname_after match. char *outputStr; #ifndef _MSC_VER wlen = wcslen(mobname_after)*sizeof(aafCharacter) + 1; outputStr = new char [wlen]; n = wcstombs (outputStr, mobname_after, wlen); if (n == -1) { fprintf(stderr, "Could not convert mobname_after to multibyte str\n"); exit(1); } #else wlen = WideCharToMultiByte(CP_UTF8, 0, mobname_after, -1, NULL, 0, NULL, NULL); if (wlen == 0) { fprintf (stderr, "Failed to convert mobname_after to multibyte string\n"); exit(1); } outputStr = new char[wlen]; wlen = WideCharToMultiByte(CP_UTF8, 0, mobname_after, -1, outputStr, wlen, NULL, NULL); #endif if (strlen((char *)inputStr) != strlen(outputStr)) { fprintf(stderr, "UTF-8 version of string: input length(%d) != output length(%d)\n", (int)strlen((char *)inputStr), (int)strlen(outputStr)); test_result = 1; } if (strcmp((char *)inputStr, outputStr) != 0) { fprintf(stderr, "UTF-8 version of string: input and output strings differ\n"); printf(" %s\n", hexDump(inputStr, strlen((char *)inputStr))); printf(" %s\n", hexDump(outputStr, strlen(outputStr))); test_result = 1; } pMob->Release(); pHeader->Release(); check(pFile->Close()); pFile->Release(); delete [] mobname; delete [] mobname_after; return test_result; }