436 lines
17 KiB
C
436 lines
17 KiB
C
|
/*
|
||
|
*
|
||
|
* @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
|