static void KPRLibrarySniffPodcastComplete(KprMessage message, void* it) { KprFunctionTarget self = it; char* mime = KprMessageGetResponseHeader(message, "content-type"); char* sniff = NULL; if (message->response.body) { if (kFskErrNone == FskMediaPlayerSniffForMIME(message->response.body, message->response.size, NULL, message->url, &sniff)) { mime = sniff; } } { xsBeginHostSandboxCode(self->the, self->code); if (mime) xsResult = xsString(mime); else xsResult = xsString(""); (void)xsCallFunction1(self->slot, xsGlobal, xsResult); xsEndHostSandboxCode(); } FskMemPtrDispose(sniff); }
void KprFILEServiceInvoke(KprService service UNUSED, KprMessage message) { FskErr err = kFskErrNone; char* path = NULL; FskFileInfo info; FskDirectoryIterator iterator = NULL; char* pathName = NULL; char* sniff = NULL; FskFile fref = NULL; char *name = NULL; if (KprMessageContinue(message)) { if (!message->method || FskStrCompare(message->method, "GET")) { bailIfError(KprURLToPath(message->url, &path)); bailIfError(FskFileGetFileInfo(path, &info)); if (kFskDirectoryItemIsDirectory == info.filetype) { unsigned char buffer[4096]; UInt32 itemType; double date; UInt32 size; xsBeginHostSandboxCode(gFILEService.machine, NULL); { xsVars(3); { xsTry { xsVar(0) = xsGet(xsGlobal, xsID("Files")); xsResult = xsNewInstanceOf(xsArrayPrototype); bailIfError(FskDirectoryIteratorNew(path, &iterator, 0)); while (kFskErrNone == FskDirectoryIteratorGetNext(iterator, &name, &itemType)) { if (name[0] == '.') { FskMemPtrDisposeAt(&name); continue; } if (kFskDirectoryItemIsFile == itemType) { pathName = FskStrDoCat(path, name); bailIfError(FskFileGetFileInfo(pathName, &info)); bailIfError(FskFileOpen(pathName, kFskFilePermissionReadOnly, &fref)); bailIfError(FskFileRead(fref, sizeof(buffer), buffer, &size)); FskFileClose(fref); fref = NULL; if (kFskErrNone == FskMediaPlayerSniffForMIME(buffer, size, NULL, pathName, &sniff)) { } else if (kFskErrNone == FskImageDecompressSniffForMIME(buffer, size, NULL, pathName, &sniff)) { } FskMemPtrDispose(pathName); pathName = NULL; } xsVar(1) = xsNewInstanceOf(xsObjectPrototype); xsNewHostProperty(xsVar(1), xsID("name"), xsString(name), xsDefault, xsDontScript); xsNewHostProperty(xsVar(1), xsID("path"), xsString(name), xsDefault, xsDontScript); FskStrCopy((char*)buffer, message->url); FskStrCat((char*)buffer, name); if (kFskDirectoryItemIsDirectory == itemType) { xsVar(2) = xsGet(xsVar(0), xsID("directoryType")); FskStrCat((char*)buffer, "/"); } else if (kFskDirectoryItemIsFile == itemType) { xsVar(2) = xsGet(xsVar(0), xsID("fileType")); if (info.fileModificationDate > info.fileCreationDate) date = info.fileModificationDate * 1000.0; else date = info.fileCreationDate * 1000.0; xsNewHostProperty(xsVar(1), xsID("date"), xsNumber(date), xsDefault, xsDontScript); xsNewHostProperty(xsVar(1), xsID("size"), xsNumber(info.filesize), xsDefault, xsDontScript); if (sniff) { xsNewHostProperty(xsVar(1), xsID("mime"), xsString(sniff), xsDefault, xsDontScript); FskMemPtrDispose(sniff); sniff = NULL; } } else xsVar(2) = xsGet(xsVar(0), xsID("linkType")); xsNewHostProperty(xsVar(1), xsID("type"), xsVar(2), xsDefault, xsDontScript); xsNewHostProperty(xsVar(1), xsID("url"), xsString((char*)buffer), xsDefault, xsDontScript); (void)xsCall1(xsResult, xsID("push"), xsVar(1)); FskMemPtrDisposeAt(&name); } xsResult = xsCall1(xsGet(xsGlobal, xsID("JSON")), xsID("stringify"), xsResult); message->response.body = FskStrDoCopy(xsToString(xsResult)); message->response.size = FskStrLen(message->response.body); KprMessageTransform(message, gFILEService.machine); } xsCatch { } } } xsEndHostSandboxCode(); } else if (kFskDirectoryItemIsFile == info.filetype) {
FskErr KprSoundLoad(KprSound self) { FskErr err = kFskErrNone; char *path = NULL; FskFile fref = NULL; FskMediaSpoolerRecord spooler; KprSoundLoadSpoolerRefconRecord refcon; FskMediaReader reader = NULL; FskMediaReaderTrack track; FskMediaPropertyValueRecord property; char *audioFormat = NULL; double duration; unsigned char *formatInfo = NULL; UInt32 formatInfoSize; UInt16 numChannels; double sampleRate; double timeScale; FskMediaReaderSampleInfo info = NULL; unsigned char *buffer = NULL; KprSoundFrame frames = NULL; UInt32 frameCount = 0; unsigned char *data = NULL; UInt32 dataSize = 0; if (self->data) goto bail; bailIfError(KprURLToPath(self->url, &path)); if (!self->mime) { unsigned char buffer[4096]; UInt32 size; char *sniff = NULL; bailIfError(FskFileOpen(path, kFskFilePermissionReadOnly, &fref)); bailIfError(FskFileRead(fref, sizeof(buffer), buffer, &size)); FskFileClose(fref); fref = NULL; bailIfError(FskMediaPlayerSniffForMIME(buffer, size, NULL, self->url, &sniff)); self->mime = sniff; } FskMemSet(&spooler, 0, sizeof(spooler)); FskMemSet(&refcon, 0, sizeof(refcon)); refcon.path = path; spooler.refcon = &refcon; spooler.doOpen = KprSoundLoadSpoolerOpen; spooler.doClose = KprSoundLoadSpoolerClose; spooler.doRead = KprSoundLoadSpoolerRead; spooler.doGetSize = KprSoundLoadSpoolerGetSize; bailIfError((*FskMediaReaderNewProc)(&reader, self->mime, self->url, &spooler, NULL, NULL)); bailIfError((*FskMediaReaderGetPropertyProc)(reader, kFskMediaPropertyTimeScale, &property)); timeScale = property.value.integer; (*FskMediaReaderGetPropertyProc)(reader, kFskMediaPropertyDuration, &property); duration = property.value.number; (*FskMediaReaderGetTrackProc)(reader, 0, &track); (*FskMediaReaderTrackGetPropertyProc)(track, kFskMediaPropertyFormat, &property); audioFormat = property.value.str; if (kFskErrNone == (*FskMediaReaderTrackGetPropertyProc)(track, kFskMediaPropertyFormatInfo, &property)) { formatInfo = property.value.data.data; formatInfoSize = property.value.data.dataSize; } else formatInfoSize = 0; (*FskMediaReaderTrackGetPropertyProc)(track, kFskMediaPropertyChannelCount, &property); numChannels = property.value.integer; (*FskMediaReaderTrackGetPropertyProc)(track, kFskMediaPropertySampleRate, &property); sampleRate = property.value.integer; bailIfError((*FskMediaReaderStartProc)(reader, NULL, NULL)); for (;;) { UInt32 c = 0, i, s; unsigned char *d; err = (*FskMediaReaderExtractProc)(reader, &track, &c, &info, &buffer); if (err == kFskErrEndOfFile) { err = kFskErrNone; break; } if (err != kFskErrNone) goto bail; for (i = 0, d = buffer; i < c; i++, d += s) { s = info[i].sampleSize * info[i].samples; bailIfError(FskMemPtrRealloc((frameCount + 1) * sizeof(KprSoundFrameRecord), &frames)); frames[frameCount].count = info[i].samples; frames[frameCount].frameSize = info[i].sampleSize; frames[frameCount].samplesPerFrame = info[i].sampleDuration; frames[frameCount].frameOffset = dataSize; frameCount++; bailIfError(FskMemPtrRealloc(dataSize + s, &data)); FskMemCopy(data + dataSize, d, s); dataSize += s; } FskMemPtrDispose(buffer); buffer = NULL; FskMemPtrDispose(info); info = NULL; } (*FskMediaReaderStopProc)(reader); self->audioFormat = audioFormat; self->duration = duration; self->formatInfo = formatInfo; self->formatInfoSize = formatInfoSize; self->numChannels = numChannels; self->sampleRate = sampleRate; self->timeScale = timeScale; self->data = data; self->dataSize = dataSize; self->frames = frames; self->frameCount = frameCount; bail: if (err) { FskMemPtrDispose(data); FskMemPtrDispose(frames); FskMemPtrDispose(formatInfo); FskMemPtrDispose(audioFormat); } FskMemPtrDispose(buffer); FskMemPtrDispose(info); (*FskMediaReaderDisposeProc)(reader); FskFileClose(fref); FskMemPtrDispose(path); return err; }