void KprServiceRegister(KprService service) { KprService *address = &gServices, current; if (!FskStrCompareWithLength(service->id, "xkpr", 4)) { while ((current = *address)) { if (!FskStrCompareWithLength(current->id, "xkpr", 4)) { if (FskStrCompare(current->id, service->id) <= 0) break; } address = &(current->next); } } else { while ((current = *address)) { address = &(current->next); } } service->next = current; *address = service; if (!service->accept) service->accept = KprServiceAccept; if (!service->cancel) service->cancel = KprServiceCancel; if (!service->invoke) service->invoke = KprServiceInvoke; if (!service->start) service->start = KprServiceStart; if (!service->stop) service->stop = KprServiceStop; }
xsIndex fxFindModuleKPR(xsMachine* the, xsIndex moduleID, xsSlot* slot) { char name[1024]; xsBooleanValue absolute, relative; xsStringValue dot, slash; xsIndex id; xsToStringBuffer(*slot, name, sizeof(name)); if ((!FskStrCompareWithLength(name, "./", 2)) || (!FskStrCompareWithLength(name, "../", 3))) { absolute = 0; relative = (moduleID == XS_NO_ID) ? 0 : 1; } else if ((!FskStrCompareWithLength(name, "/", 1))) { FskMemMove(name, name + 1, FskStrLen(name)); absolute = 1; relative = 0; } else { absolute = 1; relative = (moduleID == XS_NO_ID) ? 0 : 1; } slash = FskStrRChr(name, '/'); if (!slash) slash = name; dot = FskStrRChr(slash, '.'); if (dot) { xsBooleanValue known = 0; xsStringValue* extension; for (extension = gxExtensions; *extension; extension++) { if (!FskStrCompare(dot, *extension)) { known = 1; break; } } if (!known) dot = NULL; } if (!dot) dot = name + FskStrLen(name); if (relative) { if (fxFindURI(the, xsName(moduleID), name, dot, &id)) return id; } if (absolute) { xsStringValue* bases = gModulesBases; UInt32 c = gModulesBasesCount; UInt32 i = 1; while (i < c) { if (fxFindURI(the, bases[i], name, dot, &id)) return id; i++; } } return XS_NO_ID; }
FskErr FskFSVolumeGetID(const char *fullPath, UInt32 *volumeID) { const char *p; pMount theMount; if (!gMounts) scanVolumes(); theMount = gMounts; p = fullPath; FskAndroidFilesPrintfDebug("FskFSVolumeGetID(%s, %x)\n", p, volumeID); *volumeID = -1; while (theMount) { int len = FskStrLen(theMount->mountPoint); if (0 == FskStrCompareWithLength(theMount->mountPoint, fullPath, len)) { *volumeID = theMount->fsID; break; } theMount = theMount->next; } return kFskErrNone; }
void KprPinsInvoke(KprService service, KprMessage message) { FskErr err = kFskErrNone; KprPins self = gPins; if (KprMessageContinue(message)) { KprPinsListener listener = NULL; KprPinsListenerFind(&listener, self, message); if (listener) listener->useCount++; if (!FskStrCompareWithLength(message->parts.path, "close", message->parts.pathLength)) { if (listener) { xsBeginHostSandboxCode(listener->the, NULL); { { xsTry { (void)xsCall0(xsAccess(listener->pins), xsID("close")); } xsCatch { err = exceptionToFskErr(the); } } while (listener->pollers) KprPinsPollerDispose(listener->pollers); } xsEndHostSandboxCode(); KprPinsListenerDispose(listener, self); listener = NULL; } else { err = kFskErrNotFound; } } else if (!FskStrCompareWithLength(message->parts.path, "configure", message->parts.pathLength)) {
FskErr FskFSVolumeGetInfoFromPath(const char *pathIn, char **pathOut, char **nameOut, UInt32 *volumeType, Boolean *isRemovable, FskInt64 *capacity, FskInt64 *freeSpace) { FskErr err = kFskErrOperationFailed; int drv = -1; FskAndroidFilesPrintfDebug("FskFSVolumeGetInfoFromPath: pathIn: %s\n", pathIn); if (0 == FskStrCompare("/", pathIn)) drv = 1; else { pMount theMount = gMounts; while (theMount) { int len = FskStrLen(theMount->mountPoint); if (0 == FskStrCompareWithLength(theMount->mountPoint, pathIn, len)) { drv = theMount->fsID; break; } theMount = theMount->next; } } if (drv == -1) { FskAndroidFilesPrintfDebug("FskFSVolumeGetInfoFromPath: pathIn: %s - not found\n", pathIn); return err; } else return FskFSVolumeGetInfo(drv, pathOut, nameOut, volumeType, isRemovable, capacity, freeSpace); }
void KprMessageTransform(KprMessage self, xsMachine* machine) { KprStream stream = self->stream; if (machine && stream && stream->dispatch->transform) { if ((!FskStrCompareWithLength(self->url, "xkpr", 4) && KprMessageGetResponseHeader(self, "location"))) return; (*stream->dispatch->transform)(stream, self, machine); } }
FskErr KprMessageNotify(KprMessage self) { FskErr err = kFskErrNone; FskInstrumentedItemSendMessageDebug(self, kprInstrumentedMessageNotify, self); if (!FskStrCompareWithLength(self->parts.scheme, "xkpr", self->parts.schemeLength)) { self->usage++; // event queue FskThreadPostCallback(KprShellGetThread(gShell), (FskThreadCallback)KprMessageNotifyCallback, gShell, self, NULL, NULL); } else err = kFskErrUnimplemented; return err; }
void KprXKPRServiceInvoke(KprService self UNUSED, KprMessage message) { char* authority = message->parts.authority; UInt32 authorityLength = message->parts.authorityLength; message->usage--; // event queue if (!FskStrCompareWithLength(authority, "shell", authorityLength)) KprContextInvoke(gShell, message); else { KprContentLink link = gShell->applicationChain.first; while (link) { KprApplication application = (KprApplication)link->content; if (application->id && (!FskStrCompareWithLength(authority, application->id, authorityLength))) { KprContextInvoke(application, message); break; } link = link->next; } } if (!message->response.callback) { KprMessageTransform(message, gShell->the); KprMessageComplete(message); } }
Boolean KprMQTTMatchTopic(const char *topic, const char *pattern) { char *p; int len; do { if (FskStrCompare(topic, pattern) == 0) return true; p = FskStrChr(pattern, kMQTTSingleLevelSeparator); if (p) { len = p - pattern; if (FskStrCompareWithLength(topic, pattern, len) != 0) return false; topic += len; pattern += len + 1; topic = FskStrChr(topic, kMQTTTopicLevelSeparator); if (topic != NULL) { topic += 1; if (*pattern == 0) return false; pattern += 1; } else { if (*pattern != 0) return false; return true; } } else { break; } } while (true); p = FskStrChr(pattern, kMQTTMultiLevelSeparator); if (p == NULL) return false; len = p - pattern; if (FskStrCompareWithLength(topic, pattern, len) != 0) return false; return true; }
fstabDesc extMountToType(extMount ext) { int iter = 0; if (ext && ext->label) { int len; while ((len = (FskStrLen(gfstabDesc[iter].label)))) { if (0 == FskStrCompareWithLength(ext->label, gfstabDesc[iter].label, len)) { return &(gfstabDesc[iter]); } iter++; } FskAndroidFilesPrintfDebug("#### unknown external filesystem type - %s\n", ext->label); } return NULL; }
void androidVolumeEvent(int what, char *path) { UInt32 vid; FskFSVolumeNotifier walker = NULL; char *tmp = NULL; FskAndroidFilesPrintfDebug("androidVolumeEvent - %d, %s\n", what, path); if (NULL == gVolNotifiersMutex) return; FskMutexAcquire(gVolNotifiersMutex); if (0 == FskStrCompareWithLength(path, "file://", 7)) path += 7; if (path[FskStrLen(path)-1] != '/') tmp = FskStrDoCat(path, "/"); else tmp = FskStrDoCopy(path); FskFSVolumeGetID(tmp, &vid); FskAndroidFilesPrintfDebug("androidVolumeEvent - getvolumeid returned %d\n", vid); if (vid == kFskUInt32Max) { FskAndroidFilesPrintfDebug("couldn't find a mount for %s - try to scan again###\n", tmp); scanProcMount(); FskFSVolumeGetID(tmp, &vid); if (vid == 0) { FskAndroidFilesPrintfDebug("#### still no volume id? %s\n", tmp); } } while (gVolNotifiers) { FskFSVolumeNotifier notifier; walker = (FskFSVolumeNotifier)FskListGetNext(gVolNotifiers, walker); if (NULL == walker) break; FskAndroidFilesPrintfDebug("androidVolumeEvent - notifying %x\n", walker); notifier = (FskFSVolumeNotifier)(((char *)walker) - offsetof(FskFSVolumeNotifierRecord, next)); FskThreadPostCallback(notifier->callbackThread, callVolumeNotifier, notifier, (void*)what, (void*)vid, NULL); } FskMutexRelease(gVolNotifiersMutex); FskMemPtrDispose(tmp); }
void KPR_launchURI(xsMachine *the) { FskErr err; xsStringValue uri = xsToString(xsArg(0)); xsStringValue path = NULL; if (FskStrCompareWithLength(uri, "file://", 7)) err = FskLauncherOpenDocument(uri, 1); else { err = KprURLToPath(uri, &path); if (!err) { err = FskLauncherOpenDocument(path, 0); FskMemPtrDispose(path); } } xsThrowIfFskErr(err); }
void scanVolumes() { FILE *mountList; struct mntent *cur; int err; volInfo vi; mntdevmap *walker; struct statfs fsinfo; mountList = setmntent(kKplLinuxVolumeListFile, "r"); if (mountList) { while (NULL != (cur = getmntent(mountList))) { err = statfs(cur->mnt_dir, &fsinfo); if (0 != err) { continue; } for (walker = gMntDevMap; NULL != walker->name; walker++) { if (0 == FskStrCompareWithLength(cur->mnt_type, walker->name, FskStrLen(walker->name))) break; } if (!walker->name) { continue; } FskMemPtrNewClear(sizeof(volInfoRec), &vi); vi->type = walker->type; vi->removable = walker->removable; vi->mounted = true; vi->typeStr = FskStrDoCopy(cur->mnt_type); if (kFskErrNone == FskMemPtrNew(FskStrLen(cur->mnt_dir) + 2, &vi->mountPoint)) { FskStrCopy(vi->mountPoint, cur->mnt_dir); if (vi->mountPoint[FskStrLen(vi->mountPoint)-1] != '/') FskStrCat(vi->mountPoint, "/"); } vi->name = copyNiceName(cur->mnt_fsname); vi->capacity = fsinfo.f_blocks * fsinfo.f_bsize; vi->remaining = fsinfo.f_bavail * fsinfo.f_bsize; FskListAppend(&volumeList, vi); } endmntent(mountList); } }
void KprMessageComplete(KprMessage self) { char* url; FskThread thread = KprShellGetThread(gShell); if (!thread) return; // @@ happens on exit if (thread != FskThreadGetCurrent()) { FskThreadPostCallback(thread, (FskThreadCallback)KprMessageComplete, self, NULL, NULL, NULL); return; } FskInstrumentedItemSendMessageDebug(self, kprInstrumentedMessageComplete, self); if (FskListRemove(&gShell->messages, self)) { self->usage--; // message queue self->waiting = false; url = KprMessageGetResponseHeader(self, "location"); if (url && (!FskStrCompareWithLength(self->url, "xkpr", 4)) && ((!self->sniffing) || (!FskStrCompareWithLength(url, "xkpr", 4)))) { FskMemPtrDispose(self->url); self->url = FskStrDoCopy(url); //bailIfNULL(self->url); KprURLSplit(self->url, &self->parts); FskAssociativeArrayDispose(self->response.headers); self->response.headers = NULL; FskMemPtrDispose(self->response.body); self->response.body = NULL; self->response.size = 0; if (self->request.target) self->usage--; // @@ request if (kFskErrNone == KprMessageInvoke(self, self->request.callback, self->request.dispose, self->request.target)) return; } if (self->request.target) { if (self->request.callback) (*self->request.callback)(self, self->request.target); if (self->request.dispose) (*self->request.dispose)(self->request.target); self->request.callback = NULL; self->request.dispose = NULL; self->request.target = NULL; self->usage--; // request } if (!self->usage) KprMessageDispose(self); } }
void KPR_canvasRenderingContext2D_set_font(xsMachine *the) { FskCanvas2dContext ctx = xsGetHostData(xsThis); const struct FskFontAttributes* parent = FskCanvas2dGetFont(ctx); FskFontAttributes font; xsStringValue it = xsToString(xsArg(0)); xsStringValue p = it; xsStringValue q; char c, d; float size; char state = 0; font.family = NULL; font.size = 0; font.weight = kFskFontWeightNormal; font.style = kFskFontStyleNormal; font.anchor = kFskTextAnchorStart; font.stretch = kFskFontStretchNormal; font.decoration = kFskFontDecorationNone; font.variant = kFskFontVariantNormal; font.sizeAdjust = 0; for (;;) { while ((c = *p)) { if (c != ' ') break; p++; } if (!c) break; if (state == 2) { font.family = p; break; } q = p; while ((c = *q)) { if (c == ' ') break; q++; } if (state == 0) { if (!FskStrCompareWithLength(p, "normal", q - p)) {} else if (!FskStrCompareWithLength(p, "italic", q - p)) font.style = kFskFontStyleItalic; else if (!FskStrCompareWithLength(p, "oblique", q - p)) font.style = kFskFontStyleOblique; else if (!FskStrCompareWithLength(p, "inherit", q - p)) {} else if (!FskStrCompareWithLength(p, "bold", q - p)) font.weight = kFskFontWeightBold; else if (!FskStrCompareWithLength(p, "100", q - p)) font.weight = 100; else if (!FskStrCompareWithLength(p, "200", q - p)) font.weight = 200; else if (!FskStrCompareWithLength(p, "300", q - p)) font.weight = 300; else if (!FskStrCompareWithLength(p, "400", q - p)) font.weight = 400; else if (!FskStrCompareWithLength(p, "500", q - p)) font.weight = 500; else if (!FskStrCompareWithLength(p, "600", q - p)) font.weight = 600; else if (!FskStrCompareWithLength(p, "700", q - p)) font.weight = 700; else if (!FskStrCompareWithLength(p, "800", q - p)) font.weight = 800; else if (!FskStrCompareWithLength(p, "900", q - p)) font.weight = 900; else if (!FskStrCompareWithLength(p, "small-caps", q - p)) font.variant = kFskFontVariantSmallCaps; else state = 1; } if (state == 1) { if (!FskStrCompareWithLength(p, "xx-small", q - p)) font.size = 3 * kFskMediumFontSize / 5; else if (!FskStrCompareWithLength(p, "x-small", q - p)) font.size = 3 * kFskMediumFontSize / 4; else if (!FskStrCompareWithLength(p, "small", q - p)) font.size = 8 * kFskMediumFontSize / 9; else if (!FskStrCompareWithLength(p, "medium", q - p)) font.size = kFskMediumFontSize; else if (!FskStrCompareWithLength(p, "large", q - p)) font.size = 6 * kFskMediumFontSize / 5; else if (!FskStrCompareWithLength(p, "x-large", q - p)) font.size = 3 * kFskMediumFontSize / 2; else if (!FskStrCompareWithLength(p, "xx-large", q - p)) font.size = 2 * kFskMediumFontSize; else if (!FskStrCompareWithLength(p, "larger", q - p)) font.size = 6 * kFskMediumFontSize / 5; // @@ else if (!FskStrCompareWithLength(p, "smaller", q - p)) font.size = 8 * kFskMediumFontSize / 9; // @@ else { size = 0; while ((p < q) && ((d = *p)) && ('0' <= d) && (d <= '9')) { size = (10 * size) + (d - '0'); p++; } if (!FskStrCompareWithLength(p, "%", q - p)) font.size = parent->size * size / 100; else if (!FskStrCompareWithLength(p, "px", q - p)) font.size = size; } state = 2; } if (!c) break; p = q; } if (!font.family || !font.size) return; FskCanvas2dSetFont(ctx, &font); }
FskErr FskEnvironmentInitialize(void) { char *appPath; gEnvironment = FskAssociativeArrayNew(); appPath = FskGetApplicationPath(); FskEnvironmentSet("applicationPath", appPath); FskMemPtrDispose(appPath); #if TARGET_OS_KPL KplEnvironmentInitialize(gEnvironment); #elif TARGET_OS_ANDROID FskEnvironmentSet("application", "PLAY"); #elif TARGET_OS_WIN32 || TARGET_OS_MAC || TARGET_OS_LINUX FskEnvironmentSet("application", FSK_APPLICATION); #else FskEnvironmentSet("application", "PLAY"); #endif #if TARGET_OS_WIN32 { char name[256], *nameTemp = NULL; UInt16 nameW[256]; char num[32]; DWORD nameSize = sizeof(nameW) / sizeof(UInt16); EXTENDED_NAME_FORMAT exNameFormat = NameSamCompatible; if (GetUserNameExW(exNameFormat, (LPWSTR)nameW, &nameSize)) { FskTextUnicode16LEToUTF8(nameW, nameSize * 2, &nameTemp, NULL); FskStrCopy(name, nameTemp); FskEnvironmentSet("loginName", name); FskMemPtrDispose(nameTemp); } FskEnvironmentSet("OS", "Windows"); FskStrNumToStr(gWindowsVersionInfo.dwMajorVersion, name, sizeof(name)); FskStrCat(name, "."); FskStrNumToStr(gWindowsVersionInfo.dwMinorVersion, num, sizeof(num)); FskStrCat(name, num); FskEnvironmentSet("OSVersion", name); } #elif TARGET_OS_MAC { struct utsname un; char name[256], *model; SInt32 gen; #if TARGET_OS_IPHONE FskEnvironmentSet("OS", "iPhone"); #else FskEnvironmentSet("OS", "Mac"); #endif FskCocoaSystemGetVersion(name); FskEnvironmentSet("OSVersion", name); if (uname(&un) == 0) { model = un.machine; if (FskStrCompareWithLength(model, "iPhone", 6) == 0) gen = FskStrToNum(model + 6); else if (FskStrCompareWithLength(model, "iPad", 4) == 0) { gen = FskStrToNum(model + 4); if (gen == 3) { SInt32 minor = FskStrToNum(model + 6); if (minor == 4) /* 4th gen */ gen = 5; else gen = 4; /* Only the 3rd gen iPad doesn't follow the numbering system */ } else gen += 2; } else if (FskStrCompareWithLength(model, "iPod", 4) == 0) { gen = FskStrToNum(model + 4); if (gen > 1) --gen; } else gen = 99; } else { model = "unknown"; gen = 99; } FskEnvironmentSet("Model", model); FskStrNumToStr(gen, name, sizeof(name)); FskEnvironmentSet("Generation", name); } #elif TARGET_OS_LINUX { struct utsname name; uname(&name); if (getlogin()) FskEnvironmentSet("loginName", getlogin()); else FskEnvironmentSet("loginName", "User"); FskEnvironmentSet("OS", name.sysname); FskEnvironmentSet("OSVersion", name.release); //@@ } #endif return kFskErrNone; }
static void httpProcessRequestHeaders(FskHTTPServerRequest request) { char *str; FskHeaders* headers = request->requestHeaders; UInt32 version = FskHeaderHTTPVersion(headers); char* host = FskHeaderFind(kFskStrHost, headers); char* uri = FskHeaderURI(headers); char* filename = FskHeaderFilename(headers); request->state = kHTTPReadRequestBody; if (FskStrCompareWithLength(uri, "http://", 7) == 0) { // remove host from filename char* p = FskStrStr(filename, "://") + 3; p = FskStrChr(p, '/') + 1; FskMemMove(filename, p, FskStrLen(p) + 1); } else { if (host) { if (FskMemPtrNewClear(FskStrLen(host) + FskStrLen(uri) + 9, &str) != kFskErrNone) headers->responseCode = 500; else { FskStrCat(str, "http://"); FskStrCat(str, host); FskStrCat(str, "/"); FskStrCat(str, headers->URI); FskMemPtrDispose(headers->URI); headers->URI = str; } } else if (version >= kFskHTTPVersion1dot1) headers->responseCode = 400; else if (version == kFskHTTPVersion1dot0) { if (FskMemPtrNewClear(FskStrLen(uri) + 9, &str) != kFskErrNone) headers->responseCode = 500; else { FskStrCat(str, "http:///"); FskStrCat(str, headers->URI); FskMemPtrDispose(headers->URI); headers->URI = str; } } } str = FskHeaderFind(kFskStrConnection, request->requestHeaders); if (str && FskStrCompareCaseInsensitiveWithLength(str, kFskStrClose, 5) == 0) request->keepAlive = false; else request->keepAlive = true; str = FskHeaderFind(kFskStrContentLength, request->requestHeaders); if (str) { request->requestBodyContentLength = FskStrToNum(str); request->stats.expectedBytesToReceive = FskStrToNum(str); } else request->stats.expectedBytesToReceive = 0; str = FskHeaderFind(kFskStrTransferEncoding, request->requestHeaders); if (str && (FskStrCompareCaseInsensitiveWithLength(str, kFskStrChunked, FskStrLen(kFskStrChunked)) == 0)) request->requestBodyChunked = true; else request->requestBodyChunked = false; doCallCondition(request->http->callbacks->requestCondition, request, kFskHTTPConditionRequestReceivedRequestHeaders, request->refCon); if (NULL != (str = FskHeaderFind(kFskStrExpect, request->requestHeaders))) { if (0 == FskStrCompareCaseInsensitive(kFskStr100Continue, str)) request->state = kHTTPFulfillExpectation; else request->state = kHTTPDenyExpectation; } }
FskErr KprLibraryServerRequestConditionCallback(FskHTTPServerRequest request, UInt32 condition, void *refCon) { FskErr err = kFskErrNone; KprLibraryServer self = request->http->refCon; KprLibrarySession session = refCon; switch (condition) { case kFskHTTPConditionConnectionInitialized: case kFskHTTPConditionNoSocket: case kFskHTTPConditionRequestReceivedRequestHeaders: break; case kFskHTTPConditionRequestRequestFinished: { FskHeaders *headers; UInt32 queryIndex; KprLibraryQuery query; bailIfError(KprLibrarySessionNew(&session, request)); FskInstrumentedItemSetOwner(session, self); headers = FskHTTPServerRequestGetRequestHeaders(request); queryIndex = FskStrToNum(headers->filename); FskMutexAcquire(self->queryMutex); query = self->queries[queryIndex % kQueryCount]; if (query && (query->index == queryIndex)) { session->info = FskStrDoCopy(query->info); session->kind = query->kind; session->mime = FskStrDoCopy(query->mime); session->url = FskStrDoCopy(query->url); if (query->authorization) session->authorization = FskStrDoCopy(query->authorization); } else err = kFskErrNotFound; FskMutexRelease(self->queryMutex); if (kFskErrNone == err) { KprURLSplit(session->url, &session->parts); if (0 == FskStrCompareWithLength(session->url, "file", 4)) err = KprFileServerOpen(session); else if (0 == FskStrCompareWithLength(session->url, "http", 4)) { session->http.location = FskStrDoCopy(session->url); err = KprProxyServerOpen(session); } else err = KprDataServerOpen(session); } if (kFskErrNeedMoreTime == err) FskHTTPServerRequestSuspend(request); else session->error = err; err = kFskErrNone; } break; case kFskHTTPConditionRequestGenerateResponseHeaders: if (session) { FskHeaders *responseHeaders = FskHTTPServerRequestGetResponseHeaders(request); if (session->error) { if (kFskErrNotFound == session->error) responseHeaders->responseCode = 404; else responseHeaders->responseCode = 500; FskHeaderAddString(kFskStrContentLength, "0", responseHeaders); FskInstrumentedItemPrintfNormal(session, "response headers error %ld", session->error); } else if (session->file.file) KprFileServerGenerateResponseHeaders(session, responseHeaders); else if (session->http.client) KprProxyServerGenerateResponseHeaders(session, responseHeaders); else KprDataServerGenerateResponseHeaders(session, responseHeaders); } break; case kFskHTTPConditionConnectionTerminating: err = kFskErrUnimplemented; //@@ or hang on exit... weird. case kFskHTTPConditionRequestResponseFinished: case kFskHTTPConditionRequestErrorAbort: if (session) KprLibrarySessionDispose(session); break; default: err = kFskErrUnimplemented; break; } bail: return err; }
FskErr mp3SpoolerCallback(void *clientRefCon, UInt32 operation, void *param) { mp3Reader state = clientRefCon; FskErr err = kFskErrNone; switch (operation) { case kFskMediaSpoolerOperationDataReady: state->spoolerPosition += (UInt32)param; if (state->reader->mediaState < kFskMediaPlayerStateStopped) { if (state->id3.data) { UInt32 percent, bytesRead; void *buffer; if (state->id3.size != state->id3.offset) { err = FskMediaSpoolerRead(state->spooler, state->id3.offset, (UInt32)(state->id3.size - state->id3.offset), &buffer, &bytesRead); if (kFskErrNone == err) { FskMemMove((char *)state->id3.data + state->id3.offset, buffer, bytesRead); state->id3.offset += bytesRead; } } percent = (UInt32)((((float)state->id3.offset) / ((float)state->id3.size)) * 100.0); if (percent < 100) (state->reader->doSetState)(state->reader, kFskMediaPlayerStateInstantiatingProgress + percent); else err = mp3Instantiate(state); } else err = mp3Instantiate(state); } break; case kFskMediaSpoolerOperationSetHeaders: { FskHeaders *headers = param; FskHeaderAddString("icy-metadata", "1", headers); } break; case kFskMediaSpoolerOperationGetHeaders: { FskHeaders *headers = param; char *value = FskHeaderFind("icy-metaint", headers); state->icy.metaInt = (NULL != value) ? FskStrToNum(value) : 0; state->icy.nextMetaPosition = state->icy.metaInt; if ((NULL == state->mi.meta) || (kFskErrNone != FskMediaMetaDataGet(state->mi.meta, "FullName", 0, NULL, NULL))) { value = FskHeaderFind("icy-name", headers); if (NULL == value) value = FskHeaderFind("x-audiocast-name", headers); state->icy.title = FskStrDoCopy(value); } state->icy.isProtocol = 0 == FskStrCompare(headers->protocol, "ICY"); value = FskHeaderFind("Server", headers); if (NULL != value) { if (0 == FskStrCompareWithLength("Orbiter", value, 7)) { if (!state->isOrbiter) { state->isOrbiter = true; state->reader->needsIdle = true; FskTimeGetNow(&state->orbStart); } } } if (state->icy.isNanocaster) { value = FskHeaderFind("icy-genre", headers); if ((NULL != value) && (0 == FskStrCompareCaseInsensitive(value, "error"))) (state->reader->doSetState)(state->reader, kFskMediaPlayerStateFailed); } value = FskHeaderFind("availableSeekRange.dlna.org", headers); if (value && (0 == FskStrCompareWithLength("1 npt=", value, 6))) { char *dash = FskStrChr(value + 6, '-'); double duration; if (dash && (kFskErrNone == FskMediaParseNPT(dash + 1, &duration))) state->dlnaDuration = duration; } } break; case kFskMediaSpoolerOperationGetURI: state->spoolerPosition = ((FskMediaSpoolerGetURI)param)->position; break; } return err; }
Boolean KprServiceAccept(KprService self, KprMessage message) { return !FskStrCompareWithLength(message->url, self->id, FskStrLen(self->id)); }
FskErr FskTextFreeTypeInstallFonts(char* fontsPath, char* defaultFont) { FskErr err = kFskErrNone; FskTextEngine fte; char *fromDirectory = NULL; char* fromPath = NULL; FskDirectoryIterator iterator = NULL; char *name = NULL; UInt32 type; #if TARGET_OS_ANDROID char *toDirectory = NULL; char* toPath = NULL; FskFileInfo itemInfo; FskFileMapping map = NULL; unsigned char *data; FskInt64 dataSize; FskFile file = NULL; #endif err = FskTextEngineNew(&fte, NULL); if (err) goto bail; fromDirectory = FskEnvironmentDoApply(FskStrDoCopy(fontsPath)); if (!fromDirectory) { err = kFskErrMemFull; goto bail; } #if TARGET_OS_ANDROID if (!FskStrCompareWithLength(fromDirectory, "/data/app/", 10)) { err = FskDirectoryGetSpecialPath(kFskDirectorySpecialTypeApplicationPreference, false, NULL, &toDirectory); if (err) goto bail; } #endif err = FskDirectoryIteratorNew(fromDirectory, &iterator, 0); if (err) goto bail; while (kFskErrNone == FskDirectoryIteratorGetNext(iterator, &name, &type)) { if (type == kFskDirectoryItemIsFile) { fromPath = FskStrDoCat(fromDirectory, name); if (!fromPath) { err = kFskErrMemFull; goto bail; } FskDebugStr("from %s", fromPath); #if TARGET_OS_ANDROID if (toDirectory) { toPath = FskStrDoCat(toDirectory, name); FskDebugStr("to %s", toPath); if (kFskErrNone != FskFileGetFileInfo(toPath, &itemInfo)) { err = FskFileMap(fromPath, &data, &dataSize, 0, &map); if (err) goto bail; err = FskFileCreate(toPath); if (err) goto bail; err = FskFileOpen(toPath, kFskFilePermissionReadWrite, &file); if (err) goto bail; err = FskFileWrite(file, dataSize, data, NULL); if (err) goto bail; FskFileClose(file); file = NULL; FskFileDisposeMap(map); map = NULL; } FskDebugStr("add %s", toPath); FskTextAddFontFile(fte, toPath); FskMemPtrDisposeAt(&toPath); } else #endif FskTextAddFontFile(fte, fromPath); FskMemPtrDisposeAt(&fromPath); } FskMemPtrDisposeAt(&name); } #if TARGET_OS_ANDROID if (gAndroidCallbacks->getModelInfoCB) { char* osVersion; gAndroidCallbacks->getModelInfoCB(NULL, &osVersion, NULL, NULL, NULL); if ((FskStrStr(osVersion, "android.5") == osVersion) // for KPR applications || (FskStrStr(osVersion, "5.") == osVersion)) { // for tests BAIL_IF_ERR(err = FskFTAddMapping("/system/etc/fonts.xml")); } if ((FskStrStr(osVersion, "android.4") == osVersion) // for KPR applications || (FskStrStr(osVersion, "4.") == osVersion)) { // for tests BAIL_IF_ERR(err = FskFTAddMapping("/system/etc/system_fonts.xml")); err = FskFTAddMapping("/vendor/etc/fallback_fonts.xml"); if (err != kFskErrFileNotFound) BAIL(err); BAIL_IF_ERR(err = FskFTAddMapping("/system/etc/fallback_fonts.xml")); } else { defaultFont = "Droid Sans"; BAIL_IF_ERR(err = FskFTAddMapping(NULL)); } } #endif if (defaultFont) FskTextDefaultFontSet(fte, defaultFont); bail: #if TARGET_OS_ANDROID if (file) FskFileClose(file); if (map) FskFileDisposeMap(map); FskMemPtrDispose(toPath); FskMemPtrDispose(toDirectory); #endif FskMemPtrDispose(name); FskDirectoryIteratorDispose(iterator); FskMemPtrDispose(fromPath); FskMemPtrDispose(fromDirectory); FskTextEngineDispose(fte); return err; }
FskErr KprURLToPath(char* url, char** result) { FskErr err = kFskErrNone; unsigned char* src; SInt32 size; unsigned char c, d; unsigned char* dst; if (FskStrCompareWithLength(url, "file://", 7)) { #if TARGET_OS_WIN32 if (url[0] == '/') *result = FskStrDoCopy(url + 1); else *result = FskStrDoCopy(url); #else *result = FskStrDoCopy(url); #endif bailIfNULL(*result); goto bail; } #if TARGET_OS_WIN32 if ((url[7] == '/') && (url[8] == '/')) url += 5; else if (url[7] == '/') url += 8; else url += 7; // wrong file://C: #else if (url[7] == '/') url += 7; else return kFskErrInvalidParameter; #endif src = (unsigned char*)url; size = 0; while ((c = *src++)) { if (c == '%') { c = *src++; if (c == 0) return kFskErrInvalidParameter; d = mxURIXDigit(c) << 4; c = *src++; if (c == 0) return kFskErrInvalidParameter; d += mxURIXDigit(c); if ((d < 128) && (gxURIReservedSet[(int)d])) size += 3; else size += 1; } else size += 1; } size += 1; bailIfError(FskMemPtrNew(size, result)); src = (unsigned char*)url; dst = (unsigned char*)*result; while ((c = *src++)) { if (c == '%') { c = *src++; d = mxURIXDigit(c) << 4; c = *src++; d += mxURIXDigit(c); if ((d < 128) && (gxURIReservedSet[(int)d])) { *dst++ = *(src - 3); *dst++ = *(src - 2); *dst++ = *(src - 1); } else *dst++ = d; } else *dst++ = c; } *dst = 0; bail: return err; }