Context: I want to be able to assign/init UInt32 values with four-character strings as in the file type/creator codes of the old days, or magic numbers used in some file formats.
I developed a function that works fine. It calls the max function to make sure to use at most 4 characters from the input string:
let length = max(asciiRepresentation.count, 4)
But this lines doesn't compile when put in an extension to UInt32:
extension UInt32 {
init(asciiRepresentation: String) {
let length = max(asciiRepresentation.count, 4)
var result: UInt32 = 0
var index = asciiRepresentation.startIndex
for _ in 0 ..< length {
let char = asciiRepresentation[index]
let byte: UInt32 = UInt32(char.asciiValue ?? 0)
result = result << 8 + byte
index = asciiRepresentation.index(after:index)
}
self = result
}
}
In my playground (Xcode 11.2.1):
error: CodingDecoding.playground:46:22: error: static member 'max' cannot be used on instance of type 'UInt32'
let length = max(asciiRepresentation.count, 4)
^~~
Self.
My understanding is that the global max function is hidden by the UInt32.max static member that represents the largest possible UInt32 number.
1- Is that correct?
2- Is there a way to call the global max function anyway?
Of course, I can work around that with an if statement easily.
Also feel free to comment on my code: I am a noob, and I guess this code could be written better. I would appreciate the learning experience.
Duh, of course not max. Typical brain fart (for me). I intended min...
But thank you so much for your rewrite. It brings much value on several levels, for me as a beginner:
tip about MacRoman (though I am not sure how it applies to a file format such as .MP4)
failable Initializer
guard
the use of reduce
even the use of | instead of +
Note about String.data(using:):
I had a hard time understanding where this is coming from. This function is nowhere to be found in the Xcode documentation for String. It has a quick help, but that's it. Jumping to definition leads to a page with only imports. Jumping to definition of String leads to a very long file, where this function is missing.
though I am not sure how it applies to a file format such as .MP4
That’s an interesting question. MPEG-4’s container format is a ‘child’ of QuickTime, and QuickTime definitely used MacRoman for this. I’m not sure whether they removed that dependency as part of the standardisation process. It’s possible that they didn’t address it at all, and just standardised on the UInt32 values. The only way to know for sure is to look at the MPEG-4 standard itself.
Note about String.data(using:):
I had a hard time understanding where this is coming from.
Indeed. The Quick Help usually has a link to the documentation but that’s not present in this case. I suspect this is because the symbol is implemented in Foundation’s Swift overlay. Regardless, the fact that Xcode won’t take you to the documentation is bugworthy IMO. Please file a bug about that (and post your bug number, just for the record).
… it requires Foundation. Right?
Yes.
So this function requires bridging String to NSString.
If I’m right, and this is part of Foundation’s Swift overlay, the bridging situation is nuanced.
Personally, I don’t lose a lot of sleep worrying about this sort of bridging. If something is slow and I’ve profiled it and the profile shows that bridging is part of the problem, I look into it. Otherwise I just accept it as a part of life.