How to evalute the result of CFByteOrderGetCurrent()

In my SWIFT code I need to switch based on the ended-ness of the local host, so I call CFByteOrderGetCurrent():


import Framework
let localMachineByteOrder = CFByteOrderGetCurrent()


So far, so good - but I'm struggling to find a readible way to interpret the results. I was expecting to be able to say this:


if localMachineByteOrder == .CFByteOrderLittleEndian { ... }


However Xcode doesn't like it: "type of expression is ambiguous without more context". The best I've been able to achieve so far, with help from a developer on another forum, is this:


if localMachineByteOrder == CFByteOrder(1)     // 1 is the index of 'CFByteOrderLittleEndian' in the CFByteOrder enum


But that seems like rather unreadable code, and it would fail if the ordering of the constants in CFByteOrder changed.


Surely there must be a way to do this with symbolic constants!! Maybe I am reading the documentation wrongly but I am finding this very opaque... I would be very grateful for some guidance on this 🙂


Thanks in advance, Martin

Accepted Reply

You'd better know two things:

- Currently Swift supports only little endinan platforms.

- Integer types of Swift have many methods to support endianness without CFByteOrder functions

For example, you can write your own endian detection like this:

var isLittleEndian: Bool { return Int(littleEndian: 1) == 1 }


Back to your issue:

Surely there must be a way to do this with symbolic constants!!

Surely. You need to write someting like this:

if localMachineByteOrder == CFByteOrder(CFByteOrderLittleEndian.rawValue) {
    print("little endian")
}

You can get some hints by Cmd-clicking on the `CFByteOrderGetCurrent` and looking into the generated header:

public struct __CFByteOrder : RawRepresentable, Equatable {
    public init(_ rawValue: UInt32)
    public init(rawValue: UInt32)
    public var rawValue: UInt32
}
public var CFByteOrderUnknown: __CFByteOrder { get }
public var CFByteOrderLittleEndian: __CFByteOrder { get }
public var CFByteOrderBigEndian: __CFByteOrder { get }
public typealias CFByteOrder = CFIndex
public func CFByteOrderGetCurrent() -> CFByteOrder

The return type of CFByteOrderGetCurrent() is `CFByteOrder`, which actually is Int in Swift. And the symbol values are typed as `__CFByteOrder`, which is imported as a struct irrelevant to `CFByteOrder`.

In C/Objective-C world, they were both integer types and automatically converted to each other, and in Swift world...as you see.

Replies

You'd better know two things:

- Currently Swift supports only little endinan platforms.

- Integer types of Swift have many methods to support endianness without CFByteOrder functions

For example, you can write your own endian detection like this:

var isLittleEndian: Bool { return Int(littleEndian: 1) == 1 }


Back to your issue:

Surely there must be a way to do this with symbolic constants!!

Surely. You need to write someting like this:

if localMachineByteOrder == CFByteOrder(CFByteOrderLittleEndian.rawValue) {
    print("little endian")
}

You can get some hints by Cmd-clicking on the `CFByteOrderGetCurrent` and looking into the generated header:

public struct __CFByteOrder : RawRepresentable, Equatable {
    public init(_ rawValue: UInt32)
    public init(rawValue: UInt32)
    public var rawValue: UInt32
}
public var CFByteOrderUnknown: __CFByteOrder { get }
public var CFByteOrderLittleEndian: __CFByteOrder { get }
public var CFByteOrderBigEndian: __CFByteOrder { get }
public typealias CFByteOrder = CFIndex
public func CFByteOrderGetCurrent() -> CFByteOrder

The return type of CFByteOrderGetCurrent() is `CFByteOrder`, which actually is Int in Swift. And the symbol values are typed as `__CFByteOrder`, which is imported as a struct irrelevant to `CFByteOrder`.

In C/Objective-C world, they were both integer types and automatically converted to each other, and in Swift world...as you see.

Thanks OOPer -


I did eventually find a solution by converting the result of CFByteOrderGetCurrent() to a UInt32 and then comparing it to the raw value of the enumeration in a similar way. Your way of using the raw value to initialise an instance of CFByteOrder is more elegant though.


I had looked at the headers, but all those double underscores are too confusing for my small brain 😝