/* * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2008 Apple Inc. All Rights Reserved. * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ * */ /* File: RCFSourceInfo.cpp Contains: Implementation of object defined in .h file Copyright: © 1998 by Apple Computer, Inc., all rights reserved. */ #include "RCFSourceInfo.h" #include "PrefsSource.h" #include "StringParser.h" #include "OSMemory.h" #include "SocketUtils.h" void RCFSourceInfo::SetName(const char* inName) { if (inName != NULL) { fName = NEW char[::strlen(inName) + 1]; ::strcpy(fName, inName); } } RCFSourceInfo::~RCFSourceInfo() { if (fName != NULL) delete fName; // Not necessary anymore as the destructor of the base class will take care // of deleting all allocated memory for fOutputArray and fStreamArray /* if (fOutputArray != NULL) { for (UInt32 x = 0; x < fNumOutputs; x++) delete [] fOutputArray[x].fPortArray; char* theOutputArray = (char*)fOutputArray; delete [] theOutputArray; } if (fStreamArray != NULL) { char* theStreamArray = (char*)fStreamArray; delete [] theStreamArray; } */ } void RCFSourceInfo::Parse(XMLTag* relayTag) { XMLTag* sourceTag = relayTag->GetEmbeddedTagByNameAndAttr("OBJECT", "CLASS", "source"); if (sourceTag == NULL) return; fNumStreams = 0; UInt32 destIPAddr = 0; UInt32 srcIPAddr = 0; UInt16 ttl = 0; XMLTag* prefTag; prefTag = sourceTag->GetEmbeddedTagByNameAndAttr("PREF", "NAME", "in_addr"); if (prefTag != NULL) { char* destAddrStr = prefTag->GetValue(); if (destAddrStr != NULL) destIPAddr = SocketUtils::ConvertStringToAddr(destAddrStr); } prefTag = sourceTag->GetEmbeddedTagByNameAndAttr("PREF", "NAME", "source_addr"); if (prefTag != NULL) { char* srcAddrStr = prefTag->GetValue(); if (srcAddrStr != NULL) srcIPAddr = SocketUtils::ConvertStringToAddr(srcAddrStr); } prefTag = sourceTag->GetEmbeddedTagByNameAndAttr("PREF", "NAME", "ttl"); if (prefTag != NULL) { char* ttlStr = prefTag->GetValue(); if (ttlStr != NULL) ttl = atoi(ttlStr); } prefTag = sourceTag->GetEmbeddedTagByNameAndAttr("LIST-PREF", "NAME", "udp_ports"); if (prefTag != NULL) { fNumStreams = prefTag->GetNumEmbeddedTags(); // Allocate a proper sized stream array fStreamArray = NEW StreamInfo[fNumStreams]; for (UInt32 x = 0; x < fNumStreams; x++) { XMLTag* portTag = prefTag->GetEmbeddedTagByName("VALUE", x); int port = 0; if (portTag != NULL) { char* portStr = portTag->GetValue(); if (portStr != NULL) port = atoi(portStr); } // Setup all the StreamInfo structures fStreamArray[x].fSrcIPAddr = srcIPAddr; fStreamArray[x].fDestIPAddr = destIPAddr; fStreamArray[x].fPort = port; fStreamArray[x].fTimeToLive = ttl; fStreamArray[x].fPayloadType = qtssUnknownPayloadType; fStreamArray[x].fTrackID = x+1; } } // Now go through all the relay_destination lines (starting from the next line after the // relay_source line. this->ParseRelayDestinations(relayTag); } void RCFSourceInfo::ParseRelayDestinations(XMLTag* relayTag) { // parse the NAME attribute of the relay tag and store it in the relayname attribute char* name = relayTag->GetAttributeValue("NAME"); if (name != NULL) { fName = NEW char[::strlen(name) + 1]; ::strcpy(fName, name); } UInt32 numTags = relayTag->GetNumEmbeddedTags(); AllocateOutputArray(numTags); // not all these are relay tags, but most are // Now actually go through and figure out what to put into these OutputInfo structures, // based on what's on the relay_destination line fNumOutputs = 0; for (UInt32 y = 0; y < numTags; y++) { XMLTag* destTag = relayTag->GetEmbeddedTagByNameAndAttr("OBJECT", "CLASS", "destination", y); if (destTag == NULL) return; char* destType = destTag->GetAttributeValue("TYPE"); if (destType == NULL) return; if (!strcmp(destType, "udp_destination")) ParseDestination(destTag, y); else if (!strcmp(destType, "announced_destination")) ParseAnnouncedDestination(destTag, y); fNumOutputs++; } } void RCFSourceInfo::ParseDestination(XMLTag* destTag, UInt32 index) { XMLTag* prefTag; prefTag = destTag->GetEmbeddedTagByNameAndAttr("PREF", "NAME", "out_addr"); if (prefTag != NULL) { char* outAddrStr = prefTag->GetValue(); if (outAddrStr != NULL) fOutputArray[index].fLocalAddr = SocketUtils::ConvertStringToAddr(outAddrStr); } prefTag = destTag->GetEmbeddedTagByNameAndAttr("PREF", "NAME", "dest_addr"); if (prefTag != NULL) { char* destAddrStr = prefTag->GetValue(); if (destAddrStr != NULL) fOutputArray[index].fDestAddr = SocketUtils::ConvertStringToAddr(destAddrStr); } prefTag = destTag->GetEmbeddedTagByNameAndAttr("PREF", "NAME", "ttl"); if (prefTag != NULL) { char* ttlStr = prefTag->GetValue(); if (ttlStr != NULL) fOutputArray[index].fTimeToLive = atoi(ttlStr); } prefTag = destTag->GetEmbeddedTagByNameAndAttr("LIST-PREF", "NAME", "udp_ports"); if (prefTag != NULL) { fOutputArray[index].fNumPorts = prefTag->GetNumEmbeddedTags(); fOutputArray[index].fPortArray = NEW UInt16[fOutputArray[index].fNumPorts]; ::memset(fOutputArray[index].fPortArray, 0, fOutputArray[index].fNumPorts * sizeof(UInt16)); for (UInt32 x = 0; x < fOutputArray[index].fNumPorts; x++) { XMLTag* portTag = prefTag->GetEmbeddedTagByName("VALUE", x); if (portTag != NULL) { char* portStr = portTag->GetValue(); if (portStr != NULL) { fOutputArray[index].fPortArray[x] = atoi(portStr); } } } } else { prefTag = destTag->GetEmbeddedTagByNameAndAttr("PREF", "NAME", "udp_base_port"); if(prefTag == NULL) qtss_printf("Missing both 'udp_base_port' and 'udp_ports' tags.\n Cannot set up the destination!\n"); else { char* basePortStr = prefTag->GetValue(); if (basePortStr != NULL) fOutputArray[index].fBasePort = atoi(basePortStr); } } } void RCFSourceInfo::ParseAnnouncedDestination(XMLTag* destTag, UInt32 index) { // should log some sort of error // can't announce without an sdp } void RCFSourceInfo::AllocateOutputArray(UInt32 numOutputs) { // Allocate the proper number of relay outputs fOutputArray = NEW OutputInfo[numOutputs]; }