//Get the xml element's type name static int istar_sub_type_parser(struct ILibXMLNode **inxml) { int nRet = RSP_FAIL; struct ILibXMLNode *xml = *inxml; struct ILibXMLAttribute *attribs = NULL, *attr = NULL; memset(xml_type, '\0', sizeof(xml_type)); // Get the attributes attribs = attr = ILibGetXMLAttributes(xml); while (attr != NULL) { if (attr->NameLength == 4 && memcmp(attr->Name, "type", 4) == 0 || attr->NameLength == 4 && memcmp(attr->Name, "lang", 4) == 0) { if(attr->ValueLength > 0) { memcpy(xml_type, attr->Value, attr->ValueLength); nRet = RSP_OK; } } attr = attr->Next; } // Destruct XML attribute list ILibDestructXMLAttributeList(attribs); //*inxml = xml; return nRet; }
/* Get the movie's xml element's attributes */ static int istar_movie_attr_parser(struct ILibXMLNode **inxml, struct ISTAR_MOVIE_XML_ITEM *lpEntry) { int nRet = RSP_FAIL; struct ILibXMLNode *xml = *inxml; struct ILibXMLAttribute *attribs = NULL, *attr = NULL; // Get elements' attribute attribs = attr = ILibGetXMLAttributes(xml); while (attr != NULL) { nRet = RSP_FAIL; if (attr->ValueLength > 0 && attr->NameLength == 7 && memcmp(attr->Name, "picture", 7) == 0) { if(attr->ValueLength > ISTAR_THUMB_URL_MAX){ ERR("The thumbnail value is too big!");} else memcpy(lpEntry->thumbnail, attr->Value, attr->ValueLength); nRet = RSP_OK; } else if (attr->ValueLength > 0 && attr->NameLength == 4 && memcmp(attr->Name, "link", 4) == 0) { if(attr->ValueLength > ISTAR_VIDEO_URL_MAX){ ERR("The videourl value is too big!");} else memcpy(lpEntry->videourl, attr->Value, attr->ValueLength); nRet = RSP_OK; } else if (attr->ValueLength > 0 && attr->NameLength == 4 && memcmp(attr->Name, "name", 4) == 0) { if(attr->ValueLength > ISTAR_TITLE_LEN_MAX){ ERR("The title value is too big!");} else memcpy(lpEntry->title, attr->Value, attr->ValueLength); nRet = RSP_OK; } else if (attr->ValueLength > 0 && attr->NameLength == 4 && memcmp(attr->Name, "type", 4) == 0) { if(attr->ValueLength > ISTAR_TITLE_LEN_MAX){ ERR("The type value is too big!");} else memcpy(lpEntry->type, attr->Value, attr->ValueLength); nRet = RSP_OK; } attr = attr->Next; } // Destruct XML attribute list ILibDestructXMLAttributeList(attribs); return nRet; }
__declspec(dllexport) void* ILibWrapper_GetXMLAttributes(struct ILibXMLNode *node) { return(ILibGetXMLAttributes(node)); }
struct MMSCP_MediaObject* MMSCP_CreateMediaObject(struct ILibXMLNode *node, struct ILibXMLAttribute *attribs, int isItem, struct MMSCP_MediaObject *obj2, const char *rangeStart, const char *rangeEnd) { struct ILibXMLNode *startNode; struct ILibXMLAttribute *att; struct MMSCP_MediaObject tempObj; struct MMSCP_MediaObject* newObj; struct MMSCP_MediaResource *res; char *innerXml; int innerXmlLen; char classFragment[MMSCP_MAX_CLASS_FRAGMENT_SIZE]; int indexIntoArray; int dataSize; int mallocSize; char *di; char *emptyDI; #ifdef _DEBUG /* PRECONDITION: node is a start node*/ if (node->StartTag == 0) { printf("MMSCP_CreateMediaObject requires node->StartTag!=0.\r\n"); ASSERT(0); } /* PRECONDITION: node->Name is null terminated and this node is a container or item */ if (!( (stricmp(node->Name, MMSCP_TAG_CONTAINER) == 0) || (stricmp(node->Name, MMSCP_TAG_ITEM) == 0) )) { printf("MMSCP_CreateMediaObject requires item or container node.\r\n"); ASSERT(0); } #endif /* initialize temp obj to zero; init flags appropriately */ memset(&tempObj, 0, sizeof(struct MMSCP_MediaObject)); tempObj.Flags |= MMSCP_Flags_Restricted; /* assume object is restricted */ if (isItem == 0) { tempObj.Flags |= MMSCP_Flags_Searchable;/* assume container is searchable */ } /* * * Parse the item/container node and set the pointers in tempObj * to point into the memory referenced by node. * */ /* Parse the attributes of the item/container */ att = attribs; while (att != NULL) { /* [DONOTREPARSE] null terminate name and value. */ att->Name[att->NameLength] = '\0'; MMSCP_RemoveQuotFromAttribValue(att); att->Value[att->ValueLength] = '\0'; if (stricmp(att->Name, MMSCP_ATTRIB_ID) == 0) { tempObj.ID = att->Value; } else if (stricmp(att->Name, MMSCP_ATTRIB_PARENTID) == 0) { tempObj.ParentID = att->Value; } else if (stricmp(att->Name, MMSCP_ATTRIB_RESTRICTED) == 0) { if (MMSCP_FindStringInArray(att->Value, MMSCP_TRUE_STRINGS, MMSCP_TRUE_STRINGS_LEN) >= 0) { /* set the restricted flag. */ tempObj.Flags |= MMSCP_Flags_Restricted; } else { tempObj.Flags &= (~MMSCP_Flags_Restricted); } } else if ((isItem == 0) && (stricmp(att->Name, MMSCP_ATTRIB_SEARCHABLE) == 0)) { if (MMSCP_FindStringInArray(att->Value, MMSCP_TRUE_STRINGS, MMSCP_TRUE_STRINGS_LEN) >= 0) { /* set the searchable flag. */ tempObj.Flags |= MMSCP_Flags_Searchable; } else { tempObj.Flags &= (~MMSCP_Flags_Searchable); } } else if ((isItem != 0) && (stricmp(att->Name, MMSCP_ATTRIB_REFID) == 0)) { tempObj.RefID = att->Value; } att = att->Next; } /* * * Iterate through the child nodes of the startNode * and set the title, creator, and resources for * the media object. * */ startNode = node; node = startNode->Next; while (node != startNode->ClosingTag) { /* [DONOTREPARSE] null terminate name */ attribs = ILibGetXMLAttributes(node); att = attribs; node->Name[node->NameLength] = '\0'; if (node->StartTag != 0) { if (stricmp(node->Name, MMSCP_TAG_RESOURCE) == 0) { /* * * Create a new resource element and add it * to the existing list of resources for the * media object. The resource will point to * memory in XML, but we'll change where they * point at the very end. * */ if (tempObj.Res == NULL) { tempObj.Res = (struct MMSCP_MediaResource*) MMSCP_MALLOC (sizeof(struct MMSCP_MediaResource)); res = tempObj.Res; } else { res->Next = (struct MMSCP_MediaResource*) MMSCP_MALLOC (sizeof(struct MMSCP_MediaResource)); res = res->Next; } /* initialize everything to zero */ memset(res, 0, sizeof(struct MMSCP_MediaResource)); res->Bitrate = res->ColorDepth = res->Size = -1; /* Extract the protocolInfo from the element */ while (att != NULL) { /* [DONOTREPARSE] */ att->Name[att->NameLength] = '\0'; MMSCP_RemoveQuotFromAttribValue(att); att->Value[att->ValueLength] = '\0'; if (stricmp(att->Name, MMSCP_ATTRIB_PROTOCOLINFO) == 0) { res->ProtocolInfo = att->Value; break; } else if (stricmp(att->Name, MMSCP_ATTRIB_RESOLUTION) == 0) { res->Resolution = att->Value; } else if (stricmp(att->Name, MMSCP_ATTRIB_DURATION) == 0) { res->Duration = att->Value; } else if (stricmp(att->Name, MMSCP_ATTRIB_BITRATE) == 0) { ILibGetLong(att->Value, att->ValueLength, &(res->Bitrate)); } else if (stricmp(att->Name, MMSCP_ATTRIB_COLORDEPTH) == 0) { ILibGetLong(att->Value, att->ValueLength, &(res->ColorDepth)); } else if (stricmp(att->Name, MMSCP_ATTRIB_SIZE) == 0) { ILibGetLong(att->Value, att->ValueLength, &(res->Size)); } att = att->Next; } /* grab the URI */ innerXmlLen = ILibReadInnerXML(node, &innerXml); innerXml[innerXmlLen] = '\0'; res->Uri = innerXml; } else if (stricmp(node->NSTag, MMSCP_TAG_MEDIACLASS) == 0) { /* Figure out proper enum value given the specified media class */ innerXmlLen = ILibReadInnerXML(node, &innerXml); /* initialize to bad class */ tempObj.MediaClass = MMSCP_CLASS_MASK_BADCLASS; /* determine object type */ MMSCP_CopyUntilClassFragmentTerminator(classFragment, innerXml, MIN(innerXmlLen, MMSCP_MAX_CLASS_FRAGMENT_LEN)); indexIntoArray = MMSCP_FindStringInArray(classFragment, MMSCP_CLASS_OBJECT_TYPE, MMSCP_CLASS_OBJECT_TYPE_LEN); if (indexIntoArray == 0) { innerXml += ((int) strlen(MMSCP_CLASS_OBJECT_TYPE[indexIntoArray]) + 1); MMSCP_CopyUntilClassFragmentTerminator(classFragment, innerXml, MIN(innerXmlLen, MMSCP_MAX_CLASS_FRAGMENT_LEN)); indexIntoArray = MMSCP_FindStringInArray(classFragment, MMSCP_CLASS_OBJECT_TYPE, MMSCP_CLASS_OBJECT_TYPE_LEN); if (indexIntoArray > 0) { innerXml += ((int) strlen(MMSCP_CLASS_OBJECT_TYPE[indexIntoArray]) + 1); tempObj.MediaClass = indexIntoArray; /* Determine major type */ MMSCP_CopyUntilClassFragmentTerminator(classFragment, innerXml, MIN(innerXmlLen, MMSCP_MAX_CLASS_FRAGMENT_LEN)); indexIntoArray = MMSCP_FindStringInArray(classFragment, MMSCP_CLASS_MAJOR_TYPE, MMSCP_CLASS_MAJOR_TYPE_LEN); if (indexIntoArray > 0) { innerXml += ((int) strlen(MMSCP_CLASS_MAJOR_TYPE[indexIntoArray]) + 1); tempObj.MediaClass |= (indexIntoArray << MMSCP_SHIFT_MAJOR_TYPE); /* Determine minor type */ MMSCP_CopyUntilClassFragmentTerminator(classFragment, innerXml, MIN(innerXmlLen, MMSCP_MAX_CLASS_FRAGMENT_LEN)); indexIntoArray = MMSCP_FindStringInArray(classFragment, MMSCP_CLASS_MAJOR_TYPE, MMSCP_CLASS_MAJOR_TYPE_LEN); if (indexIntoArray > 0) { tempObj.MediaClass |= (indexIntoArray << MMSCP_SHIFT_MINOR1_TYPE); /* TODO : Add vendor-specific supported minor types parsing here */ } } } } } else if (stricmp(node->NSTag, MMSCP_TAG_CREATOR) == 0) { innerXmlLen = ILibReadInnerXML(node, &innerXml); innerXml[innerXmlLen] = '\0'; tempObj.Creator = innerXml; } else if (stricmp(node->NSTag, MMSCP_TAG_TITLE) == 0) { innerXmlLen = ILibReadInnerXML(node, &innerXml); innerXml[innerXmlLen] = '\0'; tempObj.Title = innerXml; } } node = node->Next; #ifdef _DEBUG if (node == NULL) { printf("MMSCP_CreateMediaObject: Unexpected null node.\r\n"); ASSERT(0); } #endif /* free attribute mapping */ ILibDestructXMLAttributeList(attribs); } /* * * At this point, we have a temp media object and possibly some media resources. * All string data is simply a pointer into the XML string. In order to * maximize on efficient memory usage, we do the following. * * 1) Determine size needed for all new strings in results set. Also note which strings need to be copied in this step. * 2) Create a new media object, with additional memory for storing new string data. * 3) Point new media object's fields to either the new memory or to existing memory from a previous media object. * 4) Connect new media object to resource objects (attached to temp) * 5) Point each field of each resource to memory in new memory to existing memory from a previous media object. * * */ /* * Create the new media object, with additional memory for string data appended at the end. */ dataSize = MMSCP_GetRequiredSizeForMediaObject(&tempObj, obj2); mallocSize = dataSize + sizeof(struct MMSCP_MediaObject) + 1; newObj = (struct MMSCP_MediaObject*) MMSCP_MALLOC(mallocSize); memset(newObj, 0, mallocSize); newObj->MediaClass = tempObj.MediaClass; newObj->Flags = tempObj.Flags; /* di will point to where it's safe to write string data */ di = (char*)newObj; di += sizeof(struct MMSCP_MediaObject); emptyDI = di; di ++; MMSCP_StringFixup(&(newObj->ID), &di, emptyDI, tempObj.ID, rangeStart, rangeEnd); MMSCP_StringFixup(&(newObj->ParentID), &di, emptyDI, tempObj.ParentID, rangeStart, rangeEnd); MMSCP_StringFixup(&(newObj->RefID), &di, emptyDI, tempObj.RefID, rangeStart, rangeEnd); MMSCP_StringFixup(&(newObj->Title), &di, emptyDI, tempObj.Title, rangeStart, rangeEnd); MMSCP_StringFixup(&(newObj->Creator), &di, emptyDI, tempObj.Creator, rangeStart, rangeEnd); newObj->Res = tempObj.Res; res = newObj->Res; while (res != NULL) { /* * Since resources are already allocated, we send the same parameters * for arg1 and arg3. */ MMSCP_StringFixup(&(res->ProtocolInfo), &di, emptyDI, res->ProtocolInfo, rangeStart, rangeEnd); MMSCP_StringFixup(&(res->Resolution), &di, emptyDI, res->Resolution, rangeStart, rangeEnd); MMSCP_StringFixup(&(res->Uri), &di, emptyDI, res->Uri, rangeStart, rangeEnd); res = res->Next; } /* prevent memory corruption in debug version */ ASSERT(di <= ((int)newObj) + mallocSize); return newObj; }
void _Callback2(struct UPnPService *sender, int ErrorCode, void *user, char* Result, unsigned int NumberReturned, unsigned int TotalMatches, unsigned int UpdateID) { PlayListManager_PC state = (PlayListManager_PC)user; struct ILibXMLNode* root = NULL; int count = (int)NumberReturned; state->Error = -ErrorCode; if(ErrorCode != 0) { sem_post(&state->LockObject); return; } ClearMetadata(state); if((int)TotalMatches != state->Parent->TrackCount) { state->Parent->TrackCount = (int)TotalMatches; BitArray_ChangeSize(state->Parent->ShuffleArray, state->Parent->TrackCount); if(state->Parent->OnTrackCountChanged != NULL) { state->Parent->OnTrackCountChanged(state->Parent); } } root = ILibParseXML(Result, 0, (int)strlen(Result)); if(root != NULL) { BOOL failure = FALSE; if(ILibProcessXMLNodeList(root) == 0) { int i = 0; struct ILibXMLNode* item = root->Next; ILibXML_BuildNamespaceLookupTable(root); while(item != NULL && i < count) { struct ILibXMLAttribute* attrs = ILibGetXMLAttributes(item); if(attrs != NULL) { state->Objects[i] = CDS_DeserializeDidlToObject(item, attrs, 1, Result, Result + strlen(Result)); ILibDestructXMLAttributeList(attrs); } else { failure = TRUE; state->Objects[i] = NULL; } i++; item = item->Peer; } } ILibDestructXMLNodeList(root); if(failure == TRUE) { int i; state->Count = 0; for(i = 0; i < count; i++) { if(state->Objects[i] != NULL) { CDS_ObjRef_Release(state->Objects[i]); state->Objects[i] = NULL; } } state->Error = 1; } state->Count = count; } else { state->Error = 2; } sem_post(&state->LockObject); }
struct CdsObject* ResolvePlaySingleURI(void* MSCPToken, char* playSingleUri) { struct CdsObject* result = NULL; struct _PlaySingleUri* psUri = NULL; struct _BrowseState* state = NULL; struct UPnPDevice* device = NULL; struct UPnPService* service = NULL; char* rawResult = NULL; if(MSCPToken == NULL || playSingleUri == NULL) { return NULL; } psUri = _ParsePlaySingleUri(playSingleUri); if(psUri == NULL) { return NULL; } device = MediaServerCP_GetDeviceAtUDN(MSCPToken, psUri->UDN); if(device == NULL) { free(psUri); return NULL; } service = MediaServerCP_GetService_ContentDirectory(device); if(service == NULL) { free(psUri); return NULL; } state = (struct _BrowseState*)malloc(sizeof(struct _BrowseState)); sem_init(&state->Lock, 0, 1); state->Result = NULL; sem_wait(&state->Lock); MediaServerCP_Invoke_ContentDirectory_Browse(service, &_Callback, state, psUri->ItemID, "BrowseMetadata", "res", 0, 0, ""); sem_wait(&state->Lock); sem_destroy(&state->Lock); rawResult = state->Result; free(state); free(psUri); if(rawResult != NULL) { struct ILibXMLNode* root = ILibParseXML(rawResult, 0, (int)strlen(rawResult)); if(root != NULL) { if(ILibProcessXMLNodeList(root) == 0) { struct ILibXMLNode* item = root->Next; if(item != NULL && strncmp(item->Name, "item", 4) == 0) { struct ILibXMLAttribute* attrs = ILibGetXMLAttributes(item); if(attrs != NULL) { result = CDS_DeserializeDidlToObject(item, attrs, 1, rawResult, rawResult + strlen(rawResult)); ILibDestructXMLAttributeList(attrs); } } } ILibDestructXMLNodeList(root); } free(rawResult); } return result; }
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; }