// ------------------------------------------------------------------------ void FskAssociativeArrayElementSet(FskAssociativeArray array, const char *name, const void *value, UInt32 valueSize, SInt32 valueType) { FskAssociativeArrayNameList list; SInt32 nameLen = FskStrLen(name) + 1; if (kFskStringType == valueType) valueSize = FskStrLen((const char *)value) + 1; else if (kFskBlobType == valueType) ; else valueSize = 0; FskAssociativeArrayElementDispose(array, name); if (kFskErrNone == FskMemPtrNew(sizeof(FskAssociativeArrayNameListRec) + nameLen + valueSize, &list)) { unsigned char *d = list->data; list->name = (char *)d; FskMemMove(d, name, nameLen); d += nameLen; list->valueType = valueType; list->valueSize = valueSize; list->next = NULL; if ((kFskStringType == valueType) || (kFskBlobType == valueType)) { FskMemMove(d, value, valueSize); list->value = (char *)d; } else list->value = (char *)value; FskListPrepend((FskList*)(void*)&array->arrayHead, (FskListElement)list); } }
FskErr KprURLMerge(char* base, char* reference, char** result) { FskErr err = kFskErrNone; KprURLPartsRecord parts; KprURLPartsRecord baseParts; char* path = NULL; UInt32 length; KprURLSplit(reference, &parts); if (!parts.scheme) { KprURLSplit(base, &baseParts); parts.scheme = baseParts.scheme; parts.schemeLength = baseParts.schemeLength; if (!parts.authority) { parts.authority = baseParts.authority; parts.authorityLength = baseParts.authorityLength; if (!parts.pathLength) { if (baseParts.authority && !baseParts.pathLength) { bailIfError(FskMemPtrNew(1, &path)); FskMemMove(path, "/", 1); parts.path = path; parts.pathLength = 1; } else { parts.path = baseParts.path; parts.pathLength = baseParts.pathLength; } if (!parts.query) { parts.query = baseParts.query; parts.queryLength = baseParts.queryLength; } } else if (*parts.path != '/') { if (baseParts.authority && !baseParts.pathLength) { bailIfError(FskMemPtrNew(1 + parts.pathLength, &path)); FskMemMove(path, "/", 1); FskMemMove(path + 1, parts.path, parts.pathLength); parts.path = path; parts.pathLength++; } else if (baseParts.name) { length = baseParts.name - baseParts.path; bailIfError(FskMemPtrNew(length + parts.pathLength, &path)); FskMemMove(path, baseParts.path, length); FskMemMove(path + length, parts.path, parts.pathLength); parts.path = path; parts.pathLength += length; } } } } bailIfError(KprURLJoin(&parts, result)); bail: FskMemPtrDispose(path); return err; }
FskErr mp3ScanProc(void *refCon, UInt32 bytesToRead, void *data, UInt32 *bytesReadOut, FskInt64 offset, Boolean dontSeekIfExpensive) { mp3Reader state = refCon; FskErr err = kFskErrNone; UInt32 bytesRead = 0; if (state->id3.data && (offset < state->id3.offset)) { UInt32 bytesToUse = (UInt32)(state->id3.offset - offset); if (bytesToUse > bytesToRead) bytesToUse = bytesToRead; FskMemMove(data, (char *)state->id3.data + offset, bytesToUse); if (bytesReadOut) *bytesReadOut = bytesToUse; else if (bytesToUse != bytesToRead) return kFskErrNeedMoreTime; return kFskErrNone; } while (0 != bytesToRead) { void *buffer; UInt32 readCount; if (dontSeekIfExpensive) state->spooler->flags |= kFskMediaSpoolerDontSeekIfExpensive; err = FskMediaSpoolerRead(state->spooler, offset, bytesToRead, &buffer, &readCount); state->spooler->flags &= ~kFskMediaSpoolerDontSeekIfExpensive; if (err) { if (0 == bytesRead) return err; err = kFskErrNone; // return what we have break; } FskMemMove(data, buffer, readCount); bytesRead += readCount; bytesToRead -= readCount; offset += readCount; data = readCount + (char *)data; } if (NULL != bytesReadOut) *bytesReadOut = bytesRead; else if (0 != bytesToRead) err = kFskErrNeedMoreTime; return err; }
FskErr _PushDataToLinkedFrames( int size, unsigned char *dataPtr, RTPCompressedMediaFrame *storedFrames ) { RTPCompressedMediaFrame frame = NULL; UInt32 err = 0; err = FskMemPtrNewClear( size + sizeof(RTPCompressedMediaFrameRecord), &frame); if (0 != err) goto bail; frame->next = NULL; frame->length = size; FskMemMove( frame + 1, dataPtr, size ); // Add the current buffer to our link list if( (*storedFrames) == NULL ) *storedFrames = frame; else { RTPCompressedMediaFrame currentFrames = *storedFrames; while( currentFrames->next != NULL ) currentFrames = currentFrames->next; currentFrames->next = frame; } FskInstrumentedTypePrintfDebug(&gRTPPacketParserH263TypeInstrumentation, " append: %d", size); bail: if( err != 0 && frame != NULL ) FskMemPtrDispose(frame); return err; }
FskErr _MoveLinkedFramesDataToFrame( RTPCompressedMediaFrame storedFrames, RTPCompressedMediaFrame frame ) { int copiedSize = 0; unsigned char *pData = NULL; frame->next = NULL; // Walk our list again and really prepend the data pData = (unsigned char *)( frame + 1 ); // Move pass the header while(storedFrames) { RTPCompressedMediaFrame currStoredFrames = storedFrames; UInt32 currStoredSize = storedFrames->length; FskMemMove(pData, storedFrames+1, currStoredSize); storedFrames = storedFrames->next; // Remove our stored data from our list FskMemPtrDispose(currStoredFrames); currStoredFrames = NULL; // increment our frame ptr pData += currStoredSize; copiedSize += currStoredSize; } frame->length = copiedSize; FskInstrumentedTypePrintfDebug(&gRTPPacketParserH263TypeInstrumentation, " _MoveLinkedFramesDataToFrame: %d", frame->length); return 0; }
void devFBFlip(KplScreen screen) { UInt32 dummy; struct fb_var_screeninfo *var = &screen->vinfo; Boolean skipCopy = (0 == screen->bitmapsReady); // Boolean skipCopy = 1; if (skipCopy) { ioctl(screen->fbfd, FBIO_WAITFORVSYNC, &dummy); return; } FskMutexAcquire(screen->withCare); // FskMemMove(screen->baseAddr[OFFSCREEN_PAGE(screen)], screen->bitmaps[1 & screen->bitmapsFlagRead]->bits, gScreenWidth * gScreenHeight * 2); FskMemMove(screen->baseAddr[OFFSCREEN_PAGE(screen)], screen->bitmaps[0]->bits, gScreenWidth * gScreenHeight * 2); screen->bitmapsFlagRead += 1; screen->bitmapsReady -= 1; FskMutexRelease(screen->withCare); if (ioctl(screen->fbfd, FBIO_WAITFORVSYNC, &dummy) < 0) { fprintf(stderr, " devFBFlip - problems with WAITFORVSYNC - %d\n", errno); } screen->displayPage = OFFSCREEN_PAGE(screen); #if 0 var->xoffset = 0; var->yoffset = DISPLAY_OFFSET(screen); var->activate = FB_ACTIVATE_VBL; if (ioctl(screen->fbfd, FBIOPAN_DISPLAY, var) < 0) { fprintf(stderr, " devFBFlip - problems with PAN - %d\n", errno); } #endif }
static FskErr sFskNetInterfaceEnumerate(FskNetInterfaceRecord **interfaceList) { FskErr err; KplNetInterfaceRecord *kplInterfaceList; *interfaceList = NULL; err = KplNetInterfaceEnumerate(&kplInterfaceList); BAIL_IF_ERR(err); while (kplInterfaceList) { FskNetInterfaceRecord *nir; KplNetInterfaceRecord *next = kplInterfaceList->next; err = FskMemPtrNew(sizeof(FskNetInterfaceRecord), (FskMemPtr*)&nir); BAIL_IF_ERR(err); nir->name = FskStrDoCopy(kplInterfaceList->name); nir->ip = kplInterfaceList->ip; FskMemMove(nir->MAC, kplInterfaceList->MAC, sizeof(nir->MAC)); nir->status = kplInterfaceList->status; nir->netmask = kplInterfaceList->netmask; FskListAppend((FskList*)interfaceList, nir); FskMemPtrDispose(kplInterfaceList->name); FskMemPtrDispose(kplInterfaceList); kplInterfaceList = next; } bail: return err; }
FskErr FskUUIDCreate(FskUUID uuid) { FskTimeRecord time; static UInt32 clockSequence = 0; static FskTimeRecord lastTime; char MAC[6]; FskNetInterfaceRecord *netInterface = NULL; UInt32 numInterfaces; // find a suitable network interface to get the MAC address from numInterfaces = FskNetInterfaceEnumerate(); while (numInterfaces--) { FskNetInterfaceDescribe(numInterfaces, &netInterface); if ((0 == netInterface->MAC[0]) && (0 == netInterface->MAC[1]) && (0 == netInterface->MAC[2]) && (0 == netInterface->MAC[3]) && (0 == netInterface->MAC[4]) && (0 == netInterface->MAC[5])) { FskNetInterfaceDescriptionDispose(netInterface); netInterface = NULL; continue; } break; } if (NULL == netInterface) { // can't fail - clients need a value. make something up. (this happens if all network interfaces are disabled on a phone) int i; for (i = 0; i < 6; i++) MAC[i] = (char)FskRandom(); } else { FskMemMove(MAC, netInterface->MAC, sizeof(netInterface->MAC)); FskNetInterfaceDescriptionDispose(netInterface); } // make sure the clock sequence is good while (0 == clockSequence) clockSequence = FskRandom(); // we need the time, and make sure it is unique. FskTimeGetNow(&time); //@@ should be UTC time time.useconds = (time.useconds >> 4) | (time.seconds << 28); // only uses 60 bits of time time.seconds >>= 4; // only uses 60 bits of time if (FskTimeCompare(&time, &lastTime) <= 0) clockSequence += 1; lastTime = time; // put the pieces together time.useconds = FskEndianU32_NtoB(time.useconds); FskMemCopy(&uuid->value[0], &time.useconds, sizeof(time.useconds)); uuid->value[4] = (UInt8)time.seconds; uuid->value[5] = (UInt8)(time.seconds >> 8); uuid->value[6] = (((UInt8)(time.seconds >> 24)) & 0x0f) | 1; uuid->value[7] = (UInt8)(time.seconds >> 16); uuid->value[8] = ((UInt8)(clockSequence >> 8) & 0x3f) | 0x80; uuid->value[9] = (UInt8)clockSequence; FskMemCopy(&uuid->value[10], MAC, sizeof(MAC)); return kFskErrNone; }
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; }
void xs_i2c_readBlock(xsMachine *the) { FskErr err; xsI2C i2c = xsGetHostData(xsThis); int argc = xsToInteger(xsArgc), i; int format = 2; SInt32 dataSize = xsToInteger(xsArg(0)), readCount; UInt8 data[32]; xsThrowIfNULL(i2c); DBG_I2C("xs_i2c_readBlock\n"); if ((dataSize > 32) || (dataSize <= 0)) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C readBlock invalid size %d. %s", (int)dataSize, i2c->diagnosticID); FskPinI2CSetAddress(i2c->pin, i2c->address); err = FskPinI2CReadBytes(i2c->pin, dataSize, &readCount, data); if (err) { xsTraceDiagnostic("I2C readBlock failed with error %s %s.", FskInstrumentationGetErrorString(err), i2c->diagnosticID); goto bail; } if (argc > 1) { int t = xsTypeOf(xsArg(1)); if ((xsNumberType == t) || (t == xsIntegerType)) format = xsToInteger(xsArg(1)); else { char *formatString = xsToString(xsArg(1)); if (0 == FskStrCompare(formatString, "Buffer")) format = 2; else if (0 == FskStrCompare(formatString, "Chunk")) format = 0; else if (0 == FskStrCompare(formatString, "Array")) format = 1; } } if (2 == format) { xsResult = xsArrayBuffer(data, readCount); } else if (0 == format) { xsResult = xsNew1(xsGlobal, xsID("Chunk"), xsInteger(readCount)); FskMemMove(xsGetHostData(xsResult), data, readCount); } else if (1 == format) { xsResult = xsNew1(xsGlobal, xsID("Array"), xsInteger(readCount)); for (i = 0; i < readCount; i++) xsSet(xsResult, i, xsInteger(data[i])); } bail: if (err) xsError(err); }
void KPR_message_get_responseBuffer(xsMachine *the) { KprMessage self = xsGetHostData(xsThis); void* data; UInt32 size; KprMessageGetResponseBody(self, &data, &size); if (data && size) { xsResult = xsNew1(xsGlobal, xsID_ArrayBuffer, xsInteger(size)); FskMemMove(xsToArrayBuffer(xsResult), data, size); } }
FskErr KprLabelInsertStringWithLength(KprLabel self, char* text, UInt32 size) { FskErr err = kFskErrNone; UInt32 oldSize = FskStrLen(self->text); SInt32 fromSize = fxUnicodeToUTF8Offset(self->text, self->from); SInt32 toSize = fxUnicodeToUTF8Offset(self->text, self->to); UInt32 newSize = oldSize - (toSize - fromSize) + size; char* buffer; bailIfError(FskMemPtrNew(newSize + 1, &buffer)); if (fromSize > 0) FskMemMove(buffer, self->text, fromSize); if (size > 0) FskMemMove(buffer + fromSize, text, size); if (oldSize - toSize > 0) FskMemMove(buffer + fromSize + size, self->text + toSize, oldSize - toSize); buffer[newSize] = 0; FskMemPtrDispose(self->text); if (self->flags & kprTextHidden) { if ((self->from == self->length) && (self->to == self->length) && (fxUTF8ToUnicodeOffset(text, size) == 1)) { self->flags |= kprTextShowLast; if (!self->showLastCallback) FskTimeCallbackNew(&self->showLastCallback); FskTimeCallbackScheduleFuture(self->showLastCallback, 1, 0, KprLabelShowLastCallback, self); } else { if (self->showLastCallback) FskTimeCallbackRemove(self->showLastCallback); self->flags &= ~kprTextShowLast; } } self->text = buffer; self->length = fxUnicodeLength(buffer); self->from = self->to = fxUTF8ToUnicodeOffset(buffer, fromSize + size); bail: if (self->shell) { KprLabelMeasureSelection(self); KprContentInvalidate((KprContent)self); KprContentReflow((KprContent)self, kprSizeChanged); } return err; }
FskErr lpcmPacketParserProcessPacket(RTPPacketParser parser, RTPPacket rtpHeader) { LPCMPacketParser lpcmPacketParser = (LPCMPacketParser)parser->handlerRefCon; RTPCompressedMediaFrame frame; FskErr err; err = FskMemPtrNewClear(rtpHeader->dataSize + sizeof(RTPCompressedMediaFrameRecord), &frame); BAIL_IF_ERR(err); rtpHeader->frames = frame; frame->length = rtpHeader->dataSize; FskMemMove(frame + 1, rtpHeader->data, rtpHeader->dataSize); rtpHeader->totalSamples = frame->length / (lpcmPacketParser->bitsPerSample/8) / lpcmPacketParser->nChannels; bail: return err; }
FskErr KprLabelSetText(KprLabel self, char* text, UInt32 size) { FskErr err = kFskErrNone; char* buffer; bailIfError(FskMemPtrNew(size + 1, &buffer)); if (size > 0) FskMemMove(buffer, text, size); buffer[size] = 0; self->length = fxUnicodeLength(text); self->from = self->to = 0; FskMemPtrDispose(self->text); self->text = buffer; bail: if (self->shell) { KprLabelMeasureSelection(self); KprContentInvalidate((KprContent)self); KprContentReflow((KprContent)self, kprSizeChanged); } return err; }
FskNetInterfaceNotifier FskNetInterfaceAddNotifier(FskNetInterfaceChangedCallback callback, void *param, char *debugName) { FskNetInterfaceNotifier notRef = NULL; FskThread thread = FskThreadGetCurrent(); UInt32 nameLen = debugName ? FskStrLen(debugName) + 1 : 0; if (kFskErrNone == FskMemPtrNewClear(sizeof(FskNetInterfaceNotifierRec) + nameLen, ¬Ref)) { FskInstrumentedTypePrintfDebug(&gNetInterfaceNotifierTypeInstrumentation, "NetInterfaceNotifier NEW -- %x", notRef); notRef->callback = callback; notRef->param = param; notRef->thread = thread; if (nameLen) FskMemMove(notRef->name, debugName, nameLen); FskListMutexPrepend(interfaceChangeCBList, notRef); FskInstrumentedItemNew(notRef, notRef->name, &gNetInterfaceNotifierTypeInstrumentation); } return notRef; }
void xs_i2c_readBlockDataSMB(xsMachine* the) { xsI2C i2c = xsGetHostData(xsThis); FskErr err; char* formatString; int format = 2, i; SInt32 dataSize = 0; UInt8 command = (UInt8)xsToInteger(xsArg(0)); UInt8 data[34]; //needs to be 34 because we're using I2C_SMBUS_I2C_BLOCK_BROKEN in i2cdev.c //@@ WTF - not at this layer, at least SInt32 length = (SInt32)xsToInteger(xsArg(1)); DBG_I2C("xs_i2c_readBlockDataSMB\n"); xsThrowIfNULL(i2c); if ((length < 0) || (length > 32)) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C readBlockDataSMB bad length %d %s.", length, i2c->diagnosticID); FskPinI2CSetAddress(i2c->pin, i2c->address); formatString = xsToString(xsArg(2)); if (!FskStrCompare(formatString, "Buffer")) format = 2; else if (!FskStrCompare(formatString, "Chunk")) format = 0; else if (!FskStrCompare(formatString, "Array")) format = 1; err = FskPinI2CReadDataBytes(i2c->pin, command, length, &dataSize, data); xsThrowDiagnosticIfFskErr(err, "I2C readBlockDataSMB register %d failed %s.", (int)command, i2c->diagnosticID); if (2 == format) { xsResult = xsArrayBuffer(data, dataSize); } else if (0 == format) { xsResult = xsNew1(xsGlobal, xsID("Chunk"), xsInteger(dataSize)); FskMemMove(xsGetHostData(xsResult), data, dataSize); } else if (1 == format) { xsResult = xsNew1(xsGlobal, xsID("Array"), xsInteger(dataSize)); for (i = 0; i < dataSize; i++) xsSet(xsResult, i, xsInteger(data[i])); } }
static char * kcl_int_i2str(cint_t *ai, char *s, int size, int radix) { z_t *z = NULL; cint_t *a = NULL, *d = NULL, *q = NULL, *r = NULL; char *sp; int rem; char *err = NULL; if ((err = kcl_z_init(NULL, &z)) != NULL) goto bail; if ((err = kcl_cint_init(&d)) != NULL) goto bail; d->cint_num2i(d, radix); if ((err = kcl_cint_init(&a)) != NULL) goto bail; if ((err = (*a->cint_copy)(a, ai)) != NULL) goto bail; sp = s + size; *--sp = '\0'; do { if ((err = (*z->z_div)(z, a, d, &q, &r)) != NULL) goto bail; rem = ((bn_t *)r->cint_data)->data[0]; *--sp = (char)(rem >= 10 ? 'a' + rem - 10: '0' + rem); kcl_cint_dispose(a); kcl_cint_dispose(r); a = q; } while (!(*a->cint_isZero)(a)); if (ai->cint_sign(ai)) *--sp = '-'; if (s != sp) FskMemMove(s, sp, FskStrLen(sp) + 1); bail: if (a) kcl_cint_dispose(a); if (d) kcl_cint_dispose(d); if (z) kcl_z_dispose(z); return(err); }
FskErr latmPacketParserProcessPacket(RTPPacketParser parser, RTPPacket rtpHeader) { LATMPacketParser latmPacketParser = (LATMPacketParser)parser->handlerRefCon; UInt32 frameLength; RTPCompressedMediaFrame frame = 0; FskErr err = 0; if( rtpHeader->marker == 0 ) { // Not a complete frame, store our data in a link list RTPCompressedMediaFrame storedFrames = latmPacketParser->frames; frameLength = rtpHeader->dataSize; err = FskMemPtrNewClear(frameLength + sizeof(RTPCompressedMediaFrameRecord), &frame); if (0 != err) goto bail; // Add the current buffer to our link list if(!storedFrames) { latmPacketParser->frames = frame; } else { while(storedFrames->next != NULL) storedFrames = storedFrames->next; storedFrames->next = frame; } frame->next = NULL; frame->length = frameLength; FskMemMove(frame + 1, rtpHeader->data, frameLength); rtpHeader->frames = NULL; } else { RTPCompressedMediaFrame storedFrames = latmPacketParser->frames; UInt32 storedSize = 0; // if we have saved data, get it and prepend it to the current data while(storedFrames) { storedSize += storedFrames->length; storedFrames = storedFrames->next; } if(storedSize > 0) { frameLength = (rtpHeader->dataSize) + storedSize; err = FskMemPtrNewClear(frameLength + sizeof(RTPCompressedMediaFrameRecord), &frame); if (0 != err) { } else { unsigned char *pData = NULL; rtpHeader->frames = frame; rtpHeader->totalSamples = 1024; frame->next = NULL; // Walk our list again and really prepend the data storedFrames = latmPacketParser->frames; frame += 1; // Move pass the header pData = (unsigned char *)frame; while(storedFrames) { RTPCompressedMediaFrame currStoredFrames = storedFrames; UInt32 currStoredSize = storedFrames->length; FskMemMove(pData, storedFrames+1, currStoredSize); storedFrames = storedFrames->next; // Remove our stored data from our list FskMemPtrDispose(currStoredFrames); // increment our frame ptr pData += currStoredSize; } // Advance past the length bytes do { --frameLength; } while (*pData++ == 0xFF); err = FskMemPtrNew(sizeof(UInt32) * 2, (FskMemPtr*)&frame->sampleSizes); if (0 != err) goto bail; frame->length = frameLength; frame->sampleSizes[0] = frameLength; frame->sampleSizes[1] = 0; // Now copy our current frame FskMemMove(pData, rtpHeader->data, rtpHeader->dataSize); rtpHeader->dataSize = storedSize + rtpHeader->dataSize; // Set our link list to NULL latmPacketParser->frames = NULL; } } else { // Packet is self contained // Allocate a pointer to the current + saved compressed data UInt8 *start, *data = rtpHeader->data; UInt32 i, len; UInt32 nFrames = latmPacketParser->nSubFrames + 1; // Pre-flight validation - we've found some servers/hinters don't handle // multiple sub-frames correctly... frameLength = 0; for (i = 0; i <= latmPacketParser->nSubFrames; ++i) { len = 0; // Advance past the length bytes do { len += *data; } while (*data++ == 0xFF); data += len; frameLength += len; } if (frameLength > rtpHeader->dataSize) { err = kFskErrRTSPBadPacket; goto bail; } err = FskMemPtrNewClear(rtpHeader->dataSize + sizeof(RTPCompressedMediaFrameRecord), &frame); if (0 != err) goto bail; err = FskMemPtrNew(sizeof(UInt32) * (nFrames + 1), (FskMemPtr*)&frame->sampleSizes); if (0 != err) goto bail; // Now grab the encoded frames frameLength = 0; data = rtpHeader->data; start = (UInt8*)(frame + 1); for (i = 0; i <= latmPacketParser->nSubFrames; ++i) { len = 0; // Advance past the length bytes do { len += *data; } while (*data++ == 0xFF); // This frame starts at 'data' and contains 'len' bytes FskMemMove(start, data, len); frame->sampleSizes[i] = len; data += len; start += len; frameLength += len; } frame->sampleSizes[nFrames] = 0; frame->next = NULL; frame->length = frameLength; rtpHeader->frames = frame; rtpHeader->totalSamples = nFrames * 1024; } } bail: return err; }
FskErr KprURLJoin(KprURLParts parts, char** result) { FskErr err = kFskErrNone; UInt32 length; char* target; length = 0; if (parts->scheme) length += parts->schemeLength + 1; if (parts->authority) length += 2 + parts->authorityLength; if (parts->path) length += parts->pathLength; if (parts->query) length += 1 + parts->queryLength; if (parts->fragment) length += 1 + parts->fragmentLength; length++; bailIfError(FskMemPtrNew(length, &target)); length = 0; if (parts->scheme) { FskMemMove(target + length, parts->scheme, parts->schemeLength); length += parts->schemeLength; target[length] = ':'; length++; } if (parts->authority) { target[length] = '/'; length++; target[length] = '/'; length++; FskMemMove(target + length, parts->authority, parts->authorityLength); length += parts->authorityLength; } if (parts->path) { char *src = parts->path; UInt32 srcLength = parts->pathLength; char *start = target + length; char *dst = start; SInt32 dotCount = -1; while (srcLength) { if (*src == '/') { while ((dst > start) && (dotCount > 0)) { dst--; if (*dst == '/') dotCount--; length--; } dotCount = 0; } else if (*src == '.') { if (dotCount == 0) dotCount = 1; else if (dotCount == 1) dotCount = 2; else dotCount = -1; } else dotCount = -1; *dst = *src; src++; dst++; srcLength--; length++; } } if (parts->query && parts->queryLength) { target[length] = '?'; length++; FskMemMove(target + length, parts->query, parts->queryLength); length += parts->queryLength; } if (parts->fragment) { target[length] = '#'; length++; FskMemMove(target + length, parts->fragment, parts->fragmentLength); length += parts->fragmentLength; } target[length] = 0; *result = target; bail: return err; }
unsigned char *writeOne(xsMachine *the, xsI2C i2c, xsSlot *slot, unsigned char *bufPtr, unsigned char *bufEnd) { xsType argType = xsTypeOf(*slot); switch (argType) { case xsIntegerType: case xsNumberType: { SInt32 value = xsToInteger(*slot); if ((value < 0) || (value > 255)) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C write invalid character value %s.", i2c->diagnosticID); if ((bufEnd - bufPtr) < 1) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C write 32 byte write max %s.", i2c->diagnosticID); *bufPtr++ = (char)value; } break; case xsStringType: { char *text = xsToString(*slot); SInt32 dataSize = FskStrLen(text); if ((bufEnd - bufPtr) < dataSize) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C write 32 byte write max %s.", i2c->diagnosticID); FskMemMove(bufPtr, text, dataSize); bufPtr += dataSize; } break; case xsReferenceType: if (xsIsInstanceOf(*slot, xsArrayBufferPrototype)) { char *data = xsToArrayBuffer(*slot); SInt32 dataSize = xsGetArrayBufferLength(*slot); if ((bufEnd - bufPtr) < dataSize) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C write 32 byte write max %s.", i2c->diagnosticID); FskMemMove(bufPtr, data, dataSize); bufPtr += dataSize; } else if (xsIsInstanceOf(*slot, xsChunkPrototype)) { char *data = xsGetHostData(*slot); SInt32 dataSize = xsToInteger(xsGet(*slot, xsID("length"))); if ((bufEnd - bufPtr) < dataSize) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C write 32 byte write max %s.", i2c->diagnosticID); FskMemMove(bufPtr, data, dataSize); bufPtr += dataSize; } else if (xsIsInstanceOf(*slot, xsArrayPrototype)) { SInt32 length = xsToInteger(xsGet(*slot, xsID("length"))), j; if ((bufEnd - bufPtr) < length) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C write 32 byte write max %s.", i2c->diagnosticID); for (j = 0; j < length; j++) { xsSlot item = xsGet(*slot, j); bufPtr = writeOne(the, i2c, &item, bufPtr, bufEnd); } } else xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C unsupported argument type passed to write %s.", i2c->diagnosticID); break; default: xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C unsupported argument type passed to write %s.", i2c->diagnosticID); break; } return bufPtr; }
FskErr winTextBox(FskTextEngineState state, FskBitmap bits, const char *text, UInt32 textLen, FskConstRectangle bounds, FskConstRectangleFloat boundsFloat, FskConstRectangle clipRect, FskConstColorRGBA color, UInt32 blendLevel, UInt32 textSize, UInt32 textStyle, UInt16 hAlign, UInt16 vAlign, FskFixed textExtra, const char *fontName, FskTextFormatCache formatCacheIn) { FskTextFormatCacheGDI formatCache = (FskTextFormatCacheGDI)formatCacheIn; RECT r; UINT flags = DT_SINGLELINE | DT_NOPREFIX | ((kFskTextTruncateEnd & textStyle) ? DT_END_ELLIPSIS : 0); Boolean direct = (blendLevel >= 255) && (NULL != bits->hbmp) && !((kFskTextOutline | kFskTextOutlineHeavy) & textStyle) && !bits->hasAlpha; FskBitmap scratchBits = NULL; HFONT font; HDC dc = direct ? bits->hdc : state->dc; HGDIOBJ saveFont; FskRectangleRecord clip; unsigned char scratchBuffer[256]; int saveCharExtra; // combine bounds and clip to total clip if (NULL == clipRect) { clip = *bounds; } else { if (false == FskRectangleIntersect(clipRect, bounds, &clip)) return kFskErrNone; } if (direct) { if (clipRect) IntersectClipRect(dc, clipRect->x, clipRect->y, clipRect->x + clipRect->width, clipRect->y + clipRect->height); SetRect(&r, bounds->x, bounds->y, bounds->x + bounds->width, bounds->y + bounds->height); SetTextColor(dc, RGB(color->r, color->g, color->b)); } else { FskErr err; const UInt32 kFskTextOffscreenFormat = kFskBitmapFormat24BGR; /* Negative width below indicates that we want a native bitmap */ err = FskBitmapNew(-bounds->width, bounds->height, kFskTextOffscreenFormat, &scratchBits); if (kFskErrNone == err) SetRect(&r, 0, 0, bounds->width, bounds->height); else { FskRectangleRecord b; err = winTextGetBounds(state, bits, text, textLen, textSize, textStyle, textExtra, fontName, &b, NULL, formatCacheIn); if (err) return err; err = FskBitmapNew(-b.width, b.height, kFskTextOffscreenFormat, &scratchBits); if (err) return err; SetRect(&r, 0, 0, b.width, b.height); } dc = scratchBits->hdc; SetTextColor(dc, RGB(255, 255, 255)); } if (NULL == formatCache) saveFont = syncFont(textSize, textStyle, fontName, &font, state); else saveFont = SelectObject(dc, formatCache->font); saveCharExtra = SetTextCharacterExtra(dc, textExtra >> 16); #if 0 switch (hAlign) { case kFskTextAlignLeft: default: flags |= DT_LEFT; break; case kFskTextAlignCenter: flags |= DT_CENTER; break; case kFskTextAlignRight: flags |= DT_RIGHT; break; } switch (vAlign) { case kFskTextAlignTop: default: flags |= DT_TOP; break; case kFskTextAlignCenter: flags |= DT_VCENTER; break; case kFskTextAlignBottom: flags |= DT_BOTTOM; break; } #endif { SIZE sz; UINT align; SInt32 y; char *encodedText = (char *)scratchBuffer; UInt32 encodedTextLen = sizeof(scratchBuffer); if (kFskErrNone != FskTextUTF8ToUnicode16NENoAlloc(text, textLen, (UInt16 *)scratchBuffer, &encodedTextLen)) { if (kFskErrNone != FskMemPtrNew(encodedTextLen, &encodedText)) { FskBitmapDispose(scratchBits); goto done; } FskTextUTF8ToUnicode16NENoAlloc(text, textLen, (UInt16 *)encodedText, &encodedTextLen); } encodedTextLen >>= 1; remapForMicrosoft((UInt16 *)encodedText, encodedTextLen); if (kFskTextTruncateCenter & textStyle) { // work hard to truncate the center, since Windows doesn't support this directly SIZE size; int *widths; if (kFskErrNone == FskMemPtrNew(sizeof(int) * encodedTextLen, (FskMemPtr *)&widths)) { int maxC, i, fitWidth = (r.right - r.left); GetTextExtentExPointW(dc, (WCHAR *)encodedText, encodedTextLen, 32768, &maxC, widths, &size); if (size.cx > fitWidth) { SInt32 currentWidth = size.cx; SInt32 truncBegin, truncEnd; WCHAR ellipsis = 0x2026; SIZE ellipsisSize; UInt16 *uniChars = (UInt16 *)encodedText; for (i = encodedTextLen - 1; i > 0; i--) widths[i] -= widths[i - 1]; GetTextExtentPoint32W(dc, (LPWSTR)&ellipsis, 1, &ellipsisSize); //@@ could use ellipsisWidth in cache here fitWidth -= ellipsisSize.cx; if (fitWidth > 0) { Boolean phase = true; // start towards the end truncBegin = truncEnd = encodedTextLen / 2; while ((currentWidth > fitWidth) && ((truncEnd - truncBegin) != encodedTextLen)) { if (phase) { if (truncEnd < (SInt32)encodedTextLen) { currentWidth -= widths[truncEnd]; truncEnd += 1; } } else { if (0 != truncBegin) { truncBegin -= 1; currentWidth -= widths[truncBegin]; } } phase = !phase; } FskMemMove(&uniChars[truncBegin + 1], &uniChars[truncEnd], (encodedTextLen - truncEnd) * 2); uniChars[truncBegin] = ellipsis; encodedTextLen -= (truncEnd - truncBegin); encodedTextLen += 1; flags &= ~DT_END_ELLIPSIS; } } FskMemPtrDispose(widths); } } #if 0 DrawTextW(dc, (LPWSTR)encodedText, encodedTextLen, &r, flags); #else if (kFskTextTruncateEnd & textStyle) { int fitChars; int stackWidths[256], *widths, width = r.right - r.left; WCHAR ellipsis = 0x2026; SIZE ellipsisSz; if (encodedTextLen < 256) widths = stackWidths; else { if (kFskErrNone != FskMemPtrNew(sizeof(int) * encodedTextLen, (FskMemPtr *)&widths)) { widths = stackWidths; encodedTextLen = 256; } } GetTextExtentExPointW(dc, (WCHAR *)encodedText, encodedTextLen, width, &fitChars, widths, &sz); if ((UInt32)fitChars < encodedTextLen) { // remove trailing white space if (formatCache) { if (!formatCache->haveEllipsisWidth) { GetTextExtentExPointW(dc, (WCHAR *)&ellipsis, 1, 0, NULL, NULL, &ellipsisSz); formatCache->haveEllipsisWidth = true; formatCache->ellipsisWidth = ellipsisSz.cx; } else ellipsisSz.cx = formatCache->ellipsisWidth; } else GetTextExtentExPointW(dc, (WCHAR *)&ellipsis, 1, 0, NULL, NULL, &ellipsisSz); if (width > ellipsisSz.cx) { width -= ellipsisSz.cx; while (fitChars > 2) { UInt16 c = ((UInt16 *)encodedText)[fitChars - 2]; if ((32 != c) && (9 != c) && (0x3000 != c)) break; fitChars -= 1; } // truncate if needed to make room for the ellipsis while ((widths[fitChars - 1] > width) && (fitChars > 2)) fitChars -= 1; // add ellipsis ((UInt16 *)encodedText)[fitChars - 1] = 0x2026; // ellipsis encodedTextLen = fitChars; } else encodedTextLen = 0; } if (widths != stackWidths) FskMemPtrDispose(widths); } else { if (kFskTextAlignCenter == vAlign) GetTextExtentExPointW(dc, (WCHAR *)encodedText, encodedTextLen, 0, NULL, NULL, &sz); } if (kFskTextAlignCenter == vAlign) { y = (r.top + r.bottom - sz.cy) >> 1; align = TA_TOP; } else if (kFskTextAlignTop == vAlign) {
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; }
// ------------------------------------------------------------------------ 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; }
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; }
FskErr h263PacketParserProcessPacket(RTPPacketParser parser, RTPPacket rtpHeader) { H263PacketParser h263PacketParser; unsigned char *headerStart; RTPPayloadH263 payloadHeader; UInt32 headerSize; UInt32 storedSize = 0; RTPCompressedMediaFrame outFrame = NULL; Boolean frameChanged = false; // Boolean isKeyFrame = false; Boolean isLastPacketOfAFrame = false; // Boolean thisPacketIsVOG = false; // Boolean lastPacketIsVOG = false; UInt8 *dataPtr = NULL; UInt32 dataSize = 0; UInt8 *copyBuffer = NULL; UInt32 err = 0; if(!parser || !rtpHeader) { err = kFskErrRTSPBadPacket; goto bail; } h263PacketParser = (H263PacketParser)parser->handlerRefCon; headerStart = rtpHeader->data; headerSize = 2; /* The H.263+ payload header is structured as follows: 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | RR |P|V| PLEN |PEBIT| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ RR: 5 bits Reserved bits. Shall be zero. P: 1 bit Indicates the picture start or a picture segment (GOB/Slice) start or a video sequence end (EOS or EOSBS). Two bytes of zero bits then have to be prefixed to the payload of such a packet to compose a complete picture/GOB/slice/EOS/EOSBS start code. This bit allows the omission of the two first bytes of the start codes, thus improving the compression ratio. V: 1 bit Indicates the presence of an 8 bit field containing information for Video Redundancy Coding (VRC), which follows immediately after the initial 16 bits of the payload header if present. For syntax and semantics of that 8 bit VRC field see section 4.2. PLEN: 6 bits Length in bytes of the extra picture header. If no extra picture header is attached, PLEN is 0. If PLEN>0, the extra picture header is attached immediately following the rest of the payload header. Note the length reflects the omission of the first two bytes of the picture start code (PSC). See section 5.1. PEBIT: 3 bits Indicates the number of bits that shall be ignored in the last byte of the picture header. If PLEN is not zero, the ignored bits shall be the l east significant bits of the byte. If PLEN is zero, then PEBIT shall also be zero. */ payloadHeader.P = (headerStart[0]&0x4) != 0; payloadHeader.V = (headerStart[0]&0x2) != 0; payloadHeader.PLEN = ((headerStart[0]&0x1)<<5)|(headerStart[1]>>3); payloadHeader.PEBIT = (headerStart[1]&0x7); frameChanged = h263PacketParser->lastTimeStamp != rtpHeader->timestamp; isLastPacketOfAFrame = rtpHeader->marker; //lastPacketIsVOG = mp4vPacketParserPtr->lastPacketIsVOG; h263PacketParser->lastTimeStamp = rtpHeader->timestamp; //mp4vPacketParserPtr->lastPacketIsVOG = thisPacketIsVOG; // Parse the picture header if (payloadHeader.PLEN > 0) { // only look in header for width/height information if necessary if (h263PacketParser->width == 0 && h263PacketParser->height == 0) { h263PacketParserDecodePictureHheaderPriv(headerStart, &h263PacketParser->width, &h263PacketParser->height); } headerSize += payloadHeader.PLEN; } // Skip over the extra VRC byte at the end of the header: if (payloadHeader.V) ++headerSize; dataSize = rtpHeader->dataSize - headerSize; dataPtr = rtpHeader->data + headerSize; /* Picture Segment Packets and Sequence Ending Packets (P=1) A picture segment packet is defined as a packet that starts at the location of a Picture, GOB, or slice start code in the H.263+ data stream. This corresponds to the definition of the start of a video picture segment as defined in H.263+. For such packets, P=1 always. */ if(payloadHeader.P == 1) { /* Two bytes of zero bits then have to be prefixed to the payload to compose a complete picture/GOB/slice/EOS/EOSBS start code. */ err = FskMemPtrNew(2 + dataSize, (FskMemPtr*)©Buffer); BAIL_IF_ERR(err); copyBuffer[0] = copyBuffer[1] = 0; FskMemMove(©Buffer[2], dataPtr, dataSize); dataSize += 2; dataPtr = copyBuffer; } err = _GetLinkededFramesSize( h263PacketParser->frames, &storedSize ); if( err != 0 ) goto bail; if( frameChanged && storedSize != 0 /*&& !lastPacketIsVOG*/ ) { err = FskMemPtrNewClear( storedSize + sizeof(RTPCompressedMediaFrameRecord), &outFrame ); if( err != 0 ) goto bail; err = _MoveLinkedFramesDataToFrame( h263PacketParser->frames, outFrame ); if( err != 0 ) goto bail; h263PacketParser->frames = NULL; //put this frame on top of output frame link list rtpHeader->frames = outFrame; rtpHeader->dataSize = outFrame->length; FskInstrumentedTypePrintfDebug(&gRTPPacketParserH263TypeInstrumentation, " probably pcket loss, output from stored data: %d", rtpHeader->dataSize); { //***if this's the last packet of a frame // we'll have to wait next call to output it, not very nice... // waiting for multiple frame output support // --bryan 6/30/2005 #if OUTPUT_MULTIPLE_FRAMES if( isLastPacketOfAFrame ) { FskInstrumentedTypePrintfDebug(&gRTPPacketParserH263TypeInstrumentation, "************************attaching extra!!!"); err = _PushDataToLinkedFrames( dataSize, dataPtr,&rtpHeader->frames ); } else #endif err = _PushDataToLinkedFrames( dataSize, dataPtr, &h263PacketParser->frames ); if( err != 0 ) goto bail; goto bail; } } err = _PushDataToLinkedFrames( dataSize, dataPtr, &h263PacketParser->frames ); if( err != 0 ) goto bail; //if( thisPacketIsVOG ) if( !isLastPacketOfAFrame ) //keep appending goto bail; err = _GetLinkededFramesSize( h263PacketParser->frames, &storedSize ); if( err != 0 ) goto bail; err = FskMemPtrNewClear( storedSize + sizeof(RTPCompressedMediaFrameRecord), &outFrame ); if( err != 0 ) goto bail; err = _MoveLinkedFramesDataToFrame( h263PacketParser->frames, outFrame ); if( err != 0 ) goto bail; h263PacketParser->frames = NULL; //***when multiple frame output is supported, // outFrame should be appended to rtpHeader->frames // and out size should be set in a appropriate way // --bryan 6/30/2005 rtpHeader->frames = outFrame; rtpHeader->dataSize = outFrame->length; FskInstrumentedTypePrintfDebug(&gRTPPacketParserH263TypeInstrumentation, " output from stored data: %d", rtpHeader->dataSize); bail: // Test for a key frame if (NULL != rtpHeader) { if (0 != rtpHeader->frames) { UInt8 *bs = (UInt8*)(rtpHeader->frames+1); if( bs[0] == 0 && bs[1] == 0 && (bs[2]&0xfc)== 0x80) { rtpHeader->frames->key = !(bs[4]&0x02); } } } if( err != 0 && outFrame != NULL ) FskMemPtrDispose(outFrame); FskMemPtrDispose(copyBuffer); return err; }
FskErr mp3ReaderExtract(FskMediaReader reader, void *readerState, FskMediaReaderTrack *track, UInt32 *infoCount, FskMediaReaderSampleInfo *info, unsigned char **dataOut) { mp3Reader state = readerState; FskErr err = kFskErrNone; UInt32 spaceInOutput; unsigned char *data; FskMediaReaderSampleInfo lastInfo = NULL; UInt32 infoCountFree; #if SUPPORT_MP3_LOG_TO_FILE UInt32 outputSize; #endif spaceInOutput = (state->mi.bitrate * 128) / 2; // about half a second if (spaceInOutput < 4096) spaceInOutput = 4096; #if SUPPORT_MP3_LOG_TO_FILE outputSize = spaceInOutput; #endif *track = &state->track; *infoCount = 0; *info = NULL; infoCountFree = state->mi.frequency >> 11; // quick divide by 2048... allocate enough entries for about half a second of frames err = FskMemPtrNew(infoCountFree * sizeof(FskMediaReaderSampleInfoRecord), (FskMemPtr*)(void*)info); if (err) return err; err = FskMemPtrNew(spaceInOutput + kFskDecompressorSlop, (FskMemPtr *)&data); if (err) { FskMemPtrDisposeAt((void **)info); return err; } *dataOut = data; while (0 != infoCountFree) { if (state->hasEndTime && (state->atTime >= state->endTime)) { if (0 == *infoCount ) err = kFskErrEndOfFile; goto bail; } if ((state->readBufferEnd - state->readBufferPtr) < 6) { err = mp3RefillReadBuffer(state, 6); if (err) goto bail; } if ((0xff == state->readBufferPtr[0]) && (0xe0 == (state->readBufferPtr[1] & 0xe0))) { DIDLMusicItemRecord mi; mi.doExtendedParsing = 0; if (true == (state->doHeaderParse)(state->readBufferPtr, &mi)) { if (spaceInOutput < mi.frameLength) goto bail; if ((state->readBufferEnd - state->readBufferPtr) < (SInt32)mi.frameLength) { err = mp3RefillReadBuffer(state, mi.frameLength); if (err) goto bail; } // When starting from a new location, make extra sure we're really sitting on a valid frame, // by validating the next frame. if (state->resync) { if (state->readBufferEnd - (state->readBufferPtr + mi.frameLength) > 6) { DIDLMusicItemRecord mi2; UInt8 *nextFramePtr = state->readBufferPtr + mi.frameLength; if ((0xff != nextFramePtr[0]) || (0xe0 != (nextFramePtr[1] & 0xe0))) { state->readBufferPtr += 1; continue; } mi2.doExtendedParsing = 0; if (false == (state->doHeaderParse)(nextFramePtr, &mi2)) { state->readBufferPtr += 1; continue; } } state->resync = false; } if (kFskAudioFormatAACADTS == mi.codec) { // skip adts header to get to raw aac frame. @@ if frame Count != 1 this isn't going to work mi.frameLength -= 7; state->readBufferPtr += 7; } if ((NULL != lastInfo) && (lastInfo->sampleDuration = mi.samplesPerFrame) && (lastInfo->sampleSize == mi.frameLength)) lastInfo->samples += 1; else { lastInfo = &(*info)[*infoCount]; *infoCount += 1; infoCountFree -= 1; FskMemSet(lastInfo, 0, sizeof(FskMediaReaderSampleInfoRecord)); lastInfo->samples = 1; lastInfo->sampleSize = mi.frameLength; lastInfo->flags = kFskImageFrameTypeSync; lastInfo->decodeTime = state->atTime; lastInfo->sampleDuration = mi.samplesPerFrame; lastInfo->compositionTime = -1; } FskMemMove(data, state->readBufferPtr, mi.frameLength); data += mi.frameLength; state->readBufferPtr += mi.frameLength; spaceInOutput -= mi.frameLength; state->atTime += mi.samplesPerFrame; continue; } } state->readBufferPtr += 1; state->resync = true; } bail: if (kFskErrNone != err) { if ((kFskErrNeedMoreTime == err) || (kFskErrEndOfFile == err)) { if (0 != *infoCount) err = kFskErrNone; } if (kFskErrNone != err) { FskMemPtrDisposeAt((void **)info); FskMemPtrDisposeAt((void **)dataOut); *infoCount = 0; } } #if SUPPORT_MP3_LOG_TO_FILE if (kFskErrNone == err) { if (NULL == gFref) { FskFileDelete("c:/dump.mp3"); FskFileCreate("c:/dump.mp3"); FskFileOpen("c:/dump.mp3", kFskFilePermissionReadWrite, &gFref); } FskFileWrite(gFref, outputSize - spaceInOutput, *dataOut, NULL); } #endif 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; }
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; } }