• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
warning about modifying AU ClassInfo data in RestoreState()
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Prev by Date: Negative Sample Time
  • Next by Date: Re: Negative Sample Time
  • Previous by thread: Re: Negative Sample Time
  • Next by thread: AudioFileSetProperty question
  • Index(es):
    • Date
    • Thread