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
15using namespace NWindows;
16using namespace NCOM;
17
18static 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
30HRESULT 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