[Contents] [Index] [Help] [Retrace] [Browse <] [Browse >]

/*
**  dillo.c
**
**  A code module of armadillo.library, which implements the main library
**  functions.  Strictly do-nothing code for example.
**
**  © Copyright 1993-1999, Amiga, Inc. All Rights Reserved.
**  Written by John Wiederhirn
**
*/

#include    <exec/types.h>
#include    <exec/memory.h>
#include    <clib/exec_protos.h>
#include    <pragmas/exec_pragmas.h>

extern struct ExecBase *SysBase;        /* olsen 30-Jan-96 */

#include    "dillo.h"
#include    "dillo_protos.h"

/* The next prototype is for a static function which is only available
** to code inside the library itself.
*/

static void ClearDilloName(struct Armadillo * );


/* The following global data item becomes part of the near data section
** for each library client.  Since this library is designed to give a
** different library base to each client, this data item is unique per
** client.
**
** It holds the number of armadillos a given client has open at once.
*/

ULONG TotalDillos = 0L;

/* In contrast to the previous global data item, the following goes in
** the far data section and is global to all library clients.  Read access
** doesn't need arbitration, but write access needs a semaphor or use of
** a Forbid()/Permit() pair (see CreateDillo() below).
**
** It holds the number of times CreateDillo has been called overall.
*/

ULONG __far TotalDillosCreated = 0L;

/* This routine just allocates a `struct Armadillo', and increments
** the number of armadillos this client has by one.  If the allocation
** cannot be done, this routine returns NULL.
*/

struct Armadillo * __saveds __asm
LIBCreateArmadillo( register __a6 struct Library *DilloBase )
{
    struct Armadillo *newdillo = NULL;

    if ( newdillo = AllocMem( sizeof(struct Armadillo), MEMF_CLEAR ))
    {
        /* Armadillo allocated, so increment number of dillos.
        ** Note that to reference the client-unique data takes no
        ** special coding.
        */

        TotalDillos++;

        /* Since we've also added to the overall number created, we
        ** need to also update the TotalDillosCreated variable in
        ** the far data section.  That means a Forbid() and Permit()
        ** around the action (which MUST complete).
        */

        Forbid();
        TotalDillosCreated++;
        Permit();

    }

    /* And return either the address of the new armadillo, or else
    ** return NULL if the allocation failed.
    */

    return( newdillo );
}


/* This function wipes an existing Armadillo structure out of existance
** and decrements the number of Armadillos for this client.  Note that the
** number of Armadillos created overall does not go down.
*/

VOID __saveds __asm
LIBDeleteArmadillo( register __a0 struct Armadillo *dillo,
                    register __a6 struct Library *DilloBase )
{
    /* This routine is ``safe'' in that it can handle being given a NULL
    ** pointer (in which case it does nothing).
    */

    if ( dillo )
    {
        /* We do indeed appear to have an armadillo on our hands
        ** so we decrement the overall count and deallocate the
        ** memory it uses.
        */

        TotalDillos--;

        FreeMem( dillo, sizeof( struct Armadillo ));
    }

    return;
}

/* This transfers the contents of a string up to 32 characters long into
** the name buffer of an Armadillo.  Any attempt to transfer more than 32
** characters gets truncated to 32 characters.  Returns FALSE if dillo
** was a NULL pointer, the pointer to the string was NULL, or the length
** of the transfer was to be 0L.
*/

BOOL __saveds __asm
LIBNameArmadillo( register __a0 struct Armadillo *dillo,
                  register __a1 STRPTR dname,
                  register __d0 ULONG len,
                  register __a6 struct Library *DilloBase )
{
    BOOL retval = FALSE;

    /* This routine is ``safe'' in that it can handle being given a NULL
    ** pointer (in which case it does nothing).
    */

    if ( dillo && dname && len )
    {
        CopyMem( (APTR) dname, (APTR) &(dillo->name), ((len>31L)?32L:len) );
        retval = TRUE;
    }

    return( retval );
}


/* Assigns a value to the weight field of an Armadillo structure.  It
** returns NULL if a NULL pointer is passed in or amt was 0L.
*/

BOOL __saveds __asm
LIBFillArmadillo( register __a0 struct Armadillo *dillo,
                  register __d0 ULONG amt,
                  register __a6 struct Library *DilloBase )
{
    BOOL retval = FALSE;

    /* This routine is ``safe'' in that it can handle being given a NULL
    ** pointer (in which case it does nothing).
    */

    if ( dillo && amt )
    {
        dillo->weight = amt;
        retval = TRUE;
    }

    return( retval );
}


/* In homage to the Texas state animal, the roadkill armadillo, this function
** sets whether a given Armadillo is flattened or not.  Returns NULL if a
** NULL pointer was passed as the Armadillo structure.
*/

BOOL __saveds __asm
LIBFlattenArmadillo( register __a0 struct Armadillo *dillo,
                     register __d0 BOOL flatd,
                     register __a6 struct Library *DilloBase )
{
    BOOL retval = FALSE;

    /* This routine is ``safe'' in that it can handle being given a NULL
    ** pointer (in which case it does nothing).
    */

    if ( dillo )
    {
        dillo->flat = flatd;
        retval = TRUE;
    }

    return( retval );
}


/* Returns whether or not the Armadillo has been flattened.  If a NULL
** pointer is passed in, this function returns FALSE (not really distinct).
*/

BOOL __saveds __asm
LIBDilloFlat( register __a0 struct Armadillo *dillo,
              register __a6 struct Library *DilloBase )
{
    BOOL retval = FALSE;

    /* This routine is ``safe'' in that it can handle being given a NULL
    ** pointer (in which case it returns FALSE).
    */

    if ( dillo )
    {
        retval = dillo->flat;
    }

    return( retval );
}


/* Returns the weight of a given Armadillo or 0L if a NULL pointer
** is passed instead of an Armadillo (no pointer == no weight ).
*/

ULONG __saveds __asm
LIBDilloWeight( register __a0 struct Armadillo *dillo,
                register __a6 struct Library *DilloBase )
{
    ULONG retval = 0L;

    /* This routine is ``safe'' in that it can handle being given a NULL
    ** pointer (in which case it returns 0L).
    */

    if ( dillo )
    {
        retval = dillo->weight;
    }

    return( retval );
}


/* This function copies the name of an Armadillo into the caller-specified
** buffer (which MUST be at least 32 characters in length).  A NULL pointer
** for the Armadillo, buffer or len will get a FALSE return, otherwise a
** return of TRUE if the transfer occurred.
*/

BOOL __saveds __asm
LIBDilloName( register __a0 struct Armadillo *dillo,
              register __a1 STRPTR buf,
              register __d0 ULONG len,
              register __a6 struct Library *DilloBase )
{
    BOOL retval = FALSE;

    /* This routine is ``safe'' in that it can handle being given a NULL
    ** pointer (in which case it does nothing).
    */

    if ( dillo && buf && len)
    {
        CopyMem( (APTR) &(dillo->name), (APTR) buf, ((len>31L)?32L:len) );
        retval = TRUE;
    }

    return( retval );
}


/* Following are non-public but externally-accessible entry points. */

/* This routine clears out the contents of an Armadillo.  It also is an
** example of using a non-public non-ext.-accessible routine in a shared
** library.
*/

VOID __saveds __asm
LIBClearDillo( register __a0 struct Armadillo *dillo,
               register __a6 struct Library *DilloBase )
{
    /* This routine is ``safe'' in that it can handle being given a NULL
    ** pointer (in which case it does nothing).
    */

    if ( dillo )
    {
        dillo->flat = FALSE;
        dillo->weight = 0L;
        ClearDilloName( dillo );
    }
}


/* This routine does an "unprotected" query (legal, since the access is
** read-only) of the TotalDillosCreated variable in the far data section.
*/

ULONG __saveds __asm
LIBDilloBirths( register __a6 struct Library *DilloBase )
{
    return( TotalDillosCreated );
}


/* Following call is a non-public non-externally-accessible function */

/* This function is callable ONLY from within this module.  It clears out
** the name buffer for a given Armadillo.
*/

static VOID
ClearDilloName( struct Armadillo *dillo )
{
    int i;

    /* This routine is NOT 'safe'.  Params must be pre-checked. */

    for(i=0;i<31;i++)
        dillo->name[i] = '\0';

}