Home | History | Annotate | Download | only in Common
      1 // SetProperties.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "../../../Common/MyCom.h"
      6 #include "../../../Common/MyString.h"
      7 #include "../../../Common/StringToInt.h"
      8 
      9 #include "../../../Windows/PropVariant.h"
     10 
     11 #include "../../Archive/IArchive.h"
     12 
     13 #include "SetProperties.h"
     14 
     15 using namespace NWindows;
     16 using namespace NCOM;
     17 
     18 static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
     19 {
     20   const wchar_t *end;
     21   UInt64 result = ConvertStringToUInt64(s, &end);
     22   if (*end != 0 || s.IsEmpty())
     23     prop = s;
     24   else if (result <= (UInt32)0xFFFFFFFF)
     25     prop = (UInt32)result;
     26   else
     27     prop = result;
     28 }
     29 
     30 HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties)
     31 {
     32   if (properties.IsEmpty())
     33     return S_OK;
     34   CMyComPtr<ISetProperties> setProperties;
     35   unknown->QueryInterface(IID_ISetProperties, (void **)&setProperties);
     36   if (!setProperties)
     37     return S_OK;
     38 
     39   UStringVector realNames;
     40   CPropVariant *values = new CPropVariant[properties.Size()];
     41   try
     42   {
     43     unsigned i;
     44     for (i = 0; i < properties.Size(); i++)
     45     {
     46       const CProperty &property = properties[i];
     47       NCOM::CPropVariant propVariant;
     48       UString name = property.Name;
     49       if (property.Value.IsEmpty())
     50       {
     51         if (!name.IsEmpty())
     52         {
     53           wchar_t c = name.Back();
     54           if (c == L'-')
     55             propVariant = false;
     56           else if (c == L'+')
     57             propVariant = true;
     58           if (propVariant.vt != VT_EMPTY)
     59             name.DeleteBack();
     60         }
     61       }
     62       else
     63         ParseNumberString(property.Value, propVariant);
     64       realNames.Add(name);
     65       values[i] = propVariant;
     66     }
     67     CRecordVector<const wchar_t *> names;
     68     for (i = 0; i < realNames.Size(); i++)
     69       names.Add((const wchar_t *)realNames[i]);
     70 
     71     RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));
     72   }
     73   catch(...)
     74   {
     75     delete []values;
     76     throw;
     77   }
     78   delete []values;
     79   return S_OK;
     80 }
     81