Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add byte order utilities #4792

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Foundation.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@
90E645DF1E4C89A400D0D47C /* TestNSCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90E645DE1E4C89A400D0D47C /* TestNSCache.swift */; };
91B668A32252B3C5001487A1 /* FileManager+POSIX.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91B668A22252B3C5001487A1 /* FileManager+POSIX.swift */; };
91B668A52252B3E7001487A1 /* FileManager+Win32.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91B668A42252B3E7001487A1 /* FileManager+Win32.swift */; };
9E1A0B0F2A58F2C7008E971B /* NSByteOrder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E1A0B0E2A58F2C7008E971B /* NSByteOrder.swift */; };
9F0DD3521ECD73D000F68030 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F0041781ECD5962004138BD /* main.swift */; };
9F0DD3571ECD783500F68030 /* SwiftFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B5D885D1BBC938800234F36 /* SwiftFoundation.framework */; };
A058C2021E529CF100B07AA1 /* TestMassFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A058C2011E529CF100B07AA1 /* TestMassFormatter.swift */; };
Expand Down Expand Up @@ -1134,6 +1135,7 @@
90E645DE1E4C89A400D0D47C /* TestNSCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSCache.swift; sourceTree = "<group>"; };
91B668A22252B3C5001487A1 /* FileManager+POSIX.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileManager+POSIX.swift"; sourceTree = "<group>"; };
91B668A42252B3E7001487A1 /* FileManager+Win32.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileManager+Win32.swift"; sourceTree = "<group>"; };
9E1A0B0E2A58F2C7008E971B /* NSByteOrder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSByteOrder.swift; sourceTree = "<group>"; };
9F0041781ECD5962004138BD /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
9F0DD33F1ECD734200F68030 /* xdgTestHelper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = xdgTestHelper.app; sourceTree = BUILT_PRODUCTS_DIR; };
9F0DD34F1ECD737B00F68030 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2169,6 +2171,7 @@
EADE0B6A1BD15DFF00C49C64 /* NotificationQueue.swift */,
5BDC3F2E1BCC5DCB00ED97BB /* NSArray.swift */,
EADE0B4F1BD09E3100C49C64 /* NSAttributedString.swift */,
9E1A0B0E2A58F2C7008E971B /* NSByteOrder.swift */,
EADE0B541BD15DFF00C49C64 /* NSCache.swift */,
5BDC3F301BCC5DCB00ED97BB /* NSCalendar.swift */,
5BDC3FC91BCF176100ED97BB /* NSCFArray.swift */,
Expand Down Expand Up @@ -3005,6 +3008,7 @@
5B424C761D0B6E5B007B39C8 /* IndexPath.swift in Sources */,
EADE0BB51BD15E0000C49C64 /* Scanner.swift in Sources */,
EADE0BA01BD15DFF00C49C64 /* NSIndexPath.swift in Sources */,
9E1A0B0F2A58F2C7008E971B /* NSByteOrder.swift in Sources */,
5BF7AEB51BCD51F9008F214A /* NSPathUtilities.swift in Sources */,
B96C113725BA376D00985A32 /* NSDateComponents.swift in Sources */,
EADE0B9D1BD15DFF00C49C64 /* NSGeometry.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions Sources/Foundation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ add_library(Foundation
NotificationQueue.swift
NSArray.swift
NSAttributedString.swift
NSByteOrder.swift
NSCache.swift
NSCalendar.swift
NSCFArray.swift
Expand Down
286 changes: 286 additions & 0 deletions Sources/Foundation/NSByteOrder.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//

@_implementationOnly import CoreFoundation

/// The byte order is unknown.
public let NS_UnknownByteOrder: Int = Int(CFByteOrderUnknown.rawValue)
/// The byte order is little endian.
public let NS_LittleEndian: Int = Int(CFByteOrderLittleEndian.rawValue)
/// The byte order is big endian.
public let NS_BigEndian: Int = Int(CFByteOrderBigEndian.rawValue)

/// Returns the endian format.
@inline(__always) public func NSHostByteOrder() -> Int {
return CFByteOrderGetCurrent()
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapShort(_ inv: UInt16) -> UInt16 {
return CFSwapInt16(inv)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapInt(_ inv: UInt32) -> UInt32 {
return CFSwapInt32(inv)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapLong(_ inv: UInt) -> UInt {
#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le)
return UInt(CFSwapInt64(UInt64(inv)))
#else
return CFSwapInt32(inv)
#endif
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapLongLong(_ inv: UInt64) -> UInt64 {
return CFSwapInt64(inv)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapBigShortToHost(_ x: UInt16) -> UInt16 {
return CFSwapInt16BigToHost(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapBigIntToHost(_ x: UInt32) -> UInt32 {
return CFSwapInt32BigToHost(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapBigLongToHost(_ x: UInt) -> UInt {
#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le)
return UInt(CFSwapInt64BigToHost(UInt64(x)))
#else
return CFSwapInt32BigToHost(x)
#endif
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapBigLongLongToHost(_ x: UInt64) -> UInt64 {
return CFSwapInt64BigToHost(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostShortToBig(_ x: UInt16) -> UInt16 {
return CFSwapInt16HostToBig(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostIntToBig(_ x: UInt32) -> UInt32 {
return CFSwapInt32HostToBig(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostLongToBig(_ x: UInt) -> UInt {
#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le)
return UInt(CFSwapInt64HostToBig(UInt64(x)))
#else
return CFSwapInt32HostToBig(x)
#endif
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostLongLongToBig(_ x: UInt64) -> UInt64 {
return CFSwapInt64HostToBig(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapLittleShortToHost(_ x: UInt16) -> UInt16 {
return CFSwapInt16LittleToHost(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapLittleIntToHost(_ x: UInt32) -> UInt32 {
return CFSwapInt32LittleToHost(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapLittleLongToHost(_ x: UInt) -> UInt {
#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le)
return UInt(CFSwapInt64LittleToHost(UInt64(x)))
#else
return CFSwapInt32LittleToHost(x)
#endif
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapLittleLongLongToHost(_ x: UInt64) -> UInt64 {
return CFSwapInt64LittleToHost(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostShortToLittle(_ x: UInt16) -> UInt16 {
return CFSwapInt16HostToLittle(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostIntToLittle(_ x: UInt32) -> UInt32 {
return CFSwapInt32HostToLittle(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostLongToLittle(_ x: UInt) -> UInt {
#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le)
return UInt(CFSwapInt64HostToLittle(UInt64(x)))
#else
return CFSwapInt32HostToLittle(x)
#endif
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostLongLongToLittle(_ x: UInt64) -> UInt64 {
return CFSwapInt64HostToLittle(x)
}

/// Opaque type containing an endian-independent `float` value.
public struct NSSwappedFloat : @unchecked Sendable {
public var v: UInt32

public init() {
self.v = 0
}

public init(v: UInt32) {
self.v = v
}
}

/// Opaque structure containing endian-independent `double` value.
public struct NSSwappedDouble : @unchecked Sendable {
public var v: UInt64

public init() {
self.v = 0
}

public init(v: UInt64) {
self.v = v
}
}

/// Performs a type conversion.
@inline(__always) public func NSConvertHostFloatToSwapped(_ x: Float) -> NSSwappedFloat {
return NSSwappedFloat(v: x.bitPattern)
}

/// Performs a type conversion.
@inline(__always) public func NSConvertSwappedFloatToHost(_ x: NSSwappedFloat) -> Float {
return Float(bitPattern: x.v)
}

/// Performs a type conversion.
@inline(__always) public func NSConvertHostDoubleToSwapped(_ x: Double) -> NSSwappedDouble {
return NSSwappedDouble(v: x.bitPattern)
}

/// Performs a type conversion.
@inline(__always) public func NSConvertSwappedDoubleToHost(_ x: NSSwappedDouble) -> Double {
return Double(bitPattern: x.v)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapFloat(_ x: NSSwappedFloat) -> NSSwappedFloat {
return NSSwappedFloat(v: NSSwapInt(x.v))
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapDouble(_ x: NSSwappedDouble) -> NSSwappedDouble {
return NSSwappedDouble(v: NSSwapLongLong(x.v))
}

#if _endian(big)

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapBigDoubleToHost(_ x: NSSwappedDouble) -> Double {
return NSConvertSwappedDoubleToHost(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapBigFloatToHost(_ x: NSSwappedFloat) -> Float {
return NSConvertSwappedFloatToHost(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostDoubleToBig(_ x: Double) -> NSSwappedDouble {
return NSConvertHostDoubleToSwapped(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostFloatToBig(_ x: Float) -> NSSwappedFloat {
return NSConvertHostFloatToSwapped(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapLittleDoubleToHost(_ x: NSSwappedDouble) -> Double {
return NSConvertSwappedDoubleToHost(NSSwapDouble(x))
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapLittleFloatToHost(_ x: NSSwappedFloat) -> Float {
return NSConvertSwappedFloatToHost(NSSwapFloat(x))
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostDoubleToLittle(_ x: Double) -> NSSwappedDouble {
return NSSwapDouble(NSConvertHostDoubleToSwapped(x))
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostFloatToLittle(_ x: Float) -> NSSwappedFloat {
return NSSwapFloat(NSConvertHostFloatToSwapped(x))
}

#elseif _endian(little)

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapBigDoubleToHost(_ x: NSSwappedDouble) -> Double {
return NSConvertSwappedDoubleToHost(NSSwapDouble(x))
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapBigFloatToHost(_ x: NSSwappedFloat) -> Float {
return NSConvertSwappedFloatToHost(NSSwapFloat(x))
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostDoubleToBig(_ x: Double) -> NSSwappedDouble {
return NSSwapDouble(NSConvertHostDoubleToSwapped(x))
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostFloatToBig(_ x: Float) -> NSSwappedFloat {
return NSSwapFloat(NSConvertHostFloatToSwapped(x))
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapLittleDoubleToHost(_ x: NSSwappedDouble) -> Double {
return NSConvertSwappedDoubleToHost(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapLittleFloatToHost(_ x: NSSwappedFloat) -> Float {
return NSConvertSwappedFloatToHost(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostDoubleToLittle(_ x: Double) -> NSSwappedDouble {
return NSConvertHostDoubleToSwapped(x)
}

/// Swaps the bytes of a number.
@inline(__always) public func NSSwapHostFloatToLittle(_ x: Float) -> NSSwappedFloat {
return NSConvertHostFloatToSwapped(x)
}

#else
#errors("Do not know the endianess of this architecture")
#endif