ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
Utility Functions

πŸ› οΈ String, path, IP, UTF-8, CRC32, and formatting utilities More...

Files

file  musl_c23_compat.c
 πŸ”„ musl C23 compatibility wrappers for __isoc23_* symbol aliases (glibc 2.38+ compatibility)
 
file  crc32.c
 βš‘ Hardware-accelerated CRC32 checksum with ARM64 and x86_64 CPU feature detection
 
file  aspect_ratio.c
 πŸ“ Terminal cell aspect ratio calculations for accurate image dimension scaling
 
file  format.c
 πŸ“Š Byte size formatting utilities for human-readable output (B, KB, MB, GB, TB)
 
file  image.c
 πŸ–ΌοΈ Safe overflow-checked buffer size calculations for images and video frames
 
file  ip.c
 πŸŒ IPv4/IPv6 address parsing, validation, and formatting utilities
 
file  parsing.c
 πŸ” Safe string parsing utilities for integers, sizes, and protocol messages
 
file  password.c
 πŸ”‘ Password prompting utilities with secure input and formatting
 
file  path.c
 Cross-platform path manipulation with normalization and Windows/Unix separator handling.
 
file  pcre2.c
 Centralized PCRE2 singleton pattern for efficient regex compilation.
 
file  string.c
 πŸ”€ String manipulation utilities: ASCII escaping, trimming, case conversion, and formatting
 
file  url.c
 Production-grade URL parsing and validation using PCRE2.
 
file  utf8.c
 πŸ”€ UTF-8 encoding and decoding with multi-byte character support
 
file  version.c
 πŸ·οΈ Binary-embedded version information in custom ELF/Mach-O sections for runtime inspection
 

Detailed Description

πŸ› οΈ String, path, IP, UTF-8, CRC32, and formatting utilities

Utility Functions

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:

// CRC32 with automatic hardware acceleration
uint32_t checksum = crc32_compute(data, length);
// Check if hardware acceleration is available
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:

// Calculate aspect ratio for fitting
int display_width = 80, display_height = 24;
int image_width = 1920, image_height = 1080;
dimensions_t fitted = fit_to_aspect_ratio(
display_width, display_height,
image_width, image_height
);
log_info("Fitted size: %dx%d", fitted.width, fitted.height);
int display_width(const char *text)

Maintain Aspect Ratio:

// Get dimensions that maintain aspect ratio
dimensions_t dims = calculate_aspect_ratio_fit(
src_width, src_height,
dst_width, dst_height,
maintain_aspect_ratio // true/false
);

IP Address Utilities

Parse IP Addresses:

// Parse IPv4 address
struct in_addr addr4;
if (parse_ipv4("192.168.1.1", &addr4)) {
log_info("Valid IPv4 address");
}
// Parse IPv6 address
struct in6_addr addr6;
if (parse_ipv6("::1", &addr6)) {
log_info("Valid IPv6 address");
}

Validate IP Addresses:

// Check if string is valid IP
if (is_valid_ipv4("192.168.1.1")) {
log_info("Valid IPv4");
}
if (is_valid_ipv6("2001:db8::1")) {
log_info("Valid IPv6");
}
int is_valid_ipv4(const char *ip)
Definition ip.c:58
int is_valid_ipv6(const char *ip)
Definition ip.c:105

Format IP Addresses:

char ip_str[INET6_ADDRSTRLEN];
format_ip_address(&addr, ip_str, sizeof(ip_str));
log_info("IP: %s", ip_str);
asciichat_error_t format_ip_address(int family, const struct sockaddr *addr, char *output, size_t output_size)
Definition ip.c:196

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;
size_t bytes = utf8_decode(p, &codepoint);
log_debug("Codepoint: U+%04X", codepoint);
p += bytes;
}
int utf8_decode(const uint8_t *s, uint32_t *codepoint)
Definition utf8.c:18

Path Utilities

Normalize Paths:

char normalized[PATH_MAX];
normalize_path("/path/to/../file.txt", normalized, sizeof(normalized));
// Result: "/path/file.txt"

Join Paths:

char joined[PATH_MAX];
join_path("/home/user", ".ssh/id_ed25519", joined, sizeof(joined));
// Result: "/home/user/.ssh/id_ed25519"

Expand Home Directory:

char expanded[PATH_MAX];
expand_home_dir("~/.ssh/known_hosts", expanded, sizeof(expanded));
// Result: "/home/username/.ssh/known_hosts"

Get File Extension:

const char *ext = get_file_extension("document.pdf");
// Result: "pdf"

String Utilities

Trim Whitespace:

char text[] = " hello world ";
trim_whitespace(text);
// Result: "hello world"

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);
}
// Parse with range validation
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");
}
// Accepts: "true", "false", "yes", "no", "1", "0" (case-insensitive)

Format Utilities

Format Byte Sizes:

char size_str[32];
format_bytes(1024 * 1024 * 5, size_str, sizeof(size_str));
// Result: "5.00 MB"

Format Duration:

char duration[64];
format_duration(3665, duration, sizeof(duration));
// Result: "1h 1m 5s"

Format Timestamp:

char timestamp[32];
format_timestamp(time(NULL), timestamp, sizeof(timestamp));
// Result: "2025-01-15 14:23:45"

Mathematical Utilities

Safe Integer Math:

// Clamp value to range
int clamped = clamp(value, 0, 100);
// Get minimum/maximum
int min_val = min(a, b);
int max_val = max(a, b);

Rounding:

// Round to nearest integer
int rounded = round_to_int(3.7); // Result: 4
// Round up/down
int ceil_val = round_up(3.2); // Result: 4
int floor_val = round_down(3.8); // Result: 3

Alignment:

// Align to power of 2
size_t aligned = align_up(123, 16); // Result: 128
size_t aligned_down = align_down(123, 16); // Result: 112

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