Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Series enhancement for unit prefix #6

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 105 additions & 78 deletions src/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,26 @@ App::App()
valueMapping[toString(Statistics::humanReadableByte)] = "Human Readable (Byte)";
valueMapping[toString(Statistics::bit)] = "Bit";
valueMapping[toString(Statistics::byte)] = "Byte";
valueMapping[toString(Statistics::kibiBit)] = "KiBit";
valueMapping[toString(Statistics::kibiByte)] = "KiByte";
valueMapping[toString(Statistics::mebiBit)] = "MiBit";
valueMapping[toString(Statistics::mebiByte)] = "MiByte";
valueMapping[toString(Statistics::gibiBit)] = "GiBit";
valueMapping[toString(Statistics::gibiByte)] = "GiByte";
valueMapping[toString(Statistics::tebiBit)] = "TiBit";
valueMapping[toString(Statistics::tebiByte)] = "TiByte";
valueMapping[toString(Statistics::pebiBit)] = "PiBit";
valueMapping[toString(Statistics::pebiByte)] = "PiByte";
valueMapping[toString(Statistics::kiloBit)] = "kBit";
valueMapping[toString(Statistics::kiloByte)] = "kByte";
valueMapping[toString(Statistics::megaBit)] = "MBit";
valueMapping[toString(Statistics::megaByte)] = "MByte";
valueMapping[toString(Statistics::gigaBit)] = "GBit";
valueMapping[toString(Statistics::gigaByte)] = "GByte";
valueMapping[toString(Statistics::teraBit)] = "TBit";
valueMapping[toString(Statistics::teraByte)] = "TByte";
valueMapping[toString(Statistics::petaBit)] = "PBit";
valueMapping[toString(Statistics::petaByte)] = "PByte";
SettingStore::get("TrafficFormat").pushFilter(new SettingFilterMap(valueMapping));
SettingStore::get("DataFormat").pushFilter(new SettingFilterMap(valueMapping));
valueMapping.clear();
Expand Down Expand Up @@ -207,12 +221,12 @@ int App::run(const vector<string>& arguments)
break;
}
}
// has the user set a non-default unit for traffic numbers?
else if(*itArg == "-u")
// has the user set a non-default unit for traffic numbers or amount numbers?
else if(*itArg == "-u" || *itArg == "-U")
{
Setting& setting = SettingStore::get("TrafficFormat");

if(haveNextArg && itNextArg->length() == 1)
char opt = (*itArg)[1];
Setting& setting = SettingStore::get(opt == 'u' ? "TrafficFormat" : "DataFormat");
if(haveNextArg && (itNextArg->length() == 1 || itNextArg->length() == 2))
{
switch((*itNextArg)[0])
{
Expand All @@ -229,84 +243,92 @@ int App::run(const vector<string>& arguments)
setting = Statistics::bit;
break;
case 'K':
setting = Statistics::kiloByte;
setting = Statistics::kibiByte;
break;
case 'k':
setting = Statistics::kiloBit;
setting = Statistics::kibiBit;
break;
case 'M':
setting = Statistics::megaByte;
setting = Statistics::mebiByte;
break;
case 'm':
setting = Statistics::megaBit;
setting = Statistics::mebiBit;
break;
case 'G':
setting = Statistics::gigaByte;
setting = Statistics::gibiByte;
break;
case 'g':
setting = Statistics::gigaBit;
setting = Statistics::gibiBit;
break;
default:
printHelpAndExit = true;
case 'T':
setting = Statistics::tebiByte;
break;
}

++itArg;
}
else
{
printHelpAndExit = true;
}

if(printHelpAndExit)
{
cerr << "Wrong argument for the -u parameter." << endl;
break;
}
}
// has the user set a non-default unit for numbers of amount of data?
else if(*itArg == "-U")
{
Setting& setting = SettingStore::get("DataFormat");

if(haveNextArg && itNextArg->length() == 1)
{
switch((*itNextArg)[0])
{
case 'H':
setting = Statistics::humanReadableByte;
break;
case 'h':
setting = Statistics::humanReadableBit;
break;
case 'B':
setting = Statistics::byte;
break;
case 'b':
setting = Statistics::bit;
break;
case 'K':
setting = Statistics::kiloByte;
break;
case 'k':
setting = Statistics::kiloBit;
case 't':
setting = Statistics::tebiBit;
break;
case 'M':
setting = Statistics::megaByte;
case 'P':
setting = Statistics::pebiByte;
break;
case 'm':
setting = Statistics::megaBit;
break;
case 'G':
setting = Statistics::gigaByte;
break;
case 'g':
setting = Statistics::gigaBit;
case 'p':
setting = Statistics::pebiBit;
break;
default:
printHelpAndExit = true;
break;
}
if(itNextArg->length() == 2)
{
switch((*itNextArg)[1])
{
case 'i':
// IEC binary prefixes
break;
case 's':
// SI metric prefixes
switch((int)setting) {
case Statistics::humanReadableBit:
setting = Statistics::humanReadableSiBit;
break;
case Statistics::humanReadableByte:
setting = Statistics::humanReadableSiByte;
break;
case Statistics::kibiBit:
setting = Statistics::kiloBit;
break;
case Statistics::kibiByte:
setting = Statistics::kiloByte;
break;
case Statistics::mebiBit:
setting = Statistics::megaBit;
break;
case Statistics::mebiByte:
setting = Statistics::megaByte;
break;
case Statistics::gibiBit:
setting = Statistics::gigaBit;
break;
case Statistics::gibiByte:
setting = Statistics::gigaByte;
break;
case Statistics::tebiBit:
setting = Statistics::teraBit;
break;
case Statistics::tebiByte:
setting = Statistics::teraByte;
break;
case Statistics::pebiBit:
setting = Statistics::petaBit;
break;
case Statistics::pebiByte:
setting = Statistics::petaByte;
break;
}
break;
default:
printHelpAndExit = true;
break;
}
}

++itArg;
}
Expand All @@ -317,7 +339,7 @@ int App::run(const vector<string>& arguments)

if(printHelpAndExit)
{
cerr << "Wrong argument for the -U parameter." << endl;
cerr << "Wrong argument for the -" << opt << " parameter." << endl;
break;
}
}
Expand Down Expand Up @@ -501,31 +523,36 @@ void App::printHelp(bool error)
<< "GNU General Public License Version 2 (http://www.gnu.org/copyleft/gpl.html).\n\n"

<< "Command line syntax:\n"
<< PACKAGE << " [options] [devices]\n"
<< PACKAGE << " [<options>] [<devices>]\n"
<< PACKAGE << " --help|-h\n\n"

<< "Options:\n"
<< "-a period Sets the length in seconds of the time window for average\n"
<< "-a <period> Sets the length in seconds of the time window for average\n"
<< " calculation.\n"
<< " Default is " << STANDARD_AVERAGE_WINDOW << ".\n"
<< "-i max_scaling Specifies the 100% mark in kBit/s of the graph indicating the\n"
<< "-i <max_scaling>\n"
<< " Specifies the 100% mark in kBit/s of the graph indicating the\n"
<< " incoming bandwidth usage. Use 0 for automatic scaling.\n"
<< " Ignored if the switch -m is given.\n"
<< " Default is " << STANDARD_MAX_DEFLECTION << ".\n"
<< "-m Show multiple devices at a time; no traffic graphs.\n"
<< "-o max_scaling Same as -i but for the graph indicating the outgoing bandwidth\n"
<< "-o <max_scaling>\n"
<< " Same as -i but for the graph indicating the outgoing bandwidth\n"
<< " usage.\n"
<< " Default is " << STANDARD_MAX_DEFLECTION << ".\n"
<< "-t interval Determines the refresh interval of the display in milliseconds.\n"
<< "-t <interval> Determines the refresh interval of the display in milliseconds.\n"
<< " Default is " << STANDARD_REFRESH_INTERVAL << ".\n"
<< "-u h|b|k|m|g Sets the type of unit used for the display of traffic numbers.\n"
<< " H|B|K|M|G h: auto, b: Bit/s, k: kBit/s, m: MBit/s etc.\n"
<< " H: auto, B: Byte/s, K: kByte/s, M: MByte/s etc.\n"
<< " Default is h.\n"
<< "-U h|b|k|m|g Same as -u, but for a total amount of data (without \"/s\").\n"
<< " H|B|K|M|G Default is H.\n"
<< "-f filename Append traffic data to the named file.\n"
<< "devices Network devices to use.\n"
<< "-u h|b|k|m|g|t|p|H|B|K|M|G|T|P[i|s]\n"
<< " Sets the type of unit used for the display of traffic numbers.\n"
<< " h: auto, b: Bit/s, k: {k|Ki}Bit/s, m: M[i]Bit/s etc.\n"
<< " H: auto, B: Byte/s, K: {k|Ki}Byte/s, M: M[i]Byte/s etc.\n"
<< " i: IEC binary prefixes, s: SI metric prefixes\n"
<< " Default is hi.\n"
<< "-U h|b|k|m|g|t|p|H|B|K|M|G|T|P[i|s]\n"
<< " Same as -u, but for a total amount of data (without \"/s\").\n"
<< " Default is Hi.\n"
<< "-f <filename> Append traffic data to the named file.\n"
<< "<devices> Network devices to use.\n"
<< " Default is to use all auto-detected devices.\n"
<< "--help\n"
<< "-h Print this help.\n\n"
Expand Down
84 changes: 73 additions & 11 deletions src/statistics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,31 +98,61 @@ unsigned long Statistics::getLatestTimeStampMicroseconds() const
float Statistics::getUnitFactor(dataUnit unit, unsigned long long value)
{
float factor = 1.0 / (unit % 2 == 0 ? 8 : 1);

switch(unit)
{
case humanReadableBit:
case humanReadableByte:
for(int i = 0; i < 3; ++i)
for(int i = 0; i < 5; ++i)
{
if(value / factor < 1024)
return factor;

factor *= 1024;
}
return factor;
case humanReadableSiBit:
case humanReadableSiByte:
for(int i = 0; i < 5; i++) {
if(value / factor < 1000)
return factor;

factor *= 1000;
}
return factor;
case bit:
case byte:
return factor;
case kibiBit:
case kibiByte:
return factor * 1024;
case mebiBit:
case mebiByte:
return factor * 1024 * 1024;
case gibiBit:
case gibiByte:
return factor * 1024 * 1024 * 1024;
case tebiBit:
case tebiByte:
return factor * 1024 * 1024 * 1024 * 1024;
case pebiBit:
case pebiByte:
return factor * 1024 * 1024 * 1024 * 1024 * 1024;
case kiloBit:
case kiloByte:
return factor * 1024;
return factor * 1000;
case megaBit:
case megaByte:
return factor * 1024 * 1024;
return factor * 1000 * 1000;
case gigaBit:
case gigaByte:
return factor * 1024 * 1024 * 1024;
return factor * 1000 * 1000 * 1000;
case teraBit:
case teraByte:
return factor * 1000 * 1000 * 1000 * 1000;
case petaBit:
case petaByte:
return factor * 1000 * 1000 * 1000 * 1000 * 1000;
default: // should never be executed
return factor;
}
Expand All @@ -131,33 +161,65 @@ float Statistics::getUnitFactor(dataUnit unit, unsigned long long value)
string Statistics::getUnitString(dataUnit unit, unsigned long long value)
{
const string description = (unit % 2 == 0 ? "Bit" : "Byte");
const string units[] = { "", "k", "M", "G" };
const string units[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi" };
const string si_units[] = { "", "k", "M", "G", "T", "P" };

switch(unit)
{
case humanReadableBit:
case humanReadableByte:
value *= (unit % 2 == 0 ? 8 : 1);
for(int i = 0; i < 3; ++i)
for(int i = 0; i < 5; ++i)
{
if(value < 1024)
return units[i] + description;

value /= 1024;
}
return units[3] + description;
return units[5] + description;
case humanReadableSiBit:
case humanReadableSiByte:
value *= (unit % 2 == 0 ? 8 : 1);
for(int i = 0; i < 5; i++) {
if(value < 1000)
return si_units[i] + description;

value /= 1000;
}
return si_units[5] + description;
case bit:
case byte:
return description;
case kibiBit:
case kibiByte:
return "Ki" + description;
case mebiBit:
case mebiByte:
return "Mi" + description;
case gibiBit:
case gibiByte:
return "Gi" + description;
case tebiBit:
case tebiByte:
return "Ti" + description;
case pebiBit:
case pebiByte:
return "Pi" + description;
case kiloBit:
case kiloByte:
return 'k' + description;
return "k" + description;
case megaBit:
case megaByte:
return 'M' + description;
return "M" + description;
case gigaBit:
case gigaByte:
return 'G' + description;
return "G" + description;
case teraBit:
case teraByte:
return "T" + description;
case petaBit:
case petaByte:
return "P" + description;
default: // should never be executed
return description;
}
Expand Down
Loading