Skip to content

Commit 76a5a8f

Browse files
committed
docs: documenting changes
1 parent 3ab57e2 commit 76a5a8f

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

Sources/BinaryParsing/Macros/Macros.swift

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,64 @@
1313
public macro magicNumber(_ code: String, parsing input: inout ParserSpan) =
1414
#externalMacro(module: "BinaryParsingMacros", type: "MagicNumberStringMacro")
1515

16+
/// Parses and validates a magic number or signature of arbitrary length from binary data.
17+
///
18+
/// This macro extends the functionality of `#magicNumber` to support ASCII strings of any length,
19+
/// not just the 2, 4, or 8 byte limitations of the original macro. It compiles to an optimized
20+
/// `InlineArray<N, UInt8>` comparison with zero runtime overhead.
21+
///
22+
/// The macro takes an ASCII string literal and generates compile-time code that:
23+
/// 1. Parses exactly `string.count` bytes from the input span
24+
/// 2. Compares them against the expected byte values
25+
/// 3. Throws a `ParsingError` if bytes don't match or insufficient data is available
26+
///
27+
/// ## Usage
28+
///
29+
/// ```swift
30+
/// // Parse 4-byte magic number
31+
/// try #magic("test", parsing: &input)
32+
///
33+
/// // Parse single byte
34+
/// try #magic("A", parsing: &input)
35+
///
36+
/// // Parse longer sequences (e.g., 11 bytes)
37+
/// try #magic("hello world", parsing: &input)
38+
///
39+
/// ```
40+
///
41+
/// ## Compile-time Optimization
42+
///
43+
/// The macro generates code equivalent to:
44+
/// ```swift
45+
/// _loadAndCheckInlineArrayBytes(
46+
/// parsing: &input,
47+
/// expectedBytes: [116, 101, 115, 116] // ASCII values of "test"
48+
/// )
49+
/// ```
50+
///
51+
/// This leverages Swift 6.2's `InlineArray` and Value Generics for compile-time resolution,
52+
/// providing the same performance as hand-written byte comparisons.
53+
///
54+
/// ## Error Conditions
55+
///
56+
/// Throws `ParsingError` in these cases:
57+
/// - Input span has fewer bytes than the magic string length
58+
/// - Parsed bytes don't match the expected magic string
59+
/// - Magic string contains non-ASCII characters
60+
/// - Magic string is empty
61+
///
62+
/// ## Availability
63+
///
64+
/// Requires macOS 26+, iOS 26+, watchOS 26+, tvOS 26+, visionOS 26+ due to `InlineArray` usage.
65+
///
66+
/// ## See Also
67+
///
68+
/// - `#magicNumber(_:parsing:)` for 2/4/8 byte magic numbers using fixed-width integers
69+
/// - `InlineArray` for the underlying compile-time array implementation
70+
///
71+
/// - Parameter code: An ASCII string literal representing the expected magic bytes
72+
/// - Parameter input: An inout `ParserSpan` to parse from
73+
/// - Throws: `ParsingError` if parsing fails or bytes don't match
1674
@freestanding(expression)
1775
public macro magic(_ code: String, parsing input: inout ParserSpan) =
1876
#externalMacro(module: "BinaryParsingMacros", type: "MagicMacro")

Sources/BinaryParsing/Macros/MagicNumber.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,36 @@ public func _loadAndCheckDirectBytesByteOrder<
4242
}
4343
}
4444

45+
/// Loads and validates bytes from a parser span against an expected InlineArray of bytes.
46+
///
47+
/// This function is used internally by the `#magic` macro to perform arbitrary-length
48+
/// magic number validation using InlineArray for compile-time optimization.
49+
///
50+
/// The function:
51+
/// 1. Parses exactly `N` bytes from the input span into an `InlineArray<N, UInt8>`
52+
/// 2. Compares the parsed bytes against the expected bytes using InlineArray's Equatable conformance
53+
/// 3. Throws a `ParsingError` with `.invalidValue` status if bytes don't match
54+
/// 4. Consumes the bytes from the span regardless of whether comparison succeeds or fails
55+
///
56+
/// ## Usage
57+
///
58+
/// This function is primarily intended for use by macro-generated code:
59+
/// ```swift
60+
/// // Generated by #magic("test", parsing: &input)
61+
/// try _loadAndCheckInlineArrayBytes(
62+
/// parsing: &input,
63+
/// expectedBytes: [116, 101, 115, 116]
64+
/// )
65+
/// ```
66+
///
67+
/// ## Availability
68+
///
69+
/// Requires macOS 26+, iOS 26+, watchOS 26+, tvOS 26+, visionOS 26+ due to `InlineArray` usage.
70+
///
71+
/// - Parameter input: An inout `ParserSpan` to parse bytes from
72+
/// - Parameter expectedBytes: An `InlineArray<N, UInt8>` containing the expected byte values
73+
/// - Throws: `ParsingError` with `.invalidValue` status if bytes don't match, or propagates
74+
/// any parsing errors from `InlineArray.init(parsing:)`
4575
@available(macOS 26, iOS 26, watchOS 26, tvOS 26, visionOS 26, *)
4676
@_lifetime(&input)
4777
@inlinable

0 commit comments

Comments
 (0)