コード例 #1
0
ファイル: spotlight.c プロジェクト: xli/spotlight
static VALUE convert2rb_type(CFTypeRef ref) {
    VALUE result = Qnil;
    double double_result;
    int int_result;
    long long_result;
    int i;
    if (ref) {
        if (CFGetTypeID(ref) == CFStringGetTypeID()) {
            result = cfstring2rbstr(ref);
        } else if (CFGetTypeID(ref) == CFDateGetTypeID()) {
            // 978307200.0 == (January 1, 2001 00:00 GMT) - (January 1, 1970 00:00 UTC)
            // CFAbsoluteTime => January 1, 2001 00:00 GMT
            // ruby Time => January 1, 1970 00:00 UTC
            double_result = (double) CFDateGetAbsoluteTime(ref) + 978307200;
            result = rb_funcall(rb_cTime, rb_intern("at"), 1, rb_float_new(double_result));
        } else if (CFGetTypeID(ref) == CFArrayGetTypeID()) {
            result = rb_ary_new();
            for (i = 0; i < CFArrayGetCount(ref); i++) {
                rb_ary_push(result, convert2rb_type(CFArrayGetValueAtIndex(ref, i)));
            }
        } else if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
            if (CFNumberIsFloatType(ref)) {
                CFNumberGetValue(ref, CFNumberGetType(ref), &double_result);
                result = rb_float_new(double_result);
            } else {
                CFNumberGetValue(ref, CFNumberGetType(ref), &long_result);
                result = LONG2NUM(long_result);
            }
        }
    }
    return result;
}
CF_EXPORT Boolean CFPreferencesAppBooleanValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
    CFPropertyListRef value;
    Boolean result, valid;
    CFTypeID typeID = 0;
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);

    if (!keyExistsAndHasValidFormat) {
        keyExistsAndHasValidFormat = &valid;
    }
    value = CFPreferencesCopyAppValue(key, appName);
    if (!value) {
        *keyExistsAndHasValidFormat = false;
        return false;
    }
    typeID = CFGetTypeID(value);
    if (typeID == CFStringGetTypeID()) {
        if (CFStringCompare((CFStringRef)value, CFSTR("true"), kCFCompareCaseInsensitive) == kCFCompareEqualTo || CFStringCompare((CFStringRef)value, CFSTR("YES"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
            *keyExistsAndHasValidFormat = true;
            result = true;
        } else if (CFStringCompare((CFStringRef)value, CFSTR("false"), kCFCompareCaseInsensitive) == kCFCompareEqualTo || CFStringCompare((CFStringRef)value, CFSTR("NO"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
            *keyExistsAndHasValidFormat = true;
            result = false;
        } else {
            *keyExistsAndHasValidFormat = false;
            result = false;
        }
    } else if (typeID == CFNumberGetTypeID()) {
        if (CFNumberIsFloatType((CFNumberRef)value)) {
            *keyExistsAndHasValidFormat = false;
            result = false;
        } else {
            int i;
            *keyExistsAndHasValidFormat = true;
            CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &i);
            result = (i == 0) ? false : true;
        }
    } else if (typeID == CFBooleanGetTypeID()) {
        result = (value == kCFBooleanTrue);
        *keyExistsAndHasValidFormat = true;
    } else {
        // Unknown type
        result = false;
        *keyExistsAndHasValidFormat = false;
    }
    CFRelease(value);
    return result;
}
コード例 #3
0
ファイル: battery.c プロジェクト: Civil/collectd
static double dict_get_double (CFDictionaryRef dict, char *key_string) /* {{{ */
{
	double      val_double;
	long long   val_int;
	CFNumberRef val_obj;
	CFStringRef key_obj;

	key_obj = CFStringCreateWithCString (kCFAllocatorDefault, key_string,
			kCFStringEncodingASCII);
	if (key_obj == NULL)
	{
		DEBUG ("CFStringCreateWithCString (%s) failed.\n", key_string);
		return (INVALID_VALUE);
	}

	if ((val_obj = CFDictionaryGetValue (dict, key_obj)) == NULL)
	{
		DEBUG ("CFDictionaryGetValue (%s) failed.", key_string);
		CFRelease (key_obj);
		return (INVALID_VALUE);
	}
	CFRelease (key_obj);

	if (CFGetTypeID (val_obj) == CFNumberGetTypeID ())
	{
		if (CFNumberIsFloatType (val_obj))
		{
			CFNumberGetValue (val_obj,
					kCFNumberDoubleType,
					&val_double);
		}
		else
		{
			CFNumberGetValue (val_obj,
					kCFNumberLongLongType,
					&val_int);
			val_double = val_int;
		}
	}
	else
	{
		DEBUG ("CFGetTypeID (val_obj) = %i", (int) CFGetTypeID (val_obj));
		return (INVALID_VALUE);
	}

	return (val_double);
} /* }}} double dict_get_double */
コード例 #4
0
ファイル: unimotion.c プロジェクト: ADTSH/io
static Boolean getPrefDouble(CFStringRef key, CFStringRef app, double *val)
{
    CFPropertyListRef prefRef;
    Boolean ok;
    double ret;

    ok = false;
    prefRef = CFPreferencesCopyAppValue(key, app);
    if ( prefRef ) {
        if ( CFGetTypeID(prefRef) == CFNumberGetTypeID() && CFNumberIsFloatType(prefRef) ) {
            ok = CFNumberGetValue(prefRef, kCFNumberDoubleType, &ret);
            if ( ok && val )
                *val = ret;
        }
        CFRelease(prefRef);
    }
    return ok;
}
コード例 #5
0
ファイル: keychain.c プロジェクト: fcheung/keychain_c
static void cf_hash_to_rb_hash(const void *raw_key, const void * raw_value, void *ctx){
  CFTypeRef value = (CFTypeRef)raw_value;
  CFStringRef key = (CFStringRef)raw_key;

  VALUE rubyValue = Qnil;
  VALUE hash = (VALUE)ctx;

  if(CFStringGetTypeID() == CFGetTypeID(value)){
    rubyValue = cfstring_to_rb_string((CFStringRef)value);
  }
  else if(CFDataGetTypeID() == CFGetTypeID(value)){
    CFDataRef data = (CFDataRef)value;
    rubyValue = rb_enc_str_new((const char*)CFDataGetBytePtr(data),CFDataGetLength(data), rb_ascii8bit_encoding());
  }
  else if(CFBooleanGetTypeID() == CFGetTypeID(value)){
    Boolean booleanValue = CFBooleanGetValue(value);
    rubyValue = booleanValue ? Qtrue : Qfalse;
  }
  else if(CFNumberGetTypeID() == CFGetTypeID(value)){
    if(CFNumberIsFloatType(value))
    {
      double doubleValue;
      CFNumberGetValue(value, kCFNumberDoubleType, &doubleValue);
      rubyValue = rb_float_new(doubleValue);
    }else{
      long long longValue;
      CFNumberGetValue(value, kCFNumberLongLongType, &longValue);
      rubyValue = LL2NUM(longValue);
    }
  }
  else if (CFDateGetTypeID() == CFGetTypeID(value)){
    CFDateRef date = (CFDateRef) value;
    CFAbsoluteTime abs_time = CFDateGetAbsoluteTime(date);
    double secondsSinceUnixEpoch = abs_time + kCFAbsoluteTimeIntervalSince1970;
    time_t seconds = (time_t)secondsSinceUnixEpoch;
    long usec = (secondsSinceUnixEpoch - seconds) * 1000000;
    rubyValue = rb_time_new((time_t)secondsSinceUnixEpoch, usec);
  }

  if(!NIL_P(rubyValue)){
    rb_hash_aset(hash, cfstring_to_rb_string(key), rubyValue);
  }
}
__private_extern__ CFIndex CFPreferencesAppIntegerValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
    CFPropertyListRef value;
    CFIndex result;
    CFTypeID typeID = 0;
    Boolean valid;
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);

    value = CFPreferencesCopyAppValue(key, appName);
    if (!keyExistsAndHasValidFormat) {
        keyExistsAndHasValidFormat = &valid;
    }
    if (!value) {
        *keyExistsAndHasValidFormat = false;
        return 0;
    }
    typeID = CFGetTypeID(value);
    if (typeID == CFStringGetTypeID()) {
        SInt32 charIndex = 0;
        SInt32 intVal;
        CFStringInlineBuffer buf;
        Boolean success;
        CFStringInitInlineBuffer((CFStringRef)value, &buf, CFRangeMake(0, CFStringGetLength((CFStringRef)value)));
        success = __CFStringScanInteger(&buf, NULL, &charIndex, false, &intVal);
        *keyExistsAndHasValidFormat = (success && charIndex == CFStringGetLength((CFStringRef)value));
        result = (*keyExistsAndHasValidFormat) ? intVal : 0;
    } else if (typeID == CFNumberGetTypeID()) {
        *keyExistsAndHasValidFormat = !CFNumberIsFloatType((CFNumberRef)value);
        if (*keyExistsAndHasValidFormat) {
            CFNumberGetValue((CFNumberRef)value, kCFNumberCFIndexType, &result);
        } else {
            result = 0;
        }
    } else {
        // Unknown type
        result = 0;
        *keyExistsAndHasValidFormat = false;
    }
    CFRelease(value);
    return result;
}
コード例 #7
0
ファイル: Logger.cpp プロジェクト: CiCiHope/SFBAudioEngine
std::ostream& operator<<(std::ostream& out, CFNumberRef n)
{
	if(nullptr == n)
		out << "(null)";
	else if(n == kCFNumberPositiveInfinity)
		out << "+Inf";
	else if(n == kCFNumberNegativeInfinity)
		out << "-Inf";
	else if(n == kCFNumberNaN)
		out << "NaN";
	else if(CFNumberIsFloatType(n)) {
		double val;
		if(CFNumberGetValue(n, kCFNumberDoubleType, &val))
			out << val;
	}
	else {
		long long val;
		if(CFNumberGetValue(n, kCFNumberLongLongType, &val))
			out << val;
	}

	return out;
}
コード例 #8
0
UString UserObjectImp::toString(ExecState *exec) const
{
    UString result;
    JSUserObject* jsObjPtr = KJSValueToJSObject(toObject(exec), exec);
    CFTypeRef cfValue = jsObjPtr ? jsObjPtr->CopyCFValue() : 0;
    if (cfValue)
    {
        CFTypeID cfType = CFGetTypeID(cfValue);
        if (cfValue == GetCFNull())
        {
            //
        }
        else if (cfType == CFBooleanGetTypeID())
        {
            if (cfValue == kCFBooleanTrue)
            {
                result = "true";
            }
            else
            {
                result = "false";
            }
        }
        else if (cfType == CFStringGetTypeID())
        {
            result = CFStringToUString((CFStringRef)cfValue);
        }
        else if (cfType == CFNumberGetTypeID())
        {
            if (cfValue == kCFNumberNaN)
            {
                result = "Nan";
            }
            else if (CFNumberCompare(kCFNumberPositiveInfinity, (CFNumberRef)cfValue, 0) == 0)
            {
                result = "Infinity";
            }
            else if (CFNumberCompare(kCFNumberNegativeInfinity, (CFNumberRef)cfValue, 0) == 0)
            {
                result = "-Infinity";
            }
            else
            {
                CFStringRef cfNumStr;
                double d = 0;
                CFNumberGetValue((CFNumberRef)cfValue, kCFNumberDoubleType, &d);
                if (CFNumberIsFloatType((CFNumberRef)cfValue))
                {
                    cfNumStr = CFStringCreateWithFormat(0, 0, CFSTR("%f"), d);
                }
                else
                {
                    cfNumStr = CFStringCreateWithFormat(0, 0, CFSTR("%.0f"), d);
                }
                result = CFStringToUString(cfNumStr);
                ReleaseCFType(cfNumStr);
            }
        }
        else if (cfType == CFArrayGetTypeID())
        {
            //
        }
        else if (cfType == CFDictionaryGetTypeID())
        {
            //
        }
        else if (cfType == CFSetGetTypeID())
        {
            //
        }
        else if (cfType == CFURLGetTypeID())
        {
            CFURLRef absURL = CFURLCopyAbsoluteURL((CFURLRef)cfValue);
            if (absURL)
            {
                CFStringRef cfStr = CFURLGetString(absURL);
                if (cfStr)
                {
                    result = CFStringToUString(cfStr);
                }
                ReleaseCFType(absURL);
            }
        }
    }
    ReleaseCFType(cfValue);
    if (jsObjPtr) jsObjPtr->Release();
    return result;
}
コード例 #9
0
static void initializeDb()
{
    QFontDatabasePrivate *db = privateDb();
    if(!db || db->count)
        return;

#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
    QCFType<CTFontCollectionRef> collection = CTFontCollectionCreateFromAvailableFonts(0);
    if(!collection)
        return;
    QCFType<CFArrayRef> fonts = CTFontCollectionCreateMatchingFontDescriptors(collection);
    if(!fonts)
        return;
    QString foundry_name = "CoreText";
    const int numFonts = CFArrayGetCount(fonts);
    for(int i = 0; i < numFonts; ++i) {
        CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i);

        QCFString family_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
        QtFontFamily *family = db->family(family_name, true);
        for(int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws)
            family->writingSystems[ws] = QtFontFamily::Supported;
        QtFontFoundry *foundry = family->foundry(foundry_name, true);

        QtFontStyle::Key styleKey;
        if(QCFType<CFDictionaryRef> styles = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute)) {
            if(CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
                Q_ASSERT(CFNumberIsFloatType(weight));
                double d;
                if(CFNumberGetValue(weight, kCFNumberDoubleType, &d)) {
                    //qDebug() << "BOLD" << (QString)family_name << d;
                    styleKey.weight = (d > 0.0) ? QFont::Bold : QFont::Normal;
                }
            }
            if(CFNumberRef italic = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
                Q_ASSERT(CFNumberIsFloatType(italic));
                double d;
                if(CFNumberGetValue(italic, kCFNumberDoubleType, &d)) {
                    //qDebug() << "ITALIC" << (QString)family_name << d;
                    if (d > 0.0)
                        styleKey.style = QFont::StyleItalic;
                }
            }
        }

        QtFontStyle *style = foundry->style(styleKey, true);
        style->smoothScalable = true;
        if(QCFType<CFNumberRef> size = (CFNumberRef)CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
            //qDebug() << "WHEE";
            int pixel_size=0;
            if(CFNumberIsFloatType(size)) {
                double d;
                CFNumberGetValue(size, kCFNumberDoubleType, &d);
                pixel_size = d;
            } else {
                CFNumberGetValue(size, kCFNumberIntType, &pixel_size);
            }
            //qDebug() << "SIZE" << (QString)family_name << pixel_size;
            if(pixel_size)
                style->pixelSize(pixel_size, true);
        } else {
            //qDebug() << "WTF?";
        }
    }
} else 
#endif
{ 
    FMFontIterator it;
    if (!FMCreateFontIterator(0, 0, kFMUseGlobalScopeOption, &it)) {
        while (true) {
            FMFont fmFont;
            if (FMGetNextFont(&it, &fmFont) != noErr)
                break;

            FMFontFamily fmFamily;
            FMFontStyle fmStyle;
            QString familyName;

            QtFontStyle::Key styleKey;

            ATSFontRef atsFont = FMGetATSFontRefFromFont(fmFont);

            if (!FMGetFontFamilyInstanceFromFont(fmFont, &fmFamily, &fmStyle)) {
                { //sanity check the font, and see if we can use it at all! --Sam
                    ATSUFontID fontID;
                    if(ATSUFONDtoFontID(fmFamily, 0, &fontID) != noErr)
                        continue;
                }

                if (fmStyle & ::italic)
                    styleKey.style = QFont::StyleItalic;
                if (fmStyle & ::bold)
                    styleKey.weight = QFont::Bold;

                ATSFontFamilyRef familyRef = FMGetATSFontFamilyRefFromFontFamily(fmFamily);
                QCFString cfFamilyName;;
                ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &cfFamilyName);
                familyName = cfFamilyName;
            } else {
                QCFString cfFontName;
                ATSFontGetName(atsFont, kATSOptionFlagsDefault, &cfFontName);
                familyName = cfFontName;
                quint16 macStyle = 0;
                {
                    uchar data[4];
                    ByteCount len = 4;
                    if (ATSFontGetTable(atsFont, MAKE_TAG('h', 'e', 'a', 'd'), 44, 4, &data, &len) == noErr)
                        macStyle = qFromBigEndian<quint16>(data);
                }
                if (macStyle & 1)
                    styleKey.weight = QFont::Bold;
                if (macStyle & 2)
                    styleKey.style = QFont::StyleItalic;
            }

            QtFontFamily *family = db->family(familyName, true);
            QtFontFoundry *foundry = family->foundry(QString(), true);
            QtFontStyle *style = foundry->style(styleKey, true);
            style->pixelSize(0, true);
            style->smoothScalable = true;

            initWritingSystems(family, atsFont);
        }
        FMDisposeFontIterator(&it);
    }
}
}
コード例 #10
0
ファイル: qsettings_mac.cpp プロジェクト: xjohncz/qt5
static QVariant qtValue(CFPropertyListRef cfvalue)
{
    if (!cfvalue)
        return QVariant();

    CFTypeID typeId = CFGetTypeID(cfvalue);

    /*
        Sorted grossly from most to least frequent type.
    */
    if (typeId == CFStringGetTypeID()) {
        return QSettingsPrivate::stringToVariant(QCFString::toQString(static_cast<CFStringRef>(cfvalue)));
    } else if (typeId == CFNumberGetTypeID()) {
        CFNumberRef cfnumber = static_cast<CFNumberRef>(cfvalue);
        if (CFNumberIsFloatType(cfnumber)) {
            double d;
            CFNumberGetValue(cfnumber, kCFNumberDoubleType, &d);
            return d;
        } else {
            int i;
            qint64 ll;

            if (CFNumberGetValue(cfnumber, kCFNumberIntType, &i))
                return i;
            CFNumberGetValue(cfnumber, kCFNumberLongLongType, &ll);
            return ll;
        }
    } else if (typeId == CFArrayGetTypeID()) {
        CFArrayRef cfarray = static_cast<CFArrayRef>(cfvalue);
        QList<QVariant> list;
        CFIndex size = CFArrayGetCount(cfarray);
        bool metNonString = false;
        for (CFIndex i = 0; i < size; ++i) {
            QVariant value = qtValue(CFArrayGetValueAtIndex(cfarray, i));
            if (value.type() != QVariant::String)
                metNonString = true;
            list << value;
        }
        if (metNonString)
            return list;
        else
            return QVariant(list).toStringList();
    } else if (typeId == CFBooleanGetTypeID()) {
        return (bool)CFBooleanGetValue(static_cast<CFBooleanRef>(cfvalue));
    } else if (typeId == CFDataGetTypeID()) {
        CFDataRef cfdata = static_cast<CFDataRef>(cfvalue);
        return QByteArray(reinterpret_cast<const char *>(CFDataGetBytePtr(cfdata)),
                          CFDataGetLength(cfdata));
    } else if (typeId == CFDictionaryGetTypeID()) {
        CFDictionaryRef cfdict = static_cast<CFDictionaryRef>(cfvalue);
        CFTypeID arrayTypeId = CFArrayGetTypeID();
        int size = (int)CFDictionaryGetCount(cfdict);
        QVarLengthArray<CFPropertyListRef> keys(size);
        QVarLengthArray<CFPropertyListRef> values(size);
        CFDictionaryGetKeysAndValues(cfdict, keys.data(), values.data());

        QMultiMap<QString, QVariant> map;
        for (int i = 0; i < size; ++i) {
            QString key = QCFString::toQString(static_cast<CFStringRef>(keys[i]));

            if (CFGetTypeID(values[i]) == arrayTypeId) {
                CFArrayRef cfarray = static_cast<CFArrayRef>(values[i]);
                CFIndex arraySize = CFArrayGetCount(cfarray);
                for (CFIndex j = arraySize - 1; j >= 0; --j)
                    map.insert(key, qtValue(CFArrayGetValueAtIndex(cfarray, j)));
            } else {
                map.insert(key, qtValue(values[i]));
            }
        }
        return map;
    } else if (typeId == CFDateGetTypeID()) {
        QDateTime dt;
        dt.setTime_t((uint)kCFAbsoluteTimeIntervalSince1970);
        return dt.addSecs((int)CFDateGetAbsoluteTime(static_cast<CFDateRef>(cfvalue)));
    }
    return QVariant();
}
コード例 #11
0
static QVariant q_toVariant(const CFTypeRef &obj)
{
    const CFTypeID typeId = CFGetTypeID(obj);

    if (typeId == CFStringGetTypeID())
        return QVariant(q_toString(static_cast<const CFStringRef>(obj)));

    if (typeId == CFNumberGetTypeID()) {
        const CFNumberRef num = static_cast<const CFNumberRef>(obj);
        const CFNumberType type = CFNumberGetType(num);
        switch (type) {
        case kCFNumberSInt8Type:
            return qVariantFromValue(convertCFNumber<char>(num, type));
        case kCFNumberSInt16Type:
            return qVariantFromValue(convertCFNumber<qint16>(num, type));
        case kCFNumberSInt32Type:
            return qVariantFromValue(convertCFNumber<qint32>(num, type));
        case kCFNumberSInt64Type:
            return qVariantFromValue(convertCFNumber<qint64>(num, type));
        case kCFNumberCharType:
            return qVariantFromValue(convertCFNumber<uchar>(num, type));
        case kCFNumberShortType:
            return qVariantFromValue(convertCFNumber<short>(num, type));
        case kCFNumberIntType:
            return qVariantFromValue(convertCFNumber<int>(num, type));
        case kCFNumberLongType:
            return qVariantFromValue(convertCFNumber<long>(num, type));
        case kCFNumberLongLongType:
            return qVariantFromValue(convertCFNumber<long long>(num, type));
        case kCFNumberFloatType:
            return qVariantFromValue(convertCFNumber<float>(num, type));
        case kCFNumberDoubleType:
            return qVariantFromValue(convertCFNumber<double>(num, type));
        default:
            if (CFNumberIsFloatType(num))
                return qVariantFromValue(convertCFNumber<double>(num, kCFNumberDoubleType));
            return qVariantFromValue(convertCFNumber<quint64>(num, kCFNumberLongLongType));
        }
    }

    if (typeId == CFDateGetTypeID()) {
        QDateTime dt;
        dt.setTime_t(uint(kCFAbsoluteTimeIntervalSince1970));
        return dt.addSecs(int(CFDateGetAbsoluteTime(static_cast<const CFDateRef>(obj))));
    }

    if (typeId == CFDataGetTypeID()) {
        const CFDataRef cfdata = static_cast<const CFDataRef>(obj);
        return QByteArray(reinterpret_cast<const char *>(CFDataGetBytePtr(cfdata)),
                    CFDataGetLength(cfdata));
    }

    if (typeId == CFBooleanGetTypeID())
        return QVariant(bool(CFBooleanGetValue(static_cast<const CFBooleanRef>(obj))));

    if (typeId == CFArrayGetTypeID()) {
        const CFArrayRef cfarray = static_cast<const CFArrayRef>(obj);
        QList<QVariant> list;
        CFIndex size = CFArrayGetCount(cfarray);
        bool metNonString = false;
        for (CFIndex i = 0; i < size; ++i) {
            QVariant value = q_toVariant(CFArrayGetValueAtIndex(cfarray, i));
            if (value.type() != QVariant::String)
                metNonString = true;
            list << value;
        }
        if (metNonString)
            return list;
        else
            return QVariant(list).toStringList();
    }

    if (typeId == CFDictionaryGetTypeID()) {
        const CFDictionaryRef cfdict = static_cast<const CFDictionaryRef>(obj);
        const CFTypeID arrayTypeId = CFArrayGetTypeID();
        int size = int(CFDictionaryGetCount(cfdict));
        QVarLengthArray<CFPropertyListRef> keys(size);
        QVarLengthArray<CFPropertyListRef> values(size);
        CFDictionaryGetKeysAndValues(cfdict, keys.data(), values.data());

        QMultiMap<QString, QVariant> map;
        for (int i = 0; i < size; ++i) {
            QString key = q_toString(static_cast<const CFStringRef>(keys[i]));

            if (CFGetTypeID(values[i]) == arrayTypeId) {
                const CFArrayRef cfarray = static_cast<const CFArrayRef>(values[i]);
                CFIndex arraySize = CFArrayGetCount(cfarray);
                for (CFIndex j = arraySize - 1; j >= 0; --j)
                    map.insert(key, q_toVariant(CFArrayGetValueAtIndex(cfarray, j)));
            } else {
                map.insert(key, q_toVariant(values[i]));
            }
        }
        return map;
    }

    return QVariant();
}