char* DecodeFromUTF8(const char* utf8Str) { #if defined(WIN32) wchar_t* wideStr; char* mbcsStr; int charLen; charLen = MultiByteToWideChar(CP_UTF8, 0, utf8Str, -1, NULL, 0); wideStr = (wchar_t*) malloc(sizeof(wchar_t)*charLen); MultiByteToWideChar(CP_UTF8, 0, utf8Str, -1, wideStr, charLen); charLen = WideCharToMultiByte(CP_ACP, 0, wideStr, -1, NULL, 0, NULL, NULL); mbcsStr = (char*) malloc(charLen); WideCharToMultiByte(CP_ACP, 0, wideStr, -1, mbcsStr, charLen, NULL, NULL); free(wideStr); return mbcsStr; #else return(ILibString_Copy(utf8Str, (int)strlen(utf8Str))); #endif }
int FSE_HandleCreateObject(void *fseObj, struct MSA_CdsCreateObj *createObjArg, struct DLNAProtocolInfo* protocolInfo, struct CdsObject *newCdsObject) { struct FSE_State* fse = (struct FSE_State*)fseObj; char* id = NULL; char* parentId = NULL; char* title = NULL; int size; int retVal = 0; int parentIdLen = 0; if(newCdsObject != NULL) { parentId = DecodeFromUTF8(newCdsObject->ParentID); parentIdLen = (int) strlen(parentId); if((newCdsObject->MediaClass & CDS_CLASS_MASK_OBJECT_TYPE) == CDS_CLASS_MASK_CONTAINER) { /* this is a container, so the file system will create a new folder */ char* rootPath = NULL; int i, len = 0; char* folder = NULL; if(newCdsObject->Title != NULL) { rootPath = fse->RootPath; title = DecodeFromUTF8(newCdsObject->Title); len = (int)strlen(title) + (int)strlen(rootPath) + parentIdLen; folder = malloc(len + 1); strcpy(folder, rootPath); if(ILibString_StartsWith(parentId, parentIdLen, "0\\", 2)!=0 && parentIdLen>2) { strcat(folder, parentId + 2); // skip directory 0 } else if(strnicmp(parentId, CDS_STRING_DLNA_ANYCONTAINER, CDS_STRING_DLNA_ANYCONTAINER_LEN)==0) { // ToDo: how to handle AnyContainer uploads // for now it reset to the root directory of the CDS. free(parentId); parentId = ILibString_Copy("0\\", -1); } strcat(folder, title); for(i = 0; i < len; i++) { if(folder[i] == '/') { folder[i] = '\\'; } } retVal = ILibFileDir_CreateDir(folder); free(folder); } } else { /* this is an item, the file system will map the item to a local file, and return the corresponding object ID */ char* rootPath = NULL; char* fileExtension = NULL; char* extension = NULL; int i, len = 0; char* file = NULL; char* tmp = NULL; rootPath = fse->RootPath; if(newCdsObject->Title != NULL) { title = DecodeFromUTF8(newCdsObject->Title); } else { int num = rand() % 1000000000; title = (char*) malloc(15); sprintf(title, "file%d", num); } /* we cannot rely on the title of the Cds Item to determine its media type, but rather its DLNA Profile */ switch(newCdsObject->MediaClass & CDS_CLASS_MASK_MAJOR) { case CDS_CLASS_MASK_MAJOR_AUDIOITEM: if(strcmp(protocolInfo->Profile, DLNAPROFILE_LPCM)==0) { extension = EXTENSION_AUDIO_LPCM; } else if(strcmp(protocolInfo->Profile, DLNAPROFILE_MP3)==0) { extension = EXTENSION_AUDIO_MPEG; } else if(strcmp(protocolInfo->Profile, DLNAPROFILE_AMR_3GPP)==0) { extension = EXTENSION_AUDIO_3GPP; } else if(strcmp(protocolInfo->Profile, DLNAPROFILE_AAC_ISO_320)==0) { extension = EXTENSION_AUDIO_AAC; } else if(strcmp(protocolInfo->Profile, DLNAPROFILE_WMABASE)==0) { extension = EXTENSION_AUDIO_WMA; } else { /* not supported */ } break; case CDS_CLASS_MASK_MAJOR_IMAGEITEM: if(strcmp(protocolInfo->Profile, DLNAPROFILE_JPEG_SM)==0) { extension = EXTENSION_IMAGE_JPG; } else if(strcmp(protocolInfo->Profile, DLNAPROFILE_JPEG_MED)==0) { extension = EXTENSION_IMAGE_JPG; } else if(strcmp(protocolInfo->Profile, DLNAPROFILE_JPEG_LRG)==0) { extension = EXTENSION_IMAGE_JPG; } else if(strcmp(protocolInfo->Profile, DLNAPROFILE_PNG_LRG)==0) { extension = EXTENSION_IMAGE_PNG; } else { /* not supported */ } break; case CDS_CLASS_MASK_MAJOR_VIDEOITEM: if(strcmp(protocolInfo->Profile, DLNAPROFILE_MPEG_PS_NTSC)==0) { extension = EXTENSION_VIDEO_MPEG2; } else if(strcmp(protocolInfo->Profile, DLNAPROFILE_AVC_MP4_BL_CIF15_AAC_520)==0) { extension = EXTENSION_VIDEO_AAC; } else if(strcmp(protocolInfo->Profile, DLNAPROFILE_MPEG_PS_NTSC)==0) { extension = EXTENSION_VIDEO_MPEG2; } else if(strcmp(protocolInfo->Profile, DLNAPROFILE_MPEG4_P2_ASF_SP_G726)==0) { extension = EXTENSION_VIDEO_ASF; } else if(strcmp(protocolInfo->Profile, DLNAPROFILE_WMVMED_BASE)==0) { extension = EXTENSION_VIDEO_WMV; } else { /* not supported */ } break; } if(extension == NULL) { /* no valid extension found, not a valid media item */ return -1; } /* replace file extension with the valid extension found */ fileExtension = FilePathToFileExtension(title, 0); if(fileExtension != NULL) { tmp = title; /* replace old title with new title with correct extension */ title = ILibString_Replace( title, (int) strlen(title), fileExtension, (int) strlen(fileExtension), extension, (int) strlen(extension)); free(fileExtension); free(tmp); } else { tmp = (char*) malloc((int) strlen(title) + (int) strlen(extension) + 1); strcpy(tmp, title); strcat(tmp, extension); free(title); title = tmp; } /* replace old title with UTF-8 encoded title */ if (newCdsObject->DeallocateThese & CDS_ALLOC_Title) { free(newCdsObject->Title); } newCdsObject->Title = EncodeToUTF8(title); len = (int)strlen(title) + (int)strlen(rootPath) + parentIdLen; file = malloc(len + 1); strcpy(file, rootPath); if(ILibString_StartsWith(parentId, parentIdLen, "0\\", 2)!=0 && parentIdLen>2) { strcat(file, parentId + 2); // skip directory 0 } else if(strnicmp(parentId, CDS_STRING_DLNA_ANYCONTAINER, CDS_STRING_DLNA_ANYCONTAINER_LEN)==0) { // ToDo: how to handle AnyContainer uploads // for now it reset to the root directory of the CDS. free(parentId); parentId = ILibString_Copy("0\\", -1); } strcat(file, title); for(i = 0; i < len; i++) { if(file[i] == '/') { file[i] = '\\'; } } /* Finds out if there's already a uploaded object */ tmp = (char*) malloc(strlen(file) + EXTENSION_UPLOAD_TEMP_LEN + 1); strcpy(tmp, file); strcat(tmp, EXTENSION_UPLOAD_TEMP); if(ILibFileDir_GetType(tmp) == FSE_OT_NoExist) { /* temp file does not exists, no file is currently being uploaded */ retVal = 0; /* overwriting the file, remove the old file in order to avoid duplicates in CDS*/ ILibFileDir_DeleteFile(file); newCdsObject->Source = ILibString_Copy(tmp,-1); } else { retVal = -1; } free(file); free(tmp); } } // replace requested object ID with the correct object ID; if ((newCdsObject->ParentID != NULL) && (newCdsObject->DeallocateThese & CDS_ALLOC_ParentID)) { // free previous parentId free(newCdsObject->ParentID); } newCdsObject->ParentID = EncodeToUTF8(parentId); if((newCdsObject->ID != NULL) && (newCdsObject->DeallocateThese & CDS_ALLOC_ID)) { free(newCdsObject->ID); } size = parentIdLen + (int) strlen(title) + 2; id = (char*) malloc (size); strcpy(id, parentId); if(ILibString_EndsWith(parentId, parentIdLen, "\\", 1)!=0) { strcat(id, "\\"); } strcat(id, title); newCdsObject->ID = EncodeToUTF8(id); newCdsObject->DeallocateThese |= CDS_ALLOC_ParentID; newCdsObject->DeallocateThese |= CDS_ALLOC_ID; if(id!=NULL) free(id); if(parentId!=NULL) free(parentId); if(title!=NULL) free(title); return retVal; }
struct DLNAProtocolInfo *DLNAProtocolInfo_Parse(char *protocolInfo, int protocolInfoLength) { struct parser_result *pr,*pr2,*pr3,*pr4; struct parser_result_field *prf,*prf2; char *temp; long flags; int tempInt; struct DLNAProtocolInfo *RetVal = (struct DLNAProtocolInfo*)malloc(sizeof(struct DLNAProtocolInfo)); memset(RetVal,0,sizeof(struct DLNAProtocolInfo)); RetVal->NameValueTable = ILibInitHashTree_CaseInSensitive(); RetVal->DLNA_Major_Version = 1; RetVal->Protocol = DLNAProtocolInfo_ProtocolType_UNKNOWN; pr = ILibParseString(protocolInfo,0,protocolInfoLength,":",1); if(pr->NumResults==4 || pr->NumResults==1) { if(pr->NumResults==4) { if(pr->FirstResult->datalength==8 && memcmp(pr->FirstResult->data,"http-get",8)==0) { RetVal->Protocol = DLNAProtocolInfo_ProtocolType_HTTP; } else if(pr->FirstResult->datalength==19 && memcmp(pr->FirstResult->data,"playsingle-http-get",19)==0) { RetVal->Protocol = DLNAProtocolInfo_ProtocolType_HTTP; RetVal->IsPlaySingleUri = 1; } else if(pr->FirstResult->datalength==12 && memcmp(pr->FirstResult->data,"rtsp-rtp-udp",12)==0) { RetVal->Protocol = DLNAProtocolInfo_ProtocolType_RTP; } else if(pr->FirstResult->datalength==23 && memcmp(pr->FirstResult->data,"playsingle-rtsp-rtp-udp",23)==0) { RetVal->Protocol = DLNAProtocolInfo_ProtocolType_RTP; RetVal->IsPlaySingleUri = 1; } else if(pr->FirstResult->datalength==1 && memcmp(pr->FirstResult->data,"*",1)==0) { RetVal->Protocol = DLNAProtocolInfo_ProtocolType_ANY; } RetVal->MimeType = (char*)malloc(pr->FirstResult->NextResult->NextResult->datalength+1); memcpy(RetVal->MimeType,pr->FirstResult->NextResult->NextResult->data,pr->FirstResult->NextResult->NextResult->datalength); RetVal->MimeType[pr->FirstResult->NextResult->NextResult->datalength]=0; } pr2 = ILibParseString(pr->LastResult->data,0,pr->LastResult->datalength,";",1); prf = pr2->FirstResult; while(prf!=NULL) { pr3 = ILibParseString(prf->data,0,prf->datalength,"=",1); ILibAddEntry(RetVal->NameValueTable,pr3->FirstResult->data,pr3->FirstResult->datalength,ILibString_Copy(pr3->LastResult->data,pr3->LastResult->datalength)); if(pr3->FirstResult->datalength==11 && memcmp(pr3->FirstResult->data,"DLNA.ORG_PN",11)==0) { // // Profile // temp = (char*)malloc(pr3->LastResult->datalength+1); memcpy(temp,pr3->LastResult->data,pr3->LastResult->datalength); temp[pr3->LastResult->datalength]=0; RetVal->Profile = temp; } if(pr3->FirstResult->datalength==11 && memcmp(pr3->FirstResult->data,"DLNA.ORG_OP",11)==0) { // // OP Code // flags = DLNA_StringToLong(2,pr3->LastResult->data,pr3->LastResult->datalength); if(RetVal->Protocol == DLNAProtocolInfo_ProtocolType_HTTP) { RetVal->SupportsTimeBasedSeek = DLNA_Bits(&flags)->Bit1; RetVal->SupportsByteBasedSeek = DLNA_Bits(&flags)->Bit0; } else if(RetVal->Protocol == DLNAProtocolInfo_ProtocolType_RTP) { RetVal->SupportsTimeBasedSeek = DLNA_Bits(&flags)->Bit0; } } if(pr3->FirstResult->datalength==11 && memcmp(pr3->FirstResult->data,"DLNA.ORG_PS",11)==0) { // // Supported Play Speeds // pr4 = ILibParseString(pr3->LastResult->data,0,pr3->LastResult->datalength,",",1); RetVal->SupportedPlaySpeedsLength = pr4->NumResults; RetVal->SupportedPlaySpeeds = (char**)malloc(RetVal->SupportedPlaySpeedsLength*sizeof(char*)); tempInt = 0; prf2 = pr4->FirstResult; while(prf2!=NULL) { RetVal->SupportedPlaySpeeds[tempInt] = (char*)malloc(2+prf2->datalength); memcpy(RetVal->SupportedPlaySpeeds[tempInt],prf2->data,prf2->datalength); RetVal->SupportedPlaySpeeds[tempInt][prf2->datalength]=0; ++tempInt; prf2 = prf2->NextResult; } ILibDestructParserResults(pr4); } if(pr3->FirstResult->datalength==11 && memcmp(pr3->FirstResult->data,"DLNA.ORG_CI",11)==0) { // // Conversion Indication // RetVal->IsConvertedContent = (int)DLNA_StringToLong(2,pr3->LastResult->data,pr3->LastResult->datalength); } if(pr3->FirstResult->datalength==14 && memcmp(pr3->FirstResult->data,"DLNA.ORG_FLAGS",14)==0) { // // Primary Flags (8 digits) // flags = DLNA_StringToLong(16,pr3->LastResult->data,pr3->LastResult->datalength<8?pr3->LastResult->datalength:8); if(DLNA_Bits(&flags)->Bit20) { RetVal->DLNA_Major_Version = 1; RetVal->DLNA_Minor_Version = 5; } if(RetVal->DLNA_Major_Version==1 && RetVal->DLNA_Minor_Version>=5) { RetVal->SenderPaced = DLNA_Bits(&flags)->Bit31; RetVal->LimitedOperations_TimeBasedSeek = DLNA_Bits(&flags)->Bit30; RetVal->LimitedOperations_ByteBasedSeek = DLNA_Bits(&flags)->Bit29; RetVal->DLNAPlayContainer = DLNA_Bits(&flags)->Bit28; RetVal->S0_Increasing = DLNA_Bits(&flags)->Bit27; RetVal->SN_Increasing = DLNA_Bits(&flags)->Bit26; RetVal->RTSP_Pause = DLNA_Bits(&flags)->Bit25; RetVal->TM_S = DLNA_Bits(&flags)->Bit24; RetVal->TM_I = DLNA_Bits(&flags)->Bit23; RetVal->TM_B = DLNA_Bits(&flags)->Bit22; } RetVal->HTTP_Stalling = DLNA_Bits(&flags)->Bit21; } if(pr3->FirstResult->datalength==14 && memcmp(pr3->FirstResult->data,"DLNA.ORG_MAXSP",14)==0) { pr4 = ILibParseString(pr3->LastResult->data,0,pr3->LastResult->datalength,".",1); RetVal->MaxSpeed_Major = (int)DLNA_StringToLong(10,pr4->FirstResult->data,pr4->FirstResult->datalength); if(pr4->NumResults==2) { RetVal->MaxSpeed_Minor = (int)DLNA_StringToLong(10,pr4->LastResult->data,pr4->LastResult->datalength); } ILibDestructParserResults(pr4); } ILibDestructParserResults(pr3); prf = prf->NextResult; } ILibDestructParserResults(pr2); } ILibDestructParserResults(pr); return(RetVal); }
BOOL _PLMTS_Seek(PlayListManager manager, int trackNumber) { char* format = "<DIDL-Lite xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\">%s</DIDL-Lite>"; char* fragment = NULL; char* xml = NULL; BOOL result = FALSE; char* metadata = NULL; int offset = 0; int length = 0; PlayListManager_S state = (PlayListManager_S)manager->InternalState; metadata = _GetTrackMetadata(state, trackNumber - 1, &offset, &length); if(metadata == NULL) { return FALSE; } fragment = ILibString_Copy(metadata + offset, length); xml = (char*)malloc(strlen(fragment) + strlen(format)); sprintf(xml, format, fragment); free(fragment); free(metadata); if(xml != NULL) { struct ILibXMLNode* root = ILibParseXML(xml, 0, (int)strlen(xml)); if(root != NULL) { if(ILibProcessXMLNodeList(root) == 0) { ILibXML_BuildNamespaceLookupTable(root); if(root->Next != NULL) { struct ILibXMLNode* item = root->Next; struct ILibXMLAttribute* attrs = ILibGetXMLAttributes(item); if(attrs != NULL) { struct CdsObject* cdsItem = CDS_DeserializeDidlToObject(item, attrs, 1, metadata + offset, metadata + offset + length); if(cdsItem != NULL) { if(state->Parent->TrackMetaData != NULL) { CDS_ObjRef_Release(state->Parent->TrackMetaData); state->Parent->TrackMetaData = NULL; } if(state->Parent->TrackURI != NULL) { free(state->Parent->TrackURI); state->Parent->TrackURI = NULL; } state->Parent->TrackNumber = trackNumber; state->Parent->TrackMetaData = cdsItem; state->Parent->TrackNumber = trackNumber; result = TRUE; } ILibDestructXMLAttributeList(attrs); } } } ILibDestructXMLNodeList(root); } free(xml); } return result; }