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  const 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
31struct CPropPropetiesVector
32{
33  CPropVariant *values;
34  CPropPropetiesVector(unsigned num)
35  {
36    values = new CPropVariant[num];
37  }
38  ~CPropPropetiesVector()
39  {
40    delete []values;
41  }
42};
43
44
45HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties)
46{
47  if (properties.IsEmpty())
48    return S_OK;
49  Z7_DECL_CMyComPtr_QI_FROM(
50      ISetProperties,
51      setProperties, unknown)
52  if (!setProperties)
53    return S_OK;
54
55  UStringVector realNames;
56  CPropPropetiesVector values(properties.Size());
57  {
58    unsigned i;
59    for (i = 0; i < properties.Size(); i++)
60    {
61      const CProperty &property = properties[i];
62      NCOM::CPropVariant propVariant;
63      UString name = property.Name;
64      if (property.Value.IsEmpty())
65      {
66        if (!name.IsEmpty())
67        {
68          const wchar_t c = name.Back();
69          if (c == L'-')
70            propVariant = false;
71          else if (c == L'+')
72            propVariant = true;
73          if (propVariant.vt != VT_EMPTY)
74            name.DeleteBack();
75        }
76      }
77      else
78        ParseNumberString(property.Value, propVariant);
79      realNames.Add(name);
80      values.values[i] = propVariant;
81    }
82    CRecordVector<const wchar_t *> names;
83    for (i = 0; i < realNames.Size(); i++)
84      names.Add((const wchar_t *)realNames[i]);
85
86    return setProperties->SetProperties(&names.Front(), values.values, names.Size());
87  }
88}
89