From d56e777025f3bda29feaec22c125b0e7ab975e0c Mon Sep 17 00:00:00 2001 From: Ruben Beltran del Rio Date: Sun, 14 Dec 2025 16:52:57 +0100 Subject: Format, make map equatable --- Sources/WmapParser/Utils.swift | 276 +++++++++++++++++++++-------------------- 1 file changed, 140 insertions(+), 136 deletions(-) (limited to 'Sources/WmapParser/Utils.swift') diff --git a/Sources/WmapParser/Utils.swift b/Sources/WmapParser/Utils.swift index d79578b..4886eb3 100644 --- a/Sources/WmapParser/Utils.swift +++ b/Sources/WmapParser/Utils.swift @@ -1,138 +1,142 @@ extension WmapParser { - /// Check if a byte is a digit - @inline(__always) - static func isDigit(_ byte: UInt8) -> Bool { - byte >= kZero && byte <= kNine - } - - /// Looks for x and y separated by a comma. - static func parseCoordinates(_ bytes: T, _ start: Int, _ end: Int) -> ( - MapPoint, Int - )? - where T.Element == UInt8, T.Index == Int { - var index = skipWhitespace(bytes, end, start) - - guard let (xCoordinate, nextIndex) = parseSingleCoordinate(bytes, index, end) else { - return nil - } - index = nextIndex - - guard expectComma(bytes, &index, end) else { return nil } - - guard let (yCoordinate, nextIndex) = parseSingleCoordinate(bytes, index, end) else { - return nil - } - index = nextIndex - - guard expectClosingParen(bytes, &index, end) else { return nil } - - return (MapPoint(xCoordinate: xCoordinate, yCoordinate: yCoordinate), index) - } - - /// Checks if a candidate for a coordinate is a digit, and parses it. - @inline(__always) - static func parseSingleCoordinate(_ bytes: T, _ start: Int, _ end: Int) -> (Double, Int)? - where T.Element == UInt8, T.Index == Int { - var index = start - while index < end && (isDigit(bytes[index]) || bytes[index] == 46) { index += 1 } - guard index > start else { return nil } - guard let value = parseDouble(bytes, start, index) else { return nil } - return (value, index) - } - - /// Advances the index until we find a comma. - @inline(__always) - static func expectComma(_ bytes: T, _ index: inout Int, _ end: Int) -> Bool - where T.Element == UInt8, T.Index == Int { - index = skipWhitespace(bytes, end, index) - guard index < end && bytes[index] == kComma else { return false } - index += 1 - index = skipWhitespace(bytes, end, index) - return true - } - - /// Advances the index until we find a closing parenthesis - @inline(__always) - static func expectClosingParen(_ bytes: T, _ index: inout Int, _ end: Int) -> Bool - where T.Element == UInt8, T.Index == Int { - index = skipWhitespace(bytes, end, index) - guard index < end && bytes[index] == kCloseParenthesis else { return false } - index += 1 - return true - } - - /// Parses a double - @inline(__always) - static func parseDouble(_ bytes: T, _ start: Int, _ end: Int) -> Double? - where T.Element == UInt8, T.Index == Int { - var index = skipWhitespace(bytes, end, start) - - let numStart = index - while index < end && (isDigit(bytes[index]) || bytes[index] == kPeriod) { index += 1 } - - guard index > numStart else { return nil } - - // Why not String(data:encoding:)? This is much faster. - // swiftlint:disable:next optional_data_string_conversion - let str = String(decoding: bytes[numStart..(_ bytes: T, _ end: Int, _ start: Int) -> Int - where T.Element == UInt8, T.Index == Int { - var index = start - while index < end && (bytes[index] == kSpace || bytes[index] == kTab) { index += 1 } - return index - } - - /// Decreases an index by looking for whitespace right-to-left - static func shaveWhitespace(_ bytes: T, _ start: Int, _ end: Int) -> Int - where T.Element == UInt8, T.Index == Int { - var index = end - while index > start && (bytes[index - 1] == kSpace || bytes[index - 1] == kTab) { index -= 1 } - return index - } - - /// Given the bytes buffer, finds the next non-empty line. - @inline(__always) - static func extractLine(_ bytes: T, _ index: inout Int, _ length: Int) -> ( - Int, Int - )? - where T.Element == UInt8, T.Index == Int { - while index < length && (bytes[index] == kNewline || bytes[index] == kCarriageReturn) { - index += 1 - } - let lineStart = index - - while index < length && bytes[index] != kNewline && bytes[index] != kCarriageReturn { index += 1 } - if lineStart == index { return nil } - - var start = lineStart - var end = index - - start = skipWhitespace(bytes, end, start) - end = shaveWhitespace(bytes, start, end) - - if start == end { return nil } - - return (start, end) - } - - /// Trims a byte collection and returns a string - @inline(__always) - static func extractTrimmedString(_ bytes: T, _ start: Int, _ end: Int) -> String? - where T.Element == UInt8, T.Index == Int { - var trimStart = start - var trimEnd = end - - trimStart = skipWhitespace(bytes, trimEnd, trimStart) - trimEnd = shaveWhitespace(bytes, trimStart, trimEnd) - - guard trimStart < trimEnd else { return nil } - - // Why not String(data:encoding:)? This is much faster. - // swiftlint:disable:next optional_data_string_conversion - return String(decoding: bytes[trimStart.. Bool { + byte >= kZero && byte <= kNine + } + + /// Looks for x and y separated by a comma. + static func parseCoordinates(_ bytes: T, _ start: Int, _ end: Int) -> ( + MapPoint, Int + )? + where T.Element == UInt8, T.Index == Int { + var index = skipWhitespace(bytes, end, start) + + guard let (xCoordinate, nextIndex) = parseSingleCoordinate(bytes, index, end) else { + return nil + } + index = nextIndex + + guard expectComma(bytes, &index, end) else { return nil } + + guard let (yCoordinate, nextIndex) = parseSingleCoordinate(bytes, index, end) else { + return nil + } + index = nextIndex + + guard expectClosingParen(bytes, &index, end) else { return nil } + + return (MapPoint(xCoordinate: xCoordinate, yCoordinate: yCoordinate), index) + } + + /// Checks if a candidate for a coordinate is a digit, and parses it. + @inline(__always) + static func parseSingleCoordinate(_ bytes: T, _ start: Int, _ end: Int) -> ( + Double, Int + )? + where T.Element == UInt8, T.Index == Int { + var index = start + while index < end && (isDigit(bytes[index]) || bytes[index] == 46) { index += 1 } + guard index > start else { return nil } + guard let value = parseDouble(bytes, start, index) else { return nil } + return (value, index) + } + + /// Advances the index until we find a comma. + @inline(__always) + static func expectComma(_ bytes: T, _ index: inout Int, _ end: Int) -> Bool + where T.Element == UInt8, T.Index == Int { + index = skipWhitespace(bytes, end, index) + guard index < end && bytes[index] == kComma else { return false } + index += 1 + index = skipWhitespace(bytes, end, index) + return true + } + + /// Advances the index until we find a closing parenthesis + @inline(__always) + static func expectClosingParen(_ bytes: T, _ index: inout Int, _ end: Int) -> Bool + where T.Element == UInt8, T.Index == Int { + index = skipWhitespace(bytes, end, index) + guard index < end && bytes[index] == kCloseParenthesis else { return false } + index += 1 + return true + } + + /// Parses a double + @inline(__always) + static func parseDouble(_ bytes: T, _ start: Int, _ end: Int) -> Double? + where T.Element == UInt8, T.Index == Int { + var index = skipWhitespace(bytes, end, start) + + let numStart = index + while index < end && (isDigit(bytes[index]) || bytes[index] == kPeriod) { index += 1 } + + guard index > numStart else { return nil } + + // Why not String(data:encoding:)? This is much faster. + // swiftlint:disable:next optional_data_string_conversion + let str = String(decoding: bytes[numStart..(_ bytes: T, _ end: Int, _ start: Int) -> Int + where T.Element == UInt8, T.Index == Int { + var index = start + while index < end && (bytes[index] == kSpace || bytes[index] == kTab) { index += 1 } + return index + } + + /// Decreases an index by looking for whitespace right-to-left + static func shaveWhitespace(_ bytes: T, _ start: Int, _ end: Int) -> Int + where T.Element == UInt8, T.Index == Int { + var index = end + while index > start && (bytes[index - 1] == kSpace || bytes[index - 1] == kTab) { index -= 1 } + return index + } + + /// Given the bytes buffer, finds the next non-empty line. + @inline(__always) + static func extractLine(_ bytes: T, _ index: inout Int, _ length: Int) -> ( + Int, Int + )? + where T.Element == UInt8, T.Index == Int { + while index < length && (bytes[index] == kNewline || bytes[index] == kCarriageReturn) { + index += 1 + } + let lineStart = index + + while index < length && bytes[index] != kNewline && bytes[index] != kCarriageReturn { + index += 1 + } + if lineStart == index { return nil } + + var start = lineStart + var end = index + + start = skipWhitespace(bytes, end, start) + end = shaveWhitespace(bytes, start, end) + + if start == end { return nil } + + return (start, end) + } + + /// Trims a byte collection and returns a string + @inline(__always) + static func extractTrimmedString(_ bytes: T, _ start: Int, _ end: Int) -> String? + where T.Element == UInt8, T.Index == Int { + var trimStart = start + var trimEnd = end + + trimStart = skipWhitespace(bytes, trimEnd, trimStart) + trimEnd = shaveWhitespace(bytes, trimStart, trimEnd) + + guard trimStart < trimEnd else { return nil } + + // Why not String(data:encoding:)? This is much faster. + // swiftlint:disable:next optional_data_string_conversion + return String(decoding: bytes[trimStart..