Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * propmod.c
 * Copyright (C) 2001-2003 A.J. van Os; Released under GPL
 *
 * Description:
 * Build, read and destroy a list (array) of Word property modifiers
 */

#include <stdio.h>
#include <string.h>
#include "antiword.h"

#if defined(DEBUG)
#define ELEMENTS_TO_ADD  3
#else
#define ELEMENTS_TO_ADD 30
#endif /* DEBUG */

/* Variables needed to write the property modifier list */
static UCHAR    **ppAnchor = NULL;
static size_t   tNextFree = 0;
static size_t   tMaxElements = 0;


/*
 * vDestroyPropModList - destroy the property modifier list
 */
void
vDestroyPropModList(void)
{
        size_t  tIndex;

        DBG_MSG("vDestroyPropModList");

        /* Free all the elements of the list */
        for (tIndex = 0; tIndex < tNextFree; tIndex++) {
                ppAnchor[tIndex] = xfree(ppAnchor[tIndex]);
        }
        /* Free the list itself */
        ppAnchor = xfree(ppAnchor);
        /* Reset all control variables */
        tNextFree = 0;
        tMaxElements = 0;
} /* end of vDestroyPropModList */

/*
 * vAdd2PropModList - add an element to the property modifier list
 */
void
vAdd2PropModList(const UCHAR *aucPropMod)
{
        size_t  tSize, tLen;

        fail(aucPropMod == NULL);

        NO_DBG_MSG("vAdd2PropModList");

        if (tNextFree >= tMaxElements) {
                tMaxElements += ELEMENTS_TO_ADD;
                tSize = tMaxElements * sizeof(UCHAR **);
                ppAnchor = xrealloc(ppAnchor, tSize);
        }
        NO_DBG_DEC(tNextFree);

        tLen = 2 + (size_t)usGetWord(0, aucPropMod);
        NO_DBG_HEX(tLen);
        NO_DBG_PRINT_BLOCK(pucPropMod, tLen);
        ppAnchor[tNextFree] = xmalloc(tLen);
        memcpy(ppAnchor[tNextFree], aucPropMod, tLen);
        tNextFree++;
} /* end of vAdd2PropModList */

/*
 * aucReadPropModListItem - get an item of the property modifier list
 */
const UCHAR *
aucReadPropModListItem(USHORT usPropMod)
{
        static UCHAR    aucBuffer[4];
        size_t  tIndex;

        if (usPropMod == IGNORE_PROPMOD) {
                /* This Properties Modifier must be ignored */
                return NULL;
        }

        if (!odd(usPropMod)) {
                /* Variant 1: The information is in the input ifself */
                aucBuffer[0] = 2;
                aucBuffer[1] = 0;
                aucBuffer[2] = (UCHAR)((usPropMod & 0x00fe) >> 1);
                aucBuffer[3] = (UCHAR)((usPropMod & 0xff00) >> 8);
                return aucBuffer;
        }

        if (ppAnchor == NULL) {
                /* No information available */
                return NULL;
        }

        /* Variant 2: The input contains an index */
        tIndex = (size_t)(usPropMod >> 1);
        if (tIndex >= tNextFree) {
                DBG_HEX(usPropMod);
                DBG_DEC(tIndex);
                DBG_DEC(tNextFree);
                return NULL;
        }
        return ppAnchor[tIndex];
} /* end of aucGetPropModListItem */