@@ -19,6 +19,7 @@ along with Darling. If not, see <http://www.gnu.org/licenses/>.
19
19
20
20
#include < AudioToolbox/AudioFile.h>
21
21
#include < CoreServices/MacErrors.h>
22
+ #include " AudioFileFormatManager.h"
22
23
23
24
OSStatus AudioFileCreateWithURL (CFURLRef inFileRef,
24
25
AudioFileTypeID inFileType,
@@ -193,7 +194,34 @@ OSStatus AudioFileGetGlobalInfoSize( AudioFilePropertyID inPropertyID,
193
194
void * _Nullable inSpecifier,
194
195
UInt32 *outDataSize)
195
196
{
196
- return unimpErr;
197
+ return AudioFileGetGlobalInfo (inPropertyID, inSpecifierSize, inSpecifier, outDataSize, nullptr );
198
+ }
199
+
200
+ static void writeUInt32Set (const std::set<UInt32>& set, void *outPropertyData)
201
+ {
202
+ if (outPropertyData)
203
+ {
204
+ UInt32* out = static_cast <UInt32*>(outPropertyData);
205
+ int i = 0 ;
206
+ for (UInt32 v : set)
207
+ out[i++] = v;
208
+ }
209
+ }
210
+
211
+ template <typename ContainerType>
212
+ CFArrayRef stringContainerToArray (const ContainerType& t)
213
+ {
214
+ std::unique_ptr<CFStringRef[]> ptrs (new CFStringRef[t.size ()]);
215
+ int i = 0 ;
216
+
217
+ for (const std::string& str : t)
218
+ ptrs[i++] = CFStringCreateWithCString (nullptr , str.c_str (), kCFStringEncodingUTF8 );
219
+
220
+ CFArrayRef rv = CFArrayCreate (nullptr , (const void **) ptrs.get (), t.size (), &kCFTypeArrayCallBacks );
221
+
222
+ for (int i = 0 ; i < t.size (); i++)
223
+ CFRelease (ptrs[i]);
224
+ return rv;
197
225
}
198
226
199
227
OSStatus AudioFileGetGlobalInfo ( AudioFilePropertyID inPropertyID,
@@ -202,6 +230,142 @@ OSStatus AudioFileGetGlobalInfo( AudioFilePropertyID inPropertyID,
202
230
UInt32 *ioDataSize,
203
231
void *outPropertyData)
204
232
{
233
+ switch (inPropertyID)
234
+ {
235
+ case kAudioFileGlobalInfo_ReadableTypes :
236
+ case kAudioFileGlobalInfo_WritableTypes :
237
+ {
238
+ std::set<UInt32> types = AudioFileFormatManager::instance ()->types (inPropertyID == kAudioFileGlobalInfo_WritableTypes );
239
+
240
+ *ioDataSize = types.size () * sizeof (UInt32);
241
+ writeUInt32Set (types, outPropertyData);
242
+
243
+ return noErr;
244
+ }
245
+ case kAudioFileGlobalInfo_FileTypeName :
246
+ {
247
+ const UInt32* fileType = static_cast <const UInt32*>(inSpecifier);
248
+ if (inSpecifierSize != sizeof (*fileType))
249
+ return kAudioFileBadPropertySizeError ;
250
+
251
+ const AudioFileFormatManager::ComponentInfo* ci;
252
+
253
+ ci = AudioFileFormatManager::instance ()->fileType (*fileType);
254
+ if (!ci)
255
+ return kAudioFileUnsupportedFileTypeError ;
256
+
257
+ CFStringRef* out = static_cast <CFStringRef*>(outPropertyData);
258
+ *ioDataSize = sizeof (*out);
259
+
260
+ if (out)
261
+ *out = CFStringCreateWithCString (nullptr , ci->name .c_str (), kCFStringEncodingUTF8 );
262
+
263
+ return noErr;
264
+ }
265
+ case kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat :
266
+ {
267
+ const AudioFileTypeAndFormatID* spec = static_cast <const AudioFileTypeAndFormatID*>(inSpecifier);
268
+ if (inSpecifierSize != sizeof (*spec))
269
+ return kAudioFileBadPropertySizeError ;
270
+ break ;
271
+ }
272
+ case kAudioFileGlobalInfo_AvailableFormatIDs :
273
+ {
274
+ const UInt32* fileType = static_cast <const UInt32*>(inSpecifier);
275
+ if (inSpecifierSize != sizeof (*fileType))
276
+ return kAudioFileBadPropertySizeError ;
277
+
278
+ auto set = AudioFileFormatManager::instance ()->availableFormatIDs (*fileType);
279
+ *ioDataSize = set.size () * sizeof (UInt32);
280
+
281
+ writeUInt32Set (set, outPropertyData);
282
+
283
+ return noErr;
284
+ }
285
+ case kAudioFileGlobalInfo_AllHFSTypeCodes :
286
+ case kAudioFileGlobalInfo_HFSTypeCodesForType :
287
+ case kAudioFileGlobalInfo_TypesForHFSTypeCode :
288
+ *ioDataSize = 0 ;
289
+ return noErr;
290
+ case kAudioFileGlobalInfo_AllExtensions :
291
+ case kAudioFileGlobalInfo_AllUTIs :
292
+ case kAudioFileGlobalInfo_AllMIMETypes :
293
+ {
294
+ *ioDataSize = sizeof (CFArrayRef);
295
+
296
+ if (outPropertyData)
297
+ {
298
+ std::set<std::string> set;
299
+ AudioFileFormatManager* mgr = AudioFileFormatManager::instance ();
300
+
301
+ if (inPropertyID == kAudioFileGlobalInfo_AllExtensions )
302
+ set = mgr->allExtensions ();
303
+ else if (inPropertyID == kAudioFileGlobalInfo_AllUTIs )
304
+ set = mgr->allUTIs ();
305
+ else if (inPropertyID == kAudioFileGlobalInfo_AllMIMETypes )
306
+ set = mgr->allMIMEs ();
307
+
308
+ *((CFArrayRef*)outPropertyData) = stringContainerToArray (set);
309
+ }
310
+
311
+ return noErr;
312
+ }
313
+ case kAudioFileGlobalInfo_ExtensionsForType :
314
+ case kAudioFileGlobalInfo_UTIsForType :
315
+ case kAudioFileGlobalInfo_MIMETypesForType :
316
+ {
317
+ const UInt32* fileType = static_cast <const UInt32*>(inSpecifier);
318
+ if (inSpecifierSize != sizeof (*fileType))
319
+ return kAudioFileBadPropertySizeError ;
320
+
321
+ *ioDataSize = sizeof (CFArrayRef);
322
+
323
+ if (outPropertyData)
324
+ {
325
+ const std::vector<std::string>* vector;
326
+ const AudioFileFormatManager::ComponentInfo* ci;
327
+
328
+ ci = AudioFileFormatManager::instance ()->fileType (*fileType);
329
+ if (!ci)
330
+ return kAudioFileUnsupportedFileTypeError ;
331
+
332
+ if (inPropertyID == kAudioFileGlobalInfo_ExtensionsForType )
333
+ vector = &ci->extensions ;
334
+ else if (inPropertyID == kAudioFileGlobalInfo_UTIsForType )
335
+ vector = &ci->utis ;
336
+ else if (inPropertyID == kAudioFileGlobalInfo_MIMETypesForType )
337
+ vector = &ci->mimeTypes ;
338
+
339
+ *((CFArrayRef*)outPropertyData) = stringContainerToArray (*vector);
340
+ }
341
+
342
+ return noErr;
343
+ }
344
+ case kAudioFileGlobalInfo_TypesForMIMEType :
345
+ case kAudioFileGlobalInfo_TypesForUTI :
346
+ case kAudioFileGlobalInfo_TypesForExtension :
347
+ {
348
+ CFStringRef str = static_cast <CFStringRef>(inSpecifier);
349
+ if (inSpecifierSize != sizeof (str))
350
+ return kAudioFileBadPropertySizeError ;
351
+
352
+ AudioFileFormatManager* mgr = AudioFileFormatManager::instance ();
353
+ const char * cstr = CFStringGetCStringPtr (str, kCFStringEncodingUTF8 );
354
+ std::set<UInt32> set;
355
+
356
+ if (inPropertyID == kAudioFileGlobalInfo_TypesForMIMEType )
357
+ set = mgr->typesForMIME (cstr);
358
+ else if (inPropertyID == kAudioFileGlobalInfo_TypesForUTI )
359
+ set = mgr->typesForUTI (cstr);
360
+ else if (inPropertyID == kAudioFileGlobalInfo_TypesForExtension )
361
+ set = mgr->typesForExtension (cstr);
362
+
363
+ *ioDataSize = set.size () * sizeof (UInt32);
364
+ writeUInt32Set (set, outPropertyData);
365
+
366
+ return noErr;
367
+ }
368
+ }
205
369
return unimpErr;
206
370
}
207
371
0 commit comments