Advertisement
Guest User

Untitled

a guest
Aug 15th, 2013
526
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.94 KB | None | 0 0
  1. set_max_file_asset_metadata_cf(Value** arg_list, int count)
  2. {
  3.     // setMAXFileAssetMetadata <filename> <array of AssetMetadata_StructDef instances>
  4.     check_arg_count_with_keys(setMAXFileAssetMetadata, 2, count);
  5.     TSTR  fileName = arg_list[0]->to_filename();
  6.     AssetId assetId;
  7.     if (IAssetManager::GetInstance()->StringToAssetId(fileName, assetId))
  8.         fileName = IAssetManager::GetInstance()->GetAsset(assetId).GetFileName();
  9.  
  10.     const TCHAR* scene_dir = MAXScript_interface->GetDir(APP_SCENE_DIR);
  11.     TCHAR  buf[MAX_PATH] = {0};
  12.     five_typed_value_locals(Name* struct_name, StructDef* sd, Value* assetId, Value* filename, Value* assetType);
  13.  
  14.     // for each element of <array of AssetMetadata_StructDef instances>, make sure it's an AssetMetadata_StructDef instance
  15.     // collect elements as AssetMetaData instances.
  16.     vl.struct_name = (Name*)Name::intern(ASSETMETADATA_DEFSTRUCT_NAME);
  17.     vl.sd = (StructDef*)globals->get(vl.struct_name)->eval();
  18.     Array* metadata_array = (Array*)arg_list[1];
  19.     type_check(metadata_array, Array, _T("setMAXFileAssetMetadata"));
  20.     MaxSDK::Array<AssetMetaData> new_assetMetaData(metadata_array->size);
  21.     for (int i = 0; i < metadata_array->size; i++)
  22.     {
  23.         Struct* element = (Struct*)metadata_array->data[i];
  24.         if (!is_struct(element))
  25.             throw RuntimeError(MaxSDK::GetResourceStringAsMSTR(IDS_EXPECTED_ASSETMETADATA_DEFSTRUCT), element);
  26.         StructDef *sdef = element->definition;
  27.         if (sdef != vl.sd)
  28.             throw RuntimeError(MaxSDK::GetResourceStringAsMSTR(IDS_EXPECTED_ASSETMETADATA_DEFSTRUCT), element);
  29.         vl.assetId = element->member_data[1];
  30.         vl.filename = element->member_data[2];
  31.         vl.assetType = element->member_data[3];
  32.         bool success = IAssetManager::GetInstance()->StringToAssetId(vl.assetId->to_string(), new_assetMetaData[i].assetId);
  33.         if (!success)
  34.             throw RuntimeError(MaxSDK::GetResourceStringAsMSTR(IDS_CANNOT_CONVERT_ASSETID), vl.assetId);
  35.  
  36.         TSTR  assetFileName = vl.filename->to_filename();
  37.         AssetId assetId;
  38.         if (IAssetManager::GetInstance()->StringToAssetId(assetFileName, assetId))
  39.             assetFileName = IAssetManager::GetInstance()->GetAsset(assetId).GetFileName();
  40.         new_assetMetaData[i].filename = assetFileName;
  41.  
  42.         new_assetMetaData[i].assetType = vl.assetType->to_string();
  43.     }
  44.  
  45.     // find the file
  46.     if (MSZipPackage::search_current_package(fileName, buf) ||
  47.         SearchPath(scene_dir, fileName, NULL, MAX_PATH, buf, NULL) ||
  48.         SearchPath(NULL, fileName, NULL, MAX_PATH, buf, NULL))
  49.     {
  50.         // This opens the file as an OLE structured storage file with read/write access
  51.         STGOPTIONS  StgOptions = { 0};
  52.         StgOptions.usVersion    = 1;        /* Win2k+ */
  53.         StgOptions.ulSectorSize = 4096; /* 512 limits us to 2GB */
  54.         DWORD mode = (STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE);
  55.         IStorage*   pIStorage = NULL;
  56.         HRESULT hres = StgOpenStorageEx(WStr(buf), mode, STGFMT_DOCFILE, 0, &StgOptions, NULL,
  57.             IID_IStorage, (void **) &pIStorage);
  58.         if (hres != S_OK || pIStorage == NULL)
  59.             return_value(&false_value);
  60.         // define AutoPtr for guaranteed cleanup of pIStorage
  61.         MaxSDK::AutoPtr<IUnknown, IUnknownDestructorPolicy> pIStorageAutoPtr(pIStorage);
  62.  
  63.         // This opens the Asset Metadata stream with read/write access
  64.         LPSTREAM pIStream;
  65.         hres = pIStorage->OpenStream(L"FileAssetMetaData2", NULL, mode, 0, &pIStream);
  66.         if (hres != S_OK  || pIStream == NULL)
  67.             return_value(&false_value); // valid for old files
  68.         // define AutoPtr for guaranteed cleanup of pIStream
  69.         MaxSDK::AutoPtr<IUnknown, IUnknownDestructorPolicy> pIStreamAutoPtr(pIStream);
  70.  
  71.         // get the length of the stream
  72.         STATSTG statstg;
  73.         pIStream->Stat(&statstg,STATFLAG_NONAME);
  74.         unsigned __int64 nBytes = statstg.cbSize.QuadPart;
  75.         unsigned __int64 nBytesRead = 0;
  76.  
  77.         // read from the stream while there are bytes left.
  78.         MaxSDK::Array<AssetMetaData> assetMetaDataArray;
  79.         AssetMetaData assetMetaData;
  80.         while (nBytesRead < nBytes)
  81.         {
  82.             // load an asset's metadata
  83.             if (!ReadAssetMetaData(pIStream, assetMetaData, nBytesRead))
  84.                 throw RuntimeError(MaxSDK::GetResourceStringAsMSTR(IDS_ERROR_READING_ASSETMETADATA_STREAM));
  85.             // see if user has specified data for this asset id
  86.             for (int i = 0; i < new_assetMetaData.length(); i++)
  87.             {
  88.                 if (new_assetMetaData[i].assetId == assetMetaData.assetId)
  89.                 {
  90.                     // assetType has to match, Case-insensitive compare
  91.                     if (_wcsicmp(new_assetMetaData[i].assetType, assetMetaData.assetType) != 0)
  92.                     {
  93.                         TSTR errorMsg;
  94.                         errorMsg.printf(MaxSDK::GetResourceStringAsMSTR(IDS_INCORRECT_ASSETTYPE), vl.assetId->to_string(),
  95.                             assetMetaData.assetType.data(), new_assetMetaData[i].assetType.data());
  96.                         throw RuntimeError(errorMsg);
  97.                     }
  98.                     assetMetaData.filename = new_assetMetaData[i].filename;
  99.                     break;
  100.                 }
  101.             }
  102.             assetMetaDataArray.append(assetMetaData);
  103.         }
  104.         // done reading asset metadata, reset stream and rewrite it.
  105.         LARGE_INTEGER zero = {0, 0};
  106.         pIStream->Seek(zero, STREAM_SEEK_SET, NULL);
  107.         ULARGE_INTEGER uzero = {0, 0};
  108.         pIStream->SetSize(uzero);
  109.         for (int i = 0; i < assetMetaDataArray.length(); i++)
  110.         {
  111.             ULONG nb;
  112.             // store assetId, assetType width in characters, assetType as unicode string - null terminated,
  113.             // filename width in characters, filename as unicode string - null terminated
  114.             AssetMetaData &assetMetaData = assetMetaDataArray[i];
  115.             pIStream->Write(&assetMetaData.assetId,sizeof(assetMetaData.assetId),&nb);
  116.             int len = assetMetaData.assetType.Length();
  117.             pIStream->Write(&len,sizeof(len),&nb);
  118.             if (len != 0)
  119.                 pIStream->Write(assetMetaData.assetType.data(),len*sizeof(wchar_t),&nb);
  120.             wchar_t null_char = 0;
  121.             pIStream->Write(&null_char,sizeof(null_char),&nb);
  122.             len = assetMetaData.filename.Length();
  123.             pIStream->Write(&len,sizeof(len),&nb);
  124.             if (len != 0)
  125.                 pIStream->Write(assetMetaData.filename.data(),len*sizeof(wchar_t),&nb);
  126.             pIStream->Write(&null_char,sizeof(null_char),&nb);
  127.         }
  128.     }
  129.     else
  130.         throw RuntimeError(MaxSDK::GetResourceStringAsMSTR(IDS_FILE_NOT_FOUND), arg_list[0]);
  131.     return_value(&true_value);
  132. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement