Home | History | Annotate | Download | only in Common
      1 // ParseProperties.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "ParseProperties.h"
      6 
      7 #include "Common/StringToInt.h"
      8 #include "Common/MyCom.h"
      9 
     10 HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
     11 {
     12   if (prop.vt == VT_UI4)
     13   {
     14     if (!name.IsEmpty())
     15       return E_INVALIDARG;
     16     resValue = prop.ulVal;
     17   }
     18   else if (prop.vt == VT_EMPTY)
     19   {
     20     if(!name.IsEmpty())
     21     {
     22       const wchar_t *start = name;
     23       const wchar_t *end;
     24       UInt64 v = ConvertStringToUInt64(start, &end);
     25       if (end - start != name.Length())
     26         return E_INVALIDARG;
     27       resValue = (UInt32)v;
     28     }
     29   }
     30   else
     31     return E_INVALIDARG;
     32   return S_OK;
     33 }
     34 
     35 static const int kLogarithmicSizeLimit = 32;
     36 static const wchar_t kByteSymbol = L'B';
     37 static const wchar_t kKiloByteSymbol = L'K';
     38 static const wchar_t kMegaByteSymbol = L'M';
     39 
     40 HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize)
     41 {
     42   UString srcString = srcStringSpec;
     43   srcString.MakeUpper();
     44 
     45   const wchar_t *start = srcString;
     46   const wchar_t *end;
     47   UInt64 number = ConvertStringToUInt64(start, &end);
     48   int numDigits = (int)(end - start);
     49   if (numDigits == 0 || srcString.Length() > numDigits + 1)
     50     return E_INVALIDARG;
     51   if (srcString.Length() == numDigits)
     52   {
     53     if (number >= kLogarithmicSizeLimit)
     54       return E_INVALIDARG;
     55     dicSize = (UInt32)1 << (int)number;
     56     return S_OK;
     57   }
     58   switch (srcString[numDigits])
     59   {
     60     case kByteSymbol:
     61       if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
     62         return E_INVALIDARG;
     63       dicSize = (UInt32)number;
     64       break;
     65     case kKiloByteSymbol:
     66       if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
     67         return E_INVALIDARG;
     68       dicSize = (UInt32)(number << 10);
     69       break;
     70     case kMegaByteSymbol:
     71       if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
     72         return E_INVALIDARG;
     73       dicSize = (UInt32)(number << 20);
     74       break;
     75     default:
     76       return E_INVALIDARG;
     77   }
     78   return S_OK;
     79 }
     80 
     81 HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
     82 {
     83   if (name.IsEmpty())
     84   {
     85     if (prop.vt == VT_UI4)
     86     {
     87       UInt32 logDicSize = prop.ulVal;
     88       if (logDicSize >= 32)
     89         return E_INVALIDARG;
     90       resValue = (UInt32)1 << logDicSize;
     91       return S_OK;
     92     }
     93     if (prop.vt == VT_BSTR)
     94       return ParsePropDictionaryValue(prop.bstrVal, resValue);
     95     return E_INVALIDARG;
     96   }
     97   return ParsePropDictionaryValue(name, resValue);
     98 }
     99 
    100 bool StringToBool(const UString &s, bool &res)
    101 {
    102   if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0 || s.Compare(L"+") == 0)
    103   {
    104     res = true;
    105     return true;
    106   }
    107   if (s.CompareNoCase(L"OFF") == 0 || s.Compare(L"-") == 0)
    108   {
    109     res = false;
    110     return true;
    111   }
    112   return false;
    113 }
    114 
    115 HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
    116 {
    117   switch(value.vt)
    118   {
    119     case VT_EMPTY:
    120       dest = true;
    121       return S_OK;
    122     case VT_BOOL:
    123       dest = (value.boolVal != VARIANT_FALSE);
    124       return S_OK;
    125     /*
    126     case VT_UI4:
    127       dest = (value.ulVal != 0);
    128       break;
    129     */
    130     case VT_BSTR:
    131       return StringToBool(value.bstrVal, dest) ?  S_OK : E_INVALIDARG;
    132   }
    133   return E_INVALIDARG;
    134 }
    135 
    136 int ParseStringToUInt32(const UString &srcString, UInt32 &number)
    137 {
    138   const wchar_t *start = srcString;
    139   const wchar_t *end;
    140   UInt64 number64 = ConvertStringToUInt64(start, &end);
    141   if (number64 > 0xFFFFFFFF)
    142   {
    143     number = 0;
    144     return 0;
    145   }
    146   number = (UInt32)number64;
    147   return (int)(end - start);
    148 }
    149 
    150 HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
    151 {
    152   if (name.IsEmpty())
    153   {
    154     switch(prop.vt)
    155     {
    156       case VT_UI4:
    157         numThreads = prop.ulVal;
    158         break;
    159       default:
    160       {
    161         bool val;
    162         RINOK(SetBoolProperty(val, prop));
    163         numThreads = (val ? defaultNumThreads : 1);
    164         break;
    165       }
    166     }
    167   }
    168   else
    169   {
    170     UInt32 number;
    171     int index = ParseStringToUInt32(name, number);
    172     if (index != name.Length())
    173       return E_INVALIDARG;
    174     numThreads = number;
    175   }
    176   return S_OK;
    177 }
    178