in ctsTraffic/ctsConfig.cpp [824:1061]
static void ParseForIoPattern(vector<const wchar_t*>& args)
{
auto foundArgument = ranges::find_if(args, [](const wchar_t* parameter) -> bool {
const auto* const value = ParseArgument(parameter, L"-pattern");
return value != nullptr;
});
if (foundArgument != end(args))
{
if (g_configSettings->Protocol != ProtocolType::TCP)
{
throw invalid_argument("-pattern (only applicable to TCP)");
}
// ReSharper disable once CppTooWideScopeInitStatement
const auto* const value = ParseArgument(*foundArgument, L"-pattern");
if (ctString::ctOrdinalEqualsCaseInsensative(L"push", value))
{
g_configSettings->IoPattern = IoPatternType::Push;
}
else if (ctString::ctOrdinalEqualsCaseInsensative(L"pull", value))
{
g_configSettings->IoPattern = IoPatternType::Pull;
}
else if (ctString::ctOrdinalEqualsCaseInsensative(L"pushpull", value))
{
g_configSettings->IoPattern = IoPatternType::PushPull;
}
else if (ctString::ctOrdinalEqualsCaseInsensative(L"flood", value) || ctString::ctOrdinalEqualsCaseInsensative(L"duplex", value))
{
// the old name for this was 'flood'
g_configSettings->IoPattern = IoPatternType::Duplex;
}
else
{
throw invalid_argument("-pattern");
}
// always remove the arg from our vector
args.erase(foundArgument);
}
else
{
if (g_configSettings->Protocol == ProtocolType::UDP)
{
g_configSettings->IoPattern = IoPatternType::MediaStream;
}
else
{
// default the TCP pattern to Push
g_configSettings->IoPattern = IoPatternType::Push;
}
}
// Now look for options tightly coupled to Protocol
// ReSharper disable once CppTooWideScopeInitStatement
const auto foundPushbytes = ranges::find_if(args, [](const wchar_t* parameter) -> bool {
const auto* const value = ParseArgument(parameter, L"-pushbytes");
return value != nullptr;
});
if (foundPushbytes != end(args))
{
if (g_configSettings->IoPattern != IoPatternType::PushPull)
{
throw invalid_argument("-PushBytes can only be set with -Pattern:PushPull");
}
g_configSettings->PushBytes = ConvertToIntegral<uint32_t>(ParseArgument(*foundPushbytes, L"-pushbytes"));
// always remove the arg from our vector
args.erase(foundPushbytes);
}
else
{
g_configSettings->PushBytes = c_defaultPushBytes;
}
// ReSharper disable once CppTooWideScopeInitStatement
const auto foundPullbytes = ranges::find_if(args, [](const wchar_t* parameter) -> bool {
const auto* const value = ParseArgument(parameter, L"-pullbytes");
return value != nullptr;
});
if (foundPullbytes != end(args))
{
if (g_configSettings->IoPattern != IoPatternType::PushPull)
{
throw invalid_argument("-PullBytes can only be set with -Pattern:PushPull");
}
g_configSettings->PullBytes = ConvertToIntegral<uint32_t>(ParseArgument(*foundPullbytes, L"-pullbytes"));
// always remove the arg from our vector
args.erase(foundPullbytes);
}
else
{
g_configSettings->PullBytes = c_defaultPullBytes;
}
// ReSharper disable once CppTooWideScopeInitStatement
const auto foundBurstCount = ranges::find_if(args, [](const wchar_t* parameter) -> bool {
const auto* const value = ParseArgument(parameter, L"-burstcount");
return value != nullptr;
});
if (foundBurstCount != end(args))
{
if (g_configSettings->Protocol != ProtocolType::TCP)
{
throw invalid_argument("-BurstCount requires -Protocol:TCP");
}
g_configSettings->BurstCount = ConvertToIntegral<uint32_t>(ParseArgument(*foundBurstCount, L"-burstcount"));
if (g_configSettings->BurstCount == 0ul)
{
throw invalid_argument("-BurstCount requires a non-zero value");
}
// always remove the arg from our vector
args.erase(foundBurstCount);
}
// ReSharper disable once CppTooWideScopeInitStatement
const auto foundBurstDelay = ranges::find_if(args, [](const wchar_t* parameter) -> bool {
const auto* const value = ParseArgument(parameter, L"-burstdelay");
return value != nullptr;
});
if (foundBurstDelay != end(args))
{
if (g_configSettings->Protocol != ProtocolType::TCP)
{
throw invalid_argument("-BurstDelay requires -Protocol:TCP");
}
g_configSettings->BurstDelay = ConvertToIntegral<uint32_t>(ParseArgument(*foundBurstDelay, L"-burstdelay"));
if (g_configSettings->BurstDelay == 0ul)
{
throw invalid_argument("-BurstDelay requires a non-zero value");
}
// always remove the arg from our vector
args.erase(foundBurstDelay);
}
// ReSharper disable CppRedundantParentheses
if ((g_configSettings->BurstCount.has_value() && !g_configSettings->BurstDelay.has_value()) ||
(!g_configSettings->BurstCount.has_value() && g_configSettings->BurstDelay.has_value()))
{
throw invalid_argument("-BurstCount and -BurstDelay must both be set if either are set");
}
// ReSharper restore CppRedundantParentheses
//
// Options for the UDP protocol
//
foundArgument = ranges::find_if(args, [](const wchar_t* parameter) -> bool {
const auto* const value = ParseArgument(parameter, L"-BitsPerSecond");
return value != nullptr;
});
if (foundArgument != end(args))
{
if (g_configSettings->Protocol != ProtocolType::UDP)
{
throw invalid_argument("-BitsPerSecond requires -Protocol:UDP");
}
g_mediaStreamSettings.BitsPerSecond = ConvertToIntegral<int64_t>(ParseArgument(*foundArgument, L"-BitsPerSecond"));
// bitspersecond must align on a byte-boundary
if (g_mediaStreamSettings.BitsPerSecond % 8 != 0)
{
g_mediaStreamSettings.BitsPerSecond -= g_mediaStreamSettings.BitsPerSecond % 8;
}
// always remove the arg from our vector
args.erase(foundArgument);
}
foundArgument = ranges::find_if(args, [](const wchar_t* parameter) -> bool {
const auto* const value = ParseArgument(parameter, L"-FrameRate");
return value != nullptr;
});
if (foundArgument != end(args))
{
if (g_configSettings->Protocol != ProtocolType::UDP)
{
throw invalid_argument("-FrameRate requires -Protocol:UDP");
}
g_mediaStreamSettings.FramesPerSecond = ConvertToIntegral<uint32_t>(ParseArgument(*foundArgument, L"-FrameRate"));
// always remove the arg from our vector
args.erase(foundArgument);
}
foundArgument = ranges::find_if(args, [](const wchar_t* parameter) -> bool {
const auto* const value = ParseArgument(parameter, L"-BufferDepth");
return value != nullptr;
});
if (foundArgument != end(args))
{
if (g_configSettings->Protocol != ProtocolType::UDP)
{
throw invalid_argument("-BufferDepth requires -Protocol:UDP");
}
g_mediaStreamSettings.BufferDepthSeconds = ConvertToIntegral<uint32_t>(ParseArgument(*foundArgument, L"-BufferDepth"));
// always remove the arg from our vector
args.erase(foundArgument);
}
else
{
// default buffer depth to 1
g_mediaStreamSettings.BufferDepthSeconds = 1;
}
foundArgument = ranges::find_if(args, [](const wchar_t* parameter) -> bool {
const auto* const value = ParseArgument(parameter, L"-StreamLength");
return value != nullptr;
});
if (foundArgument != end(args))
{
if (g_configSettings->Protocol != ProtocolType::UDP)
{
throw invalid_argument("-StreamLength requires -Protocol:UDP");
}
g_mediaStreamSettings.StreamLengthSeconds = ConvertToIntegral<uint32_t>(ParseArgument(*foundArgument, L"-StreamLength"));
// always remove the arg from our vector
args.erase(foundArgument);
}
// validate and resolve the UDP protocol options
if (ProtocolType::UDP == g_configSettings->Protocol)
{
if (0 == g_mediaStreamSettings.BitsPerSecond)
{
throw invalid_argument("-BitsPerSecond is required");
}
if (0 == g_mediaStreamSettings.FramesPerSecond)
{
throw invalid_argument("-FrameRate is required");
}
if (0 == g_mediaStreamSettings.StreamLengthSeconds)
{
throw invalid_argument("-StreamLength is required");
}
// finally calculate the total stream length after all settings are captured from the user
g_transferSizeLow = g_mediaStreamSettings.CalculateTransferSize();
}
}