mirror of
https://github.com/holub/mame
synced 2025-06-10 14:52:42 +03:00
312 lines
6.5 KiB
C++
312 lines
6.5 KiB
C++
// HandlerOut.cpp
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "../../../Common/StringToInt.h"
|
|
|
|
#include "../Common/ParseProperties.h"
|
|
|
|
#include "HandlerOut.h"
|
|
|
|
namespace NArchive {
|
|
|
|
bool ParseSizeString(const wchar_t *s, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res)
|
|
{
|
|
if (*s == 0)
|
|
{
|
|
switch (prop.vt)
|
|
{
|
|
case VT_UI4: res = prop.ulVal; return true;
|
|
case VT_UI8: res = prop.uhVal.QuadPart; return true;
|
|
case VT_BSTR:
|
|
s = prop.bstrVal;
|
|
break;
|
|
default: return false;
|
|
}
|
|
}
|
|
else if (prop.vt != VT_EMPTY)
|
|
return false;
|
|
|
|
bool percentMode = false;
|
|
{
|
|
const wchar_t c = *s;
|
|
if (MyCharLower_Ascii(c) == 'p')
|
|
{
|
|
percentMode = true;
|
|
s++;
|
|
}
|
|
}
|
|
|
|
const wchar_t *end;
|
|
const UInt64 v = ConvertStringToUInt64(s, &end);
|
|
if (s == end)
|
|
return false;
|
|
const wchar_t c = *end;
|
|
|
|
if (percentMode)
|
|
{
|
|
if (c != 0)
|
|
return false;
|
|
res = Calc_From_Val_Percents(percentsBase, v);
|
|
return true;
|
|
}
|
|
|
|
if (c == 0)
|
|
{
|
|
res = v;
|
|
return true;
|
|
}
|
|
if (end[1] != 0)
|
|
return false;
|
|
|
|
if (c == '%')
|
|
{
|
|
res = Calc_From_Val_Percents(percentsBase, v);
|
|
return true;
|
|
}
|
|
|
|
unsigned numBits;
|
|
switch (MyCharLower_Ascii(c))
|
|
{
|
|
case 'b': numBits = 0; break;
|
|
case 'k': numBits = 10; break;
|
|
case 'm': numBits = 20; break;
|
|
case 'g': numBits = 30; break;
|
|
case 't': numBits = 40; break;
|
|
default: return false;
|
|
}
|
|
const UInt64 val2 = v << numBits;
|
|
if ((val2 >> numBits) != v)
|
|
return false;
|
|
res = val2;
|
|
return true;
|
|
}
|
|
|
|
bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres)
|
|
{
|
|
hres = S_OK;
|
|
|
|
if (name.IsPrefixedBy_Ascii_NoCase("mt"))
|
|
{
|
|
#ifndef Z7_ST
|
|
_numThreads = _numProcessors;
|
|
_numThreads_WasForced = false;
|
|
hres = ParseMtProp2(name.Ptr(2), value, _numThreads, _numThreads_WasForced);
|
|
// "mt" means "_numThreads_WasForced = false" here
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
|
|
{
|
|
UInt64 v;
|
|
if (!ParseSizeString(name.Ptr(6), value, _memAvail, v))
|
|
hres = E_INVALIDARG;
|
|
_memUsage_Decompress = v;
|
|
_memUsage_Compress = v;
|
|
_memUsage_WasSet = true;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
#ifndef Z7_EXTRACT_ONLY
|
|
|
|
static void SetMethodProp32(CMethodProps &m, PROPID propID, UInt32 value)
|
|
{
|
|
if (m.FindProp(propID) < 0)
|
|
m.AddProp32(propID, value);
|
|
}
|
|
|
|
void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
|
|
{
|
|
UInt32 level = _level;
|
|
if (level != (UInt32)(Int32)-1)
|
|
SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
|
|
}
|
|
|
|
#ifndef Z7_ST
|
|
|
|
static void SetMethodProp32_Replace(CMethodProps &m, PROPID propID, UInt32 value)
|
|
{
|
|
const int i = m.FindProp(propID);
|
|
if (i >= 0)
|
|
{
|
|
NWindows::NCOM::CPropVariant &val = m.Props[(unsigned)i].Value;
|
|
val = (UInt32)value;
|
|
return;
|
|
}
|
|
m.AddProp32(propID, value);
|
|
}
|
|
|
|
void CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(CMethodProps &oneMethodInfo, UInt32 numThreads)
|
|
{
|
|
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
|
}
|
|
|
|
void CMultiMethodProps::SetMethodThreadsTo_Replace(CMethodProps &oneMethodInfo, UInt32 numThreads)
|
|
{
|
|
SetMethodProp32_Replace(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
|
}
|
|
|
|
#endif // Z7_ST
|
|
|
|
|
|
void CMultiMethodProps::InitMulti()
|
|
{
|
|
_level = (UInt32)(Int32)-1;
|
|
_analysisLevel = -1;
|
|
_crcSize = 4;
|
|
_autoFilter = true;
|
|
}
|
|
|
|
void CMultiMethodProps::Init()
|
|
{
|
|
InitCommon();
|
|
InitMulti();
|
|
_methods.Clear();
|
|
_filterMethod.Clear();
|
|
}
|
|
|
|
|
|
HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
|
|
{
|
|
UString name = nameSpec;
|
|
name.MakeLower_Ascii();
|
|
if (name.IsEmpty())
|
|
return E_INVALIDARG;
|
|
|
|
if (name[0] == 'x')
|
|
{
|
|
name.Delete(0);
|
|
_level = 9;
|
|
return ParsePropToUInt32(name, value, _level);
|
|
}
|
|
|
|
if (name.IsPrefixedBy_Ascii_NoCase("yx"))
|
|
{
|
|
name.Delete(0, 2);
|
|
UInt32 v = 9;
|
|
RINOK(ParsePropToUInt32(name, value, v))
|
|
_analysisLevel = (int)v;
|
|
return S_OK;
|
|
}
|
|
|
|
if (name.IsPrefixedBy_Ascii_NoCase("crc"))
|
|
{
|
|
name.Delete(0, 3);
|
|
_crcSize = 4;
|
|
return ParsePropToUInt32(name, value, _crcSize);
|
|
}
|
|
|
|
{
|
|
HRESULT hres;
|
|
if (SetCommonProperty(name, value, hres))
|
|
return hres;
|
|
}
|
|
|
|
UInt32 number;
|
|
const unsigned index = ParseStringToUInt32(name, number);
|
|
const UString realName = name.Ptr(index);
|
|
if (index == 0)
|
|
{
|
|
if (name.IsEqualTo("f"))
|
|
{
|
|
const HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
|
|
if (res == S_OK)
|
|
return res;
|
|
if (value.vt != VT_BSTR)
|
|
return E_INVALIDARG;
|
|
return _filterMethod.ParseMethodFromPROPVARIANT(UString(), value);
|
|
}
|
|
number = 0;
|
|
}
|
|
if (number > 64)
|
|
return E_INVALIDARG;
|
|
for (unsigned j = _methods.Size(); j <= number; j++)
|
|
_methods.AddNew();
|
|
return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
|
|
}
|
|
|
|
|
|
|
|
void CSingleMethodProps::Init()
|
|
{
|
|
InitCommon();
|
|
InitSingle();
|
|
Clear();
|
|
}
|
|
|
|
|
|
HRESULT CSingleMethodProps::SetProperty(const wchar_t *name2, const PROPVARIANT &value)
|
|
{
|
|
// processed = false;
|
|
UString name = name2;
|
|
name.MakeLower_Ascii();
|
|
if (name.IsEmpty())
|
|
return E_INVALIDARG;
|
|
if (name.IsPrefixedBy_Ascii_NoCase("x"))
|
|
{
|
|
UInt32 a = 9;
|
|
RINOK(ParsePropToUInt32(name.Ptr(1), value, a))
|
|
_level = a;
|
|
AddProp_Level(a);
|
|
// processed = true;
|
|
return S_OK;
|
|
}
|
|
{
|
|
HRESULT hres;
|
|
if (SetCommonProperty(name, value, hres))
|
|
{
|
|
// processed = true;
|
|
return S_OK;
|
|
}
|
|
}
|
|
RINOK(ParseMethodFromPROPVARIANT(name, value))
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
|
|
{
|
|
Init();
|
|
|
|
for (UInt32 i = 0; i < numProps; i++)
|
|
{
|
|
RINOK(SetProperty(names[i], values[i]))
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest)
|
|
{
|
|
RINOK(PROPVARIANT_to_bool(prop, dest.Val))
|
|
dest.Def = true;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CHandlerTimeOptions::Parse(const UString &name, const PROPVARIANT &prop, bool &processed)
|
|
{
|
|
processed = true;
|
|
if (name.IsEqualTo_Ascii_NoCase("tm")) { return PROPVARIANT_to_BoolPair(prop, Write_MTime); }
|
|
if (name.IsEqualTo_Ascii_NoCase("ta")) { return PROPVARIANT_to_BoolPair(prop, Write_ATime); }
|
|
if (name.IsEqualTo_Ascii_NoCase("tc")) { return PROPVARIANT_to_BoolPair(prop, Write_CTime); }
|
|
if (name.IsPrefixedBy_Ascii_NoCase("tp"))
|
|
{
|
|
UInt32 v = 0;
|
|
RINOK(ParsePropToUInt32(name.Ptr(2), prop, v))
|
|
Prec = v;
|
|
return S_OK;
|
|
}
|
|
processed = false;
|
|
return S_OK;
|
|
}
|
|
|
|
}
|