std::string System::get_language() { #ifdef WIN32 char* lang_c = getenv("LC_MESSAGES"); #else char* lang_c = setlocale(LC_MESSAGES, NULL); #endif std::string lang; if (lang_c) { lang = lang_c; } if (lang.empty() || lang == "C") { lang_c = getenv("LANG"); if (lang_c) { lang = lang_c; } } if (lang.empty() || lang == "C") { #ifndef __APPLE__ return globals::default_language; #else /* on Mac OS X we get "C" if launched using Finder, so we ask the OS for the language */ /* Note: this is used as last resort to allow the use of LANG when starting via Terminal */ CFArrayRef preferred_languages = CFLocaleCopyPreferredLanguages(); //CFShow(preferred_languages); CFStringRef language = (CFStringRef)CFArrayGetValueAtIndex(preferred_languages, 0 /* most important language */); //CFShow(language); CFRelease(preferred_languages); CFStringRef substring = CFStringCreateWithSubstring(NULL, language, CFRangeMake(0, 2)); CFRelease(language); char buff[3]; CFStringGetCString(substring, buff, 3, kCFStringEncodingUTF8); CFRelease(substring); lang = buff; return lang; #endif } else { return lang.substr(0, 2); } }
CFBundleRef mac_loadExeBundle(const char *name) { CFBundleRef baseBundle = CFBundleGetBundleWithIdentifier(CFSTR("org.demi3d.Demi")); CFBundleRef mainBundle = CFBundleGetMainBundle(); CFStringRef nameRef = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII); CFURLRef bundleURL = 0; //URL of bundle to load CFBundleRef bundle = 0; //bundle to load //cut off .bundle if present if (CFStringHasSuffix(nameRef, CFSTR(".bundle"))) { CFStringRef nameTempRef = nameRef; int end = CFStringGetLength(nameTempRef) - CFStringGetLength(CFSTR(".bundle")); nameRef = CFStringCreateWithSubstring(NULL, nameTempRef, CFRangeMake(0, end)); CFRelease(nameTempRef); } //assume relative to Resources/ directory of Main bundle bundleURL = CFBundleCopyResourceURL(mainBundle, nameRef, CFSTR("bundle"), NULL); if (bundleURL) { bundle = CFBundleCreate(NULL, bundleURL); CFRelease(bundleURL); } //otherwise, try Resources/ directory of Ogre Framework bundle if (!bundle) { bundleURL = CFBundleCopyResourceURL(baseBundle, nameRef, CFSTR("bundle"), NULL); if (bundleURL) { bundle = CFBundleCreate(NULL, bundleURL); CFRelease(bundleURL); } } CFRelease(nameRef); if (bundle) { if (CFBundleLoadExecutable(bundle)) return bundle; else CFRelease(bundle); } return 0; }
// ____________________________________________________________________________________ // Infer an audio file type from a filename's extension. static Boolean InferAudioFileFormatFromFilename(CFStringRef filename, AudioFileTypeID *outFiletype) { OSStatus err; // find the extension in the filename. CFRange range = CFStringFind(filename, CFSTR("."), kCFCompareBackwards); if (range.location == kCFNotFound) return FALSE; range.location += 1; range.length = CFStringGetLength(filename) - range.location; CFStringRef extension = CFStringCreateWithSubstring(NULL, filename, range); UInt32 propertySize = sizeof(AudioFileTypeID); err = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_TypesForExtension, sizeof(extension), &extension, &propertySize, outFiletype); CFRelease(extension); return (err == noErr && propertySize > 0); }
bool CAAudioFileFormats::InferFileFormatFromFilename(CFStringRef filename, AudioFileTypeID &filetype) { bool result = false; CFRange range = CFStringFind(filename, CFSTR("."), kCFCompareBackwards); if (range.location == kCFNotFound) return false; range.location += 1; range.length = CFStringGetLength(filename) - range.location; CFStringRef ext = CFStringCreateWithSubstring(NULL, filename, range); for (int i = 0; i < mNumFileFormats; ++i) { FileFormatInfo *ffi = &mFileFormats[i]; if (ffi->MatchExtension(ext)) { filetype = ffi->mFileTypeID; result = true; break; } } CFRelease(ext); return result; }
CFStringRef SDMMD_PathToDeviceSupport(SDMMD_AMDeviceRef device) { CFStringRef dev_support_path = NULL; if (device) { SDMMD_AMDeviceConnect(device); SDMMD_AMDeviceStartSession(device); CFStringRef full_os_version = SDMMD_AMDeviceCopyValue(device, NULL, CFSTR(kProductVersion)); CFStringRef os_version = CFStringCreateWithSubstring(kCFAllocatorDefault, full_os_version, CFRangeMake(0, 3)); CFSafeRelease(full_os_version); CFStringRef build_version = SDMMD_AMDeviceCopyValue(device, NULL, CFSTR(kBuildVersion)); SDMMD_AMDeviceStopSession(device); SDMMD_AMDeviceDisconnect(device); if (os_version && build_version) { CFStringRef sdk_path = SDMMD_CopyDeviceSupportPathFromXCRUN(); CFStringRef device_support = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@/DeviceSupport/%@"), sdk_path, os_version); char *device_support_cstr = SDMCFStringGetString(device_support); bool isDir = false; bool file_exists = FileExistsAtPathIsDir(device_support_cstr, &isDir); if (file_exists && isDir) { dev_support_path = CFStringCreateCopy(kCFAllocatorDefault, device_support); } else { CFStringRef device_support_build = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ (%@)"), device_support, build_version); char *device_support_build_cstr = SDMCFStringGetString(device_support_build); file_exists = FileExistsAtPathIsDir(device_support_build_cstr, &isDir); if (file_exists && isDir) { dev_support_path = CFStringCreateCopy(kCFAllocatorDefault, device_support_build); } Safe(free, device_support_build_cstr); CFSafeRelease(device_support_build); } Safe(free, device_support_cstr); CFSafeRelease(sdk_path); CFSafeRelease(device_support); } CFSafeRelease(os_version); CFSafeRelease(build_version); } return dev_support_path; }
void HTTP_Stream::parseICYStream(UInt8 *buf, CFIndex bufSize) { CFIndex offset = 0; if (!m_icyHeadersRead) { // TODO: fail after n tries? for (; offset < bufSize; offset++) { if (m_icyHeaderCR && buf[offset] == '\n') { m_icyHeaderLines.push_back(std::string("")); size_t n = m_icyHeaderLines.size(); /* If the last two lines were empty, we have reached the end of the headers */ if (n >= 2) { if (m_icyHeaderLines[n-2].empty() && m_icyHeaderLines[n-1].empty()) { m_icyHeadersRead = true; break; } } continue; } if (buf[offset] == '\r') { m_icyHeaderCR = true; continue; } else { m_icyHeaderCR = false; } size_t numberOfLines = m_icyHeaderLines.size(); if (numberOfLines == 0) { continue; } m_icyHeaderLines[numberOfLines - 1].push_back(buf[offset]); } } else if (!m_icyHeadersParsed) { const char *icyContentTypeHeader = "content-type:"; const char *icyMetaDataHeader = "icy-metaint:"; size_t icyContenTypeHeaderLength = strlen(icyContentTypeHeader); size_t icyMetaDataHeaderLength = strlen(icyMetaDataHeader); for (std::vector<std::string>::iterator h = m_icyHeaderLines.begin(); h != m_icyHeaderLines.end(); ++h) { if (h->compare(0, icyContenTypeHeaderLength, icyContentTypeHeader) == 0) { m_contentType = h->substr(icyContenTypeHeaderLength, h->length() - icyContenTypeHeaderLength); } if (h->compare(0, icyMetaDataHeaderLength, icyMetaDataHeader) == 0) { m_icyMetaDataInterval = atoi(h->substr(icyMetaDataHeaderLength, h->length() - icyMetaDataHeaderLength).c_str()); } } m_icyHeadersParsed = true; offset++; if (m_delegate) { m_delegate->streamIsReadyRead(); } } if (!m_icyReadBuffer) { m_icyReadBuffer = new UInt8[STREAM_BUFSIZ]; } UInt32 i=0; for (; offset < bufSize; offset++) { // is this a metadata byte? if (m_metaDataBytesRemaining > 0) { m_metaDataBytesRemaining--; if (m_metaDataBytesRemaining == 0) { m_dataByteReadCount = 0; if (m_delegate && !m_icyMetaData.empty()) { std::map<CFStringRef,CFStringRef> metadataMap; CFStringRef metaData = createMetaDataStringWithMostReasonableEncoding(&m_icyMetaData[0], m_icyMetaData.size()); if (!metaData) { // Metadata encoding failed, cannot parse. m_icyMetaData.clear(); continue; } CFArrayRef tokens = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, metaData, CFSTR(";")); for (CFIndex i=0, max=CFArrayGetCount(tokens); i < max; i++) { CFStringRef token = (CFStringRef) CFArrayGetValueAtIndex(tokens, i); CFRange foundRange; if (CFStringFindWithOptions(token, CFSTR("='"), CFRangeMake(0, CFStringGetLength(token)), NULL, &foundRange) == true) { CFRange keyRange = CFRangeMake(0, foundRange.location); CFStringRef metadaKey = CFStringCreateWithSubstring(kCFAllocatorDefault, token, keyRange); CFRange valueRange = CFRangeMake(foundRange.location + 2, CFStringGetLength(token) - keyRange.length - 3); CFStringRef metadaValue = CFStringCreateWithSubstring(kCFAllocatorDefault, token, valueRange); metadataMap[metadaKey] = metadaValue; } } CFRelease(tokens); CFRelease(metaData); m_delegate->streamMetaDataAvailable(metadataMap); } m_icyMetaData.clear(); continue; } m_icyMetaData.push_back(buf[offset]); continue; } // is this the interval byte? if (m_icyMetaDataInterval > 0 && m_dataByteReadCount == m_icyMetaDataInterval) { m_metaDataBytesRemaining = buf[offset] * 16; if (m_metaDataBytesRemaining == 0) { m_dataByteReadCount = 0; } continue; } // a data byte m_dataByteReadCount++; m_icyReadBuffer[i++] = buf[offset]; } if (m_delegate && i > 0) { m_delegate->streamHasBytesAvailable(m_icyReadBuffer, i); } }
static CFStringRef CopyUserVisibleSlotName(CFStringRef slotName) // Translate the PCI card slot name into a user friendly number. // // Machine Slot Name (in numeric order, starting at 1) // --------- --------- // Beige G3 A1, B1, C1 // B&W G3, G4 (PCI Graphics) J12, J11, J10, J9 // G4 (AGP Graphics) A, B, C, D // G4 (Digital Audio)... 1, 2, 3, 4, 5 // ... and later ditto { CFStringRef result; CFStringRef slotPrefix; CFStringRef trimmedSlotName; UInt32 sysVer; Boolean tenTwoOrLater; assert(slotName != NULL); result = NULL; // not really necessary, but used for post-condition debug assert slotPrefix = NULL; trimmedSlotName = NULL; slotPrefix = CFSTR("SLOT-"); if ( CFStringHasPrefix(slotName, slotPrefix) ) { trimmedSlotName = CFStringCreateWithSubstring(NULL, slotName, CFRangeMake(CFStringGetLength(slotPrefix), CFStringGetLength(slotName) - CFStringGetLength(slotPrefix)) ); } if (trimmedSlotName == NULL) { trimmedSlotName = (CFStringRef) CFRetain(slotName); } // The Network preferences panel on 10.2 and later will translate // slot names into slot numbers. We replicate it's behaviour here. tenTwoOrLater = (Gestalt(gestaltSystemVersion, (SInt32 *) &sysVer) == noErr) && (sysVer >= 0x01020); if (tenTwoOrLater) { // Beige G3 if ( CFEqual(trimmedSlotName, CFSTR("A1")) ) { result = CFSTR("1"); } else if ( CFEqual(trimmedSlotName, CFSTR("B1")) ) { result = CFSTR("2"); } else if ( CFEqual(trimmedSlotName, CFSTR("C1")) ) { result = CFSTR("3"); // Blue and White G3, G4 (PCI Graphics) } else if ( CFEqual(trimmedSlotName, CFSTR("J12")) ) { result = CFSTR("1"); } else if ( CFEqual(trimmedSlotName, CFSTR("J11")) ) { result = CFSTR("2"); } else if ( CFEqual(trimmedSlotName, CFSTR("J10")) ) { result = CFSTR("3"); } else if ( CFEqual(trimmedSlotName, CFSTR("J9")) ) { result = CFSTR("4"); // G4 (AGP Graphics) } else if ( CFEqual(trimmedSlotName, CFSTR("A")) ) { result = CFSTR("1"); } else if ( CFEqual(trimmedSlotName, CFSTR("B")) ) { result = CFSTR("2"); } else if ( CFEqual(trimmedSlotName, CFSTR("C")) ) { result = CFSTR("3"); } else if ( CFEqual(trimmedSlotName, CFSTR("D")) ) { result = CFSTR("4"); // all later models } else { result = trimmedSlotName; } } else { result = trimmedSlotName; } CFRetain(result); CFQRelease(trimmedSlotName); assert(result != NULL); return result; }
CF_INLINE void diff_mungeTokenForRange(CFStringRef text, CFRange tokenRange, CFMutableStringRef chars, CFMutableDictionaryRef tokenHash, CFMutableArrayRef tokenArray) { CFStringRef token = CFStringCreateWithSubstring(kCFAllocatorDefault, text, tokenRange); diff_mungeHelper(token, tokenArray, tokenHash, chars); CFRelease(token); }
int odkerb_get_im_handle_with_user_record(ODRecordRef userRecord, CFStringRef imType, CFStringRef realm, CFStringRef allegedShortName, char im_handle[], size_t im_handle_size) { int retval = -1; CFArrayRef cfIMHandles = NULL; CFErrorRef cfError = NULL; CFMutableArrayRef cfMatches = NULL; CFStringRef cfRealID = NULL; int i; ODKERB_PARAM_ASSERT(userRecord != NULL); ODKERB_PARAM_ASSERT(allegedShortName != NULL); ODKERB_PARAM_ASSERT(im_handle != 0); ODKERB_PARAM_ASSERT(im_handle_size > 0); *im_handle = '\0'; cfIMHandles = ODRecordCopyValues(userRecord, kODAttributeTypeIMHandle, &cfError); if (cfIMHandles == NULL || cfError != NULL) { ODKERB_LOG_CFERROR(LOG_ERR, "Unable to obtain IM handles", cfError); goto failure; } else if (CFArrayGetCount(cfIMHandles) == 0) { ODKERB_LOG_CFSTRING(LOG_DEBUG, "No IM handles", allegedShortName); goto failure; } /* there could be many IM handles that look plausible, so we heuristically determine which * one is the most likely to be the correct one. imagine, for instance, that the following * ones are available: * JABBER: [email protected] * JABBER: [email protected] * JABBER: [email protected] * YAHOO: [email protected] */ /* first, remove those of the wrong type or realm because they can't possibly be right */ cfMatches = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, cfIMHandles); if (cfMatches == NULL) { ODKERB_LOG_ERRNO(LOG_ERR, ENOMEM); goto failure; } for (i = CFArrayGetCount(cfMatches) - 1; i >= 0; --i) { CFStringRef cfID = CFArrayGetValueAtIndex(cfMatches, i); if (cfID != NULL && odkerb_CFStringHasPrefixWithOptions(cfID, imType, kCFCompareCaseInsensitive) && odkerb_CFStringHasSuffixWithOptions(cfID, realm, kCFCompareCaseInsensitive)) continue; /* isn't a match, so remove it from the list */ CFArrayRemoveValueAtIndex(cfMatches, i); } CFStringRef match = NULL; if (CFArrayGetCount(cfMatches) == 0) { ODKERB_LOG_CFSTRING(LOG_INFO, "No IM handles matching type and realm", allegedShortName); goto failure; } else if (CFArrayGetCount(cfMatches) == 1) { match = CFArrayGetValueAtIndex(cfMatches, 0); goto found_match; } /* second, attempt to use the short name to disasmbiguate among the several choices */ for (i = 0; i < CFArrayGetCount(cfMatches); ++i) { CFStringRef cfID = CFArrayGetValueAtIndex(cfMatches, i); if (cfID == NULL) continue; CFRange where = CFStringFind(cfID, allegedShortName, kCFCompareCaseInsensitive | kCFCompareDiacriticInsensitive); if (where.location != kCFNotFound) { match = cfID; goto found_match; } } /* at this point, there are several possibilities, but none of them contain the * short name, so just choose the first one */ match = CFArrayGetValueAtIndex(cfMatches, 0); found_match: assert(match != NULL); /* the ID is the substring following the IM type specifier prefix (kIMTypeJABBER) */ assert(CFStringGetLength(match) > CFStringGetLength(imType)); cfRealID = CFStringCreateWithSubstring(kCFAllocatorDefault, match, CFRangeMake(CFStringGetLength(imType), CFStringGetLength(match)-CFStringGetLength(imType))); if (cfRealID == NULL) { ODKERB_LOG_ERRNO(LOG_ERR, ENOMEM); goto failure; } if (CFStringGetCString(cfRealID, im_handle, im_handle_size-1, kCFStringEncodingUTF8) == FALSE) { ODKERB_LOG_CFSTRING(LOG_ERR, "Cannot obtain IM handle string", cfRealID); goto failure; } retval = 0; failure: CF_SAFE_RELEASE(cfError); CF_SAFE_RELEASE(cfRealID); CF_SAFE_RELEASE(cfMatches); CF_SAFE_RELEASE(cfIMHandles); return retval; }
void HTTP_Stream::parseICYStream(const UInt8 *buf, const CFIndex bufSize) { HS_TRACE("Parsing an IceCast stream, received %li bytes\n", bufSize); CFIndex offset = 0; CFIndex bytesFound = 0; if (!m_icyHeadersRead) { HS_TRACE("ICY headers not read, reading\n"); for (; offset < bufSize; offset++) { if (m_icyHeaderCR && buf[offset] == '\n') { if (bytesFound > 0) { m_icyHeaderLines.push_back(createMetaDataStringWithMostReasonableEncoding(&buf[offset-bytesFound-1], bytesFound)); bytesFound = 0; HS_TRACE_CFSTRING(m_icyHeaderLines[m_icyHeaderLines.size()-1]); continue; } HS_TRACE("End of ICY headers\n"); m_icyHeadersRead = true; break; } if (buf[offset] == '\r') { m_icyHeaderCR = true; continue; } else { m_icyHeaderCR = false; } bytesFound++; } } else if (!m_icyHeadersParsed) { HS_TRACE("ICY headers not parsed, parsing\n"); const CFStringRef icyContentTypeHeader = CFSTR("content-type:"); const CFStringRef icyMetaDataHeader = CFSTR("icy-metaint:"); const CFStringRef icyNameHeader = CFSTR("icy-name:"); const CFIndex icyContenTypeHeaderLength = CFStringGetLength(icyContentTypeHeader); const CFIndex icyMetaDataHeaderLength = CFStringGetLength(icyMetaDataHeader); const CFIndex icyNameHeaderLength = CFStringGetLength(icyNameHeader); for (std::vector<CFStringRef>::iterator h = m_icyHeaderLines.begin(); h != m_icyHeaderLines.end(); ++h) { CFStringRef line = *h; const CFIndex lineLength = CFStringGetLength(line); if (lineLength == 0) { continue; } HS_TRACE_CFSTRING(line); if (CFStringCompareWithOptions(line, icyContentTypeHeader, CFRangeMake(0, icyContenTypeHeaderLength), 0) == kCFCompareEqualTo) { if (m_contentType) { CFRelease(m_contentType), m_contentType = 0; } m_contentType = CFStringCreateWithSubstring(kCFAllocatorDefault, line, CFRangeMake(icyContenTypeHeaderLength, lineLength - icyContenTypeHeaderLength)); } if (CFStringCompareWithOptions(line, icyMetaDataHeader, CFRangeMake(0, icyMetaDataHeaderLength), 0) == kCFCompareEqualTo) { CFStringRef metadataInterval = CFStringCreateWithSubstring(kCFAllocatorDefault, line, CFRangeMake(icyMetaDataHeaderLength, lineLength - icyMetaDataHeaderLength)); if (metadataInterval) { m_icyMetaDataInterval = CFStringGetIntValue(metadataInterval); CFRelease(metadataInterval); } else { m_icyMetaDataInterval = 0; } } if (CFStringCompareWithOptions(line, icyNameHeader, CFRangeMake(0, icyNameHeaderLength), 0) == kCFCompareEqualTo) { if (m_icyName) { CFRelease(m_icyName); } m_icyName = CFStringCreateWithSubstring(kCFAllocatorDefault, line, CFRangeMake(icyNameHeaderLength, lineLength - icyNameHeaderLength)); } } m_icyHeadersParsed = true; offset++; if (m_delegate) { m_delegate->streamIsReadyRead(); } } Stream_Configuration *config = Stream_Configuration::configuration(); if (!m_icyReadBuffer) { m_icyReadBuffer = new UInt8[config->httpConnectionBufferSize]; } HS_TRACE("Reading ICY stream for playback\n"); UInt32 i=0; for (; offset < bufSize; offset++) { // is this a metadata byte? if (m_metaDataBytesRemaining > 0) { m_metaDataBytesRemaining--; if (m_metaDataBytesRemaining == 0) { m_dataByteReadCount = 0; if (m_delegate && !m_icyMetaData.empty()) { std::map<CFStringRef,CFStringRef> metadataMap; CFStringRef metaData = createMetaDataStringWithMostReasonableEncoding(&m_icyMetaData[0], m_icyMetaData.size()); if (!metaData) { // Metadata encoding failed, cannot parse. m_icyMetaData.clear(); continue; } CFArrayRef tokens = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, metaData, CFSTR(";")); for (CFIndex i=0, max=CFArrayGetCount(tokens); i < max; i++) { CFStringRef token = (CFStringRef) CFArrayGetValueAtIndex(tokens, i); CFRange foundRange; if (CFStringFindWithOptions(token, CFSTR("='"), CFRangeMake(0, CFStringGetLength(token)), NULL, &foundRange) == true) { CFRange keyRange = CFRangeMake(0, foundRange.location); CFStringRef metadaKey = CFStringCreateWithSubstring(kCFAllocatorDefault, token, keyRange); CFRange valueRange = CFRangeMake(foundRange.location + 2, CFStringGetLength(token) - keyRange.length - 3); CFStringRef metadaValue = CFStringCreateWithSubstring(kCFAllocatorDefault, token, valueRange); metadataMap[metadaKey] = metadaValue; } } CFRelease(tokens); CFRelease(metaData); if (m_icyName) { metadataMap[CFSTR("IcecastStationName")] = CFStringCreateCopy(kCFAllocatorDefault, m_icyName); } m_delegate->streamMetaDataAvailable(metadataMap); } m_icyMetaData.clear(); continue; } m_icyMetaData.push_back(buf[offset]); continue; } // is this the interval byte? if (m_icyMetaDataInterval > 0 && m_dataByteReadCount == m_icyMetaDataInterval) { m_metaDataBytesRemaining = buf[offset] * 16; if (m_metaDataBytesRemaining == 0) { m_dataByteReadCount = 0; } continue; } // a data byte m_dataByteReadCount++; m_icyReadBuffer[i++] = buf[offset]; } if (m_delegate && i > 0) { m_delegate->streamHasBytesAvailable(m_icyReadBuffer, i); } }
CFStringRef CopyNextWorkstationName(SCDynamicStoreRef store, CFStringRef currentName) { CFMutableStringRef computerName = NULL; CFStringRef macAddress = NULL; if (currentName) { /* Sanity check to make sure the current Workstation name is longer than the length of a MAC address string */ CFIndex totalLengh = CFStringGetLength(currentName); if (totalLengh >= (CFIndex)kMACAddressLengh) { /* Create a substring that chops off the MAC addres, giving us the Computer Name */ CFRange range = CFRangeMake(0, totalLengh - kMACAddressLengh); CFStringRef oldComputerName = CFStringCreateWithSubstring(NULL, currentName, range); /* If the Computer Name contains a trailing close paren it means that this name may have already experienced a name conflict which means it could have a trailing digit to increment */ if (CFStringHasSuffix(oldComputerName, CFSTR(")"))) { CFRange result; /* Search for the first open paren, starting the search from the end of the Computer Name */ if (CFStringFindWithOptions(oldComputerName, CFSTR("("), range, kCFCompareBackwards, &result)) { /* Create a substring which contains the contents between the open and close paren */ range = CFRangeMake(result.location + 1, CFStringGetLength(oldComputerName) - result.location - 2); CFStringRef countString = CFStringCreateWithSubstring(NULL, currentName, range); /* Try converting the substring to an integer */ SInt32 conflictCount = CFStringGetIntValue(countString); if (conflictCount) { /* Create a substring of just the Computer Name without the trailing open paren, conflict integer, close paren */ range = CFRangeMake(0, result.location); CFStringRef tempComputerName = CFStringCreateWithSubstring(NULL, oldComputerName, range); /* Create a mutable copy of the Computer Name base substring */ computerName = CFStringCreateMutableCopy(NULL, 0, tempComputerName); /* Create a string containing a space, open paren, previous conflict digit incremented by one, close paren */ CFStringRef numberString = CFStringCreateWithFormat(NULL, NULL, CFSTR(" (%d)"), ++conflictCount); /* Truncate the Computer Name base as neccessary to ensure we can append the conflict digits */ CFStringTruncateToUTF8Length(computerName, kMaxComputerName - CFStringGetLength(numberString)); /* Append the incremented conflict digit to the Computer Name base string */ CFStringAppend(computerName, numberString); } } } /* If computerName is NULL it means that the previous Computer Name didn't contain any conflict digits so append a " (2)" */ if (!computerName) { /* Create mutable copy of previous Computer Name */ computerName = CFStringCreateMutableCopy(NULL, 0, oldComputerName); /* Make sure we have enough room to append 4 characters to the name by truncating the Computer Name if neccessary */ CFStringTruncateToUTF8Length(computerName, kMaxComputerName - 4); /* Append the name conflict digits */ CFStringAppend(computerName, CFSTR(" (2)")); } CFRelease(oldComputerName); } else { DbgLog( kLogError, "Workstation name is shorter than a MAC address which shouldn't be possible" ); } } else { /* There's currently no registered Workstation name so get the Computer Name from the dynamic store */ CFStringRef tempName = SCDynamicStoreCopyComputerName(store, NULL); if (tempName) { /* Create a mutable copy of the Computer Name */ computerName = CFStringCreateMutableCopy(NULL, 0, tempName); CFRelease(tempName); /* Truncate the Computer Name to ensure we can append the MAC address */ CFStringTruncateToUTF8Length(computerName, kMaxComputerName); } else { return NULL; } } /* Copy the primary MAC address string */ macAddress = CopyPrimaryMacAddress(); if (!macAddress) { if (computerName) { CFRelease(computerName); } return NULL; } /* Append a space */ CFStringAppend(computerName, CFSTR(" ")); /* Append the MAC address string */ CFStringAppend(computerName, macAddress); CFRelease(macAddress); return computerName; }
void configSet(CFMutableArrayRef config, CFStringRef key, CFStringRef value) { CFMutableStringRef pref; CFIndex configLen = CFArrayGetCount(config); CFIndex i; CFIndex n; CFMutableStringRef newValue; CFRange range; CFStringRef specialChars = CFSTR(" \"'$!|\\<>`{}[]"); boolean_t mustQuote = FALSE; /* create search prefix */ pref = CFStringCreateMutableCopy(NULL, 0, key); CFStringAppend(pref, CFSTR("=")); /* * create new / replacement value * * Note: Since the configuration file may be processed by a * shell script we need to ensure that, if needed, the * string is properly quoted. */ newValue = CFStringCreateMutableCopy(NULL, 0, value); n = CFStringGetLength(specialChars); for (i = 0; i < n; i++) { CFStringRef specialChar; specialChar = CFStringCreateWithSubstring(NULL, specialChars, CFRangeMake(i, 1)); range = CFStringFind(newValue, specialChar, 0); CFRelease(specialChar); if (range.location != kCFNotFound) { /* this string has at least one special character */ mustQuote = TRUE; break; } } if (mustQuote) { CFStringRef charsToQuote = CFSTR("\\\"$`"); /* * in addition to quoting the entire string we also need to escape the * space " " and backslash "\" characters */ n = CFStringGetLength(charsToQuote); for (i = 0; i < n; i++) { CFStringRef quoteChar; CFArrayRef matches; quoteChar = CFStringCreateWithSubstring(NULL, charsToQuote, CFRangeMake(i, 1)); range = CFRangeMake(0, CFStringGetLength(newValue)); matches = CFStringCreateArrayWithFindResults(NULL, newValue, quoteChar, range, 0); CFRelease(quoteChar); if (matches) { CFIndex j = CFArrayGetCount(matches); while (--j >= 0) { const CFRange *range; range = CFArrayGetValueAtIndex(matches, j); CFStringInsert(newValue, range->location, CFSTR("\\")); } CFRelease(matches); } } CFStringInsert(newValue, 0, CFSTR("\"")); CFStringAppend(newValue, CFSTR("\"")); } /* locate existing key */ for (i = 0; i < configLen; i++) { if (CFStringHasPrefix(CFArrayGetValueAtIndex(config, i), pref)) { break; } } CFStringAppend(pref, newValue); CFRelease(newValue); if (i < configLen) { /* if replacing an existing entry */ CFArraySetValueAtIndex(config, i, pref); } else { /* * if new entry, insert it just prior to the last (emtpy) * array element. */ CFArrayInsertValueAtIndex(config, configLen-1, pref); } CFRelease(pref); return; }
/******************************************************************************* * copyAdjustedPathForURL() * * This function takes an URL with a given kext, and adjusts it to be absolute * or relative to the kext's containing repository, properly handling plugin * kexts to include the repository-path of the containing kext as well. *******************************************************************************/ CFStringRef copyAdjustedPathForURL( OSKextRef theKext, CFURLRef urlToAdjust, PathSpec pathSpec) { CFStringRef result = NULL; CFURLRef absURL = NULL; // must release CFStringRef absPath = NULL; // must release CFStringRef kextAbsPath = NULL; // must release CFStringRef kextRelPath = NULL; // must release CFStringRef pathInKext = NULL; // must release CFRange scratchRange; if (pathSpec != kPathsFull && pathSpec != kPathsRelative) { OSKextLog(theKext, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Invalid argument to copyAdjustedPathForURL()."); } absURL = CFURLCopyAbsoluteURL(urlToAdjust); if (!absURL) { OSKextLogMemError(); goto finish; } if (pathSpec == kPathsFull) { result = CFURLCopyFileSystemPath(absURL, kCFURLPOSIXPathStyle); goto finish; } /***** * Okay, we are doing repository-relative paths here. Here's how! * We are strip the matching part of the kext's absolute path * from the URL/path handed in, which gives us the path in the kext. * Then we tack that back onto the kext's repository-relative path. Got it? */ kextAbsPath = copyPathForKext(theKext, kPathsFull); kextRelPath = copyPathForKext(theKext, kPathsRelative); absPath = CFURLCopyFileSystemPath(absURL, kCFURLPOSIXPathStyle); if (!kextAbsPath || !kextRelPath || !absPath) { goto finish; } scratchRange = CFRangeMake(CFStringGetLength(kextAbsPath), CFStringGetLength(absPath) - CFStringGetLength(kextAbsPath)); pathInKext = CFStringCreateWithSubstring(kCFAllocatorDefault, absPath, scratchRange); if (!pathInKext) { OSKextLogMemError(); } result = CFStringCreateWithFormat(kCFAllocatorDefault, /* options */ 0, CFSTR("%@%@"), kextRelPath, pathInKext); finish: SAFE_RELEASE(absURL); SAFE_RELEASE(absPath); SAFE_RELEASE(kextAbsPath); SAFE_RELEASE(kextRelPath); SAFE_RELEASE(pathInKext); return result; }
CFStringRef copyPathForKext( OSKextRef theKext, PathSpec pathSpec) { CFStringRef result = CFSTR("(can't determine kext path)"); CFURLRef kextURL = OSKextGetURL(theKext); // do not release CFURLRef absURL = NULL; // must release OSKextRef containerKext = NULL; // must release CFURLRef containerURL = NULL; // do not release CFURLRef containerAbsURL = NULL; // must release CFURLRef repositoryURL = NULL; // must release CFStringRef repositoryPath = NULL; // must release CFStringRef kextPath = NULL; // must release if (!kextURL) { OSKextLog(theKext, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Kext has no URL!"); goto finish; } if (pathSpec == kPathsNone) { result = CFURLCopyLastPathComponent(kextURL); } else if (pathSpec == kPathsFull) { absURL = CFURLCopyAbsoluteURL(kextURL); if (!absURL) { OSKextLogMemError(); goto finish; } result = CFURLCopyFileSystemPath(absURL, kCFURLPOSIXPathStyle); } else if (pathSpec == kPathsRelative) { CFRange relativeRange; absURL = CFURLCopyAbsoluteURL(kextURL); if (!absURL) { OSKextLogMemError(); goto finish; } containerKext = OSKextCopyContainerForPluginKext(theKext); if (containerKext) { containerURL = OSKextGetURL(containerKext); if (!containerURL) { OSKextLog(containerKext, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Container kext has no URL!"); goto finish; } containerAbsURL = CFURLCopyAbsoluteURL(containerURL); if (!containerAbsURL) { OSKextLogMemError(); goto finish; } repositoryURL = CFURLCreateCopyDeletingLastPathComponent( kCFAllocatorDefault, containerAbsURL); if (!repositoryURL) { OSKextLogMemError(); goto finish; } } else { repositoryURL = CFURLCreateCopyDeletingLastPathComponent( kCFAllocatorDefault, absURL); if (!repositoryURL) { OSKextLogMemError(); goto finish; } } repositoryPath = CFURLCopyFileSystemPath(repositoryURL, kCFURLPOSIXPathStyle); kextPath = CFURLCopyFileSystemPath(absURL, kCFURLPOSIXPathStyle); if (!repositoryPath || !kextPath) { OSKextLogMemError(); goto finish; } /* We add 1 to the length of the repositoryPath to handle the * intermediate '/' character. */ relativeRange = CFRangeMake(1+CFStringGetLength(repositoryPath), CFStringGetLength(kextPath) - (1+CFStringGetLength(repositoryPath))); result = CFStringCreateWithSubstring(kCFAllocatorDefault, kextPath, relativeRange); } else { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Internal error."); goto finish; } finish: SAFE_RELEASE(absURL); SAFE_RELEASE(containerKext); SAFE_RELEASE(containerAbsURL); SAFE_RELEASE(repositoryURL); SAFE_RELEASE(repositoryPath); SAFE_RELEASE(kextPath); return result; }
bool MODDecoder::Open(CFErrorRef *error) { if(IsOpen()) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioDecoder.MOD"); LOG4CXX_WARN(logger, "Open() called on an AudioDecoder that is already open"); return true; } // Ensure the input source is open if(!mInputSource->IsOpen() && !mInputSource->Open(error)) return false; dfs.open = NULL; dfs.skip = skip_callback; dfs.getc = getc_callback; dfs.getnc = getnc_callback; dfs.close = close_callback; df = dumbfile_open_ex(this, &dfs); if(NULL == df) { return false; } CFStringRef fileSystemPath = CFURLCopyFileSystemPath(GetURL(), kCFURLPOSIXPathStyle); CFStringRef extension = NULL; CFRange range; if(CFStringFindWithOptionsAndLocale(fileSystemPath, CFSTR("."), CFRangeMake(0, CFStringGetLength(fileSystemPath)), kCFCompareBackwards, CFLocaleGetSystem(), &range)) { extension = CFStringCreateWithSubstring(kCFAllocatorDefault, fileSystemPath, CFRangeMake(range.location + 1, CFStringGetLength(fileSystemPath) - range.location - 1)); } CFRelease(fileSystemPath), fileSystemPath = NULL; if(NULL == extension) { return false; } // Attempt to create the appropriate decoder based on the file's extension if(kCFCompareEqualTo == CFStringCompare(extension, CFSTR("it"), kCFCompareCaseInsensitive)) duh = dumb_read_it(df); else if(kCFCompareEqualTo == CFStringCompare(extension, CFSTR("xm"), kCFCompareCaseInsensitive)) duh = dumb_read_xm(df); else if(kCFCompareEqualTo == CFStringCompare(extension, CFSTR("s3m"), kCFCompareCaseInsensitive)) duh = dumb_read_s3m(df); else if(kCFCompareEqualTo == CFStringCompare(extension, CFSTR("mod"), kCFCompareCaseInsensitive)) duh = dumb_read_mod(df); CFRelease(extension), extension = NULL; if(NULL == duh) { if(error) { CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 32, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFStringRef displayName = CreateDisplayNameForURL(mInputSource->GetURL()); CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFCopyLocalizedString(CFSTR("The file “%@” is not a valid MOD file."), ""), displayName); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedDescriptionKey, errorString); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedFailureReasonKey, CFCopyLocalizedString(CFSTR("Not a MOD file"), "")); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedRecoverySuggestionKey, CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); CFRelease(errorString), errorString = NULL; CFRelease(displayName), displayName = NULL; *error = CFErrorCreate(kCFAllocatorDefault, AudioDecoderErrorDomain, AudioDecoderInputOutputError, errorDictionary); CFRelease(errorDictionary), errorDictionary = NULL; } if(df) dumbfile_close(df), df = NULL; return false; } mTotalFrames = duh_get_length(duh); dsr = duh_start_sigrenderer(duh, 0, 2, 0); if(NULL == dsr) { if(error) { CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 32, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFStringRef displayName = CreateDisplayNameForURL(mInputSource->GetURL()); CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFCopyLocalizedString(CFSTR("The file “%@” is not a valid MOD file."), ""), displayName); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedDescriptionKey, errorString); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedFailureReasonKey, CFCopyLocalizedString(CFSTR("Not a MOD file"), "")); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedRecoverySuggestionKey, CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); CFRelease(errorString), errorString = NULL; CFRelease(displayName), displayName = NULL; *error = CFErrorCreate(kCFAllocatorDefault, AudioDecoderErrorDomain, AudioDecoderInputOutputError, errorDictionary); CFRelease(errorDictionary), errorDictionary = NULL; } if(df) dumbfile_close(df), df = NULL; if(duh) unload_duh(duh), duh = NULL; return false; } // Generate interleaved 2 channel 44.1 16-bit output mFormat.mFormatID = kAudioFormatLinearPCM; mFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; mFormat.mSampleRate = DUMB_SAMPLE_RATE; mFormat.mChannelsPerFrame = DUMB_CHANNELS; mFormat.mBitsPerChannel = DUMB_BIT_DEPTH; mFormat.mBytesPerPacket = (mFormat.mBitsPerChannel / 8) * mFormat.mChannelsPerFrame; mFormat.mFramesPerPacket = 1; mFormat.mBytesPerFrame = mFormat.mBytesPerPacket * mFormat.mFramesPerPacket; mFormat.mReserved = 0; // Set up the source format mSourceFormat.mFormatID = 'MOD '; mSourceFormat.mSampleRate = DUMB_SAMPLE_RATE; mSourceFormat.mChannelsPerFrame = DUMB_CHANNELS; // Setup the channel layout mChannelLayout = CreateChannelLayoutWithTag(kAudioChannelLayoutTag_Stereo); mIsOpen = true; return true; }
__private_extern__ CFArrayRef _CFPreferencesCreateDomainList(CFStringRef userName, CFStringRef hostName) { CFAllocatorRef prefAlloc = __CFPreferencesAllocator(); CFArrayRef domains; CFMutableArrayRef marray; CFStringRef *cachedDomainKeys; CFPreferencesDomainRef *cachedDomains; SInt32 idx, cnt; CFStringRef suffix; UInt32 suffixLen; CFURLRef prefDir = _preferencesDirectoryForUserHost(userName, hostName); if (!prefDir) { return NULL; } if (hostName == kCFPreferencesAnyHost) { suffix = CFStringCreateWithCString(prefAlloc, ".plist", kCFStringEncodingASCII); } else if (hostName == kCFPreferencesCurrentHost) { CFStringRef hostID = _CFPreferencesGetByHostIdentifierString(); suffix = CFStringCreateWithFormat(prefAlloc, NULL, CFSTR(".%@.plist"), hostID); } else { suffix = CFStringCreateWithFormat(prefAlloc, NULL, CFSTR(".%@.plist"), hostName); // sketchy - this allows someone to create a domain list for an arbitrary hostname. } suffixLen = CFStringGetLength(suffix); domains = (CFArrayRef)CFURLCreatePropertyFromResource(prefAlloc, prefDir, kCFURLFileDirectoryContents, NULL); CFRelease(prefDir); if (domains){ marray = CFArrayCreateMutableCopy(prefAlloc, 0, domains); CFRelease(domains); } else { marray = CFArrayCreateMutable(prefAlloc, 0, & kCFTypeArrayCallBacks); } for (idx = CFArrayGetCount(marray)-1; idx >= 0; idx --) { CFURLRef url = (CFURLRef)CFArrayGetValueAtIndex(marray, idx); CFStringRef string = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); if (!CFStringHasSuffix(string, suffix)) { CFArrayRemoveValueAtIndex(marray, idx); } else { CFStringRef dom = CFStringCreateWithSubstring(prefAlloc, string, CFRangeMake(0, CFStringGetLength(string) - suffixLen)); if (CFEqual(dom, CFSTR(".GlobalPreferences"))) { CFArraySetValueAtIndex(marray, idx, kCFPreferencesAnyApplication); } else { CFArraySetValueAtIndex(marray, idx, dom); } CFRelease(dom); } CFRelease(string); } CFRelease(suffix); // Now add any domains added in the cache; delete any that have been deleted in the cache __CFSpinLock(&domainCacheLock); if (!domainCache) { __CFSpinUnlock(&domainCacheLock); return marray; } cnt = CFDictionaryGetCount(domainCache); cachedDomainKeys = (CFStringRef *)CFAllocatorAllocate(prefAlloc, 2 * cnt * sizeof(CFStringRef), 0); cachedDomains = (CFPreferencesDomainRef *)(cachedDomainKeys + cnt); CFDictionaryGetKeysAndValues(domainCache, (const void **)cachedDomainKeys, (const void **)cachedDomains); __CFSpinUnlock(&domainCacheLock); suffix = _CFPreferencesCachePrefixForUserHost(userName, hostName); suffixLen = CFStringGetLength(suffix); for (idx = 0; idx < cnt; idx ++) { CFStringRef domainKey = cachedDomainKeys[idx]; CFPreferencesDomainRef domain = cachedDomains[idx]; CFStringRef domainName; CFIndex keyCount = 0; if (!CFStringHasPrefix(domainKey, suffix)) continue; domainName = CFStringCreateWithSubstring(prefAlloc, domainKey, CFRangeMake(suffixLen, CFStringGetLength(domainKey) - suffixLen)); if (CFEqual(domainName, CFSTR("*"))) { CFRelease(domainName); domainName = (CFStringRef)CFRetain(kCFPreferencesAnyApplication); } else if (CFEqual(domainName, kCFPreferencesCurrentApplication)) { CFRelease(domainName); domainName = (CFStringRef)CFRetain(_CFProcessNameString()); } CFDictionaryRef d = _CFPreferencesDomainDeepCopyDictionary(domain); keyCount = d ? CFDictionaryGetCount(d) : 0; if (keyCount) CFRelease(d); if (keyCount == 0) { // Domain was deleted SInt32 firstIndexOfValue = CFArrayGetFirstIndexOfValue(marray, CFRangeMake(0, CFArrayGetCount(marray)), domainName); if (0 <= firstIndexOfValue) { CFArrayRemoveValueAtIndex(marray, firstIndexOfValue); } } else if (!CFArrayContainsValue(marray, CFRangeMake(0, CFArrayGetCount(marray)), domainName)) { CFArrayAppendValue(marray, domainName); } CFRelease(domainName); } CFRelease(suffix); CFAllocatorDeallocate(prefAlloc, cachedDomainKeys); return marray; }
Boolean DAMountContainsArgument( CFStringRef arguments, CFStringRef argument ) { CFBooleanRef argumentValue; CFBooleanRef argumentsValue; argumentsValue = NULL; if ( CFStringHasPrefix( argument, CFSTR( "no" ) ) ) { argument = CFStringCreateWithSubstring( kCFAllocatorDefault, argument, CFRangeMake( 2, CFStringGetLength( argument ) - 2 ) ); argumentValue = kCFBooleanFalse; } else { argument = CFRetain( argument ); argumentValue = kCFBooleanTrue; } if ( argument ) { CFArrayRef argumentList; CFIndex argumentListCount; CFIndex argumentListIndex; argumentList = CFStringCreateArrayBySeparatingStrings( kCFAllocatorDefault, arguments, CFSTR( "," ) ); if ( argumentList ) { argumentListCount = CFArrayGetCount( argumentList ); for ( argumentListIndex = 0; argumentListIndex < argumentListCount; argumentListIndex++ ) { CFStringRef compare; compare = CFArrayGetValueAtIndex( argumentList, argumentListIndex ); if ( compare ) { CFBooleanRef compareValue; if ( CFStringHasPrefix( compare, CFSTR( "no" ) ) ) { compare = CFStringCreateWithSubstring( kCFAllocatorDefault, compare, CFRangeMake( 2, CFStringGetLength( compare ) - 2 ) ); compareValue = kCFBooleanFalse; } else { compare = CFRetain( compare ); compareValue = kCFBooleanTrue; } if ( compare ) { if ( CFEqual( compare, CFSTR( FSTAB_RO ) ) ) { CFRelease( compare ); compare = CFRetain( kDAFileSystemMountArgumentNoWrite ); compareValue = compareValue; } if ( CFEqual( compare, CFSTR( FSTAB_RW ) ) ) { CFRelease( compare ); compare = CFRetain( kDAFileSystemMountArgumentNoWrite ); compareValue = ( compareValue == kCFBooleanTrue ) ? kCFBooleanFalse : kCFBooleanTrue; } } if ( compare ) { if ( CFEqual( argument, compare ) ) { argumentsValue = compareValue; } CFRelease( compare ); } } } CFRelease( argumentList ); } CFRelease( argument ); } return ( argumentValue == argumentsValue ) ? TRUE : FALSE; }
/* There has got to be an easier way to do this. For now we based this code on CFNetwork/Connection/URLResponse.cpp. */ static CFStringRef copyParseMaxAge(CFStringRef cacheControlHeader) { /* The format of the cache control header is a comma-separated list, but each list element could be a key-value pair, with the value quoted and possibly containing a comma. */ CFStringInlineBuffer inlineBuf; CFRange componentRange; CFIndex length = CFStringGetLength(cacheControlHeader); bool done = false; CFCharacterSetRef whitespaceSet = CFCharacterSetGetPredefined(kCFCharacterSetWhitespace); CFStringRef maxAgeValue = NULL; CFStringInitInlineBuffer(cacheControlHeader, &inlineBuf, CFRangeMake(0, length)); componentRange.location = 0; while (!done) { bool inQuotes = false; bool foundComponentStart = false; CFIndex charIndex = componentRange.location; CFIndex componentEnd = -1; CFRange maxAgeRg; componentRange.length = 0; while (charIndex < length) { UniChar ch = CFStringGetCharacterFromInlineBuffer(&inlineBuf, charIndex); if (!inQuotes && ch == ',') { componentRange.length = charIndex - componentRange.location; break; } if (!CFCharacterSetIsCharacterMember(whitespaceSet, ch)) { if (!foundComponentStart) { foundComponentStart = true; componentRange.location = charIndex; } else { componentEnd = charIndex; } if (ch == '\"') { inQuotes = (inQuotes == false); } } charIndex ++; } if (componentEnd == -1) { componentRange.length = charIndex - componentRange.location; } else { componentRange.length = componentEnd - componentRange.location + 1; } if (charIndex == length) { /* Fell off the end; this is the last component. */ done = true; } /* componentRange should now contain the range of the current component; trimmed of any whitespace. */ /* We want to look for a max-age value. */ if (!maxAgeValue && CFStringFindWithOptions(cacheControlHeader, CFSTR("max-age"), componentRange, kCFCompareCaseInsensitive | kCFCompareAnchored, &maxAgeRg)) { CFIndex equalIdx; CFIndex maxCompRg = componentRange.location + componentRange.length; for (equalIdx = maxAgeRg.location + maxAgeRg.length; equalIdx < maxCompRg; equalIdx ++) { UniChar equalCh = CFStringGetCharacterFromInlineBuffer(&inlineBuf, equalIdx); if (equalCh == '=') { // Parse out max-age value equalIdx ++; while (equalIdx < maxCompRg && CFCharacterSetIsCharacterMember(whitespaceSet, CFStringGetCharacterAtIndex(cacheControlHeader, equalIdx))) { equalIdx ++; } if (equalIdx < maxCompRg) { maxAgeValue = CFStringCreateWithSubstring(kCFAllocatorDefault, cacheControlHeader, CFRangeMake(equalIdx, maxCompRg-equalIdx)); } } else if (!CFCharacterSetIsCharacterMember(whitespaceSet, equalCh)) { // Not a valid max-age header; break out doing nothing break; } } } if (!done && maxAgeValue) { done = true; } if (!done) { /* Advance to the next component; + 1 to get past the comma. */ componentRange.location = charIndex + 1; } } return maxAgeValue; }
int main (int argc, const char* argv[]) { if (argc == 1) { printf("Usage: LocalizationStatusHelper <bundle-path>\n"); } else { if (chdir(argv[1]) == -1) { printf("Cannot change directory to %s", argv[1]); perror(""); return 0; } DIR* dir = opendir("."); if (dir == NULL) { printf("Cannot open %s for reading", argv[1]); perror(""); return 0; } struct languagesAndKeys sk; sk.languages = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); sk.keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); CFMutableSetRef unionKeys = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks); struct dirent* dp; // Scan for the directory. while ((dp = readdir(dir)) != NULL) { if (dp->d_type == DT_DIR) { CFStringRef dirName = CFStringCreateWithCString(NULL, dp->d_name, kCFStringEncodingUTF8); // Check if it's an lproj. if (CFStringHasSuffix(dirName, CFSTR(".lproj"))) { CFMutableSetRef langKeys = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks); // Scan for strings files. chdir(dp->d_name); DIR* subdir = opendir("."); if (subdir != NULL) { struct dirent* dp2; while ((dp2 = readdir(subdir)) != NULL) { // Ignore linked strings files. if (dp2->d_type == DT_REG) { CFStringRef stringsName = CFStringCreateWithCString(NULL, dp2->d_name, kCFStringEncodingUTF8); // Ignore non-strings files. if (CFStringHasSuffix(stringsName, CFSTR(".strings"))) { // Convert to CFURLRef stringsURL = CFURLCreateWithFileSystemPath(NULL, stringsName, kCFURLPOSIXPathStyle, false); CFReadStreamRef stringsStream = CFReadStreamCreateWithFile(NULL, stringsURL); CFRelease(stringsURL); CFReadStreamOpen(stringsStream); CFPropertyListRef strings = CFPropertyListCreateFromStream(NULL, stringsStream, 0, kCFPropertyListImmutable, NULL, NULL); CFReadStreamClose(stringsStream); CFRelease(stringsStream); CFDictionaryApplyFunction(strings, (CFDictionaryApplierFunction)&addKeysToSet, langKeys); CFDictionaryApplyFunction(strings, (CFDictionaryApplierFunction)&addKeysToSet, unionKeys); CFRelease(strings); } CFRelease(stringsName); } } closedir(subdir); } chdir(".."); CFStringRef langCode = CFStringCreateWithSubstring(NULL, dirName, CFRangeMake(0, CFStringGetLength(dirName)-6)); CFArrayAppendValue(sk.languages, langCode); CFArrayAppendValue(sk.keys, langKeys); CFRelease(langKeys); CFRelease(langCode); } CFRelease(dirName); } } closedir(dir); sk.count = CFArrayGetCount(sk.languages); printf("|| *Key* ||"); CFArrayApplyFunction(sk.languages, CFRangeMake(0, sk.count), (CFArrayApplierFunction)&printHeader, NULL); printf("\n"); CFSetApplyFunction(unionKeys, (CFSetApplierFunction)&printSupportedLanguages, &sk); CFRelease(sk.keys); CFRelease(sk.languages); CFRelease(unionKeys); } return 0; }