CFStringRef __NCParseExtendedFormatString( CFStringRef format ) { CFMutableStringRef newFormat = CFStringCreateMutableCopy( kCFAllocatorDefault, 0, format); CFIndex length = CFStringGetLength(newFormat); CFRange searchRange = CFRangeMake(0,length); CFRange foundRange; // Scan through the mutable copy looking for '%!' sequences to // parse-out: while (CFStringFindWithOptions(newFormat,CFSTR("%!"),searchRange,0,&foundRange)) { CFIndex start = foundRange.location; CFIndex end; if (CFStringFindWithOptions(newFormat,CFSTR(";"),CFRangeMake(start,length - start),0,&foundRange)) end = foundRange.location; else end = length; __NCReplaceFormatToken(newFormat,start,end); length = CFStringGetLength(newFormat); if (end >= length) break; searchRange = CFRangeMake(start,length - start); } return newFormat; }
// Check the serial number is the same as the computer we are now on int cstr_ours(const char* pszCString) { CFStringRef SerialNumber; CFStringRef SerialNumberInCString; CFRange Rng; int nRet; if ( NULL==pszCString ) return -1; // Quick check that it's previously owned by our driver if ( 0 != strncmp(pszCString, APPLE_DRIVER_PREFIX, strlen(APPLE_DRIVER_PREFIX)) ) return -1; // Check the computer serial number CopySerialNumber(&SerialNumber); Rng.location = 0; Rng.length = CFStringGetLength(SerialNumber); SerialNumberInCString = CFStringCreateWithCString(NULL, pszCString+strlen(APPLE_DRIVER_PREFIX)+1, kCFStringEncodingUTF8); nRet = CFStringFindWithOptions(SerialNumberInCString, SerialNumber, Rng, 0, 0) ? 0 : -1; CFRelease(SerialNumberInCString); CFRelease(SerialNumber); return nRet; }
void _CFFSGetLastPathComponent(CFStringRef* result, CFStringRef path) { if (!result) { return; } if (!path) { *result = NULL; return; } CFRange slash = CFStringFind(path, CFSTR("/"), kCFCompareBackwards); if (slash.location == kCFNotFound) { *result = (CFStringRef)CFRetain(path); return; } CFIndex lastSlashLocation = CFStringGetLength(path); while (slash.location == lastSlashLocation - 1) { lastSlashLocation = slash.location; Boolean found = CFStringFindWithOptions( path, CFSTR("/"), CFRangeMake(0, lastSlashLocation), kCFCompareBackwards, &slash); if (!found) { slash.location = -1; break; } } slash.location += 1; *result = CFStringCreateWithSubstring( kCFAllocatorDefault, path, CFRangeMake(slash.location, lastSlashLocation - slash.location)); }
Boolean odkerb_CFStringHasPrefixWithOptions(CFStringRef theString, CFStringRef prefix, CFOptionFlags searchOptions) { /* restrict search options to those that make sense */ searchOptions &= (kCFCompareCaseInsensitive | kCFCompareNonliteral | kCFCompareLocalized | kCFCompareDiacriticInsensitive | kCFCompareWidthInsensitive); /* anchor search to the start of the string */ searchOptions |= kCFCompareAnchored; return CFStringFindWithOptions(theString, prefix, CFRangeMake(0, CFStringGetLength(theString)), searchOptions, NULL); }
CF_PRIVATE Boolean _CFAppendPathExtension2(CFMutableStringRef path, CFStringRef extension) { if (!path) { return false; } if (0 < CFStringGetLength(extension) && IS_SLASH(CFStringGetCharacterAtIndex(extension, 0))) { return false; } if (1 < CFStringGetLength(extension)) { if (_hasDrive(extension)) return false; } Boolean destHasDrive = (1 < CFStringGetLength(path)) && _hasDrive(path); while (((destHasDrive && 3 < CFStringGetLength(path)) || (!destHasDrive && 1 < CFStringGetLength(path))) && IS_SLASH(CFStringGetCharacterAtIndex(path, CFStringGetLength(path) - 1))) { CFStringDelete(path, CFRangeMake(CFStringGetLength(path) - 1, 1)); } if (CFStringGetLength(path) == 0) { return false; } UniChar firstChar = CFStringGetCharacterAtIndex(path, 0); CFIndex newLength = CFStringGetLength(path); switch (newLength) { case 0: return false; case 1: if (IS_SLASH(firstChar) || firstChar == '~') { return false; } break; case 2: if (_hasDrive(path) || _hasNet(path)) { return false; } break; case 3: if (IS_SLASH(CFStringGetCharacterAtIndex(path, 2)) && _hasDrive(path)) { return false; } break; } if (0 < newLength && firstChar == '~') { // Make sure we have a slash in the string if (!CFStringFindWithOptions(path, CFPreferredSlashStr, CFRangeMake(1, newLength - 1), 0, NULL)) { return false; } } static const UniChar dotChar = '.'; CFStringAppendCharacters(path, &dotChar, 1); CFStringAppend(path, extension); return true; }
void MDSAttrParser::parseAttrs(CFStringRef subdir) { /* get all *.mdsinfo files */ CFArrayRef bundleInfoFiles = CFBundleCopyResourceURLsOfType(mBundle, CFSTR(MDS_INFO_TYPE), subdir); if(bundleInfoFiles == NULL) { Syslog::alert("MDSAttrParser: no mdsattr files for %s", mPath); return; } assert(CFGetTypeID(bundleInfoFiles) == CFArrayGetTypeID()); /* process each .mdsinfo file */ CFIndex numFiles = CFArrayGetCount(bundleInfoFiles); for(CFIndex i=0; i<numFiles; i++) { /* get filename as CFURL */ CFURLRef infoUrl = NULL; infoUrl = reinterpret_cast<CFURLRef>( CFArrayGetValueAtIndex(bundleInfoFiles, i)); if(infoUrl == NULL) { MPDebug("MDSAttrParser: CFBundleCopyResourceURLsOfType screwup 1"); continue; } if(CFGetTypeID(infoUrl) != CFURLGetTypeID()) { MPDebug("MDSAttrParser: CFBundleCopyResourceURLsOfType screwup 2"); continue; } // @@@ Workaround for 4234967: skip any filename beginning with "._" CFStringRef lastComponent = CFURLCopyLastPathComponent(infoUrl); if (lastComponent) { CFStringRef resFilePfx = CFSTR("._"); // setting the search length and location like this permits, // e.g., ".foo.mdsinfo" to be valid CFIndex resFilePfxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(resFilePfx), kCFStringEncodingUTF8); CFRange range = CFRangeMake(0, resFilePfxLen); Boolean skip = CFStringFindWithOptions(lastComponent, resFilePfx, range, 0/*options*/, NULL/*returned substr*/); CFRelease(lastComponent); if (skip == true) { Syslog::warning("MDSAttrParser: ignoring resource file"); continue; } } parseFile(infoUrl, subdir); } /* for each mdsinfo */ CF_RELEASE(bundleInfoFiles); }
Boolean odkerb_CFStringHasSuffixWithOptions(CFStringRef theString, CFStringRef suffix, CFOptionFlags searchOptions) { /* restrict search options to those that make sense */ searchOptions &= (kCFCompareCaseInsensitive | kCFCompareNonliteral | kCFCompareLocalized | kCFCompareDiacriticInsensitive | kCFCompareWidthInsensitive); /* make the suffix search faster, anchor it to the end of the string */ searchOptions |= (kCFCompareBackwards | kCFCompareAnchored); return CFStringFindWithOptions(theString, suffix, CFRangeMake(0, CFStringGetLength(theString)), searchOptions, NULL); }
CFStringRef _SC_trimDomain(CFStringRef domain) { CFIndex length; if (!isA_CFString(domain)) { return NULL; } // remove any leading/trailing dots length = CFStringGetLength(domain); if ((length > 0) && (CFStringFindWithOptions(domain, CFSTR("."), CFRangeMake(0, 1), kCFCompareAnchored, NULL) || CFStringFindWithOptions(domain, CFSTR("."), CFRangeMake(0, length), kCFCompareAnchored|kCFCompareBackwards, NULL))) { CFMutableStringRef trimmed; trimmed = CFStringCreateMutableCopy(NULL, 0, domain); CFStringTrim(trimmed, CFSTR(".")); domain = (CFStringRef)trimmed; length = CFStringGetLength(domain); } else { CFRetain(domain); } if (length == 0) { CFRelease(domain); domain = NULL; } return domain; }
BOOL SiDeviceMatch(const USBDeviceSI*const & pclDevice_) { BOOL bReturnValue; CFStringRef hDevicePath = CFStringCreateWithCString(kCFAllocatorDefault, (const char*)(pclDevice_->GetBsdName()), kCFStringEncodingUTF8); if(CFStringFindWithOptions(hDevicePath, CFSTR(ANT_SI_BSD_NAME), CFRangeMake(0,CFStringGetLength(hDevicePath)), 0, NULL) == FALSE) bReturnValue = FALSE; else bReturnValue = TRUE; CFRelease(hDevicePath); return bReturnValue; }
CF_PRIVATE CFArrayRef _CFBundleDYLDCopyLoadedImagePathsForHint(CFStringRef hint) { uint32_t i, numImages = _dyld_image_count(); CFMutableArrayRef result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks); CFRange range = CFRangeMake(0, CFStringGetLength(hint)), altRange = CFRangeMake(0, 0), testRange = CFRangeMake(0, 0); const char *processPath = _CFProcessPath(); const void *mhp = (const void *)_NSGetMachExecuteHeader(); if (range.length > 14) { // handle some common variations on framework bundle identifiers if (CFStringFindWithOptions(hint, CFSTR(".framework"), range, kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, &testRange) && testRange.location > 0 && testRange.length > 0) { // identifier has .framework appended altRange.length = testRange.location; } else if (CFStringFindWithOptions(hint, CFSTR("framework"), range, kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, &testRange) && testRange.location > 0 && testRange.length > 0) { // identifier has Framework appended altRange.length = testRange.location; } else if (CFStringFindWithOptions(hint, CFSTR("fw"), range, kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, &testRange) && testRange.location > 0 && testRange.length > 0) { // identifier has FW appended altRange.length = testRange.location; } } for (i = 0; i < numImages; i++) { const char *curName = _dyld_get_image_name(i), *lastComponent = NULL; if (curName && (!processPath || 0 != strcmp(curName, processPath)) && mhp != (void *)_dyld_get_image_header(i)) lastComponent = strrchr(curName, '/'); if (lastComponent) { CFStringRef str = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, lastComponent + 1); if (str) { if (CFStringFindWithOptions(hint, str, range, kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, NULL) || (altRange.length > 0 && CFStringFindWithOptions(hint, str, altRange, kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, NULL))) { CFStringRef curStr = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, curName); if (curStr) { CFArrayAppendValue(result, curStr); CFRelease(curStr); } } CFRelease(str); } } } return result; }
void ParseURL(CFStringRef urlPtr, CFStringRef * name) { CFIndex count; char * tempPtr; if (urlPtr) { tempPtr = (char *)strstr(CFStringGetCStringPtr(urlPtr, CFStringGetSystemEncoding()), kAppleTalkKey); if (tempPtr != NULL) { tempPtr += 5; count = 0; while (tempPtr[count] != '\0' && tempPtr[count] != ':') count++; *name = CFStringCreateWithBytes(NULL, tempPtr, count, CFStringGetSystemEncoding(), false); } else if (CFStringFindWithOptions(urlPtr, CFSTR("?"), CFRangeMake(0, CFStringGetLength(urlPtr)), 0, NULL) == false) { *name = CFStringCreateCopy(NULL, urlPtr); } else { tempPtr = (char *)strstr(CFStringGetCStringPtr(urlPtr, CFStringGetSystemEncoding()), kNameKey); if (tempPtr != NULL) { tempPtr += 5; count = 0; while (tempPtr[count] != '\0' && tempPtr[count] != '&') count++; *name = CFStringCreateWithBytes(NULL, tempPtr, count, CFStringGetSystemEncoding(), false); } else { *name = CFStringCreateCopy(NULL, urlPtr); } } } else { *name = NULL; } }
/** * Split a text into a list of strings. Reduce the texts to a CFStringRef of * hashes where each Unicode character represents one line. * @param text CFString to encode. * @param lineArray CFMutableArray of unique strings. * @param lineHash Map of strings to indices. * @return Encoded CFStringRef. */ CFStringRef diff_linesToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef lineArray, CFMutableDictionaryRef lineHash) { #define lineStart lineStartRange.location #define lineEnd lineEndRange.location CFRange lineStartRange; CFRange lineEndRange; lineStart = 0; lineEnd = -1; CFStringRef line; CFMutableStringRef chars = CFStringCreateMutable(kCFAllocatorDefault, 0); CFIndex textLength = CFStringGetLength(text); // Walk the text, pulling out a Substring for each line. // CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, text, CFSTR("\n")) would temporarily double our memory footprint. // Modifying text would create many large strings. while (lineEnd < textLength - 1) { lineStartRange.length = textLength - lineStart; if (CFStringFindWithOptions(text, CFSTR("\n"), lineStartRange, 0, &lineEndRange) == false) { lineEnd = textLength - 1; } /* else { lineEnd = lineEndRange.location; }*/ line = diff_CFStringCreateJavaSubstring(text, lineStart, lineEnd + 1); lineStart = lineEnd + 1; diff_mungeHelper(line, lineArray, lineHash, chars); CFRelease(line); } return chars; #undef diff_UniCharMax #undef lineStart #undef lineEnd }
CFArrayRef CFStringCreateArrayBySeparatingStrings (CFAllocatorRef alloc, CFStringRef str, CFStringRef separator) { /* This is basically a port of -componentsSeparatedByString: */ CFIndex end; CFRange search; CFRange found; CFStringRef tmp; CFArrayRef ret; CFMutableArrayRef array; array = CFArrayCreateMutable (alloc, 0, &kCFTypeArrayCallBacks); search = CFRangeMake (0, CFStringGetLength(str)); end = search.length; while (CFStringFindWithOptions(str, separator, search, 0, &found)) { CFRange current; current = CFRangeMake (search.location, found.location - search.location); tmp = CFStringCreateWithSubstring(alloc, str, current); CFArrayAppendValue (array, tmp); CFRelease (tmp); search = CFRangeMake (found.location + found.length, end - found.location - found.length); } /* Add the last search string range */ tmp = CFStringCreateWithSubstring(alloc, str, search); CFArrayAppendValue (array, tmp); CFRelease (tmp); ret = CFArrayCreateCopy (alloc, array); CFRelease(array); return ret; }
/* 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; }
static void ptr_query_callback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info) { CFDictionaryRef dict; CFStringRef name; CFMutableDictionaryRef newDict; struct timeval ptrQueryComplete; struct timeval ptrQueryElapsed; (void) gettimeofday(&ptrQueryComplete, NULL); timersub(&ptrQueryComplete, &ptrQueryStart, &ptrQueryElapsed); my_log(LOG_INFO, "NetBIOS name: ptr query complete%s (query time = %ld.%3.3d)", (flags & kSCNetworkReachabilityFlagsReachable) ? "" : ", host not found", ptrQueryElapsed.tv_sec, ptrQueryElapsed.tv_usec / 1000); // get network configuration dict = smb_copy_global_configuration(store); // use NetBIOS name from network configuration (if available) name = CFDictionaryGetValue(dict, kSCPropNetSMBNetBIOSName); if ((name != NULL) && _SC_CFStringIsValidNetBIOSName(name)) { my_log(LOG_INFO, "NetBIOS name (network configuration) = %@", name); goto setDict; } // use reverse DNS name, if available name = NULL; if (flags & kSCNetworkReachabilityFlagsReachable) { int error_num; CFArrayRef hosts; /* * if [reverse] DNS query was successful */ hosts = SCNetworkReachabilityCopyResolvedAddress(target, &error_num); if (hosts != NULL) { if (CFArrayGetCount(hosts) > 0) { CFIndex ptrLen; CFMutableStringRef ptrName; CFRange range; name = CFArrayGetValueAtIndex(hosts, 0); ptrName = CFStringCreateMutableCopy(NULL, 0, name); ptrLen = CFStringGetLength(ptrName); if (CFStringFindWithOptions(ptrName, CFSTR("."), CFRangeMake(0, ptrLen), 0, &range)) { CFStringDelete(ptrName, CFRangeMake(range.location, ptrLen - range.location)); } name = ptrName; } CFRelease(hosts); } } if (name != NULL) { if (_SC_CFStringIsValidNetBIOSName(name)) { my_log(LOG_INFO, "NetBIOS name (reverse DNS query) = %@", name); goto setName; } CFRelease(name); } // try local (multicast DNS) name, if available name = SCDynamicStoreCopyLocalHostName(store); if (name != NULL) { if (_SC_CFStringIsValidNetBIOSName(name)) { my_log(LOG_INFO, "NetBIOS name (multicast DNS) = %@", name); goto setName; } CFRelease(name); } // use "default" name name = copy_default_name(); if (name != NULL) { my_log(LOG_INFO, "NetBIOS name (default) = %@", name); goto setName; } goto setDict; setName : newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); CFDictionarySetValue(newDict, kSCPropNetSMBNetBIOSName, name); CFRelease(dict); dict = newDict; CFRelease(name); setDict : // update SMB configuration smb_set_configuration(store, dict); CFRelease(dict); ptr_query_stop(); #ifdef MAIN CFRunLoopStop(rl); #endif // MAIN return; }
int main(int argc, char **argv) { int i; if (argc <= 1) { // TODO: Man page? fprintf(stderr, "Usage: abquery <name>\n" "The <name> parameter accepts similarities: \"dan fer\" matches \"Däniel Ferrêira\".\n" "Details on /usr/share/tiutils/abquery-ex.txt\n"); return 1; } CFMutableArrayRef args = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (i=1; i<argc; i++) { CFStringRef str = CFStringCreateWithCString(NULL, argv[i], kCFStringEncodingUTF8); CFArrayAppendValue(args, str); CFRelease(str); } ABAddressBookRef ab = ABAddressBookCreate(); CFIndex count = ABAddressBookGetPersonCount(ab); if (count == 0) { CFRelease(ab); puts("No entries on the address book database."); return 0; } else printf("Total name matches: %lu\n", count); CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(ab); if (!people || CFArrayGetCount(people)==0) { if (people) CFRelease(people); CFRelease(ab); fprintf(stderr, "[Error] Inconsistency: ABAddressBookCopyArrayOfAllPeople returned NULL or contains no people, but address book people count is bigger than zero.\n"); return 2; } for (i=0; i<count; i++) { ABRecordRef dude = (ABRecordRef)CFArrayGetValueAtIndex(people, i); if (!dude) { fprintf(stderr, "[Error] Null entry at index %d. Skipping.\n", i); continue; } CFStringRef name = ABRecordCopyCompositeName(dude); if (!name || CFStringGetLength(name)==0) continue; Boolean found = false; CFIndex j, cnt=CFArrayGetCount(args); for (j=0; j<cnt; j++) { CFStringRef str = (CFStringRef)CFArrayGetValueAtIndex(args, j); found = CFStringFindWithOptions(name, str, CFRangeMake(0, CFStringGetLength(name)), kCFCompareCaseInsensitive|kCFCompareDiacriticInsensitive, NULL); if (!found) break; } if (found) { // NOTE: We can have a lot more here. // But for now let's stick with what Erica did originally char nm[1024]; CFStringGetCString(name, nm, sizeof(nm), kCFStringEncodingUTF8); printf("%s\n", nm); printmv(dude, kABPersonPhoneProperty); printmv(dude, kABPersonEmailProperty); } } CFRelease(people); CFRelease(ab); return 0; }
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); } }
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; }
CF_PRIVATE void appendQuotedString(CFMutableStringRef str, CFStringRef strToQuote) { char quoteChar = CFStringFindWithOptions(strToQuote, CFSTR("\""), CFRangeMake(0, CFStringGetLength(strToQuote)), 0, NULL) ? '\'' : '\"'; CFStringAppendFormat(str, NULL, CFSTR("%c%@%c"), quoteChar, strToQuote, quoteChar); }
static kern_return_t SubstituteKeywordsInUserVisibleName(io_object_t interface, CFMutableDictionaryRef interfaceInfo, CFStringRef nameTemplate, CFStringRef *userVisibleName) // This routine creates a new string and returns it in *userVisibleName. // The string is based on nameTemplate, with any of the keywords (defined // in our header file) replace with the appropriate strings. // // I could probably write better, more general, code to do this, but // this is the way the code turned out (after several design iterations) // and it's not too atrocious. // // Note that this routine assumes that whoever set up nameTemplate // to included a keyword also included the appropriate string in the // interfaceInfo dictionary. This might not be true if the client's // callback routine returns a wacky localisation for the user-visible // name. I haven't seen fit to fix this because it's an obscure // case and the client's callback could fix it by adding the appropriate // keys to the interfaceInfo dictionary (which it is passed). // // I originally tried to using CFStringCreateWithFormat to create // the output string (hence the keyword syntax) but I discovered // that the CF routine requires you to always substitute all keywords // (which is obvious when you consider how varargs works, but it // threw me for a loop). So I abandoned CFStringCreateWithFormat, but // I couldn't think of any good reason to change the keyword syntax. { #pragma unused(interface) kern_return_t err; CFMutableStringRef result; CFRange foundRange; assert( interface != 0 ); assert( interfaceInfo != NULL); assert( nameTemplate != NULL); assert( userVisibleName != NULL); assert(*userVisibleName == NULL); err = 0; result = CFStringCreateMutableCopy(NULL, 0, nameTemplate); if (result == NULL) { err = -1; } // BSD Name if ( (err == 0) && CFStringFindWithOptions(result, CFSTR("%1$@"), CFRangeMake(0, CFStringGetLength(result)), kNilOptions, &foundRange) ) { assert(CFDictionaryGetValue(interfaceInfo, CFSTR(kIOBSDNameKey)) != NULL); CFStringReplace(result, foundRange, (CFStringRef) CFDictionaryGetValue(interfaceInfo, CFSTR(kIOBSDNameKey))); } // PCI Slot Name if ( (err == 0) && CFStringFindWithOptions(result, CFSTR("%2$@"), CFRangeMake(0, CFStringGetLength(result)), kNilOptions, &foundRange) ) { assert(CFDictionaryGetValue(interfaceInfo, CFSTR("AAPL,slot-name")) != NULL); CFStringReplace(result, foundRange, (CFStringRef) CFDictionaryGetValue(interfaceInfo, CFSTR("AAPL,slot-name"))); } // PCI Function Number if ( (err == 0) && CFStringFindWithOptions(result, CFSTR("%3$@"), CFRangeMake(0, CFStringGetLength(result)), kNilOptions, &foundRange) ) { assert(CFDictionaryGetValue(interfaceInfo, CFSTR("IOChildIndex")) != NULL); CFStringReplace(result, foundRange, (CFStringRef) CFDictionaryGetValue(interfaceInfo, CFSTR("IOChildIndex"))); } // IOTTYBaseName if ( (err == 0) && CFStringFindWithOptions(result, CFSTR("%4$@"), CFRangeMake(0, CFStringGetLength(result)), kNilOptions, &foundRange) ) { assert(CFDictionaryGetValue(interfaceInfo, CFSTR(kIOTTYBaseNameKey)) != NULL); CFStringReplace(result, foundRange, (CFStringRef) CFDictionaryGetValue(interfaceInfo, CFSTR(kIOTTYBaseNameKey))); } // Clean up. if (err == 0) { *userVisibleName = result; } else { CFQRelease(result); } assert( (err == 0) == (*userVisibleName != NULL) ); return err; }
/** * Does a Substring of shorttext exist within longtext such that the * Substring is at least half the length of longtext? * @param longtext Longer CFStringRef. * @param shorttext Shorter CFStringRef. * @param i Start index of quarter length Substring within longtext. * @return Five element CFStringRef array, containing the prefix of longtext, the * suffix of longtext, the prefix of shorttext, the suffix of shorttext * and the common middle. Or NULL if there was no match. */ CFArrayRef diff_halfMatchICreate(CFStringRef longtext, CFStringRef shorttext, CFIndex i) { // Start with a 1/4 length Substring at position i as a seed. CFStringRef seed = diff_CFStringCreateSubstring(longtext, i, CFStringGetLength(longtext) / 4); CFIndex j = -1; CFStringRef best_common = CFSTR(""); CFStringRef best_longtext_a = CFSTR(""), best_longtext_b = CFSTR(""); CFStringRef best_shorttext_a = CFSTR(""), best_shorttext_b = CFSTR(""); CFStringRef best_common_part1, best_common_part2; CFStringRef longtext_substring, shorttext_substring; CFIndex shorttext_length = CFStringGetLength(shorttext); CFRange resultRange; CFRange rangeToSearch; rangeToSearch.length = shorttext_length - (j + 1); rangeToSearch.location = j + 1; while (j < CFStringGetLength(shorttext) && (CFStringFindWithOptions(shorttext, seed, rangeToSearch, 0, &resultRange) == true)) { j = resultRange.location; rangeToSearch.length = shorttext_length - (j + 1); rangeToSearch.location = j + 1; longtext_substring = diff_CFStringCreateSubstringWithStartIndex(longtext, i); shorttext_substring = diff_CFStringCreateSubstringWithStartIndex(shorttext, j); CFIndex prefixLength = diff_commonPrefix(longtext_substring, shorttext_substring); CFRelease(longtext_substring); CFRelease(shorttext_substring); longtext_substring = diff_CFStringCreateLeftSubstring(longtext, i); shorttext_substring = diff_CFStringCreateLeftSubstring(shorttext, j); CFIndex suffixLength = diff_commonSuffix(longtext_substring, shorttext_substring); CFRelease(longtext_substring); CFRelease(shorttext_substring); if (CFStringGetLength(best_common) < suffixLength + prefixLength) { CFRelease(best_common); CFRelease(best_longtext_a); CFRelease(best_longtext_b); CFRelease(best_shorttext_a); CFRelease(best_shorttext_b); best_common_part1 = diff_CFStringCreateSubstring(shorttext, j - suffixLength, suffixLength); best_common_part2 = diff_CFStringCreateSubstring(shorttext, j, prefixLength); best_common = diff_CFStringCreateByCombiningTwoStrings(best_common_part1, best_common_part2); CFRelease(best_common_part1); CFRelease(best_common_part2); best_longtext_a = diff_CFStringCreateLeftSubstring(longtext, i - suffixLength); best_longtext_b = diff_CFStringCreateSubstringWithStartIndex(longtext, i + prefixLength); best_shorttext_a = diff_CFStringCreateLeftSubstring(shorttext, j - suffixLength); best_shorttext_b = diff_CFStringCreateSubstringWithStartIndex(shorttext, j + prefixLength); } } CFRelease(seed); CFArrayRef halfMatchIArray; if (CFStringGetLength(best_common) * 2 >= CFStringGetLength(longtext)) { const CFStringRef values[] = { best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b, best_common }; halfMatchIArray = CFArrayCreate(kCFAllocatorDefault, (const void **)values, (sizeof(values) / sizeof(values[0])), &kCFTypeArrayCallBacks); } else { halfMatchIArray = NULL; } CFRelease(best_common); CFRelease(best_longtext_a); CFRelease(best_longtext_b); CFRelease(best_shorttext_a); CFRelease(best_shorttext_b); return halfMatchIArray; }
Boolean GetMetadataForFile(void* thisInterface, CFMutableDictionaryRef attributes, CFStringRef contentTypeUTI, CFStringRef pathToFile) { Boolean success = false; CFDictionaryRef tempDictRef; CFStringRef tempTitleRef; CFArrayRef tempContentRef; // load the document at the specified location CFURLRef pathToFileURL; pathToFileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, pathToFile, kCFURLPOSIXPathStyle, false); tempDictRef = (CFDictionaryRef)CreatePropertiesFromXMLFile(pathToFileURL); CFRelease(pathToFileURL); if (tempDictRef) { CFStringRef tempBrdNameRef; CFStringRef tempDatNumberRef; CFNumberRef tempLengthRef; CFDateRef tempCreatedDateRef; CFDateRef tempModifiedDateRef; CFDictionarySetValue(attributes, kMDItemCreator, CFSTR("BathyScaphe")); // set the kMDItemTitle attribute to the Title tempTitleRef = CFDictionaryGetValue(tempDictRef, CFSTR("Title")); if (tempTitleRef != NULL) { CFDictionarySetValue(attributes, kMDItemTitle, tempTitleRef); CFDictionarySetValue(attributes, kMDItemDisplayName, tempTitleRef); } tempBrdNameRef = CFDictionaryGetValue(tempDictRef, CFSTR("BoardName")); if (tempBrdNameRef != NULL) CFDictionarySetValue(attributes, CFSTR("jp_tsawada2_bathyscaphe_thread_BoardName"), tempBrdNameRef); tempDatNumberRef = CFDictionaryGetValue(tempDictRef, CFSTR("dat")); if (tempDatNumberRef != NULL) CFDictionarySetValue(attributes, CFSTR("jp_tsawada2_bathyscaphe_thread_DatNumber"), tempDatNumberRef); tempLengthRef = CFDictionaryGetValue(tempDictRef, CFSTR("Length")); if (tempLengthRef != NULL) CFDictionarySetValue(attributes, CFSTR("jp_tsawada2_bathyscaphe_thread_DatSize"), tempLengthRef); tempCreatedDateRef = CFDictionaryGetValue(tempDictRef, CFSTR("CreatedDate")); if (tempCreatedDateRef != NULL) CFDictionarySetValue(attributes, kMDItemContentCreationDate, tempCreatedDateRef); tempModifiedDateRef = CFDictionaryGetValue(tempDictRef, CFSTR("ModifiedDate")); if (tempModifiedDateRef != NULL) CFDictionarySetValue(attributes, kMDItemContentModificationDate, tempModifiedDateRef); tempContentRef = CFDictionaryGetValue(tempDictRef, CFSTR("Contents")); if (tempContentRef) { CFIndex i, count_; CFNumberRef countRef_; CFMutableStringRef cont_ = CFStringCreateMutable(kCFAllocatorDefault, 0); CFMutableArrayRef nameArray_ = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); CFDictionaryRef obj; CFNumberRef statusStr; count_ = CFArrayGetCount(tempContentRef); countRef_ = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &count_); CFDictionarySetValue(attributes, CFSTR("jp_tsawada2_bathyscaphe_thread_ResCount"), countRef_); CFRelease(countRef_); for (i=0; i<count_; i++) { obj = CFArrayGetValueAtIndex(tempContentRef, i); if (obj == NULL) continue; statusStr = CFDictionaryGetValue(obj, CFSTR("Status")); if (isNotAbonedRes(statusStr)) { CFStringRef msg_; CFStringRef name_; msg_ = CFDictionaryGetValue(obj, CFSTR("Message")); if (msg_) { CFStringAppend(cont_, msg_); } name_ = CFDictionaryGetValue(obj, CFSTR("Name")); if (name_) { Boolean already_ = CFArrayContainsValue(nameArray_, CFRangeMake(0, CFArrayGetCount(nameArray_)), name_); if (already_ == false) CFArrayAppendValue(nameArray_, name_); } } } CFStringFindAndReplace(cont_, CFSTR(" <br> "), CFSTR(""), CFRangeMake(0, CFStringGetLength(cont_)), 0); CFStringTrimWhitespace(cont_); CFIndex len; CFRange searchRange; CFRange resultRange; CFRange gtRange; len = CFStringGetLength(cont_); searchRange = CFRangeMake(0, len); while (1) { Boolean found_ = CFStringFindWithOptions(cont_, CFSTR("<a "), searchRange, kCFCompareCaseInsensitive, &resultRange); if (found_ == false) break; // Start searching next to "<" searchRange.location = resultRange.location + resultRange.length; searchRange.length = (len - searchRange.location); found_ = CFStringFindWithOptions(cont_, CFSTR("</a>"), searchRange, kCFCompareCaseInsensitive, >Range); if (found_ == false) break; resultRange.length = gtRange.location + gtRange.length - resultRange.location; CFStringDelete(cont_, resultRange); searchRange.length -= resultRange.length; len -= resultRange.length; if (searchRange.location >= len) break; } CFDictionarySetValue(attributes, kMDItemTextContent, cont_); CFDictionarySetValue(attributes, kMDItemContributors, nameArray_); CFRelease(cont_); CFRelease(nameArray_); } // release the loaded document CFRelease(tempDictRef); // return YES so that the attributes are imported success = true; } return success; }
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); } }