Files
CPP/common/utility.hpp
2025-12-05 09:22:45 -05:00

185 lines
4.6 KiB
C++

#ifndef _COMMON_UTILITY_HPP_
#define _COMMON_UTILITY_HPP_
#include <stdio.h>
#include <limits>
#include <cmath>
#include <filesystem>
#include <sys/statvfs.h>
#include <common/string.hpp>
class Utility
{
public:
static String formatNumber(size_t number,bool commas=true);
static String formatNumber(long number,bool commas=true);
static String formatNumber(double number,bool commas=true);
static String formatNumber(double number,int places=2);
static String formatCurrency(double number,int places=2);
static bool fmod(double dividend,double divisor);
static bool fmod(double dividend, double divisor,double epsilon);
static String byteCountToString(double bytesTransferred, bool perSecond = true);
static size_t getAvailableDiskSpace(const String &path);
private:
static String pad(String theString,char padChar,int toLength);
static String addCommas(String& theString);
Utility();
~Utility();
};
inline
Utility::Utility()
{
}
inline
Utility::~Utility()
{
}
inline
String Utility::byteCountToString(double bytesTransferred, bool perSecond)
{
double roundedValue = std::round(bytesTransferred * 100.00)/100.00;
String strBytesTransferrred;
if(roundedValue >= 1E+15)
{
strBytesTransferrred = Utility::formatNumber(roundedValue/1E+15,2) + "Pb";
}
else if(roundedValue >= 1000000000000)
{
strBytesTransferrred = Utility::formatNumber(roundedValue/1000000000000,2) + "Tb";
}
else if(roundedValue >= 1073741824)
{
strBytesTransferrred = Utility::formatNumber(roundedValue/1073741824,2) + "Gb";
}
else if(roundedValue >= 1000000)
{
strBytesTransferrred = Utility::formatNumber(roundedValue/1000000,2) + "Mb";
}
else if(roundedValue >= 1000)
{
strBytesTransferrred = Utility::formatNumber(roundedValue/1000,2) + "Kb";
}
else strBytesTransferrred = Utility::formatNumber(roundedValue,2) + "B";
if(perSecond)strBytesTransferrred+="/s";
return strBytesTransferrred;
}
inline
String Utility::formatNumber(size_t number, bool commas)
{
String formattedString;
String format="%lu";
::sprintf(formattedString.str(),format,number);
return addCommas(formattedString);
}
inline
String Utility::formatNumber(long number,bool commas)
{
String formattedString;
String format="%ld";
::sprintf(formattedString.str(),format,number);
return addCommas(formattedString);
}
inline
String Utility::formatNumber(double number,int places)
{
String numberString = formatCurrency(number, places);
return numberString.substr(1);
}
inline
String Utility::formatCurrency(double number,int places)
{
String formattedString;
String format="%.";
format+=String().fromInt(places);
format+="f";
::sprintf(formattedString.str(),format,number);
Block<String> items = formattedString.split('.');
if(items[0].length()<=3)
{
if(2==items.size())
{
return "$"+items[0]+"."+items[1];
}
else
{
return "$"+items[0];
}
}
String wholePart = addCommas(items[0]);
if(2==items.size())
{
return "$"+wholePart+"."+items[1];
}
return "$"+wholePart;
}
inline
String Utility::addCommas(String& wholePart)
{
String placesString;
wholePart=wholePart.reverse();
for(int index=0;index<wholePart.length();index++)
{
if(index>0 && 0==(index%3))placesString+=",";
placesString+=wholePart.charAt(index);
}
placesString=placesString.reverse();
return placesString;
}
inline
String Utility::pad(String theString,char padChar,int toLength)
{
while(theString.length()<toLength)theString+=padChar;
return theString;
}
inline
bool Utility::fmod(double dividend, double divisor,double epsilon)
{
if (divisor == 0.0)
{
return false;
}
// Calculate the remainder
double remainder = std::fmod(dividend, divisor);
// Check if the absolute remainder is less than epsilon
return std::fabs(remainder) < std::fabs(epsilon);
}
inline
bool Utility::fmod(double dividend, double divisor)
{
if (divisor == 0.0)
{
return false;
}
// Define a small epsilon value for floating-point comparisons
// Using machine epsilon for double is a common choice.
const double epsilon = std::numeric_limits<double>::epsilon() * 100; // Multiplied for a slightly larger tolerance
// Calculate the remainder
double remainder = std::fmod(dividend, divisor);
// Check if the absolute remainder is less than epsilon
return std::fabs(remainder) < epsilon;
}
inline
size_t Utility::getAvailableDiskSpace(const String& path)
{
std::filesystem::space_info si = std::filesystem::space(path.str());
return si.available;
}
#endif