mirror of
https://github.com/MacPaw/XADMaster.git
synced 2025-08-29 03:23:48 +02:00
275 lines
8.1 KiB
C
275 lines
8.1 KiB
C
#ifndef XADMASTER_OBJECTS_C
|
||
#define XADMASTER_OBJECTS_C
|
||
|
||
/* $Id: objects.c,v 1.10 2005/06/23 14:54:37 stoecker Exp $
|
||
object allocation functions
|
||
|
||
XAD library system for archive handling
|
||
Copyright (C) 1998 and later by Dirk Stˆcker <soft@dstoecker.de>
|
||
|
||
This library is free software; you can redistribute it and/or
|
||
modify it under the terms of the GNU Lesser General Public
|
||
License as published by the Free Software Foundation; either
|
||
version 2.1 of the License, or (at your option) any later version.
|
||
|
||
This library is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public
|
||
License along with this library; if not, write to the Free Software
|
||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||
*/
|
||
|
||
#include "include/functions.h"
|
||
|
||
#ifndef AMIGA
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#define ObtainSemaphore(a)
|
||
#define ReleaseSemaphore(a)
|
||
#define AllocMem(a,b) malloc(a)
|
||
#define FreeMem(a,b) free(a)
|
||
#else
|
||
#include <proto/exec.h>
|
||
#define SysBase xadMasterBase->xmb_SysBase
|
||
#endif
|
||
|
||
FUNCxadAllocVec /* xadSize size, xadUINT32 flags */
|
||
{
|
||
struct xadObject *obj;
|
||
|
||
size += sizeof(struct xadObject);
|
||
if((obj = (struct xadObject *) AllocMem((size_t)size, flags)))
|
||
{
|
||
#ifndef AMIGA
|
||
if(flags & XADMEMF_CLEAR)
|
||
memset(obj, 0, size);
|
||
#endif
|
||
obj->xo_Size = (xadUINT32)size;
|
||
obj->xo_Type = XADOBJ_MEMBLOCK;
|
||
#ifdef DEBUGRESOURCE
|
||
obj->xo_Next = 0;
|
||
obj->xo_Cookie = XADOBJCOOKIE;
|
||
#ifdef AMIGA
|
||
obj->xo_Task = FindTask(NULL);
|
||
ObtainSemaphore(&xadMasterBase->xmb_ResourceLock);
|
||
#endif
|
||
if((obj->xo_Last = xadMasterBase->xmb_Resource))
|
||
obj->xo_Last->xo_Next = obj;
|
||
xadMasterBase->xmb_Resource = obj;
|
||
ReleaseSemaphore(&xadMasterBase->xmb_ResourceLock);
|
||
#endif
|
||
++obj;
|
||
}
|
||
|
||
#ifdef DEBUG
|
||
DebugMem("xadAllocVec: $%08lx, size %ld(+%ld)", obj,
|
||
size-sizeof(struct xadObject), sizeof(struct xadObject));
|
||
#endif
|
||
|
||
return obj;
|
||
}
|
||
ENDFUNC
|
||
|
||
#define ENDSTRUCT(b) (((xadUINT8 *) obj) + sizeof(struct b))
|
||
|
||
#if defined(DEBUG) || defined(DEBUGRESOURCE)
|
||
static const xadSTRPTR debtype[] = {"unknown", "XADOBJ_ARCHIVEINFO",
|
||
"XADOBJ_FILEINFO", "XADOBJ_DISKINFO", "XADOBJ_HOOKPARAM",
|
||
"XADOBJ_DEVICEINFO", "XADOBJ_PROGRESSINFO", "XADOBJ_TEXTINFO",
|
||
"XADOBJ_SPLITFILE", "XADOBJ_SKIPINFO", "XADOBJ_IMAGEINFO",
|
||
"XADOBJ_SPECIAL"};
|
||
|
||
xadSTRPTR xadGetObjectTypeName(xadUINT32 type)
|
||
{
|
||
if(type == XADOBJ_MEMBLOCK)
|
||
return "XADOBJ_MEMBLOCK";
|
||
else if(type == XADOBJ_STRING)
|
||
return "XADOBJ_STRING";
|
||
else if(type <= XADOBJ_SPECIAL)
|
||
return debtype[type];
|
||
return debtype[0];
|
||
}
|
||
#endif
|
||
|
||
FUNCxadAllocObject /* xadUINT32 type, xadTAGPTR tags */
|
||
{
|
||
struct xadObject *obj = 0;
|
||
|
||
#ifdef DEBUG
|
||
DebugTagListMem("xadAllocObjectA(%s [%ld], ...)", tags,
|
||
debtype[type > XADOBJ_SPECIAL ? 0 : type], type);
|
||
#endif
|
||
|
||
switch(type)
|
||
{
|
||
case XADOBJ_FILEINFO:
|
||
{
|
||
xadTAGPTR ti;
|
||
xadSize nsize = 0, csize = 0, psize = 0;
|
||
if((ti = FindTagItem(XAD_OBJNAMESIZE, tags)))
|
||
nsize = ti->ti_Data + 1; /* +1 for programs forgetting 0 byte */
|
||
if((ti = FindTagItem(XAD_OBJCOMMENTSIZE, tags)))
|
||
csize = ti->ti_Data + 1;
|
||
if((ti = FindTagItem(XAD_OBJPRIVINFOSIZE, tags)))
|
||
psize = ti->ti_Data;
|
||
|
||
if((obj = xadAllocVec(XADM nsize + csize + psize + sizeof(struct xadFileInfo),
|
||
XADMEMF_PUBLIC|XADMEMF_CLEAR)))
|
||
{
|
||
if(psize)
|
||
((struct xadFileInfo *) obj)->xfi_PrivateInfo
|
||
= ENDSTRUCT(xadFileInfo);
|
||
if(nsize)
|
||
((struct xadFileInfo *) obj)->xfi_FileName
|
||
= (xadSTRPTR) ENDSTRUCT(xadFileInfo) + psize;
|
||
if(csize)
|
||
((struct xadFileInfo *) obj)->xfi_Comment
|
||
= (xadSTRPTR) ENDSTRUCT(xadFileInfo) + psize + nsize;
|
||
}
|
||
}
|
||
break;
|
||
case XADOBJ_DISKINFO:
|
||
{
|
||
xadTAGPTR ti;
|
||
xadSize bsize = 0, psize = 0;
|
||
if((ti = FindTagItem(XAD_OBJBLOCKENTRIES, tags)))
|
||
bsize = ti->ti_Data;
|
||
if((ti = FindTagItem(XAD_OBJPRIVINFOSIZE, tags)))
|
||
psize = (ti->ti_Data+3)&(~3); /* rounded to long */
|
||
if((obj = xadAllocVec(XADM bsize + psize + sizeof(struct xadDiskInfo),
|
||
XADMEMF_PUBLIC|XADMEMF_CLEAR)))
|
||
{
|
||
if(psize)
|
||
((struct xadDiskInfo *) obj)->xdi_PrivateInfo
|
||
= ENDSTRUCT(xadDiskInfo);
|
||
if(bsize)
|
||
{
|
||
((struct xadDiskInfo *) obj)->xdi_BlockInfo
|
||
= (xadUINT8 *) ENDSTRUCT(xadDiskInfo) + psize;
|
||
((struct xadDiskInfo *) obj)->xdi_BlockInfoSize = (xadUINT32)bsize;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case XADOBJ_ARCHIVEINFO:
|
||
obj = xadAllocVec(XADM sizeof(struct xadArchiveInfoP),
|
||
XADMEMF_PUBLIC|XADMEMF_CLEAR); break;
|
||
case XADOBJ_HOOKPARAM:
|
||
obj = xadAllocVec(XADM sizeof(struct xadHookParam),
|
||
XADMEMF_PUBLIC|XADMEMF_CLEAR); break;
|
||
case XADOBJ_DEVICEINFO:
|
||
obj = xadAllocVec(XADM sizeof(struct xadDeviceInfo),
|
||
XADMEMF_PUBLIC|XADMEMF_CLEAR); break;
|
||
case XADOBJ_PROGRESSINFO:
|
||
obj = xadAllocVec(XADM sizeof(struct xadProgressInfo),
|
||
XADMEMF_PUBLIC|XADMEMF_CLEAR); break;
|
||
case XADOBJ_TEXTINFO:
|
||
obj = xadAllocVec(XADM sizeof(struct xadTextInfo),
|
||
XADMEMF_PUBLIC|XADMEMF_CLEAR); break;
|
||
case XADOBJ_SPLITFILE:
|
||
obj = xadAllocVec(XADM sizeof(struct xadSplitFile),
|
||
XADMEMF_PUBLIC|XADMEMF_CLEAR); break;
|
||
case XADOBJ_SKIPINFO:
|
||
obj = xadAllocVec(XADM sizeof(struct xadSkipInfo),
|
||
XADMEMF_PUBLIC|XADMEMF_CLEAR); break;
|
||
case XADOBJ_IMAGEINFO:
|
||
obj = xadAllocVec(XADM sizeof(struct xadImageInfo),
|
||
XADMEMF_PUBLIC|XADMEMF_CLEAR); break;
|
||
case XADOBJ_SPECIAL:
|
||
obj = xadAllocVec(XADM sizeof(struct xadSpecial),
|
||
XADMEMF_PUBLIC|XADMEMF_CLEAR); break;
|
||
}
|
||
|
||
if(obj)
|
||
(obj-1)->xo_Type = type;
|
||
|
||
return obj;
|
||
}
|
||
ENDFUNC
|
||
|
||
FUNCxadFreeObject /* xadPTR object, xadTAGPTR tags */
|
||
{
|
||
if(!object)
|
||
{
|
||
#ifdef DEBUG
|
||
DebugError("xadFreeObjectA: empty object pointer");
|
||
#endif
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
struct xadObject *obj;
|
||
|
||
obj = ((struct xadObject *) object) - 1; /* get xadObject header */
|
||
|
||
#ifdef DEBUG
|
||
if(obj->xo_Type == XADOBJ_MEMBLOCK)
|
||
{
|
||
if(!tags)
|
||
DebugMem("xadFreeObjectA: XADOBJ_MEMBLOCK ($%08lx)", object);
|
||
else
|
||
DebugTagListMem("xadFreeObjectA: XADOBJ_MEMBLOCK ($%08lx)", tags,
|
||
object);
|
||
}
|
||
else
|
||
DebugTagListMem("xadFreeObjectA: %s ($%08lx)", tags,
|
||
xadGetObjectTypeName(obj->xo_Type), object);
|
||
#endif
|
||
#ifdef DEBUGRESOURCE
|
||
if(obj->xo_Cookie != XADOBJCOOKIE)
|
||
{
|
||
DebugResource(xadMasterBase,
|
||
"xadFreeObjectA: %s ($%08lx) has defective cookie $%08lx",
|
||
xadGetObjectTypeName(obj->xo_Type), object, obj->xo_Cookie);
|
||
}
|
||
|
||
if((obj->xo_Task != FindTask(NULL)))
|
||
{
|
||
DebugResource(xadMasterBase,
|
||
"xadFreeObjectA: %s ($%08lx) was allocated by task $%08lx",
|
||
xadGetObjectTypeName(obj->xo_Type), object, obj->xo_Task);
|
||
}
|
||
|
||
ObtainSemaphore(&xadMasterBase->xmb_ResourceLock);
|
||
if(!obj->xo_Next) /* this is last entry, correct list */
|
||
{
|
||
if(obj != xadMasterBase->xmb_Resource)
|
||
{
|
||
DebugResource(xadMasterBase,
|
||
"xadFreeObjectA: %s ($%08lx) last entry incorrect",
|
||
xadGetObjectTypeName(obj->xo_Type), object);
|
||
}
|
||
xadMasterBase->xmb_Resource = obj->xo_Last;
|
||
}
|
||
else
|
||
{
|
||
if(obj->xo_Next->xo_Cookie != XADOBJCOOKIE)
|
||
{
|
||
DebugResource(xadMasterBase,
|
||
"xadFreeObjectA: %s ($%08lx) has defective next cookie $%08lx",
|
||
xadGetObjectTypeName(obj->xo_Type), object, obj->xo_Next->xo_Cookie);
|
||
}
|
||
obj->xo_Next->xo_Last = obj->xo_Last;
|
||
}
|
||
if(obj->xo_Last)
|
||
{
|
||
if(obj->xo_Last->xo_Cookie != XADOBJCOOKIE)
|
||
{
|
||
DebugResource(xadMasterBase,
|
||
"xadFreeObjectA: %s ($%08lx) has defective last cookie $%08lx",
|
||
xadGetObjectTypeName(obj->xo_Type), object, obj->xo_Last->xo_Cookie);
|
||
}
|
||
obj->xo_Last->xo_Next = obj->xo_Next;
|
||
}
|
||
ReleaseSemaphore(&xadMasterBase->xmb_ResourceLock);
|
||
#endif
|
||
|
||
FreeMem(obj, obj->xo_Size);
|
||
}
|
||
}
|
||
ENDFUNC
|
||
|
||
#endif /* XADMASTER_OBJECTS_C */
|