#include #include #include #include #include "fast_float/fast_float.h" char* uint8_to_chars_manual(char* ptr, uint8_t value) { if (value == 0) { *ptr++ = '0'; return ptr; } char* start = ptr; while (value > 0) { *ptr++ = '0' + (value % 10); value /= 10; } // Reverse the digits written so far std::reverse(start, ptr); return ptr; } void uint32_to_ipv4_string(uint32_t ip, char* buffer) { uint8_t octets[4] = { static_cast(ip >> 24), static_cast(ip >> 16), static_cast(ip >> 8), static_cast(ip) }; char* ptr = buffer; for (int i = 0; i < 4; ++i) { ptr = uint8_to_chars_manual(ptr, octets[i]); if (i < 3) { *ptr++ = '.'; } } *ptr = '\0'; } fastfloat_really_inline uint32_t ipv4_string_to_uint32(const char* str, const char* end) { uint32_t ip = 0; const char* current = str; for (int i = 0; i < 4; ++i) { uint8_t value; auto r = fast_float::from_chars(current, end, value); if (r.ec != std::errc()) { throw std::invalid_argument("Invalid IP address format"); } current = r.ptr; ip = (ip << 8) | value; if (i < 3) { if (current == end || *current++ != '.') { throw std::invalid_argument("Invalid IP address format"); } } } return ip; } bool test_all_ipv4_conversions() { std::cout << "Testing all IPv4 conversions... 0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, ..." << std::endl; char buffer[16]; for (uint64_t ip = 0; ip <= 0xFFFFFFFF; ip+=1000) { if(ip % 10000000 == 0) { std::cout << "." << std::flush; } uint32_to_ipv4_string(static_cast(ip), buffer); const char* end = buffer + strlen(buffer); uint32_t parsed_ip = ipv4_string_to_uint32(buffer, end); if (parsed_ip != ip) { std::cerr << "Mismatch: original " << ip << ", parsed " << parsed_ip << std::endl; return false; } } std::cout << std::endl; return true; } int main() { if (test_all_ipv4_conversions()) { std::cout << "All IPv4 conversions passed!" << std::endl; return EXIT_SUCCESS; } else { std::cerr << "IPv4 conversion test failed!" << std::endl; return EXIT_FAILURE; } }