warning about modifying AU ClassInfo data in RestoreState()
warning about modifying AU ClassInfo data in RestoreState()
- Subject: warning about modifying AU ClassInfo data in RestoreState()
- From: "Sophia Poirier [dfx]" <email@hidden>
- Date: Mon, 23 Jun 2008 19:54:50 -0400
Hello folks. I just learned that a somewhat esoteric bug was causing
crashing of many of my AUs (Destroy FX and some job ones) when
restoring state data. I think it's an easy mistake to make, and one
that only comes up in a rather rare situation, so I thought I'd post
something about it in case it's helpful to anyone else.
Basically the lesson that I learned is that, if you store some opaque
block of data in your AU state data during SaveState() and you are
doing byte-ordering operations to make data readable on big or little-
endian CPUs, you want to make sure to only do those operations on your
own copy of the data, not the data that is passed to you from the
host. The reason is because the host may still access this data
later, so you can't muck it up, and in the case of Soundtrack Pro 2
with its AppleScripting feature, this does happen. STP will request
your ClassInfo, then restore that same CFDictionary of data, and only
then after that will it store the data into the AppleScript. So if
you are doing some byte-reordering during RestoreState() on the actual
data passed in, it will then be reverse of the order you expect when
STP gets around to actually storing the data. (I hope that made
sense, not sure I worded it as clearly as I could.)
Here's a brief example of the wrong thing to do:
struct {
SInt32 foot;
SInt32 elbow;
SInt32 finger;
} SpecialData;
ComponentResult YourPlugin::RestoreState(CFPropertyListRef inData)
{
CFDataRef cfdata = (CFDataRef)
CFDictionaryGetValue((CFDictionaryRef)inData, CFSTR("your-special-data-
key"));
SpecialData * data = (SpecialData*) CFDataGetBytePtr(cfdata);
data->foot = CFSwapInt32BigToHost(data->foot);
data->elbow = CFSwapInt32BigToHost(data->elbow);
data->finger = CFSwapInt32BigToHost(data->finger);
DoSomethingWithData(data->foot, data->elbow, data->finger);
}
Here's an example of a better idea:
ComponentResult YourPlugin::RestoreState(CFPropertyListRef inData)
{
CFDataRef cfdata = (CFDataRef)
CFDictionaryGetValue((CFDictionaryRef)inData, CFSTR("your-special-data-
key"));
SpecialData * data = (SpecialData*) CFDataGetBytePtr(cfdata);
SpecialData dataPrivateCopy;
dataPrivateCopy.foot = CFSwapInt32BigToHost(data->foot);
dataPrivateCopy.elbow = CFSwapInt32BigToHost(data->elbow);
dataPrivateCopy.finger = CFSwapInt32BigToHost(data->finger);
DoSomethingWithData(dataPrivateCopy.foot, dataPrivateCopy.elbow,
dataPrivateCopy.finger);
}
Another thing about all this is that I learned that, unlike most other
CFTypes, CFData does give you direct access to its internal buffer
store via CFDataGetBytePtr(). So that's the other thing to realize
about all of this.
Anyway, hope that's helpful to someone...
Sophia
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden