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.
tdepim/akregator/src/mk4storage/metakit/src/univ.cpp

228 lines
4.6 KiB

// univ.cpp --
// $Id$
// This is part of Metakit, see http://www.equi4.com/metakit/
/** @file
* A simple implementation of dynamic arrays
*/
#include "header.h"
#if q4_UNIV // until end of source
/////////////////////////////////////////////////////////////////////////////
#include <stdlib.h> // malloc
#if !q4_INLINE
#include "univ.inl"
#endif
/////////////////////////////////////////////////////////////////////////////
#if q4_UNIX || __MINGW32__
#define _strdup strdup
#elif !q4_BORC && !q4_MSVC && !q4_WATC && !(q4_MWCW && defined(_WIN32)) && \
!(q4_MWCW && __MWERKS__ >= 0x3000)
static char* _strdup(const char* p)
{
if (!p)
return 0;
char* s = (char*) malloc(strlen(p) + 1);
return strcpy(s, p);
}
#endif
// The Borland C++ RTL does not want file handle objects to cross
// DLL boundaries, so we add special fopen/fclose hooks to this DLL.
#if q4_BORC
#include <stdio.h>
#if q4_WIN32
__declspec(dllexport) FILE*
#else
FILE* __export
#endif
f4_FileOpenInDLL(const char* name_, const char* mode_)
{
return fopen(name_, mode_);
}
#if q4_WIN32
__declspec(dllexport)
#else
int __export
#endif
f4_FileCloseInDLL(FILE* file_)
{
return fclose(file_);
}
#endif
/////////////////////////////////////////////////////////////////////////////
// c4_BaseArray
c4_BaseArray::c4_BaseArray ()
: _data (0), _size (0)
{
}
c4_BaseArray::~c4_BaseArray ()
{
SetLength(0);
}
void c4_BaseArray::SetLength(int nNewSize)
{
// 2001-11-25: use more granular allocation, as optimization
const int bits = 6;
if (((_size - 1) ^ (nNewSize - 1)) >> bits) {
const int n = (nNewSize + (1<<bits) - 1) & -(1<<bits);
_data = _data == 0 ? n == 0 ? (char*) 0
: (char*) malloc(n)
: n == 0 ? (free(_data), (char*) 0)
: (char*) realloc(_data, n);
}
d4_assert(_data != 0 || nNewSize == 0);
int n = _size;
_size = nNewSize;
if (nNewSize > n)
memset(GetData(n), 0, nNewSize - n);
}
void c4_BaseArray::Grow(int nIndex)
{
if (nIndex > _size)
SetLength(nIndex);
}
void c4_BaseArray::InsertAt(int nIndex, int nCount)
{
SetLength(_size + nCount);
int to = nIndex + nCount;
if (_size > to)
d4_memmove(GetData(to), GetData(nIndex), _size - to);
}
void c4_BaseArray::RemoveAt(int nIndex, int nCount)
{
int from = nIndex + nCount;
if (_size > from)
d4_memmove(GetData(nIndex), GetData(from), _size - from);
SetLength(_size - nCount);
}
/////////////////////////////////////////////////////////////////////////////
// c4_DWordArray
int c4_DWordArray::Add(t4_i32 newElement)
{
int n = GetSize();
_vector.Grow(Off(n + 1));
SetAt(n, newElement);
return n;
}
void c4_DWordArray::InsertAt(int nIndex, t4_i32 newElement, int nCount)
{
_vector.InsertAt(Off(nIndex), nCount * sizeof (t4_i32));
while (--nCount >= 0)
SetAt(nIndex++, newElement);
}
void c4_DWordArray::RemoveAt(int nIndex, int nCount)
{
_vector.RemoveAt(Off(nIndex), nCount * sizeof (t4_i32));
}
/////////////////////////////////////////////////////////////////////////////
// c4_PtrArray
int c4_PtrArray::Add(void* newElement)
{
int n = GetSize();
_vector.Grow(Off(n + 1));
SetAt(n, newElement);
return n;
}
void c4_PtrArray::InsertAt(int nIndex, void* newElement, int nCount)
{
_vector.InsertAt(Off(nIndex), nCount * sizeof (void*));
while (--nCount >= 0)
SetAt(nIndex++, newElement);
}
void c4_PtrArray::RemoveAt(int nIndex, int nCount)
{
_vector.RemoveAt(Off(nIndex), nCount * sizeof (void*));
}
/////////////////////////////////////////////////////////////////////////////
// c4_StringArray
c4_StringArray::~c4_StringArray()
{
SetSize(0);
}
void c4_StringArray::SetSize(int nNewSize, int)
{
int i = nNewSize;
while (i < GetSize())
SetAt(i++, 0);
_ptrs.SetSize(nNewSize);
while (i < GetSize())
_ptrs.SetAt(i++, "");
}
void c4_StringArray::SetAt(int nIndex, const char* newElement)
{
char* s = (char*) _ptrs.GetAt(nIndex);
if (s && *s)
free(s);
_ptrs.SetAt(nIndex, newElement && *newElement? _strdup(newElement) : "");
}
int c4_StringArray::Add(const char* newElement)
{
int n = _ptrs.Add(0);
SetAt(n, newElement);
return n;
}
void c4_StringArray::InsertAt(int nIndex, const char* newElement, int nCount)
{
_ptrs.InsertAt(nIndex, 0, nCount);
while (--nCount >= 0)
SetAt(nIndex++, newElement);
}
void c4_StringArray::RemoveAt(int nIndex, int nCount)
{
for (int i = 0; i < nCount; ++i)
SetAt(nIndex + i, 0);
_ptrs.RemoveAt(nIndex, nCount);
}
/////////////////////////////////////////////////////////////////////////////
#endif // q4_UNIV