📄 mmscp.c
字号:
} res = res->Next; } return retVal;}static void MMSCP_RemoveQuotFromAttribValue(struct ILibXMLAttribute *att){ /*if ((att->Value[0] == '"') || (att->Value[0] == '\'')) { att->Value++; att->ValueLength -= 2; }*/}/* * Creates an MMSCP_MediaObject from an XML node representing a CDS object. * * node : the XML data that represents our CDS object * attribs : the XML attributes of the CDS object (i.e. item or container attributes) * isItem : nonzero indicates the CDS object is a CDS item * rangeStart/rangeEnd : the actual string data for 'node' occupies the [rangeStart,rangeEnd] portion of memory. */static struct MMSCP_MediaObject* MMSCP_CreateMediaObject(struct ILibXMLNode *node, struct ILibXMLAttribute *attribs, int isItem, const char *rangeStart, const char *rangeEnd){ struct ILibXMLNode *startNode; struct ILibXMLAttribute *att; struct MMSCP_MediaObject tempObj; struct MMSCP_MediaObject* newObj; struct MMSCP_MediaResource *res = NULL; char *innerXml; int innerXmlLen; char classFragment[MMSCP_MAX_CLASS_FRAGMENT_SIZE]; int indexIntoArray; int dataSize; int mallocSize; char *di; char *emptyDI; char c; int l; #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->Duration = 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) { l = (int) strlen(att->Value); if ( (l >= 8) && (att->Value[2] == ':') && (att->Value[5] == ':') ) { /* parse out number of seconds from hh:mm:ss string */ att->Value[2] = '\0'; att->Value[5] = '\0'; c = att->Value[8]; att->Value[8] = '\0'; /* 1 hr = 3600 seconds, 1 min = 60 seconds*/ res->Duration = (atoi(att->Value) * 3600) + (atoi(att->Value+3) * 60) + (atoi(att->Value+6) ); att->Value[2] = ':'; att->Value[5] = ':'; att->Value[8] = c; } else if ( (l >= 5) && (att->Value[2] == ':') ) { /* parse out number of seconds from mm:ss string */ att->Value[2] = '\0'; c = att->Value[5]; att->Value[5] = '\0'; /* 1 min = 60 seconds*/ res->Duration = (atoi(att->Value) * 60) + (atoi(att->Value+3) ); att->Value[2] = ':'; att->Value[5] = c; } else { /* parse out number of seconds from mm:ss string */ c = att->Value[2]; att->Value[2] = '\0'; res->Duration = (atoi(att->Value)); att->Value[2] = c; } } 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; } else if (stricmp(node->NSTag, MMSCP_TAG_GENRE) == 0) { innerXmlLen = ILibReadInnerXML(node, &innerXml); innerXml[innerXmlLen] = '\0'; tempObj.Genre = innerXml; } else if (stricmp(node->NSTag, MMSCP_TAG_ALBUM) == 0) { innerXmlLen = ILibReadInnerXML(node, &innerXml); innerXml[innerXmlLen] = '\0'; tempObj.Album = 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. */ /* amount of data needed to store various pointer-based fields */ dataSize = MMSCP_GetRequiredSizeForMediaObject(&tempObj, NULL); /* total size needed for the string data and the CDS media object struct */ mallocSize = dataSize + sizeof(struct MMSCP_MediaObject) + 1; /* create the new CDS object */ newObj = (struct MMSCP_MediaObject*) MMSCP_MALLOC(mallocSize); memset(newObj, 0, mallocSize); /* initialize fields on CDS object */ newObj->MallocSize = mallocSize; newObj->RefCount = 0; 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 ++; /* * Call MMSCP_StringFixup so that string data is stored in the data blocks that follow * the portion allocated for the MMSCP_MediaObject. * (i.e. mallocSize = [data for CDS object] + [data for pointer-based fields]) */ 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); MMSCP_StringFixup(&(newObj->Genre), &di, emptyDI, tempObj.Genre, rangeStart, rangeEnd); MMSCP_StringFixup(&(newObj->Album), &di, emptyDI, tempObj.Album, 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 <= ((char*)newObj) + mallocSize); return newObj;}/*********************************************************************************************************************** * END: Helper methods ***********************************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -