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 
ParseNumberString(const UString & s,NCOM::CPropVariant & prop)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 
SetProperties(IUnknown * unknown,const CObjectVector<CProperty> & properties)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