Overview
The Utility module provides a collection of helper functions and utilities used throughout ascii-chat. These include string manipulation, path handling, IP address parsing, mathematical operations, and format conversion.
Implementation: lib/util/*.h
Key Features:
- Hardware-accelerated CRC32 checksums (SSE4.2, ARM CRC32)
- Aspect ratio calculations and frame fitting
- IP address parsing and validation (IPv4/IPv6)
- UTF-8 string handling and validation
- Path manipulation and normalization
- String parsing and formatting utilities
- Cross-platform mathematical operations
Utility Modules
CRC32 Checksums
Hardware Acceleration:
uint32_t checksum = crc32_compute(data, length);
if (crc32_hw_supported()) {
log_info("Using hardware CRC32 acceleration");
}
Platforms:
- x86/x64: SSE4.2 instructions (CRC32C)
- ARM: ARM CRC32 instructions
- Fallback: Software table-based CRC32
Aspect Ratio
Calculate Aspect Ratio:
int image_width = 1920, image_height = 1080;
dimensions_t fitted = fit_to_aspect_ratio(
image_width, image_height
);
log_info("Fitted size: %dx%d", fitted.width, fitted.height);
int display_width(const char *text)
Maintain Aspect Ratio:
dimensions_t dims = calculate_aspect_ratio_fit(
src_width, src_height,
dst_width, dst_height,
maintain_aspect_ratio
);
IP Address Utilities
Parse IP Addresses:
struct in_addr addr4;
if (parse_ipv4("192.168.1.1", &addr4)) {
log_info("Valid IPv4 address");
}
struct in6_addr addr6;
if (parse_ipv6("::1", &addr6)) {
log_info("Valid IPv6 address");
}
Validate IP Addresses:
log_info("Valid IPv4");
}
log_info("Valid IPv6");
}
int is_valid_ipv4(const char *ip)
int is_valid_ipv6(const char *ip)
Format IP Addresses:
char ip_str[INET6_ADDRSTRLEN];
log_info("IP: %s", ip_str);
asciichat_error_t format_ip_address(int family, const struct sockaddr *addr, char *output, size_t output_size)
UTF-8 String Handling
Validate UTF-8:
const char *text = "Hello, δΈη!";
if (is_valid_utf8(text)) {
log_info("Valid UTF-8 string");
}
Count UTF-8 Characters:
size_t char_count = utf8_strlen(text);
size_t byte_count = strlen(text);
log_info("Characters: %zu, Bytes: %zu", char_count, byte_count);
Iterate UTF-8 Characters:
const char *p = text;
while (*p) {
uint32_t codepoint;
log_debug("Codepoint: U+%04X", codepoint);
p += bytes;
}
int utf8_decode(const uint8_t *s, uint32_t *codepoint)
Path Utilities
Normalize Paths:
char normalized[PATH_MAX];
normalize_path("/path/to/../file.txt", normalized, sizeof(normalized));
Join Paths:
char joined[PATH_MAX];
join_path("/home/user", ".ssh/id_ed25519", joined, sizeof(joined));
Expand Home Directory:
char expanded[PATH_MAX];
expand_home_dir("~/.ssh/known_hosts", expanded, sizeof(expanded));
Get File Extension:
const char *ext = get_file_extension("document.pdf");
String Utilities
Trim Whitespace:
char text[] = " hello world ";
trim_whitespace(text);
String Matching:
if (str_starts_with(text, "hello")) {
log_info("Text starts with 'hello'");
}
if (str_ends_with(text, "world")) {
log_info("Text ends with 'world'");
}
Case-Insensitive Compare:
if (strcasecmp_safe(str1, str2) == 0) {
log_info("Strings are equal (case-insensitive)");
}
Parsing Utilities
Parse Integers:
int value;
if (parse_int("1234", &value)) {
log_info("Parsed: %d", value);
}
if (parse_int_range("42", &value, 0, 100)) {
log_info("Valid value in range: %d", value);
}
Parse Floating Point:
double value;
if (parse_double("3.14159", &value)) {
log_info("Parsed: %f", value);
}
Parse Boolean:
bool value;
if (parse_bool("true", &value)) {
log_info("Boolean: %s", value ? "true" : "false");
}
Format Utilities
Format Byte Sizes:
char size_str[32];
format_bytes(1024 * 1024 * 5, size_str, sizeof(size_str));
Format Duration:
char duration[64];
format_duration(3665, duration, sizeof(duration));
Format Timestamp:
char timestamp[32];
format_timestamp(time(NULL), timestamp, sizeof(timestamp));
Mathematical Utilities
Safe Integer Math:
int clamped = clamp(value, 0, 100);
int min_val = min(a, b);
int max_val = max(a, b);
Rounding:
int rounded = round_to_int(3.7);
int ceil_val = round_up(3.2);
int floor_val = round_down(3.8);
Alignment:
size_t aligned = align_up(123, 16);
size_t aligned_down = align_down(123, 16);
Performance Notes
CRC32 Hardware Acceleration:
- ~10x faster on x86 with SSE4.2
- ~8x faster on ARM with CRC32 instructions
- Automatically detected at runtime
UTF-8 Validation:
- Optimized for ASCII-common case
- SIMD acceleration where available
- Early exit on invalid sequences
Path Operations:
- In-place modifications where possible
- Minimal allocations
- Platform-specific optimizations
Best Practices
DO:
- Validate input strings before processing
- Use UTF-8 functions for international text
- Check return values from parsing functions
- Use hardware-accelerated CRC32 when available
- Normalize paths before comparison
DON'T:
- Don't assume ASCII-only input
- Don't ignore parse errors
- Don't use strcpy/sprintf (use safe versions)
- Don't hard-code path separators
- Don't perform string operations without bounds checking
- See also
- lib/crc32.h
-
lib/util/aspect_ratio.h
-
lib/util/ip.h
-
lib/util/utf8.h
-
lib/util/path.h
-
lib/util/string.h
-
lib/util/parsing.h
-
lib/util/format.h
-
lib/util/math.h