// // Endian.swift // TrueTime // // Created by Michael Sanders on 7/11/16. // Copyright © 2016 Instacart. All rights reserved. // import Foundation protocol NetworkOrderConvertible { var byteSwapped: Self { get } } extension NetworkOrderConvertible { var bigEndian: Self { return isLittleEndian ? byteSwapped : self } var littleEndian: Self { return isLittleEndian ? self : byteSwapped } /// Returns the native representation converted from big-endian, changing /// the byte order if necessary. var nativeEndian: Self { return isLittleEndian ? byteSwapped : self } } extension Int: NetworkOrderConvertible {} extension ntp_time32_t: NetworkOrderConvertible { var byteSwapped: ntp_time32_t { return ntp_time32_t(whole: whole.byteSwapped, fraction: fraction.byteSwapped) } } extension ntp_time64_t: NetworkOrderConvertible { var byteSwapped: ntp_time64_t { return ntp_time64_t(whole: whole.byteSwapped, fraction: fraction.byteSwapped) } } extension ntp_packet_t: NetworkOrderConvertible { var byteSwapped: ntp_packet_t { return ntp_packet_t(client_mode: client_mode, version_number: version_number, leap_indicator: leap_indicator, stratum: stratum, poll: poll, precision: precision, root_delay: root_delay.byteSwapped, root_dispersion: root_dispersion.byteSwapped, reference_id: reference_id, reference_time: reference_time.byteSwapped, originate_time: originate_time.byteSwapped, receive_time: receive_time.byteSwapped, transmit_time: transmit_time.byteSwapped) } } extension sockaddr_in6: NetworkOrderConvertible { var byteSwapped: sockaddr_in6 { return sockaddr_in6(sin6_len: sin6_len, sin6_family: sin6_family, sin6_port: sin6_port.byteSwapped, sin6_flowinfo: sin6_flowinfo.byteSwapped, sin6_addr: sin6_addr, sin6_scope_id: sin6_scope_id.byteSwapped) } } extension sockaddr_in: NetworkOrderConvertible { var byteSwapped: sockaddr_in { return sockaddr_in(sin_len: sin_len, sin_family: sin_family, sin_port: sin_port.byteSwapped, sin_addr: in_addr(s_addr: sin_addr.s_addr.byteSwapped), sin_zero: sin_zero) } } private enum ByteOrder { static let BigEndian = CFByteOrder(CFByteOrderBigEndian.rawValue) static let LittleEndian = CFByteOrder(CFByteOrderLittleEndian.rawValue) static let Unknown = CFByteOrder(CFByteOrderUnknown.rawValue) } private let isLittleEndian = CFByteOrderGetCurrent() == ByteOrder.LittleEndian