swift-incits-4-1986

0.1.0

Swift implementation of INCITS 4-1986 (R2022): US-ASCII standard.
swift-standards/swift-incits-4-1986

What's New

0.1.0

2025-11-27T22:23:06Z

INCITS 4-1986 v0.1.0

Pure Swift implementation of INCITS 4-1986 (R2022): Coded Character Sets - 7-Bit American Standard Code for Information Interchange (US-ASCII).

Features

Complete ASCII Character Set

  • 128 ASCII characters (0x00-0x7F) with named constants
  • Control characters (33 characters): NUL, SOH, STX, ..., DEL
  • SPACE (0x20): Dual-nature character
  • Graphic characters (94 characters): Letters, digits, punctuation

Character Operations

  • Classification predicates: whitespace, digits, letters, alphanumeric, hex digits, case
  • Case conversion: ASCII-only uppercase/lowercase conversion
  • Numeric parsing: Extract values from digit and hex digit bytes

String Operations

  • Bidirectional conversion: String ⟷ [UInt8] with ASCII validation
  • Case conversion: Convert ASCII letters in strings (Unicode-safe)
  • Trimming: Remove characters from string edges (whitespace, custom sets)
  • Line ending normalization: Convert between LF, CR, CRLF

Performance

  • High throughput: 17.3 MB/sec ASCII validation, 2.5 MB/sec case conversion
  • Linear scaling: All operations scale linearly with input size
  • Zero-cost abstractions: Cross-module inlining with @inlinable and @_transparent
  • Minimal allocations: Optimized hot paths with zero allocations

Swift Embedded Support

  • Pure Swift: No Foundation dependencies
  • No existentials: No runtime type requirements
  • Suitable for constrained environments

Installation

dependencies: [
    .package(url: "https://github.com/swift-standards/swift-incits-4-1986.git", from: "0.1.0")
]

Quick Start

import INCITS_4_1986

// Character classification
let byte: UInt8 = 0x41  // 'A'
byte.ascii.isLetter      // true
byte.ascii.isUppercase   // true

// Case conversion
"Hello World".ascii(case: .upper)  // "HELLO WORLD"

// String ⟷ bytes conversion
let bytes = [UInt8].ascii("hello")  // [104, 101, 108, 108, 111]
let text = String.ascii(bytes)      // "hello"

// String trimming
"  Hello  ".trimming(.ascii.whitespaces)  // "Hello"

Testing

500+ tests across 80+ test suites covering:

  • Character classification for all 128 ASCII bytes
  • Case conversion (upper, lower, round-trip)
  • String ⟷ byte array conversion
  • Line ending normalization
  • String trimming
  • Edge cases and brutal stress tests
  • Performance benchmarks
  • Linear scaling validation

Requirements

  • Swift 6.0+
  • macOS 15.0+ / iOS 18.0+ / tvOS 18.0+ / watchOS 11.0+
  • No Foundation dependencies

Standards Compliance

Conforms to INCITS 4-1986 (Reaffirmed 2022):

  • 7-bit ASCII character set (0x00-0x7F)
  • Control characters (Section 4.1)
  • SPACE character (Section 4.2)
  • Graphic characters (Section 4.3)

Also known as: ANSI X3.4-1986, ANSI X3.4-1968, ASA X3.4-1963, US-ASCII (IANA)

INCITS 4-1986

CI Development Status

Swift implementation of INCITS 4-1986 (R2022): Coded Character Sets - 7-Bit American Standard Code for Information Interchange (US-ASCII).

Overview

This package provides a complete implementation of the US-ASCII character set standard. The implementation follows INCITS 4-1986 (Reaffirmed 2022), offering character classification, case conversion, string validation, and byte-level operations for all 128 ASCII characters (0x00-0x7F).

Pure Swift implementation with no Foundation dependencies, suitable for Swift Embedded and constrained environments.

Features

  • 128 ASCII character constants (0x00-0x7F) organized by standard sections
  • Character classification predicates (whitespace, digits, letters, alphanumeric, hex digits)
  • ASCII-only case conversion for strings and byte arrays
  • String trimming with optimized UTF-8 fast path for ASCII whitespace
  • Line ending normalization (LF, CR, CRLF) for cross-platform text processing
  • Bidirectional String ⟷ [UInt8] conversion with ASCII validation
  • Cross-module inlining via @inlinable and @_transparent for zero-cost abstractions
  • 500+ tests covering edge cases, performance, and standards compliance

Installation

Add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/swift-standards/swift-incits-4-1986.git", from: "0.1.0")
]

Then add the dependency to your target:

.target(
    name: "YourTarget",
    dependencies: [
        .product(name: "INCITS 4 1986", package: "swift-incits-4-1986")
    ]
)

Quick Start

import INCITS_4_1986

// Character classification
let byte: UInt8 = 0x41  // 'A'
byte.ascii.isLetter      // true
byte.ascii.isUppercase   // true

// Case conversion
"Hello World".ascii(case: .upper)  // "HELLO WORLD"

// String ⟷ bytes conversion
let bytes = [UInt8].ascii("hello")  // [104, 101, 108, 108, 111]
let text = String.ascii(bytes)      // "hello"

// String trimming
"  Hello  ".trimming(.ascii.whitespaces)  // "Hello"

Usage Examples

Character Constants

Direct access to all 128 ASCII characters:

import INCITS_4_1986

// Control characters (0x00-0x1F, 0x7F)
UInt8.ascii.nul    // 0x00 (NULL)
UInt8.ascii.htab   // 0x09 (HORIZONTAL TAB)
UInt8.ascii.lf     // 0x0A (LINE FEED)
UInt8.ascii.cr     // 0x0D (CARRIAGE RETURN)
UInt8.ascii.esc    // 0x1B (ESCAPE)
UInt8.ascii.del    // 0x7F (DELETE)

// SPACE (0x20) - dual nature character
UInt8.ascii.sp     // 0x20 (SPACE)

// Graphic characters (0x21-0x7E)
UInt8.ascii.exclamationPoint  // 0x21 (!)
UInt8.ascii.`0`    // 0x30 (digit 0)
UInt8.ascii.`A`    // 0x41 (capital A)
UInt8.ascii.`a`    // 0x61 (lowercase a)
UInt8.ascii.tilde  // 0x7E (~)

// Common sequences
let crlf = INCITS_4_1986.crlf  // [0x0D, 0x0A]
let whitespaces = INCITS_4_1986.whitespaces  // {0x20, 0x09, 0x0A, 0x0D}

Byte-Level Classification

Test character properties at the byte level:

let byte: UInt8 = 0x41  // 'A'

// Character type classification
byte.ascii.isWhitespace    // false
byte.ascii.isControl       // false
byte.ascii.isPrintable     // true
byte.ascii.isVisible       // true

// Letter and digit classification
byte.ascii.isDigit         // false
byte.ascii.isLetter        // true
byte.ascii.isAlphanumeric  // true
byte.ascii.isHexDigit      // true (A-F are hex)

// Case classification
byte.ascii.isUppercase     // true
byte.ascii.isLowercase     // false

// Whitespace examples
UInt8.ascii.sp.ascii.isWhitespace    // true (SPACE)
UInt8.ascii.htab.ascii.isWhitespace  // true (TAB)
UInt8.ascii.lf.ascii.isWhitespace    // true (LF)
UInt8.ascii.cr.ascii.isWhitespace    // true (CR)

Byte-Level Case Conversion

Convert individual bytes between cases:

// Uppercase to lowercase
let upper: UInt8 = 0x41  // 'A'
let lower = upper.ascii(case: .lower)  // 0x61 ('a')

// Lowercase to uppercase
let a: UInt8 = 0x61  // 'a'
let A = a.ascii(case: .upper)  // 0x41 ('A')

// Non-letters unchanged
let digit: UInt8 = 0x30  // '0'
digit.ascii(case: .upper)  // 0x30 (unchanged)

Numeric Value Parsing

Extract numeric values from ASCII digit bytes:

// Decimal digits
let five: UInt8 = 0x35  // '5'
UInt8.ascii(digit: five)  // 5

// Hexadecimal digits
UInt8.ascii(hexDigit: 0x41)  // 10 ('A')
UInt8.ascii(hexDigit: 0x61)  // 10 ('a')
UInt8.ascii(hexDigit: 0x46)  // 15 ('F')
UInt8.ascii(hexDigit: 0x66)  // 15 ('f')

String to Bytes Conversion

Convert strings to ASCII byte arrays with validation:

// Valid ASCII string
let bytes = [UInt8].ascii("Hello")
// [72, 101, 108, 108, 111]

// With validation
if let asciiBytes = [UInt8].ascii("Hello World") {
    // All characters are valid ASCII
}

// Non-ASCII returns nil
[UInt8].ascii("Hello🌍")  // nil (emoji not ASCII)
[UInt8].ascii("café")     // nil (é not ASCII)

// Unchecked conversion (no validation)
let bytes = [UInt8].ascii(unchecked: "Hello")
// Use only when you know string is ASCII

Bytes to String Conversion

Convert ASCII byte arrays to strings:

// With validation
let text = String.ascii([72, 101, 108, 108, 111])  // "Hello"

// Invalid ASCII returns nil
String.ascii([0xFF])  // nil (not valid 7-bit ASCII)
String.ascii([0x80])  // nil (high bit set)

// Unchecked conversion (no validation)
let text = String.ascii(unchecked: [72, 105])  // "Hi"
// Use only when you know bytes are ASCII

Byte Array Validation

Check if all bytes in an array are valid ASCII:

let hello: [UInt8] = [72, 101, 108, 108, 111]
hello.ascii.isAllASCII  // true

let mixed: [UInt8] = [72, 101, 0xFF, 108, 111]
mixed.ascii.isAllASCII  // false (0xFF > 0x7F)

let empty: [UInt8] = []
empty.ascii.isAllASCII  // true (empty array is valid)

Byte Array Case Conversion

Convert all ASCII letters in a byte array:

let hello = [UInt8].ascii("Hello World")!

// To uppercase
hello.ascii.convertingCase(to: .upper)
// [72, 69, 76, 76, 79, 32, 87, 79, 82, 76, 68] ("HELLO WORLD")

// To lowercase
hello.ascii.convertingCase(to: .lower)
// [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100] ("hello world")

// Non-letters unchanged
let mixed = [UInt8].ascii("Test123!")!
mixed.ascii.convertingCase(to: .upper)
// [84, 69, 83, 84, 49, 50, 51, 33] ("TEST123!")

String Case Conversion

Convert ASCII letters in strings (Unicode-safe):

// Basic case conversion
"Hello World".ascii(case: .upper)  // "HELLO WORLD"
"Hello World".ascii(case: .lower)  // "hello world"

// Unicode safety - non-ASCII preserved
"hello🌍".ascii(case: .upper)  // "HELLO🌍"
"café".ascii(case: .upper)     // "CAFé" (only ASCII 'c', 'a', 'f' converted)

// Only ASCII letters affected
"Test123!".ascii(case: .upper)  // "TEST123!"

String Trimming

Remove characters from both ends of strings:

// Trim ASCII whitespace
let text = "  Hello World  "
text.trimming(.ascii.whitespaces)  // "Hello World"

// Static method
String.trimming(text, of: .ascii.whitespaces)  // "Hello World"

// Trim custom characters
let padded = "***important***"
padded.trimming(["*"])  // "important"

let quoted = "\"hello\""
quoted.trimming(["\""])  // "hello"

// Only edges are trimmed
let spaced = "  Hello  World  "
spaced.trimming(.ascii.whitespaces)  // "Hello  World"

Line Ending Normalization

Normalize line endings for cross-platform compatibility:

// Normalize to CRLF (Windows, Internet protocols)
let text = "line1\nline2\rline3\r\nline4"
text.normalized(to: .crlf)
// "line1\r\nline2\r\nline3\r\nline4"

// Normalize to LF (Unix, Linux, macOS)
let windows = "Hello\r\nWorld\r\n"
windows.normalized(to: .lf)  // "Hello\nWorld\n"

// Normalize to CR (Classic Mac OS)
let unix = "Hello\nWorld\n"
unix.normalized(to: .cr)  // "Hello\rWorld\r"

// Handles mixed line endings
let mixed = "A\nB\rC\r\nD"
mixed.normalized(to: .lf)  // "A\nB\nC\nD"

Line Ending Byte Sequences

Get line ending bytes for network protocols:

// String line endings
let lf = String.ascii(lineEnding: .lf)      // "\n"
let cr = String.ascii(lineEnding: .cr)      // "\r"
let crlf = String.ascii(lineEnding: .crlf)  // "\r\n"

// Byte array line endings
let lfBytes = [UInt8].ascii(lineEnding: .lf)      // [0x0A]
let crBytes = [UInt8].ascii(lineEnding: .cr)      // [0x0D]
let crlfBytes = [UInt8].ascii(lineEnding: .crlf)  // [0x0D, 0x0A]

// Use in protocol implementation
var httpResponse: [UInt8] = [UInt8].ascii("HTTP/1.1 200 OK")!
httpResponse += [UInt8].ascii.crlf
httpResponse += [UInt8].ascii("Content-Type: text/plain")!
httpResponse += [UInt8].ascii.crlf

Character-Level Operations

Swift Character extensions for ASCII operations:

let char: Character = "A"

// Classification
char.ascii.isWhitespace    // false
char.ascii.isDigit         // false
char.ascii.isLetter        // true
char.ascii.isAlphanumeric  // true
char.ascii.isHexDigit      // true
char.ascii.isUppercase     // true
char.ascii.isLowercase     // false

// Character set operations
let whitespace: Set<Character> = .ascii.whitespaces  // {' ', '\t', '\n', '\r'}
whitespace.contains(" ")  // true
whitespace.contains("\t")  // true

Authoritative API

Direct access to the INCITS 4-1986 namespace:

// Access character constants
let space = INCITS_4_1986.SPACE.sp          // 0x20
let tab = INCITS_4_1986.ControlCharacters.htab     // 0x09
let letterA = INCITS_4_1986.GraphicCharacters.A    // 0x41

// Common byte sequences
let crlf = INCITS_4_1986.crlf  // [0x0D, 0x0A]

// Whitespace set
let whitespaces = INCITS_4_1986.whitespaces
// {0x20, 0x09, 0x0A, 0x0D}

// Case conversion offset
let offset = INCITS_4_1986.caseConversionOffset  // 0x20
// 'A' (0x41) + 0x20 = 'a' (0x61)

Performance

Benchmarked on Apple Silicon (M-series):

Throughput

  • ASCII validation: 17.3 MB/sec (1M bytes in ~58ms)
  • Case conversion: 2.5 MB/sec (1M bytes in ~400ms)
  • String normalization: 2 MB/sec (1M bytes in ~500ms)
  • String trimming: 5 MB/sec (1M spaces in ~200ms)

Linear Scaling

All operations scale linearly with input size:

  • 1K bytes → 10K bytes: 10× time increase
  • 10K bytes → 100K bytes: 10× time increase
  • 100K bytes → 1M bytes: 10× time increase

Optimizations

  • Zero-copy UTF-8 fast path for ASCII operations
  • Direct byte-level comparisons instead of Set lookups
  • Cross-module inlining for zero-cost abstractions
  • Minimal memory allocations (often zero for hot paths)

Standards Compliance

Conforms to INCITS 4-1986 (Reaffirmed 2022):

  • Character set: 7-bit ASCII (0x00-0x7F, 128 characters)
  • Control characters (Section 4.1): 33 characters (0x00-0x1F, 0x7F)
  • SPACE (Section 4.2): Dual-nature character (0x20)
  • Graphic characters (Section 4.3): 94 printable characters (0x21-0x7E)

Historical Designations

  • Current: INCITS 4-1986 (R2022)
  • Previous: ANSI X3.4-1986
  • Original: ANSI X3.4-1968, ASA X3.4-1963
  • IANA: US-ASCII

Special Values

  • Whitespace: SPACE (0x20), HORIZONTAL TAB (0x09), LINE FEED (0x0A), CARRIAGE RETURN (0x0D)
  • CRLF: Required line ending for HTTP, SMTP, FTP, MIME per their RFCs
  • Case conversion: Offset of 0x20 between uppercase and lowercase letters

Testing

Test suite: 500+ tests in 80+ suites

Coverage:

  • Character classification for all 128 ASCII bytes
  • Case conversion (upper, lower, round-trip)
  • String ⟷ byte array conversion (valid, invalid, empty)
  • Line ending normalization (LF, CR, CRLF, mixed)
  • String trimming (whitespace, custom sets)
  • Edge cases (empty arrays, control characters, non-ASCII)
  • Performance benchmarks at multiple scales
  • Linear scaling validation

Run tests:

swift test

Run specific test suites:

swift test --filter "Character Classification"
swift test --filter "Linear Scaling"

Requirements

  • Swift 6.0 or later
  • macOS 15.0+ / iOS 18.0+ / tvOS 18.0+ / watchOS 11.0+
  • No Foundation dependencies (Swift Embedded compatible)

Related Packages

License

This package is licensed under the Apache License 2.0. See LICENSE.md for details.

Contributing

Contributions are welcome. Please ensure all tests pass and new features include test coverage.

Description

  • Swift Tools 6.2.0
View More Packages from this Author

Dependencies

Last updated: Thu Apr 09 2026 14:56:13 GMT-0900 (Hawaii-Aleutian Daylight Time)