This has worked fine up until I run it under Sonoma. For some reason, the last 3 characters are now encoded differently. I’ll get “5/28/24 10/46/57���”, with " AM" corresponding to hex “E2 80 AF” instead of “20 41 4D”.
Thanks for the comments. I’ll fix it with encoding.
What’s strange to me is that this has been working for years with all MacOS versions up through Ventura. The only other difference in my testing is that the Sonoma machine is an M2 versus other test machines having M1 or Intel, but I can’t see how that would make a change like this.
I was mistaken about the origin of this problem (writing to memoryblock). This unicode character (3 bytes) is output by the DateTime.ToString function. The reason I’m not seeing the AM or PM (just the unknown characters) is that I’m using String.Length for how many bytes to write to the memoryblock and it’s now 2 bytes longer (I guess I should have used String.Bytes). But I want to save it as simple string anyway.
I couldn’t figure out how to change those bytes back to a space character with Encodings. When I tried to use ConvertEncoding, I got a “?”. I ended up using ReplaceAllBytes to do it:
mytime = mytime.ReplaceAllBytes(&u202f, " ")
Maybe there’s a more eloquent way to do it, but this works for now.
I don’t see that you could accomplish that with ConvertEncoding, unless you tried to convert to ASCII. But then it would depend how clever ConvertEncoding is.
Fixing this seemed to me to be a big waste of time, but I’m sure all those people who lost sleep over the huge amount of wasted space before “AM” or “PM” will be happy now that Sonoma has come along.
Do you really need memoryblocks to do whatever you are doing? Are you just appending strings? Sometimes users use shotguns to kill flies, that’s why I ask.
Sometimes more direct things like these are enough:
Var someDateTime As DateTime = DateTime.Now
Var tf As TextOutputStream = TextOutputStream.Open(SpecialFolder.Desktop.Child("dates_test.txt"))
For offsetDays As Integer = 1 to 10
tf.WriteLine someDateTime.AddInterval(0,0,offsetDays) _ // next day
.ToString(new Locale("en-us"), DateTime.FormatStyles.Short) _ // m/d/y h:m:s am/pm
.ReplaceAll(&u202f, " ") // user prefer normal space
Next
tf.Close
Quit
Ha ha. I’m saving dozen or even hundreds of “songs” which are MIDI performances containing possibly thousands of 3-byte MIDI events including timestamps. I found it to be way too slow to save it all writing to a stream so I build my file in a memory block. What took 25 seconds before now takes about 1 second.
Thanks for your more direct example. I try to do that but often forget.
25x slower is weird, a BinaryStream is supposed to be fast and use buffers (a memoryblock) internally to speed things up, flushing its contents over time. Should not be so slow. Something seems not well tuned in the Xojo framework.
Part of my optimization was achieved by using a memoryblock in each song to hold the MIDI event data instead of an array of thousands of MIDI event classes. When those events are needed for playback, the time to parse it into an array is negligible. That might explain much of the speed difference. The 25x difference was extreme when testing with hundreds of thousands of songs resulting in a file of several hundred MBs. To use it as an example may have been a bit dramatic. Maybe it took 2 seconds.