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