Darwin-Streaming-Server/Server.tproj/QTSSDictionary.h

436 lines
17 KiB
C
Raw Permalink Normal View History

/*
*
* @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: QTSSDictionary.h
Contains: Definitions of two classes: QTSSDictionary and QTSSDictionaryMap.
Collectively, these classes implement the "dictionary" APIs in QTSS
API. A QTSSDictionary corresponds to a QTSS_Object,
a QTSSDictionaryMap corresponds to a QTSS_ObjectType.
Created: Tue, Mar 2, 1999 @ 4:23 PM
*/
#ifndef _QTSSDICTIONARY_H_
#define _QTSSDICTIONARY_H_
#include <stdlib.h>
#include "SafeStdLib.h"
#include "QTSS.h"
#include "OSHeaders.h"
#include "OSMutex.h"
#include "StrPtrLen.h"
#include "MyAssert.h"
#include "QTSSStream.h"
class QTSSDictionary;
class QTSSDictionaryMap;
class QTSSAttrInfoDict;
#define __DICTIONARY_TESTING__ 0
//
// Function prototype for attr functions
typedef void* (*QTSS_AttrFunctionPtr)(QTSSDictionary* , UInt32* );
class QTSSDictionary : public QTSSStream
{
public:
//
// CONSTRUCTOR / DESTRUCTOR
QTSSDictionary(QTSSDictionaryMap* inMap, OSMutex* inMutex = NULL);
virtual ~QTSSDictionary();
//
// QTSS API CALLS
// Flags used by internal callers of these routines
enum
{
kNoFlags = 0,
kDontObeyReadOnly = 1,
kDontCallCompletionRoutine = 2
};
// This version of GetValue copies the element into a buffer provided by the caller
// Returns: QTSS_BadArgument, QTSS_NotPreemptiveSafe (if attribute is not preemptive safe),
// QTSS_BadIndex (if inIndex is bad)
QTSS_Error GetValue(QTSS_AttributeID inAttrID, UInt32 inIndex, void* ioValueBuffer, UInt32* ioValueLen);
//This version of GetValue returns a pointer to the internal buffer for the attribute.
//Only usable if the attribute is preemptive safe.
//
// Returns: Same as above, but also QTSS_NotEnoughSpace, if value is too big for buffer.
QTSS_Error GetValuePtr(QTSS_AttributeID inAttrID, UInt32 inIndex, void** outValueBuffer, UInt32* outValueLen)
{ return GetValuePtr(inAttrID, inIndex, outValueBuffer, outValueLen, false); }
// This version of GetValue converts the value to a string before returning it. Memory for
// the string is allocated internally.
//
// Returns: QTSS_BadArgument, QTSS_BadIndex, QTSS_ValueNotFound
QTSS_Error GetValueAsString(QTSS_AttributeID inAttrID, UInt32 inIndex, char** outString);
// Returns: QTSS_BadArgument, QTSS_ReadOnly (if attribute is read only),
// QTSS_BadIndex (attempt to set indexed parameter with param retrieval)
QTSS_Error SetValue(QTSS_AttributeID inAttrID, UInt32 inIndex,
const void* inBuffer, UInt32 inLen, UInt32 inFlags = kNoFlags);
// Returns: QTSS_BadArgument, QTSS_ReadOnly (if attribute is read only),
QTSS_Error SetValuePtr(QTSS_AttributeID inAttrID,
const void* inBuffer, UInt32 inLen, UInt32 inFlags = kNoFlags);
// Returns: QTSS_BadArgument, QTSS_ReadOnly (if attribute is read only),
QTSS_Error CreateObjectValue(QTSS_AttributeID inAttrID, UInt32* outIndex,
QTSSDictionary** newObject, QTSSDictionaryMap* inMap = NULL,
UInt32 inFlags = kNoFlags);
// Returns: QTSS_BadArgument, QTSS_ReadOnly, QTSS_BadIndex
QTSS_Error RemoveValue(QTSS_AttributeID inAttrID, UInt32 inIndex, UInt32 inFlags = kNoFlags);
// Utility routine used by the two external flavors of GetValue
QTSS_Error GetValuePtr(QTSS_AttributeID inAttrID, UInt32 inIndex,
void** outValueBuffer, UInt32* outValueLen,
Bool16 isInternal);
//
// ACCESSORS
QTSSDictionaryMap* GetDictionaryMap() { return fMap; }
// Returns the Instance dictionary map for this dictionary. This may return NULL
// if there are no instance attributes in this dictionary
QTSSDictionaryMap* GetInstanceDictMap() { return fInstanceMap; }
// Returns the number of values associated with a given attribute
UInt32 GetNumValues(QTSS_AttributeID inAttrID);
void SetNumValues(QTSS_AttributeID inAttrID, UInt32 inNumValues);
// Meant only for internal server use. Does no error checking,
// doesn't invoke the param retrieval function.
StrPtrLen* GetValue(QTSS_AttributeID inAttrID)
{ return &fAttributes[inAttrID].fAttributeData; }
OSMutex* GetMutex() { return fMutexP; }
void SetLocked(Bool16 inLocked) { fLocked = inLocked; }
Bool16 IsLocked() { return fLocked; }
//
// GETTING ATTRIBUTE INFO
QTSS_Error GetAttrInfoByIndex(UInt32 inIndex, QTSSAttrInfoDict** outAttrInfoDict);
QTSS_Error GetAttrInfoByName(const char* inAttrName, QTSSAttrInfoDict** outAttrInfoDict);
QTSS_Error GetAttrInfoByID(QTSS_AttributeID inAttrID, QTSSAttrInfoDict** outAttrInfoDict);
//
// INSTANCE ATTRIBUTES
QTSS_Error AddInstanceAttribute( const char* inAttrName,
QTSS_AttrFunctionPtr inFuncPtr,
QTSS_AttrDataType inDataType,
QTSS_AttrPermission inPermission );
QTSS_Error RemoveInstanceAttribute(QTSS_AttributeID inAttr);
//
// MODIFIERS
// These functions are meant to be used by the server when it is setting up the
// dictionary attributes. They do no error checking.
// They don't set fNumAttributes & fAllocatedInternally.
void SetVal(QTSS_AttributeID inAttrID, void* inValueBuffer, UInt32 inBufferLen);
void SetVal(QTSS_AttributeID inAttrID, StrPtrLen* inNewValue)
{ this->SetVal(inAttrID, inNewValue->Ptr, inNewValue->Len); }
// Call this if you want to assign empty storage to an attribute
void SetEmptyVal(QTSS_AttributeID inAttrID, void* inBuf, UInt32 inBufLen);
#if __DICTIONARY_TESTING__
static void Test(); // API test for these objects
#endif
protected:
// Derived classes can provide a completion routine for some dictionary functions
virtual void RemoveValueComplete(UInt32 /*inAttrIndex*/, QTSSDictionaryMap* /*inMap*/, UInt32 /*inValueIndex*/) {}
virtual void SetValueComplete(UInt32 /*inAttrIndex*/, QTSSDictionaryMap* /*inMap*/,
UInt32 /*inValueIndex*/, void* /*inNewValue*/, UInt32 /*inNewValueLen*/) {}
virtual void RemoveInstanceAttrComplete(UInt32 /*inAttrindex*/, QTSSDictionaryMap* /*inMap*/) {}
virtual QTSSDictionary* CreateNewDictionary(QTSSDictionaryMap* inMap, OSMutex* inMutex);
private:
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;
DictValueElement* fInstanceAttrs;
UInt32 fInstanceArraySize;
QTSSDictionaryMap* fMap;
QTSSDictionaryMap* fInstanceMap;
OSMutex* fMutexP;
Bool16 fMyMutex;
Bool16 fLocked;
void DeleteAttributeData(DictValueElement* inDictValues, UInt32 inNumValues);
};
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;
};
class QTSSDictionaryMap
{
public:
//
// This must be called before using any QTSSDictionary or QTSSDictionaryMap functionality
static void Initialize();
// Stores all meta-information for attributes
// CONSTRUCTOR FLAGS
enum
{
kNoFlags = 0,
kAllowRemoval = 1,
kIsInstanceMap = 2,
kInstanceAttrsAllowed = 4,
kCompleteFunctionsAllowed = 8
};
//
// CONSTRUCTOR / DESTRUCTOR
QTSSDictionaryMap(UInt32 inNumReservedAttrs, UInt32 inFlags = kNoFlags);
~QTSSDictionaryMap(){ delete fAttrArray; }
//
// QTSS API CALLS
// All functions either return QTSS_BadArgument or QTSS_NoErr
QTSS_Error AddAttribute( const char* inAttrName,
QTSS_AttrFunctionPtr inFuncPtr,
QTSS_AttrDataType inDataType,
QTSS_AttrPermission inPermission );
//
// Marks this attribute as removed
QTSS_Error RemoveAttribute(QTSS_AttributeID inAttrID);
QTSS_Error UnRemoveAttribute(QTSS_AttributeID inAttrID);
QTSS_Error CheckRemovePermission(QTSS_AttributeID inAttrID);
//
// Searching / Iteration. These never return removed attributes
QTSS_Error GetAttrInfoByName(const char* inAttrName, QTSSAttrInfoDict** outAttrInfoDict, Bool16 returnRemovedAttr = false);
QTSS_Error GetAttrInfoByID(QTSS_AttributeID inID, QTSSAttrInfoDict** outAttrInfoDict);
QTSS_Error GetAttrInfoByIndex(UInt32 inIndex, QTSSAttrInfoDict** outAttrInfoDict);
QTSS_Error GetAttrID(const char* inAttrName, QTSS_AttributeID* outID);
//
// PRIVATE ATTR PERMISSIONS
enum
{
qtssPrivateAttrModeRemoved = 0x80000000
};
//
// CONVERTING attribute IDs to array indexes. Returns -1 if inAttrID doesn't exist
inline SInt32 ConvertAttrIDToArrayIndex(QTSS_AttributeID inAttrID);
static Bool16 IsInstanceAttrID(QTSS_AttributeID inAttrID)
{ return (inAttrID & 0x80000000) != 0; }
// ACCESSORS
// These functions do no error checking. Be careful.
// Includes removed attributes
UInt32 GetNumAttrs() { return fNextAvailableID; }
UInt32 GetNumNonRemovedAttrs() { return fNumValidAttrs; }
Bool16 IsPreemptiveSafe(UInt32 inIndex)
{ Assert(inIndex < fNextAvailableID); return (Bool16) (fAttrArray[inIndex]->fAttrInfo.fAttrPermission & qtssAttrModePreempSafe); }
Bool16 IsWriteable(UInt32 inIndex)
{ Assert(inIndex < fNextAvailableID); return (Bool16) (fAttrArray[inIndex]->fAttrInfo.fAttrPermission & qtssAttrModeWrite); }
Bool16 IsCacheable(UInt32 inIndex)
{ Assert(inIndex < fNextAvailableID); return (Bool16) (fAttrArray[inIndex]->fAttrInfo.fAttrPermission & qtssAttrModeCacheable); }
Bool16 IsRemoved(UInt32 inIndex)
{ Assert(inIndex < fNextAvailableID); return (Bool16) (fAttrArray[inIndex]->fAttrInfo.fAttrPermission & qtssPrivateAttrModeRemoved) ; }
QTSS_AttrFunctionPtr GetAttrFunction(UInt32 inIndex)
{ Assert(inIndex < fNextAvailableID); return fAttrArray[inIndex]->fAttrInfo.fFuncPtr; }
char* GetAttrName(UInt32 inIndex)
{ Assert(inIndex < fNextAvailableID); return fAttrArray[inIndex]->fAttrInfo.fAttrName; }
QTSS_AttributeID GetAttrID(UInt32 inIndex)
{ Assert(inIndex < fNextAvailableID); return fAttrArray[inIndex]->fID; }
QTSS_AttrDataType GetAttrType(UInt32 inIndex)
{ Assert(inIndex < fNextAvailableID); return fAttrArray[inIndex]->fAttrInfo.fAttrDataType; }
Bool16 InstanceAttrsAllowed() { return (Bool16) (fFlags & kInstanceAttrsAllowed); }
Bool16 CompleteFunctionsAllowed() { return (Bool16) (fFlags & kCompleteFunctionsAllowed) ; }
// MODIFIERS
// Sets this attribute ID to have this information
void SetAttribute( QTSS_AttributeID inID,
const char* inAttrName,
QTSS_AttrFunctionPtr inFuncPtr,
QTSS_AttrDataType inDataType,
QTSS_AttrPermission inPermission );
//
// DICTIONARY MAPS
// All dictionary maps are stored here, and are accessable
// through these routines
// This enum allows all QTSSDictionaryMaps to be stored in an array
enum
{
kServerDictIndex = 0,
kPrefsDictIndex = 1,
kTextMessagesDictIndex = 2,
kServiceDictIndex = 3,
kRTPStreamDictIndex = 4,
kClientSessionDictIndex = 5,
kRTSPSessionDictIndex = 6,
kRTSPRequestDictIndex = 7,
kRTSPHeaderDictIndex = 8,
kFileDictIndex = 9,
kModuleDictIndex = 10,
kModulePrefsDictIndex = 11,
kAttrInfoDictIndex = 12,
kQTSSUserProfileDictIndex = 13,
kQTSSConnectedUserDictIndex = 14,
k3GPPRequestDictIndex = 15,
k3GPPStreamDictIndex = 16,
k3GPPClientSessionDictIndex = 17,
k3GPPRTSPSessionDictIndex = 18,
kNumDictionaries = 19,
kNumDynamicDictionaryTypes = 500,
kIllegalDictionary = kNumDynamicDictionaryTypes + kNumDictionaries
};
// This function converts a QTSS_ObjectType to an index
static UInt32 GetMapIndex(QTSS_ObjectType inType);
// Using one of the above predefined indexes, this returns the corresponding map
static QTSSDictionaryMap* GetMap(UInt32 inIndex)
{ Assert(inIndex < kNumDynamicDictionaryTypes + kNumDictionaries); return sDictionaryMaps[inIndex]; }
static QTSS_ObjectType CreateNewMap();
private:
//
// Repository for dictionary maps
static QTSSDictionaryMap* sDictionaryMaps[kNumDictionaries + kNumDynamicDictionaryTypes];
static UInt32 sNextDynamicMap;
enum
{
kMinArraySize = 20
};
UInt32 fNextAvailableID;
UInt32 fNumValidAttrs;
UInt32 fAttrArraySize;
QTSSAttrInfoDict** fAttrArray;
UInt32 fFlags;
friend class QTSSDictionary;
};
inline SInt32 QTSSDictionaryMap::ConvertAttrIDToArrayIndex(QTSS_AttributeID inAttrID)
{
SInt32 theIndex = inAttrID & 0x7FFFFFFF;
if ((theIndex < 0) || (theIndex >= (SInt32)fNextAvailableID))
return -1;
else
return theIndex;
}
#endif