cdesktopenv/cde/lib/DtHelp/il/ilobject.c

179 lines
6.4 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they 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 these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: ilobject.c /main/3 1995/10/23 15:58:21 rswiston $ */
/**---------------------------------------------------------------------
***
*** (c)Copyright 1991 Hewlett-Packard Co.
***
*** RESTRICTED RIGHTS LEGEND
*** Use, duplication, or disclosure by the U.S. Government is subject to
*** restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
*** Technical Data and Computer Software clause in DFARS 252.227-7013.
*** Hewlett-Packard Company
*** 3000 Hanover Street
*** Palo Alto, CA 94304 U.S.A.
*** Rights for non-DOD U.S. Government Departments and Agencies are as set
*** forth in FAR 52.227-19(c)(1,2).
***
***-------------------------------------------------------------------*/
/* /ilc/ilobject.c : General object handling code, e.g. ilDestroyObject().
*/
#include <stdlib.h>
#include "ilint.h"
#include "ilcontext.h"
#include "ilerrors.h"
/* ------------------------ ilCreateObject ----------------------------------- */
/* Creates an object of size "sizeInBytes" and returns a ptr to it, or null
if failure (the error code in "context" is set in either case). The object
is added to the given "context". "sizeInBytes" must be a minimum of
"sizeof(ilObjectRec)".
The function "Destroy" will be called by ilDestroyObject(), as:
Destroy (ilObjectPtr pObject);
Before destroying this object. The Destroy() function must free any
object-specific data etc. It MUST not touch the fields in the object header
(ilObjectRec) or free *pObject.
*/
IL_PRIVATE ilObjectPtr _ilCreateObject (
ilContext context, /* context to add object to */
int objectType, /* code for object, e.g. IL_PIPE */
void (*Destroy)(), /* destroy function; see above */
/* Use portable type, bug report OSF_QAR#32082 */
size_t sizeInBytes /* size of object to create */
)
{
ilContextPtr pContext;
ilObjectPtr pObject;
/* Allocate object rec, return if failure.
*/
pContext = (ilContextPtr)context;
pObject = (ilObjectPtr)IL_MALLOC (sizeInBytes);
if (!pObject) {
pContext->p.error = IL_ERROR_MALLOC;
return (ilObjectPtr)NULL;
}
/* Fill in object header, init refCount to 1 => no one attached to it yet.
*/
pObject->p.context = (ilContext)pContext;
pObject->p.objectType = objectType;
pObject->p.pPrivate = (ilPtr)NULL;
pObject->Destroy = Destroy;
pObject->refCount = 1;
/* Add the object to the front of the list of objects.
*/
pObject->pNext = pContext->objectHead.pNext;
pObject->pPrev = (ilPtr)&pContext->objectHead;
((ilObjectPtr)pContext->objectHead.pNext)->pPrev = (ilPtr)pObject;
pContext->objectHead.pNext = (ilPtr)pObject;
pContext->p.error = IL_OK;
return pObject;
}
/* ------------------------ ilDestroyObject -------------------------------- */
/* Public function: see spec.
*/
ilBool ilDestroyObject (
ilObject object
)
{
ilObjectPtr pObject;
/* Downcount refCount, exit if not zero - object is still attached to others.
Call object-specific destroy function, free client private if present,
remove object from the linked list, free the object.
*/
pObject = (ilObjectPtr)object;
if ((pObject->p.objectType == IL_NULL_OBJECT)
|| (pObject->p.objectType > IL_MAX_OBJECT_TYPE)) {
pObject->p.context->error = IL_ERROR_OBJECT_TYPE;
return FALSE;
}
pObject->p.context->error = 0;
if (--pObject->refCount > 0)
return TRUE; /* object still attached; EXIT */
(*pObject->Destroy) (pObject);
if (pObject->p.pPrivate)
free (pObject->p.pPrivate); /* note: caller used malloc, not IL_MALLOC() */
((ilObjectPtr)pObject->pPrev)->pNext = (ilPtr)pObject->pNext;
((ilObjectPtr)pObject->pNext)->pPrev = (ilPtr)pObject->pPrev;
IL_FREE (pObject);
return TRUE;
}
/* ------------------------ ilObjectInitContext ------------------------- */
/* Called by ilCreateContext() to create object data in the given context.
Returns: true if add was ok, else error: caller should free all.
*/
IL_PRIVATE ilBool _ilObjectInitContext (
ilContextPtr pContext
)
{
/* pCOD->head points to the list of objects; init list to null (point to self).
*/
pContext->objectHead.p.context = (ilContext)pContext;
pContext->objectHead.pPrev = pContext->objectHead.pNext = (ilPtr)&pContext->objectHead;
return TRUE;
}
/* ------------------------ ilObjectDestroyContext ------------------------- */
/* Called by ilDestroyContext() to destroy object data in the given context.
*/
IL_PRIVATE void _ilObjectDestroyContext (
ilContextPtr pContext
)
{
ilObjectPtr pObject, pNextObject, pObjectHead;
/* Loop thru and destroy all objects until list points back to head (done).
*/
pObjectHead = &pContext->objectHead;
pObject = (ilObjectPtr)pObjectHead->pNext;
while (pObject != pObjectHead) {
pNextObject = (ilObjectPtr)pObject->pNext;
ilDestroyObject ((ilObject)pObject);
pObject = pNextObject;
}
}