Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

204 lines
4.1 KiB

//
// strary.h
//
// CStructArray -- growable struct array
//
#ifndef STRARY_H
#define STRARY_H
#include "private.h"
#include "mem.h"
class CVoidStructArray
{
public:
CVoidStructArray(int iElemSize)
{
_iElemSize = iElemSize; // Issue: iElemSize should be const in template
_pb = NULL;
_cElems = 0;
_iSize = 0;
}
virtual ~CVoidStructArray() { cicMemFree(_pb); }
inline void *GetPtr(int iIndex)
{
Assert(iIndex >= 0);
Assert(iIndex <= _cElems); // there's code that uses the first invalid offset for loop termination
return _pb + (iIndex * _iElemSize);
}
BOOL Insert(int iIndex, int cElems);
void Remove(int iIndex, int cElems);
void *Append(int cElems)
{
return Insert(Count(), cElems) ? GetPtr(Count()-cElems) : NULL;
}
int Count()
{
return _cElems;
}
void Clear()
{
cicMemFree(_pb);
_pb = NULL;
_cElems = _iSize = 0;
}
void Reset(int iMaxSize)
{
BYTE *pb;
_cElems = 0;
if (_iSize <= iMaxSize)
return;
Assert(_pb != NULL); // _iSize should be zero in this case
if ((pb = (BYTE *)cicMemReAlloc(_pb, iMaxSize*_iElemSize))
== NULL)
{
return;
}
_pb = pb;
_iSize = iMaxSize;
}
protected:
BYTE *_pb; // the array
int _cElems; // num eles in the array
int _iElemSize; // num eles in the array
int _iSize; // actual size (in void *'s) of the array
};
//
// typesafe version
//
template<class T>
class CStructArray : public CVoidStructArray
{
public:
CStructArray():CVoidStructArray(sizeof(T)) {}
T *GetPtr(int iIndex) { return (T *)CVoidStructArray::GetPtr(iIndex); }
T *Append(int cElems) { return (T *)CVoidStructArray::Append(cElems); }
};
//
// GUID version
//
class CGUIDArray : private CVoidStructArray
{
public:
CGUIDArray():CVoidStructArray(sizeof(GUID)) {}
int Count() { return _cElems; }
GUID *GetPtr(int iIndex) { return (GUID *)CVoidStructArray::GetPtr(iIndex); }
GUID *Append(int cElems) { return (GUID *)CVoidStructArray::Append(cElems); }
int InsertGuid(const GUID *pguid)
{
int nIndex;
Find(pguid, &nIndex);
nIndex++;
Insert(nIndex, 1);
*(((GUID *)_pb) + nIndex) = *pguid;
return nIndex;
}
int RemoveGuid(const GUID *pguid)
{
int nIndex = Find(pguid, NULL);
if (nIndex == -1)
return -1;
Remove(nIndex, 1);
return nIndex;
}
int Find(const GUID *pguid, int *piOut)
{
int iMatch = -1;
int iMid = -1;
int iMin = 0;
int iMax = _cElems;
LONG l;
while(iMin < iMax)
{
iMid = (iMin + iMax) / 2;
l = memcmp(pguid, ((GUID *)_pb) + iMid, sizeof(GUID));
if (l < 0)
{
iMax = iMid;
}
else if (l > 0)
{
iMin = iMid + 1;
}
else
{
iMatch = iMid;
break;
}
}
if (piOut)
{
if ((iMatch == -1) && (iMid >= 0))
{
if (memcmp(pguid, ((GUID *)_pb) + iMid, sizeof(GUID)) < 0)
iMid--;
}
*piOut = iMid;
}
return iMatch;
}
};
//
// Ref-counted version.
//
// Note: this is limited, because there's no dtor for struct elements.
//
template<class T>
class CSharedStructArray : public CStructArray<T>
{
public:
CSharedStructArray() : CStructArray<T>()
{
_cRef = 1;
}
void _AddRef()
{
_cRef++;
}
void _Release()
{
Assert(_cRef > 0);
if (--_cRef == 0)
{
delete this;
}
}
private:
LONG _cRef;
};
#endif // STRARY_H