Exemple #1
0
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);
  }
}
Exemple #2
0
    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);
}
Exemple #9
0
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;
}
Exemple #17
0
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;
}