Boolean KprMQTTIsValidTopic(const char *topic, Boolean allowWildcard) { UInt32 len = FskStrLen(topic), len2, pos; // A topic must be at least one character long. if (len == 0) return false; // The length is limited to 64k if (len > 65535LU) return false; if (allowWildcard) { char *multi = FskStrChr(topic, kMQTTMultiLevelSeparator), *single; if (multi != NULL) { len2 = FskStrLen(multi); // The multi-level wildcard must be the last character used within the topic tree. if (len2 > 1 /* not the last character */) return false; if (len > len2 /* not the 1st character */) { pos = len - len2 - 1; if (topic[pos] != kMQTTTopicLevelSeparator) return false; } } single = FskStrChr(topic, kMQTTSingleLevelSeparator); while (single != NULL) { len2 = FskStrLen(single); // It must be used next to the topic level separator, except when it is specified on its own. if (len2 > 1 /* not the last character */) { if (single[1] != kMQTTTopicLevelSeparator) return false; } if (len > len2 /* not the 1st character */) { pos = len - len2 - 1; if (topic[pos] != kMQTTTopicLevelSeparator) return false; } single = FskStrChr(single + 1, kMQTTSingleLevelSeparator); } } else { // The multi-level wildcard and single-level wildcard can be used for subscriptions, // but they cannot be used within a topic by the publisher of a message. if (FskStrChr(topic, kMQTTMultiLevelSeparator) != NULL || FskStrChr(topic, kMQTTSingleLevelSeparator) != NULL) return false; } return true; }
FskErr KprZeroconfServiceNewAuthority(char* type, char** it) { #define kKPRZeroconfKinomaServe "_%s._tcp." FskErr err = kFskErrNone; char* authority = type + 1; char* dot = FskStrChr(type, '.'); char* ptr; bailIfNULL(dot); *dot = 0; authority = FskStrDoCopy(type + 1); *dot = '.'; bailIfNULL(authority); for (ptr = FskStrChr(authority, '_'); ptr; ptr = FskStrChr(ptr, '_')) *ptr = '.'; *it = authority; bail: return err; }
FskErr KprZeroconfServiceNewType(char* authority, char** it) { #define kKPRZeroconfKinomaServe "_%s._tcp." FskErr err = kFskErrNone; char* type = NULL; char* ptr; UInt32 length = FskStrLen(authority); UInt32 size = length + FskStrLen(kKPRZeroconfKinomaServe); bailIfError(FskMemPtrNewClear(size, &type)); snprintf(type, size, kKPRZeroconfKinomaServe, authority); type[length + 1] = 0; for (ptr = FskStrChr(type, '.'); ptr; ptr = FskStrChr(ptr, '.')) *ptr = '_'; type[length + 1] = '.'; *it = type; bail: return err; }
// ------------------------------------------------------------------------ UInt32 FskHeaderHTTPVersion(FskHeaders *headers) { if (headers->protocol) { char *pos, *tmp; int major = 0, minor = 0; tmp = FskStrDoCopy(headers->protocol); pos = FskStrChr(headers->protocol, '/'); if (pos) { major = FskStrToNum(pos+1); pos = FskStrChr(pos, '.'); if (pos) minor = FskStrToNum(pos+1); } FskMemPtrDispose(tmp); return (major << 16) | minor; } else return 0; }
FskErr KprModulesBasesSetup(char* url, char* path) { FskErr err = kFskErrNone; char* paths = FskEnvironmentGet("modulePath"); UInt32 i = 1; char* colon; if (path) i++; if (paths) { colon = FskStrChr(paths, ';'); while (colon) { i++; colon = FskStrChr(colon + 1, ';'); } i++; } bailIfError(FskMemPtrNewClear(i * sizeof(char*), &gModulesBases)); i = 1; if (path) { bailIfError(KprURLMerge(url, path, &gModulesBases[i])); i++; } if (paths) { path = paths; colon = FskStrChr(path, ';'); while (colon) { *colon = 0; bailIfError(KprURLMerge(url, path, &gModulesBases[i])); *colon = ';'; i++; path = colon + 1; colon = FskStrChr(path, ';'); } bailIfError(KprURLMerge(url, path, &gModulesBases[i])); i++; } gModulesBasesCount = i; bail: return err; }
void Zeroconf_browser_callback(KprZeroconfBrowser self, char* function, KprZeroconfServiceInfo service) { xsBeginHostSandboxCode(self->the, self->code); if (xsTypeOf(self->behavior) == xsUndefinedType) goto bail; xsVars(3); { xsTry { xsVar(0) = xsAccess(self->behavior); xsVar(1) = xsNewInstanceOf(xsObjectPrototype); xsSet(xsVar(1), xsID("name"), xsString(service->name)); xsSet(xsVar(1), xsID("type"), xsString(service->type)); if (service->host) xsSet(xsVar(1), xsID("host"), xsString(service->host)); if (service->ip) { xsSet(xsVar(1), xsID("ip"), xsString(service->ip)); xsSet(xsVar(1), xsID("port"), xsInteger(service->port)); } if (service->txt) { char* txt = service->txt; UInt32 position = 0, size = FskStrLen(txt); UInt32 length = 0; xsVar(2) = xsNewInstanceOf(xsObjectPrototype); xsSet(xsVar(1), xsID("txt"), xsVar(2)); length = txt[position++] & 0xFF; while ((position + length) <= size) { char end; char* equal; if (!length) break; end = txt[position + length]; txt[position + length] = 0; equal = FskStrChr(txt + position, '='); if (equal) { *equal = 0; xsSet(xsVar(2), xsID(txt + position), xsString(equal + 1)); *equal = '='; } txt[position + length] = end; position += length; length = txt[position++] & 0xFF; } } if (xsFindResult(xsVar(0), xsID(function))) { (void)xsCallFunction1(xsResult, xsVar(0), xsVar(1)); } } xsCatch { } } bail: xsEndHostSandboxCode(); }
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; }
Boolean mp3ReaderCanHandle(const char *mimeType) { const char *semi = FskStrChr(mimeType, ';'); UInt32 length = semi ? (UInt32)(semi - mimeType) : FskStrLen(mimeType); if (0 == FskStrCompareCaseInsensitiveWithLength("audio/mpeg", mimeType, length)) return true; if (0 == FskStrCompareCaseInsensitiveWithLength("audio/aac", mimeType, length)) return true; if (0 == FskStrCompareCaseInsensitiveWithLength("audio/vnd.dlna.adts", mimeType, length)) return true; return false; }
void fxReadAddressAutomatic(txMachine* the) { /* read debugAddress and debugAutomatic from a file... */ #if TARGET_OS_ANDROID char *folder = NULL; char *file = FskStrDoCat(folder, "/sdcard/debug.txt"); { #else char *folder; if (kFskErrNone == FskDirectoryGetSpecialPath(kFskDirectorySpecialTypeApplicationPreference, true, NULL, &folder)) { char *file = FskStrDoCat(folder, "debug.txt"); #endif char *data; if (kFskErrNone == FskFileLoad(file, (FskMemPtr *)&data, NULL)) { char *lf = FskStrChr(data, 10); if ((NULL != lf) && (FskStrLen(data) < sizeof(debugAddress))) { *lf = 0; FskStrCopy(debugAddress, data); debugAutomatic = '1' == lf[1]; } FskMemPtrDispose(data); } else { FskECMAScriptGetDebug(&data, NULL, NULL); if (data) { FskStrCopy(debugAddress, data); FskStrCat(debugAddress, ":5002"); debugAutomatic = 1; } } FskMemPtrDispose(file); FskMemPtrDispose(folder); } } void fxSetAddress(txMachine* the, char* theAddress) { c_strcpy(debugAddress, theAddress); fxWriteAddressAutomatic(the); }
// // /etc/vold.fstab // Format: dev_mount <label> <mount_point> <part> <sysfs_path1...> // void scanVoldFstab() { FskErr err; FILE *mntFile; char *mntFileBuffer; int bufEnd = 0; int done = 0; int amt; char *bufPos, *lineEnd; mntFile = FOPEN(VOLD_FSTAB_FILE, "r"); if (NULL == mntFile) { FskAndroidFilesPrintfDebug("failed opening %s - %d\n", VOLD_FSTAB_FILE, errno); // oldscanVolumes(); return; } err = FskMemPtrNew(MOUNT_BUF_SIZE + 1, &mntFileBuffer); BAIL_IF_ERR(err); bufPos = mntFileBuffer; while (!done) { // fill the buffer amt = fread(mntFileBuffer + bufEnd, 1, MOUNT_BUF_SIZE - bufEnd, mntFile); FskAndroidFilesPrintfDebug("fread %x, %d - got %d\n", mntFileBuffer + bufEnd, MOUNT_BUF_SIZE - bufEnd, amt); if (amt > 0) { bufEnd += amt; } mntFileBuffer[bufEnd] = '\0'; FskAndroidFilesPrintfDebug("check while(bufpos...) - %d < %d\n", bufPos, mntFileBuffer + bufEnd); while (bufPos < mntFileBuffer + bufEnd) { extMount mnt = NULL; char fsName[256], fsMnt[256], tmp[256], fsPath[256]; // Format: dev_mount <label> <mount_point> <part> <sysfs_path1...> if (NULL == (lineEnd = FskStrChr(bufPos, kFskLF))) break; bufPos = FskStrNCopyUntilSpace(tmp, bufPos, 255); if (0 != FskStrCompare(tmp, "dev_mount")) { // no dev_mount, move bufPos to end of line and then continue; FskAndroidFilesPrintfDebug("didn't find dev_mount in '%s' - bail\n", tmp); bufPos = lineEnd + 1; continue; } // Format: dev_mount <label> <mount_point> <part> <sysfs_path1...> bufPos = FskStrNCopyUntilSpace(fsName, bufPos, 255); bufPos = FskStrNCopyUntilSpace(fsMnt, bufPos, 255); bufPos = FskStrNCopyUntilSpace(tmp, bufPos, 255); bufPos = FskStrNCopyUntilSpace(fsPath, bufPos, 255); FskAndroidFilesPrintfDebug("got Name: %s Mnt: %s tmp: %s fsPath: %s\n", fsName, fsMnt, tmp, fsPath); err = FskMemPtrNew(sizeof(extMountRec), &mnt); BAIL_IF_ERR(err); mnt->label = FskStrDoCopy(fsName); mnt->mountPoint = FskStrDoCopy(fsMnt); FskAndroidFilesPrintfDebug("Make an external filesystem record with label: %s, mountPoint: %s\n", mnt->label, mnt->mountPoint); FskListAppend(&gExtMounts, mnt); bufPos = lineEnd + 1; } if (amt == 0) { // we read no more done = 1; } else { // push buffer to beginning amt = (mntFileBuffer + bufEnd) - bufPos; FskAndroidFilesPrintfDebug("push unread %d bytes to beginning of buffer\n - mntFileBuffer: %d bufEnd: %d bufPos: %d", amt, mntFileBuffer, bufEnd, bufPos); if (amt > 0) { FskMemCopy(mntFileBuffer, bufPos, amt); bufEnd = amt; } else bufEnd = 0; bufPos = mntFileBuffer; } } bail: fclose(mntFile); }
char *FskUUIDGetForKey(const char *key) { char *uuidStr; FskUUIDRecord uuid; char *uuidCachePath = NULL, *prefFolder; FskFile fref; if (kFskErrNone == FskDirectoryGetSpecialPath(kFskDirectorySpecialTypeApplicationPreference, true, NULL, &prefFolder)) { uuidCachePath = FskStrDoCat(prefFolder, "fskuuidcache.txt"); FskMemPtrDispose(prefFolder); } // load the cache if (NULL == gUUIDCache) { char *uuidCache; FskInt64 cacheSize; gUUIDCache = FskAssociativeArrayNew(); if ((NULL != uuidCachePath) && (kFskErrNone == FskFileLoad(uuidCachePath, (unsigned char **)(void *)&uuidCache, &cacheSize))) { char *p = uuidCache; while (true) { char *uuid = p; char *mykey = FskStrChr(p, '\t'); char *cr; if (NULL == mykey) break; cr = FskStrChr(mykey, '\n'); if (NULL == cr) break; *mykey++ = 0; *cr = 0; FskAssociativeArrayElementSetString(gUUIDCache, mykey, uuid); p = cr + 1; } FskMemPtrDispose(uuidCache); } } // check the cache uuidStr = FskAssociativeArrayElementGetString(gUUIDCache, key); if (uuidStr) { FskMemPtrDispose(uuidCachePath); return uuidStr; } // not in cache FskUUIDCreate(&uuid); uuidStr = FskUUIDtoString_844412(&uuid); FskAssociativeArrayElementSetString(gUUIDCache, key, uuidStr); FskMemPtrDispose(uuidStr); // flush cache FskFileDelete(uuidCachePath); FskFileCreate(uuidCachePath); if (kFskErrNone == FskFileOpen(uuidCachePath, kFskFilePermissionReadWrite, &fref)) { FskAssociativeArrayIterator iterate = FskAssociativeArrayIteratorNew(gUUIDCache); char tab = '\t', cr = '\n'; while (iterate) { FskFileWrite(fref, FskStrLen(iterate->value), iterate->value, NULL); FskFileWrite(fref, 1, &tab, NULL); FskFileWrite(fref, FskStrLen(iterate->name), iterate->name, NULL); FskFileWrite(fref, 1, &cr, NULL); iterate = FskAssociativeArrayIteratorNext(iterate); } FskFileClose(fref); } FskMemPtrDispose(uuidCachePath); return FskAssociativeArrayElementGetString(gUUIDCache, key); // caller doesn't have to dispose }
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; } }
// ------------------------------------------------------------------------ int FskHeadersParseChunk(char *blob, int blobSize, UInt16 headerType, FskHeaders *headers) { char *line = NULL; int lineMax; int copySize, lineSize; char *blobPtr = blob, *pos; int consumed = 0, leftoverSize = 0; char *name, *value; Boolean withComma; int consumedSize = 0; if (headers->headersParsed) return 0; if (headers->leftover) { leftoverSize = FskStrLen(headers->leftover); lineMax = blobSize + leftoverSize + 1; if (kFskErrNone != FskMemPtrRealloc(lineMax, &line)) { consumedSize = -1; goto bail; } FskStrCopy(line, headers->leftover); FskMemPtrDisposeAt((void**)(void*)&headers->leftover); } else { lineMax = blobSize + 1; if (kFskErrNone != FskMemPtrNew(lineMax, &line)) { consumedSize = -1; goto bail; } line[0] = '\0'; } lineSize = FskStrLen(line); while (blobPtr) { copySize = blobSize; pos = FskStrNChr(blobPtr, copySize, kFskLF); if (pos) { int i; copySize = (pos - blobPtr) + 1; for (i=0; i<copySize; i++) { if (blobPtr[i] & 0x80) { headers->headersParsed = true; consumedSize = consumed - leftoverSize; if (consumedSize == 0) consumedSize = -1; goto bail; } if (':' == blobPtr[i]) break; // high ascii allowed after the colon } } FskStrNCopy(&line[lineSize], blobPtr, copySize); line[lineSize+copySize] = '\0'; blobPtr += copySize; blobSize -= copySize; lineSize = FskStrLen(line); if (((2 == lineSize) && (kFskCR == line[0]) && (kFskLF == line[1])) || ((1 == lineSize) && (kFskLF == line[0]))) { // the LF only case is to handle known bug with yimg.com (Yahoo Image server) consumed += lineSize; headers->headersParsed = true; consumedSize = consumed - leftoverSize; goto bail; } if (!pos) { if (lineSize) { headers->leftover = FskStrDoCopy(line); consumed += lineSize; } consumedSize = consumed - leftoverSize; goto bail; } consumed += lineSize; if (NULL == headers->protocol) { if ((-1 == sParseStartLine(line, headerType, headers) || (NULL == headers->protocol))) { consumedSize = -1; goto bail; } lineSize = 0; line[0] = '\0'; continue; } withComma = true; if (FskStrIsSpace(*line)) { withComma = false; name = headers->lastName; value = line; } else { name = FskStrStripHeadSpace(line); value = FskStrChr(line, ':'); } if (value) { *value++ = '\0'; value = FskStrStripHeadSpace(value); FskStrStripTailSpace(value); } if (NULL == name) { consumedSize = -1; goto bail; } FskStrStripTailSpace(name); if (headers->flags & kFskHeadersDoNotMergeDuplicates) { // raw headers FskAssociativeArrayNameList list; SInt32 nameLen = FskStrLen(name) + 1; SInt32 valueType = kFskStringType; UInt32 valueSize = FskStrLen(value) + 1; if (NULL == value) { consumedSize = -1; goto bail; } //bailIfError(FskMemPtrNew(sizeof(FskAssociativeArrayNameListRec) + nameLen + valueSize, &list)); if (kFskErrNone == FskMemPtrNew(sizeof(FskAssociativeArrayNameListRec) + nameLen + valueSize, &list)) { unsigned char *d = list->data; // name FskMemMove(d, name, nameLen); list->name = (char *)d; d += nameLen; // value FskMemMove(d, value, valueSize); list->value = (char *)d; list->valueSize = valueSize; list->valueType = valueType; list->next = NULL; FskListPrepend(headers->theHeaders, list); } } else FskAssociativeArrayElementCatenateString(headers->theHeaders, name, value, withComma); if (name != headers->lastName) { FskMemPtrDispose(headers->lastName); headers->lastName = FskStrDoCopy(name); } line[0] = '\0'; lineSize = 0; } if (lineSize) { headers->leftover = FskStrDoCopy(line); consumed += lineSize; } consumedSize = consumed - leftoverSize; bail: if (line) FskMemPtrDispose(line); return consumedSize; }
// ------------------------------------------------------------------------ static int sParseStartLine(char *startLine, UInt16 headerType, FskHeaders *headers) { FskErr err; int l; const char *p; char *c = startLine; char *firstPart; // Get method or protocol p = c; c = FskStrChr(c, ' '); if (!c) return -1; l = (c++) - p; err = FskMemPtrNew(l+1, &firstPart); if (err != kFskErrNone) return -1; FskStrNCopy(firstPart, p, l); firstPart[l] = '\0'; if (kFskHeaderTypeResponse == headerType) headers->protocol = firstPart; else headers->method = firstPart; c = FskStrStripHeadSpace(c); // skip over space headers->headerType = headerType; if (kFskHeaderTypeResponse == headerType) { // Get response code and message (if message not in HTTP_Responses) headers->responseCode = FskStrToNum(c); if (headers->flags & kFskHeadersNonStandardResponseReasonPhrase) { c = FskStrChr(c, ' '); if (c) { char *r, *s; s = FskStrStripHeadSpace(c); r = FskFindResponse(headers->responseCode); if (!r || (0 != FskStrCompareCaseInsensitiveWithLength(s, r, FskStrLen(r)))) { headers->responseReasonPhrase = FskStrDoCopy(s); if (NULL != headers->responseReasonPhrase) FskStrStripTailSpace(headers->responseReasonPhrase); } } } } else { char *s, *t = NULL; char *uri = NULL; // Get URI if ((*c == '/') && !(headers->flags & kFskHeadersDoNotStripURILeadingSlash)) c++; s = FskStrChr(c, ' '); if (!s) { headers->responseCode = 400; return -1; } headers->protocol = FskStrDoCopy(s + 1); if (NULL != headers->protocol) FskStrStripTailSpace(headers->protocol); BAIL_IF_ERR(FskMemPtrNew((s-c)+1, &uri)); BAIL_IF_ERR(FskMemPtrNew((s-c)+1, &t)); FskMemCopy(uri, c, s-c); uri[s-c] = '\0'; s = FskStrChr(uri, '?'); if (s) *s = 0; FskStrDecodeEscapedChars(uri, t); if (s) { *s = '?'; FskStrCat(t, s); } headers->URI = FskStrDoCopy(t); // Break URI into filename and parameters s = FskStrChr(t, '?'); if (!s) { headers->filename = FskStrDoCopy(t); } else { // URI has parameters *s++ = '\0'; // cap off the filename headers->filename = FskStrDoCopy(t); headers->parameters = FskAssociativeArrayNew(); while (s) { char *name = s; char *value = FskStrChr(name, '='); if (!value) break; s = FskStrChr(value, '&'); *value++ = '\0'; // cap off the name if (s) *s++ = '\0'; // cap off the value FskAssociativeArrayElementSetString(headers->parameters, name, value); } } bail: FskMemPtrDispose(uri); FskMemPtrDispose(t); } return headers->headerType; }
char *FskEnvironmentApply(char *input) { FskErr err; char *p; char *out = NULL; char *start, *end; UInt32 outCount = 0; char tempName[256]; UInt32 nameLen; char *value; Boolean doApply = false; if (NULL == input) goto bail; if ('"' == *input) { // special case for string literal - useful when there is leading or trailing white space or [ or ] in the string UInt32 len = FskStrLen(input); if ('"' == input[len - 1]) { err = FskMemPtrNew(len - 1, &out); BAIL_IF_ERR(err); out[len - 2] = 0; FskMemMove(out, input + 1, len - 2); goto bail; } } // scan p = input; while (true) { start = FskStrChr(p, '['); if (NULL == start) { outCount += FskStrLen(p); break; } outCount += start - p; end = FskStrChr(start + 1, ']'); if (NULL == end) { outCount += FskStrLen(start); break; } nameLen = end - start - 1; if (nameLen > (sizeof(tempName) - 1)) goto bail; FskMemMove(tempName, start + 1, nameLen); tempName[nameLen] = 0; value = FskEnvironmentGet(tempName); outCount += FskStrLen(value); doApply = true; p = end + 1; } if (!doApply) goto bail; // replace err = FskMemPtrNew(outCount + 1, &out); BAIL_IF_ERR(err); out[0] = 0; p = input; while (true) { start = FskStrChr(p, '['); if (NULL == start) { FskStrCat(out, p); break; } outCount += start - p; end = FskStrChr(start + 1, ']'); if (NULL == end) { FskStrCat(out, start); break; } FskStrNCat(out, p, start - p); nameLen = end - start - 1; FskMemMove(tempName, start + 1, nameLen); tempName[nameLen] = 0; FskStrCat(out, FskEnvironmentGet(tempName)); p = end + 1; } bail: return out; }
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; }
FskErr mp3RefillReadBuffer(mp3Reader state, UInt32 minimumBytesNeeded) { FskErr err = kFskErrNone; UInt32 bytesInBuffer = (UInt32)(state->readBufferEnd - state->readBufferPtr); UInt32 bytesRead; void *buffer; Boolean firstTime = true; FskMemMove(state->readBuffer, state->readBufferPtr, bytesInBuffer); state->readBufferPtr = state->readBuffer; state->readBufferEnd = state->readBufferPtr + bytesInBuffer; while (true) { UInt32 bytesToRead = kMP3ReadBufferSize - bytesInBuffer; if (state->spoolerSize && ((state->position + bytesToRead) > state->spoolerSize)) { bytesToRead = (UInt32)(state->spoolerSize - state->position); if (0 == bytesToRead) { err = kFskErrEndOfFile; goto bail; } } if (0 != state->icy.metaInt) { if (0 != state->icy.metaBytesToCollect) { err = FskMediaSpoolerRead(state->spooler, state->position, state->icy.metaBytesToCollect, &buffer, &bytesRead); if (kFskErrNone != err) goto readErr; state->position += bytesRead; err = FskMemPtrRealloc(state->icy.metaBytesCollected + bytesRead + 1, &state->icy.metaBytes); if (err) return err; FskMemMove(state->icy.metaBytes + state->icy.metaBytesCollected, buffer, bytesRead); state->icy.metaBytes[state->icy.metaBytesCollected + bytesRead] = 0; state->icy.metaBytesCollected += bytesRead; state->icy.metaBytesToCollect -= bytesRead; if (0 == state->icy.metaBytesToCollect) { if (0 == FskStrCompareCaseInsensitiveWithLength((char *)state->icy.metaBytes, "StreamTitle=", 12)) { char *start = (char *)state->icy.metaBytes + 13; char *end = start; char *dash; FskMediaPropertyValueRecord prop; while (true) { end = FskStrChr(end, start[-1]); if (NULL == end) break; if ((0 != end[1]) && (';' != end[1])) { end += 1; continue; } break; } if (end) *end = 0; while (true) { if (kFskErrNone != FskMediaMetaDataRemove(state->mi.meta, "FullName", 0)) break; } dash = FskStrStr(start, " - "); if (NULL != dash) { while (true) { if (kFskErrNone != FskMediaMetaDataRemove(state->mi.meta, "Artist", 0)) break; } *dash = 0; prop.type = kFskMediaPropertyTypeString; prop.value.str = icyString(start); FskMediaMetaDataAdd(state->mi.meta, "Artist", NULL, &prop, kFskMediaMetaDataFlagOwnIt); prop.type = kFskMediaPropertyTypeString; prop.value.str = icyString(dash + 3); FskMediaMetaDataAdd(state->mi.meta, "FullName", NULL, &prop, kFskMediaMetaDataFlagOwnIt); } else { prop.type = kFskMediaPropertyTypeString; prop.value.str = icyString(start); FskMediaMetaDataAdd(state->mi.meta, "FullName", NULL, &prop, kFskMediaMetaDataFlagOwnIt); } FskMediaReaderSendEvent(state->reader, kFskEventMediaPlayerMetaDataChanged); } FskMemPtrDisposeAt((void**)(void*)(&state->icy.metaBytes)); } continue; } else if (state->position == state->icy.nextMetaPosition) { err = FskMediaSpoolerRead(state->spooler, state->position, 1, &buffer, &bytesRead); if (kFskErrNone != err) goto readErr; state->position += 1; state->icy.metaBytesToCollect = ((unsigned char *)buffer)[0] * 16; state->icy.metaBytesCollected = 0; state->icy.nextMetaPosition += 1 + state->icy.metaBytesToCollect + state->icy.metaInt; continue; } else if ((state->position <= state->icy.nextMetaPosition) && (state->icy.nextMetaPosition < (state->position + bytesToRead))) bytesToRead = (UInt32)(state->icy.nextMetaPosition - state->position); } err = FskMediaSpoolerRead(state->spooler, state->position, bytesToRead, &buffer, &bytesRead); readErr: if (err) { if (false == firstTime) { err = kFskErrNone; break; } goto bail; } FskMemMove(state->readBufferEnd, buffer, bytesRead); state->position += bytesRead; state->readBufferEnd += bytesRead; bytesInBuffer = (UInt32)(state->readBufferEnd - state->readBufferPtr); if ((kMP3ReadBufferSize == bytesInBuffer) || (bytesInBuffer >= minimumBytesNeeded)) break; firstTime = false; } if (bytesInBuffer < minimumBytesNeeded) { err = kFskErrNeedMoreTime; goto bail; } bail: return err; }
void fxWriteAddressAutomatic(txMachine* the) { /* write debugAddress and debugAutomatic to a file... */ #if TARGET_OS_ANDROID char *folder = NULL; char *file = FskStrDoCat(folder, "/sdcard/debug.txt"); { #else char *folder; if (kFskErrNone == FskDirectoryGetSpecialPath(kFskDirectorySpecialTypeApplicationPreference, true, NULL, &folder)) { char *file = FskStrDoCat(folder, "debug.txt"); #endif FskFile fref; FskFileDelete(file); FskFileCreate(file); if (kFskErrNone == FskFileOpen(file, kFskFilePermissionReadWrite, &fref)) { char *data = FskStrDoCat(debugAddress, debugAutomatic ? "\n1\n" : "\n0\n"); if (data) { FskFileWrite(fref, FskStrLen(data), data, NULL); FskFileClose(fref); FskMemPtrDispose(data); } } } } #endif /* !KPR_CONFIG */ void fxReadBreakpoints(txMachine* the) { char *breakpoints; FskMemPtr file = NULL; FskInt64 fileSize; char *p; FskECMAScriptGetDebug(NULL, &breakpoints, NULL); if ((NULL == breakpoints) || (0 == *breakpoints)) goto bail; if (kFskErrNone != FskFileLoad(breakpoints, &file, &fileSize)) goto bail; p = (char *)file; while (true) { char *path = p; char *line = FskStrChr(p, '\t'); char *cr; if (NULL == line) break; cr = FskStrChr(line, '\n'); if (NULL == cr) break; *line++ = 0; *cr = 0; fxSetBreakpoint(the, path, line); p = cr + 1; } bail: FskMemPtrDispose(file); }
void KPR_shell_splitError(xsMachine* the) { xsStringValue string, p, q; char c; xsIndex ids[4]; size_t offsets[4], lengths[4]; int i; xsVars(1); string = p = xsToString(xsArg(0)); ids[0] = xsID_path; offsets[0] = p - string; c = *p; if (c == '/') p = FskStrChr(p, ':'); else if (('A' <= c) && (c <= 'Z') && (*(p + 1) == ':')) p = FskStrChr(p + 2, ':'); else goto bail; if (!p) goto bail; ids[1] = xsID_line; q = p - 1; c = *q; if (c == ')') { q--; while ((q > string) && ((c = *q)) && ('0' <= c) && (c <= '9')) q--; if (c != '(') goto bail; lengths[0] = q - string; offsets[1] = q + 1 - string; lengths[1] = (p - q) - 2; } else { lengths[0] = p - string; p++; offsets[1] = p - string; while (((c = *p)) && ('0' <= c) && (c <= '9')) p++; if (c != ':') goto bail; lengths[1] = (p - string) - offsets[1]; } p++; c = *p; if (('0' <= c) && (c <= '9')) { p++; while (((c = *p)) && ('0' <= c) && (c <= '9')) p++; if (c != ':') goto bail; p++; c = *p; } if (c != ' ') goto bail; p++; ids[2] = xsID_kind; offsets[2] = p - string; p = FskStrChr(p, ':'); if (!p) goto bail; lengths[2] = (p - string) - offsets[2]; p++; c = *p; if (c != ' ') goto bail; p++; ids[3] = xsID_reason; offsets[3] = p - string; lengths[3] = FskStrLen(p); xsResult = xsNewInstanceOf(xsObjectPrototype); for (i = 0; i < 4; i++) { xsVar(0) = xsStringBuffer(NULL, lengths[i]); string = xsToString(xsArg(0)); FskMemCopy(xsToString(xsVar(0)), string + offsets[i], lengths[i]); xsNewHostProperty(xsResult, ids[i], xsVar(0), xsDefault, xsDontScript); } bail: return; }
// scanProcMount void scanProcMount() { FskErr err; FILE *mntFile = NULL; char *mntFileBuffer; int bufEnd = 0; int done = 0; int amt; char *bufPos, *lineEnd, *path; extMount ext = NULL; fstabDesc fsDesc = NULL; // the default addVolume(gAndroidCallbacks->getStaticDataDirCB(), kFskVolumeTypeFixed, 0); // and the Jellybean user-space addVolume(gAndroidCallbacks->getStaticExternalDirCB(), kFskVolumeTypeSDMemory, 0); // read mount file err = FskMemPtrNew(MOUNT_BUF_SIZE+1, &mntFileBuffer); BAIL_IF_ERR(err); bufPos = mntFileBuffer; mntFile = FOPEN(LINUX_MOUNT_FILE, "r"); if (NULL == mntFile) { FskAndroidFilesPrintfDebug("opening %s - %d\n", LINUX_MOUNT_FILE, errno); return; } while (!done) { // fill the buffer amt = fread(mntFileBuffer + bufEnd, 1, MOUNT_BUF_SIZE - bufEnd, mntFile); mntFileBuffer[bufEnd + amt + 1] = '\0'; FskAndroidFilesPrintfDebug("fread %x, %d - got %d\n", mntFileBuffer + bufEnd, MOUNT_BUF_SIZE - bufEnd, amt); if (amt > 0) bufEnd += amt; FskAndroidFilesPrintfDebug("check while(bufpos...) - %p < %p (%d left)\n", bufPos, mntFileBuffer + bufEnd, mntFileBuffer+bufEnd - bufPos); while (bufPos < mntFileBuffer + bufEnd) { char fsName[256], fsMnt[256], fsType[32]; // until we have a full line if (NULL == (lineEnd = FskStrChr(bufPos, kFskLF))) break; bufPos = FskStrNCopyUntilSpace(fsName, bufPos, 255); bufPos = FskStrNCopyUntilSpace(fsMnt, bufPos, 255); bufPos = FskStrNCopyUntilSpace(fsType, bufPos, 31); FskAndroidFilesPrintfDebug("got Name: %s Mnt: %s Type: %s\n", fsName, fsMnt, fsType); path = fsMnt; if ((ext = extMountsContain(path))) { FskAndroidFilesPrintfDebug("found path in external mounts %s\n", path); fsDesc = extMountToType(ext); if (fsDesc) addVolume(path, fsDesc->type, fsDesc->removable); else addVolume(path, kFskVolumeTypeSDMemory, 1); goto nextLine; } FskAndroidFilesPrintfDebug(" - didn't find path in external mounts %s\n", path); if (0 == FskStrCompare(fsType, "vfat") || 0 == FskStrCompare(fsType, "fuse")) { if (0 != FskStrStr(fsMnt, "emulated")) { FskAndroidFilesPrintfDebug(" - emulated - ignore\n"); goto nextLine; } path = fsMnt; FskAndroidFilesPrintfDebug(" - got a vfat (or fuse) - path is %s\n", path); if (0 == FskStrStr(path, "/asec")) { FskAndroidFilesPrintfDebug(" - vfat without asec: %s\n", path); addVolume(path, kFskVolumeTypeSDMemory, 1); } else { FskAndroidFilesPrintfDebug(" - vfat with asec - ignore - %s\n", path); } } nextLine: bufPos = lineEnd + 1; } if (amt == 0) { // we read no more done = 1; } else { // push buffer to beginning amt = (mntFileBuffer + bufEnd) - bufPos; FskAndroidFilesPrintfDebug("push unread %d bytes to beginning of buffer\n - mntFileBuffer: %d bufEnd: %d bufPos: %d\n", amt, mntFileBuffer, bufEnd, bufPos); if (amt > 0) FskMemCopy(mntFileBuffer, bufPos, amt); bufPos = mntFileBuffer; bufEnd -= amt; } } bail: if (NULL != mntFile) fclose(mntFile); }