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 
ParseNumberString(const UString & s,NCOM::CPropVariant & prop)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 
SetProperties(IUnknown * unknown,const CObjectVector<CProperty> & properties)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.Back();
53           if (c == L'-')
54             propVariant = false;
55           else if (c == L'+')
56             propVariant = true;
57           if (propVariant.vt != VT_EMPTY)
58             name.DeleteBack();
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