QTSSDictionaryMap内部有一个静态数组:
static QTSSDictionaryMap* sDictionaryMaps[kNumDictionaries + kNumDynamicDictionaryTypes];
其中的每一个元素在QTSSDictionary::Initialize中进行分配内存:
sDictionaryMaps[kAttrInfoDictIndex] = new QTSSDictionaryMap(qtssAttrInfoNumParams);
而每一个元素QTSSDictionaryMap的赋值是在QTSSDictionary::Initialize中进行。
QTSSDictionary的每一派生类(如QTSServerInterface)都有一些静态属性:
QTSSAttrInfoDict::AttrInfo QTSServerInterface::sAttributes[]={}
在QTSServerInterface::Initialize中进行所有元素的赋值
void QTSServerInterface::Initialize()
{
for (UInt32 x = 0; x < qtssSvrNumParams; x++)
QTSSDictionaryMap::GetMap(QTSSDictionaryMap::kServerDictIndex)->
SetAttribute \
(x, sAttributes[x].fAttrName, sAttributes[x].fFuncPtr, sAttributes[x].fAttrDataType, sAttributes[x].fAttrPermission);
}
在构造函数中,将每个元素的值进行赋值。
{
this->SetVal(qtssSvrState,&fServerState,sizeof(fServerState));
this->SetVal(qtssServerAPIVersion,&sServerAPIVersion,sizeof(sServerAPIVersion));
}
void QTSSDictionary::SetVal( QTSS_AttributeID inAttrID,
void* inValueBuffer,
UInt32 inBufferLen)
{
Assert(inAttrID >= 0);
Assert(fMap);
Assert((UInt32)inAttrID < fMap->GetNumAttrs());
fAttributes[inAttrID].fAttributeData.Ptr = (char*)inValueBuffer;
fAttributes[inAttrID].fAttributeData.Len = inBufferLen;
fAttributes[inAttrID].fAllocatedLen = inBufferLen;
// This function assumes there is only one value and that it isn't allocated internally
fAttributes[inAttrID].fNumAttributes = 1;
}
DictValueElement* fAttributes;
struct DictValueElement
{
// This stores all necessary information for each attribute value.
DictValueElement() : fAllocatedLen(0), fNumAttributes(0),
fAllocatedInternally(false), fIsDynamicDictionary(false) {}
// Does not delete! You Must call DeleteAttributeData for that
~DictValueElement() {}
StrPtrLen fAttributeData; // The data
UInt32 fAllocatedLen; // How much space do we have allocated?
UInt32 fNumAttributes; // If this is an iterated attribute, how many?
Bool16 fAllocatedInternally; //Should we delete this memory?
Bool16 fIsDynamicDictionary; //is this a dictionary object?
};
// test.cpp : 定义控制台应用程序的入口点。
//
#include <iostream>
using namespace std;
#include "XMLPrefsParser.h"
#include "StringFormatter.h"
#include "QTSSDictionary.h"
enum
{
//QTSS_ServerObject parameters
// These parameters ARE pre-emptive safe.
qtssServerAPIVersion = 0, //read //UInt32 //The API version supported by this server (format 0xMMMMmmmm, where M=major version, m=minor version)
qtssSvrDefaultDNSName = 1, //read //char array //The "default" DNS name of the server
qtssSvrDefaultIPAddr = 2, //read //UInt32 //The "default" IP address of the server
qtssSvrServerName = 3, //read //char array //Name of the server
qtssSvrServerVersion = 4, //read //char array //Version of the server
qtssSvrServerBuildDate = 5, //read //char array //When was the server built?
qtssSvrRTSPPorts = 6, //read // NOT PREEMPTIVE SAFE!//UInt16 //Indexed parameter: all the ports the server is listening on
qtssSvrRTSPServerHeader = 7, //read //char array //Server: header that the server uses to respond to RTSP clients
// These parameters are NOT pre-emptive safe, they cannot be accessed
// via. QTSS_GetValuePtr. Some exceptions noted below
qtssSvrState = 8, //r/w //QTSS_ServerState //The current state of the server. If a module sets the server state, the server will respond in the appropriate fashion. Setting to qtssRefusingConnectionsState causes the server to refuse connections, setting to qtssFatalErrorState or qtssShuttingDownState causes the server to quit.
qtssSvrIsOutOfDescriptors = 9, //read //Bool16 //true if the server has run out of file descriptors, false otherwise
qtssRTSPCurrentSessionCount = 10, //read //UInt32 //Current number of connected clients over standard RTSP
qtssRTSPHTTPCurrentSessionCount = 11, //read //UInt32 //Current number of connected clients over RTSP / HTTP
qtssRTPSvrNumUDPSockets = 12, //read //UInt32 //Number of UDP sockets currently being used by the server
qtssRTPSvrCurConn = 13, //read //UInt32 //Number of clients currently connected to the server
qtssRTPSvrTotalConn = 14, //read //UInt32 //Total number of clients since startup
qtssRTPSvrCurBandwidth = 15, //read //UInt32 //Current bandwidth being output by the server in bits per second
qtssRTPSvrTotalBytes = 16, //read //UInt64 //Total number of bytes served since startup
qtssRTPSvrAvgBandwidth = 17, //read //UInt32 //Average bandwidth being output by the server in bits per second
qtssRTPSvrCurPackets = 18, //read //UInt32 //Current packets per second being output by the server
qtssRTPSvrTotalPackets = 19, //read //UInt64 //Total number of bytes served since startup
qtssSvrHandledMethods = 20, //r/w //QTSS_RTSPMethod //The methods that the server supports. Modules should append the methods they support to this attribute in their QTSS_Initialize_Role.
qtssSvrModuleObjects = 21, //read // this IS PREMPTIVE SAFE! //QTSS_ModuleObject // A module object representing each module
qtssSvrStartupTime = 22, //read //QTSS_TimeVal //Time the server started up
qtssSvrGMTOffsetInHrs = 23, //read //SInt32 //Server time zone (offset from GMT in hours)
qtssSvrDefaultIPAddrStr = 24, //read //char array //The "default" IP address of the server as a string
qtssSvrPreferences = 25, //read //QTSS_PrefsObject // An object representing each the server's preferences
qtssSvrMessages = 26, //read //QTSS_Object // An object containing the server's error messages.
qtssSvrClientSessions = 27, //read //QTSS_Object // An object containing all client sessions stored as indexed QTSS_ClientSessionObject(s).
qtssSvrCurrentTimeMilliseconds = 28, //read //QTSS_TimeVal //Server's current time in milliseconds. Retrieving this attribute is equivalent to calling QTSS_Milliseconds
qtssSvrCPULoadPercent = 29, //read //Float32 //Current % CPU being used by the server
qtssSvrNumReliableUDPBuffers = 30, //read //UInt32 //Number of buffers currently allocated for UDP retransmits
qtssSvrReliableUDPWastageInBytes= 31, //read //UInt32 //Amount of data in the reliable UDP buffers being wasted
qtssSvrConnectedUsers = 32, //r/w //QTSS_Object //List of connected user sessions (updated by modules for their sessions)
qtssMP3SvrCurConn = 33, //r/w //UInt32 //Number of MP3 client sessions connected
qtssMP3SvrTotalConn = 34, //r/w //UInt32 //Total number of MP3 clients since startup
qtssMP3SvrCurBandwidth = 35, //r/w //UInt32 //Current MP3 bandwidth being output by the server in bits per second
qtssMP3SvrTotalBytes = 36, //r/w //UInt64 //Total number of MP3 bytes served since startup
qtssMP3SvrAvgBandwidth = 37, //r/w //UInt32 //Average MP3 bandwidth being output by the server in bits per second
qtssSvrServerBuild = 38, //read //char array //build of the server
qtssSvrServerPlatform = 39, //read //char array //Platform (OS) of the server
qtssSvrRTSPServerComment = 40, //read //char array //RTSP comment for the server header
qtssSvrNumThinned = 41, //r/w //SInt32 //Number of thinned sessions
qtssSvrNumParams = 42
};
void QTSSDictionaryMap::Initialize()
{
//
// Have to do this one first because this dict map is used by all the other
// dict maps.
sDictionaryMaps[kAttrInfoDictIndex] = new QTSSDictionaryMap(qtssAttrInfoNumParams);
// Setup the Attr Info attributes before constructing any other dictionaries
for (UInt32 x = 0; x < qtssAttrInfoNumParams; x++)
sDictionaryMaps[kAttrInfoDictIndex]->SetAttribute(x, QTSSAttrInfoDict::sAttributes[x].fAttrName,
QTSSAttrInfoDict::sAttributes[x].fFuncPtr,
QTSSAttrInfoDict::sAttributes[x].fAttrDataType,
QTSSAttrInfoDict::sAttributes[x].fAttrPermission);
sDictionaryMaps[kServerDictIndex] = new QTSSDictionaryMap(qtssSvrNumParams, QTSSDictionaryMap::kCompleteFunctionsAllowed);
sDictionaryMaps[kPrefsDictIndex] = new QTSSDictionaryMap(qtssPrefsNumParams, QTSSDictionaryMap::kInstanceAttrsAllowed | QTSSDictionaryMap::kCompleteFunctionsAllowed);
sDictionaryMaps[kTextMessagesDictIndex] = new QTSSDictionaryMap(qtssMsgNumParams);
sDictionaryMaps[kServiceDictIndex] = new QTSSDictionaryMap(0);
sDictionaryMaps[kRTPStreamDictIndex] = new QTSSDictionaryMap(qtssRTPStrNumParams);
sDictionaryMaps[kClientSessionDictIndex]= new QTSSDictionaryMap(qtssCliSesNumParams, QTSSDictionaryMap::kCompleteFunctionsAllowed);
sDictionaryMaps[kRTSPSessionDictIndex] = new QTSSDictionaryMap(qtssRTSPSesNumParams);
sDictionaryMaps[kRTSPRequestDictIndex] = new QTSSDictionaryMap(qtssRTSPReqNumParams);
sDictionaryMaps[kRTSPHeaderDictIndex] = new QTSSDictionaryMap(qtssNumHeaders);
sDictionaryMaps[kFileDictIndex] = new QTSSDictionaryMap(qtssFlObjNumParams);
sDictionaryMaps[kModuleDictIndex] = new QTSSDictionaryMap(qtssModNumParams);
sDictionaryMaps[kModulePrefsDictIndex] = new QTSSDictionaryMap(0, QTSSDictionaryMap::kInstanceAttrsAllowed | QTSSDictionaryMap::kCompleteFunctionsAllowed);
sDictionaryMaps[kQTSSUserProfileDictIndex] = new QTSSDictionaryMap(qtssUserNumParams);
sDictionaryMaps[kQTSSConnectedUserDictIndex] = new QTSSDictionaryMap(qtssConnectionNumParams);
}
class B:public QTSSDictionary
{
private:
static QTSSAttrInfoDict::AttrInfo sAttributes[];
UInt32 sServerAPIVersion;
UInt32 fDefaultIPAddr;
static StrPtrLen sServerNameStr;
public:
B():QTSSDictionary(QTSSDictionaryMap::GetMap(QTSSDictionaryMap::kServerDictIndex))
{
this->SetVal(qtssServerAPIVersion, &sServerAPIVersion, sizeof(sServerAPIVersion));
this->SetVal(qtssSvrDefaultIPAddr, &fDefaultIPAddr, sizeof(fDefaultIPAddr));
this->SetVal(qtssSvrServerName, sServerNameStr.Ptr, sServerNameStr.Len);
this->SetVal(qtssSvrState, &fServerState, sizeof(fServerState));
this->SetVal(qtssServerAPIVersion, &sServerAPIVersion, sizeof(sServerAPIVersion));
this->SetVal(qtssSvrDefaultIPAddr, &fDefaultIPAddr, sizeof(fDefaultIPAddr));
this->SetVal(qtssSvrServerName, sServerNameStr.Ptr, sServerNameStr.Len);
this->SetVal(qtssSvrServerVersion, sServerVersionStr.Ptr, sServerVersionStr.Len);
this->SetVal(qtssSvrServerBuildDate, sServerBuildDateStr.Ptr, sServerBuildDateStr.Len);
this->SetVal(qtssSvrRTSPServerHeader, sServerHeaderPtr.Ptr, sServerHeaderPtr.Len);
this->SetVal(qtssRTSPCurrentSessionCount, &fNumRTSPSessions, sizeof(fNumRTSPSessions));
this->SetVal(qtssRTSPHTTPCurrentSessionCount, &fNumRTSPHTTPSessions,sizeof(fNumRTSPHTTPSessions));
this->SetVal(qtssRTPSvrCurConn, &fNumRTPSessions, sizeof(fNumRTPSessions));
this->SetVal(qtssRTPSvrTotalConn, &fTotalRTPSessions, sizeof(fTotalRTPSessions));
this->SetVal(qtssRTPSvrCurBandwidth, &fCurrentRTPBandwidthInBits,sizeof(fCurrentRTPBandwidthInBits));
this->SetVal(qtssRTPSvrTotalBytes, &fTotalRTPBytes, sizeof(fTotalRTPBytes));
this->SetVal(qtssRTPSvrAvgBandwidth, &fAvgRTPBandwidthInBits, sizeof(fAvgRTPBandwidthInBits));
this->SetVal(qtssRTPSvrCurPackets, &fRTPPacketsPerSecond, sizeof(fRTPPacketsPerSecond));
this->SetVal(qtssRTPSvrTotalPackets, &fTotalRTPPackets, sizeof(fTotalRTPPackets));
this->SetVal(qtssSvrStartupTime, &fStartupTime_UnixMilli, sizeof(fStartupTime_UnixMilli));
this->SetVal(qtssSvrGMTOffsetInHrs, &fGMTOffset, sizeof(fGMTOffset));
this->SetVal(qtssSvrCPULoadPercent, &fCPUPercent, sizeof(fCPUPercent));
this->SetVal(qtssMP3SvrCurConn, &fNumMP3Sessions, sizeof(fNumMP3Sessions));
this->SetVal(qtssMP3SvrTotalConn, &fTotalMP3Sessions, sizeof(fTotalMP3Sessions));
this->SetVal(qtssMP3SvrCurBandwidth, &fCurrentMP3BandwidthInBits,sizeof(fCurrentMP3BandwidthInBits));
this->SetVal(qtssMP3SvrTotalBytes, &fTotalMP3Bytes, sizeof(fTotalMP3Bytes));
this->SetVal(qtssMP3SvrAvgBandwidth, &fAvgMP3BandwidthInBits, sizeof(fAvgMP3BandwidthInBits));
this->SetVal(qtssSvrServerBuild, sServerBuildStr.Ptr, sServerBuildStr.Len);
this->SetVal(qtssSvrRTSPServerComment, sServerCommentStr.Ptr, sServerCommentStr.Len);
this->SetVal(qtssSvrServerPlatform, sServerPlatformStr.Ptr, sServerPlatformStr.Len);
this->SetVal(qtssSvrNumThinned, &fNumThinned, sizeof(fNumThinned));
//......以下就不赋值了.........
}
static void Initialize()
{
for (UInt32 x = 0; x < qtssSvrNumParams; x++)
QTSSDictionaryMap::GetMap(QTSSDictionaryMap::kServerDictIndex)->
SetAttribute(x, sAttributes[x].fAttrName, sAttributes[x].fFuncPtr,
sAttributes[x].fAttrDataType, sAttributes[x].fAttrPermission);
}
};
StrPtrLen B::sServerNameStr("DSS");
QTSSAttrInfoDict::AttrInfo B::sAttributes[] =
{ /*fields: fAttrName, fFuncPtr, fAttrDataType, fAttrPermission */
/* 0 */ { "qtssServerAPIVersion", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModePreempSafe },
/* 1 */ { "qtssSvrDefaultDNSName", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead },
/* 2 */ { "qtssSvrDefaultIPAddr", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead },
/* 3 */ { "qtssSvrServerName", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
/* 4 */ { "qtssRTSPSvrServerVersion", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
/* 5 */ { "qtssRTSPSvrServerBuildDate", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
/* 6 */ { "qtssSvrRTSPPorts", NULL, qtssAttrDataTypeUInt16, qtssAttrModeRead },
/* 7 */ { "qtssSvrRTSPServerHeader", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
/* 8 */ { "qtssSvrState", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModeWrite },
/* 9 */ { "qtssSvrIsOutOfDescriptors", NULL, qtssAttrDataTypeBool16, qtssAttrModeRead },
/* 10 */ { "qtssRTSPCurrentSessionCount", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead },
/* 11 */ { "qtssRTSPHTTPCurrentSessionCount",NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead },
/* 12 */ { "qtssRTPSvrNumUDPSockets", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead },
/* 13 */ { "qtssRTPSvrCurConn", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead },
/* 14 */ { "qtssRTPSvrTotalConn", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead },
/* 15 */ { "qtssRTPSvrCurBandwidth", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead },
/* 16 */ { "qtssRTPSvrTotalBytes", NULL, qtssAttrDataTypeUInt64, qtssAttrModeRead },
/* 17 */ { "qtssRTPSvrAvgBandwidth", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead },
/* 18 */ { "qtssRTPSvrCurPackets", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead },
/* 19 */ { "qtssRTPSvrTotalPackets", NULL, qtssAttrDataTypeUInt64, qtssAttrModeRead },
/* 20 */ { "qtssSvrHandledMethods", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModeWrite | qtssAttrModePreempSafe },
/* 21 */ { "qtssSvrModuleObjects", NULL, qtssAttrDataTypeQTSS_Object,qtssAttrModeRead | qtssAttrModePreempSafe },
/* 22 */ { "qtssSvrStartupTime", NULL, qtssAttrDataTypeTimeVal, qtssAttrModeRead },
/* 23 */ { "qtssSvrGMTOffsetInHrs", NULL, qtssAttrDataTypeSInt32, qtssAttrModeRead },
/* 24 */ { "qtssSvrDefaultIPAddrStr", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead },
/* 25 */ { "qtssSvrPreferences", NULL, qtssAttrDataTypeQTSS_Object,qtssAttrModeRead | qtssAttrModeInstanceAttrAllowed},
/* 26 */ { "qtssSvrMessages", NULL, qtssAttrDataTypeQTSS_Object,qtssAttrModeRead },
/* 27 */ { "qtssSvrClientSessions", NULL, qtssAttrDataTypeQTSS_Object,qtssAttrModeRead },
/* 28 */ { "qtssSvrCurrentTimeMilliseconds",NULL, qtssAttrDataTypeTimeVal,qtssAttrModeRead},
/* 29 */ { "qtssSvrCPULoadPercent", NULL, qtssAttrDataTypeFloat32, qtssAttrModeRead},
/* 30 */ { "qtssSvrNumReliableUDPBuffers", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead },
/* 31 */ { "qtssSvrReliableUDPWastageInBytes",NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead },
/* 32 */ { "qtssSvrConnectedUsers", NULL, qtssAttrDataTypeQTSS_Object, qtssAttrModeRead | qtssAttrModeWrite },
/* 33 */ { "qtssMP3SvrCurConn", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModeWrite | qtssAttrModePreempSafe },
/* 34 */ { "qtssMP3SvrTotalConn", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModeWrite | qtssAttrModePreempSafe },
/* 35 */ { "qtssMP3SvrCurBandwidth", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModeWrite | qtssAttrModePreempSafe },
/* 36 */ { "qtssMP3SvrTotalBytes", NULL, qtssAttrDataTypeUInt64, qtssAttrModeRead | qtssAttrModeWrite | qtssAttrModePreempSafe },
/* 37 */ { "qtssMP3SvrAvgBandwidth", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModeWrite | qtssAttrModePreempSafe },
/* 38 */ { "qtssSvrServerBuild", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
/* 39 */ { "qtssSvrServerPlatform", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
/* 40 */ { "qtssSvrRTSPServerComment", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
/* 41 */ { "qtssSvrNumThinned", NULL, qtssAttrDataTypeSInt32, qtssAttrModeRead | qtssAttrModeWrite }
};
class QTSSDictionary : public QTSSStream
{
struct DictValueElement
{
// This stores all necessary information for each attribute value.
DictValueElement() : fAllocatedLen(0), fNumAttributes(0),
fAllocatedInternally(false), fIsDynamicDictionary(false) {}
// Does not delete! You Must call DeleteAttributeData for that
~DictValueElement() {}
StrPtrLen fAttributeData; // The data
UInt32 fAllocatedLen; // How much space do we have allocated?
UInt32 fNumAttributes; // If this is an iterated attribute, how many?
Bool16 fAllocatedInternally; //Should we delete this memory?
Bool16 fIsDynamicDictionary; //is this a dictionary object?
};
DictValueElement* fAttributes;
void SetVal( QTSS_AttributeID inAttrID,
void* inValueBuffer,
UInt32 inBufferLen)
{
Assert(inAttrID >= 0);
Assert(fMap);
Assert((UInt32)inAttrID < fMap->GetNumAttrs());
fAttributes[inAttrID].fAttributeData.Ptr = (char*)inValueBuffer;
fAttributes[inAttrID].fAttributeData.Len = inBufferLen;
fAttributes[inAttrID].fAllocatedLen = inBufferLen;
// This function assumes there is only one value and that it isn't allocated internally
fAttributes[inAttrID].fNumAttributes = 1;
}
};
QTSSDictionary::QTSSDictionary(QTSSDictionaryMap* inMap, OSMutex* inMutex)
: fAttributes(NULL), fInstanceAttrs(NULL), fInstanceArraySize(0),
fMap(inMap), fInstanceMap(NULL), fMutexP(inMutex), fMyMutex(false), fLocked(false)
{
if (fMap != NULL)
fAttributes = NEW DictValueElement[inMap->GetNumAttrs()];
if (fMutexP == NULL)
{
fMyMutex = true;
fMutexP = NEW OSMutex();
}
}
class QTSSAttrInfoDict : public QTSSDictionary
{
public:
struct AttrInfo
{
// This is all the relevent information for each dictionary
// attribute.
char fAttrName[QTSS_MAX_ATTRIBUTE_NAME_SIZE + 1];
QTSS_AttrFunctionPtr fFuncPtr;
QTSS_AttrDataType fAttrDataType;
QTSS_AttrPermission fAttrPermission;
};
QTSSAttrInfoDict();
virtual ~QTSSAttrInfoDict();
private:
AttrInfo fAttrInfo;
QTSS_AttributeID fID;
static AttrInfo sAttributes[];
friend class QTSSDictionaryMap;
};
char* theXMLFilePath = "c:\\Program Files\\Darwin Streaming Server\\streamingserver.xml";
int main(int argc, char * argv[])
{
QTSSDictionaryMap::Initialize();
B b;
return 0;
}