khronosfws/openmax_al/src/common/xametadataextractionitf.c
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 15:43:02 +0300
branchRCL_3
changeset 45 095bea5f582e
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 *
 * Initial Contributors:
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
 *
 * Description: Metadata Extraction Interface Implementation
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "xametadataextractionitf.h"
#include "xadebug.h"

#include "xametadataadaptation.h"

#include "xaadaptationmmf.h"
#include "xametadataadaptctxmmf.h"
#include "xamediaplayeradaptctxmmf.h"
#include "cmetadatautilityitf.h"

/* XAMetadataExtractionItfImpl* GetImpl(XAMetadataExtractionItf self)
 * Description: Validate interface pointer and cast it to implementation pointer.
 **/
static XAMetadataExtractionItfImpl* GetImpl(XAMetadataExtractionItf self)
    {
    if (self)
        {
        XAMetadataExtractionItfImpl* impl =
                (XAMetadataExtractionItfImpl*) (*self);
        if (impl && (impl == impl->self))
            {
            return impl;
            }
        }
    return NULL;
    }

static void* GetMetadataUtilityContext(XAAdaptationMMFCtx* adaptCtx)
    {
    if (adaptCtx)
        {
        switch (adaptCtx->baseObj.ctxId)
            {
            case XAMediaPlayerAdaptation:
                return ((XAMediaPlayerAdaptationMMFCtx*) adaptCtx)->mmfMetadataContext;
            case XAMDAdaptation:
                return ((XAMetadataAdaptationMMFCtx*) adaptCtx)->mmfContext;
            default:
                break;
            }

        }
    return NULL;
    }
/*****************************************************************************
 * Base interface XAMetadataExtractionItf implementation
 *****************************************************************************/

/*
 * Returns the number of metadata items within the current scope of the object.
 * @XAuint32 *pItemCount
 *      Number of metadata items.  Must be non-NULL
 */
XAresult XAMetadataExtractionItfImpl_GetItemCount(
        XAMetadataExtractionItf self, XAuint32 *pItemCount)
    {
    XAMetadataExtractionItfImpl *impl = NULL;
    XAresult res = XA_RESULT_SUCCESS;
    DEBUG_API("->XAMetadataExtractionItfImpl_GetItemCount");

    impl = GetImpl(self);
    /* check parameters */
    if (!impl || !pItemCount)
        {
        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
        res = XA_RESULT_PARAMETER_INVALID;
        }
    else
        {

        if (impl->adaptCtx)
            {

            if (impl->adaptCtx->fwtype == FWMgrFWMMF)
                {
                void *mmfCtx = GetMetadataUtilityContext(
                        (XAAdaptationMMFCtx*) impl->adaptCtx);
                if (mmfCtx)
                    {
                    res = mmf_get_item_count(mmfCtx, pItemCount);
                    }
                else
                    {
                    res = XA_RESULT_PARAMETER_INVALID;
                    }
                }
            else
                {
                if (impl->filteringOn)
                    {
                    *pItemCount = impl->filteredcount;
                    }
                else
                    {
                    *pItemCount = impl->currentTags.itemcount;
                    }
                res = XA_RESULT_SUCCESS;
                }
            }
        else
            {
            res = XA_RESULT_INTERNAL_ERROR;
            }

        DEBUG_INFO_A1("itemCount = %d", (int)*pItemCount);
        }

    DEBUG_API_A1("<-XAMetadataExtractionItfImpl_GetItemCount (%d)", (int)res);
    return res;
    }

/*
 * Returns the byte size of a given metadata key
 *
 * @XAuint32 index
 *      Metadata item Index. Range is [0, GetItemCount)
 * @XAuint32 *pKeySize
 *      Address to store key size. size must be greater than 0.  Must be non-NULL
 */
XAresult XAMetadataExtractionItfImpl_GetKeySize(XAMetadataExtractionItf self,
        XAuint32 index, XAuint32 *pKeySize)
    {
    XAMetadataExtractionItfImpl *impl = NULL;
    XAresult res = XA_RESULT_SUCCESS;
    XAuint32 newidx = 0;
    DEBUG_API("->XAMetadataExtractionItfImpl_GetKeySize");

    impl = GetImpl(self);
    if (!impl || !pKeySize)
        {
        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
        DEBUG_API("<-XAMetadataExtractionItfImpl_GetKeySize");
        return XA_RESULT_PARAMETER_INVALID;
        }
    *pKeySize = 0;

    if (impl->adaptCtx && impl->adaptCtx->fwtype == FWMgrFWMMF)
        {
        void *mmfCtx = GetMetadataUtilityContext(
                (XAAdaptationMMFCtx*) impl->adaptCtx);
        if (mmfCtx)
            {
            res = mmf_get_key_size(mmfCtx, index, pKeySize);
            }
        else
            {
            res = XA_RESULT_PARAMETER_INVALID;
            }
        }
    else
        {
        /* check index and return unfiltered index */
        if (CheckAndUnfilterIndex(impl, index, &newidx) != XA_RESULT_SUCCESS)
            {
            DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
            DEBUG_API("<-XAMetadataExtractionItfImpl_GetKeySize");
            return XA_RESULT_PARAMETER_INVALID;
            }

        /* size = size of struct + size of data - 1 (struct size already includes one char) */
        *pKeySize = sizeof(XAMetadataInfo)
                + impl->currentTags.mdeKeys[newidx]->size - 1;
        }

    DEBUG_API_A1("<-XAMetadataExtractionItfImpl_GetKeySize (%d)", (int)res);
    return res;
    }

/*
 * Returns a XAMetadataInfo structure and associated data referenced by the structure for a key.
 * @XAuint32 index
 *      Metadata item Index. Range is [0, GetItemCount())
 * @XAuint32 keySize
 *      Size of the memory block passed as key. Range is [1, GetKeySize].
 * @XAMetadataInfo *pKey
 *      Address to store the key.  Must be non-NULL
 */
XAresult XAMetadataExtractionItfImpl_GetKey(XAMetadataExtractionItf self,
        XAuint32 index, XAuint32 keySize, XAMetadataInfo *pKey)
    {
    XAMetadataExtractionItfImpl *impl = NULL;
    XAresult res = XA_RESULT_SUCCESS;
    XAuint32 newidx = 0;

    XAuint32 neededsize = 0;

    XAuint32 newdatasize = 0;
    DEBUG_API("->XAMetadataExtractionItfImpl_GetKey");

    impl = GetImpl(self);
    if (!impl || !pKey)
        {
        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
        DEBUG_API("<-XAMetadataExtractionItfImpl_GetKey");
        return XA_RESULT_PARAMETER_INVALID;
        }

    memset(pKey, 0, keySize);

    if (impl->adaptCtx && impl->adaptCtx->fwtype == FWMgrFWMMF)
        {
        void *mmfCtx = GetMetadataUtilityContext(
                (XAAdaptationMMFCtx*) impl->adaptCtx);
        if (mmfCtx)
            {
            res = mmf_get_key(mmfCtx, index, keySize, pKey);
            }
        else
            {
            res = XA_RESULT_PARAMETER_INVALID;
            }
        }
    else
        {

        /* check index and return unfiltered index */
        if (CheckAndUnfilterIndex(impl, index, &newidx) != XA_RESULT_SUCCESS)
            {
            DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
            DEBUG_API("<-XAMetadataExtractionItfImpl_GetKey");
            return XA_RESULT_PARAMETER_INVALID;
            }

        /* needed size = size of struct + size of data - 1 (struct size already includes one char) */
        neededsize = sizeof(XAMetadataInfo)
                + impl->currentTags.mdeKeys[newidx]->size - 1;
        if (keySize < neededsize)
            { /* cannot fit all of key data */
            newdatasize = impl->currentTags.mdeKeys[newidx]->size
                    - (neededsize - keySize);
            DEBUG_ERR("XA_RESULT_BUFFER_INSUFFICIENT");
            res = XA_RESULT_BUFFER_INSUFFICIENT;
            }
        else
            {
            newdatasize = impl->currentTags.mdeKeys[newidx]->size;
            res = XA_RESULT_SUCCESS;
            }
        /* copy data up to given size */
        memcpy(pKey, impl->currentTags.mdeKeys[newidx], keySize - 1);
        /* ensure null-termination */

        memset(pKey->data + newdatasize - 1, 0, 1);
        pKey->size = newdatasize;
        }

    DEBUG_API_A1("<-XAMetadataExtractionItfImpl_GetKey (%d)", (int)res);
    return res;
    }

/*
 * Returns the byte size of a given metadata value
 * @XAuint32 index
 *      Metadata item Index. Range is [0, GetItemCount())
 * @XAuint32 *pValueSize
 *      Address to store value size. size must be greater than 0.  Must be non-NULL
 */
XAresult XAMetadataExtractionItfImpl_GetValueSize(
        XAMetadataExtractionItf self, XAuint32 index, XAuint32 *pValueSize)
    {
    XAMetadataExtractionItfImpl *impl = NULL;
    XAresult res = XA_RESULT_SUCCESS;
    XAuint32 newidx = 0;
    DEBUG_API("->XAMetadataExtractionItfImpl_GetValueSize");

    impl = GetImpl(self);
    if (!impl || !pValueSize)
        {
        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
        DEBUG_API("<-XAMetadataExtractionItfImpl_GetValueSize");
        return XA_RESULT_PARAMETER_INVALID;
        }
    *pValueSize = 0;

    if (impl->adaptCtx && impl->adaptCtx->fwtype == FWMgrFWMMF)
        {
        void *mmfCtx = GetMetadataUtilityContext(
                (XAAdaptationMMFCtx*) impl->adaptCtx);
        if (mmfCtx)
            {
            res = mmf_get_value_size(mmfCtx, index, pValueSize);
            }
        else
            {
            res = XA_RESULT_PARAMETER_INVALID;
            }
        }
    else
        {
        /* check index and return unfiltered index */
        if (CheckAndUnfilterIndex(impl, index, &newidx) != XA_RESULT_SUCCESS)
            {
            DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
            DEBUG_API("<-XAMetadataExtractionItfImpl_GetValueSize");
            return XA_RESULT_PARAMETER_INVALID;
            }

        /* size = size of struct + size of data - 1 (struct size already includes one char) */
        *pValueSize = sizeof(XAMetadataInfo)
                + impl->currentTags.mdeValues[newidx]->size - 1;
        }

    DEBUG_API_A1("<-XAMetadataExtractionItfImpl_GetValueSize (%d)", (int)res);
    return res;
    }

/*
 * Returns a XAMetadataInfo structure and associated data referenced by the structure for a value.
 *  @XAuint32 index
 *      Metadata item Index. Range is [0, GetItemCount())
 *  @XAuint32 valueSize
 *      Size of the memory block passed as value. Range is [0, GetValueSize]
 *  @XAMetadataInfo *pValue
 *      Address to store the value.  Must be non-NULL
 */
XAresult XAMetadataExtractionItfImpl_GetValue(XAMetadataExtractionItf self,
        XAuint32 index, XAuint32 valueSize, XAMetadataInfo *pValue)
    {
    XAMetadataExtractionItfImpl *impl = NULL;
    XAresult res = XA_RESULT_SUCCESS;
    XAuint32 newidx = 0;

    XAuint32 neededsize = 0;

    XAuint32 newdatasize = 0;
    DEBUG_API("->XAMetadataExtractionItfImpl_GetValue");

    impl = GetImpl(self);
    if (!impl || !pValue)
        {
        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
        DEBUG_API("<-XAMetadataExtractionItfImpl_GetValue");
        return XA_RESULT_PARAMETER_INVALID;
        }

    memset(pValue, 0, valueSize);

    if (impl->adaptCtx && impl->adaptCtx->fwtype == FWMgrFWMMF)
        {
        void *mmfCtx = GetMetadataUtilityContext(
                (XAAdaptationMMFCtx*) impl->adaptCtx);
        if (mmfCtx)
            {
            res = mmf_get_value(mmfCtx, index, valueSize, pValue);
            }
        else
            {
            res = XA_RESULT_PARAMETER_INVALID;
            }
        }
    else
        {
        /* check index and return unfiltered index */
        if (CheckAndUnfilterIndex(impl, index, &newidx) != XA_RESULT_SUCCESS)
            {
            DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
            DEBUG_API("<-XAMetadataExtractionItfImpl_GetValue");
            return XA_RESULT_PARAMETER_INVALID;
            }

        /* needed size = size of struct + size of data - 1 (struct size already includes one char) */
        neededsize = sizeof(XAMetadataInfo)
                + impl->currentTags.mdeValues[newidx]->size - 1;
        if (valueSize < neededsize)
            { /* cannot fit all of key data */
            newdatasize = impl->currentTags.mdeValues[newidx]->size
                    - (neededsize - valueSize);
            DEBUG_ERR("XA_RESULT_BUFFER_INSUFFICIENT");
            res = XA_RESULT_BUFFER_INSUFFICIENT;
            }
        else
            {
            newdatasize = impl->currentTags.mdeValues[newidx]->size;
            res = XA_RESULT_SUCCESS;
            }
        /* copy data up to given size */
        memcpy(pValue, impl->currentTags.mdeValues[newidx], valueSize - 1);
        /* ensure null-termination */

        memset(pValue->data + newdatasize - 1, 0, 1);

        pValue->size = newdatasize;
        }

    DEBUG_API_A1("<-XAMetadataExtractionItfImpl_GetValue (%d)",(int)res);
    return res;
    }

/*
 * Adds a filter for a specific key
 * @XAuint32 keySize
 *      Size in bytes, of the pKey parameter. Ignored if filtering by key is disabled
 * @const void *pKey
 *      The key to filter by. The entire key must match. Ignored if filtering by key is disabled.
 * @XAuint32 keyEncoding
 *      Character encoding of the pKey parameter. Ignored if filtering by key is disabled
 * @const XAchar *pValueLangCountry
 *      Language / country code of the value to filter by. Ignored if filtering by language / country is disabled
 * @XAuint32 valueEncoding
 *      Encoding of the value to filter by. Ignored if filtering by encoding is disabled
 * @XAuint8 filterMask
 *      Bitmask indicating which criteria to filter by. Should be one of the XA_METADATA_FILTER macros
 */
XAresult XAMetadataExtractionItfImpl_AddKeyFilter(
        XAMetadataExtractionItf self, XAuint32 keySize, const void *pKey,
        XAuint32 keyEncoding, const XAchar *pValueLangCountry,
        XAuint32 valueEncoding, XAuint8 filterMask)
    {
    XAresult res = XA_RESULT_SUCCESS;

    XAuint32 idx = 0;
    XAuint8 matchMask = 0;

    XAMetadataExtractionItfImpl *impl = NULL;
    const XAchar* parsedkey;
    impl = GetImpl(self);

    DEBUG_API("->XAMetadataExtractionItfImpl_AddKeyFilter");

    if (!impl)
        {
        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
        DEBUG_API("<-XAMetadataExtractionItfImpl_AddKeyFilter");
        return XA_RESULT_PARAMETER_INVALID;
        }
    else
        {

        if (impl->adaptCtx && impl->adaptCtx->fwtype == FWMgrFWMMF)
            {
            DEBUG_API("<-XAMetadataExtractionItfImpl_AddKeyFilter Not Supported in MMF");
            res = XA_RESULT_PARAMETER_INVALID;
            }
        else
            {
            impl->filteringOn = XA_BOOLEAN_TRUE;
            for (idx = 0; idx < impl->currentTags.itemcount; idx++)
                {
                if ((filterMask & XA_METADATA_FILTER_KEY) && pKey)
                    {
                    parsedkey = XAMetadataAdapt_ParseKhronosKey(pKey);
                    if (strcmp((char*) parsedkey,
                            (char*) impl->currentTags.mdeKeys[idx]->data)
                            == 0)
                        {
                        matchMask |= XA_METADATA_FILTER_KEY;
                        }
                    }
                if (filterMask & XA_METADATA_FILTER_LANG && pValueLangCountry)
                    {
                    if (strcmp(
                            (char*) pValueLangCountry,
                            (char*) impl->currentTags.mdeKeys[idx]->langCountry)
                            == 0)
                        {
                        matchMask |= XA_METADATA_FILTER_LANG;
                        }
                    }
                if (filterMask & XA_METADATA_FILTER_ENCODING)
                    {
                    if (keyEncoding
                            == impl->currentTags.mdeKeys[idx]->encoding)
                        {
                        matchMask |= XA_METADATA_FILTER_ENCODING;
                        }
                    if (valueEncoding
                            == impl->currentTags.mdeValues[idx]->encoding)
                        {
                        matchMask |= XA_METADATA_FILTER_ENCODING;
                        }
                    }
                /* check if all filters apply */
                if (filterMask == matchMask)
                    {
                    if (impl->tagmatchesfilter[idx] == XA_BOOLEAN_FALSE)
                        {
                        impl->tagmatchesfilter[idx] = XA_BOOLEAN_TRUE;
                        impl->filteredcount++;
                        }
                    }
                /*reset matchmask*/
                matchMask = 0;
                }
            }
        }
    DEBUG_API_A1("<-XAMetadataExtractionItfImpl_AddKeyFilter (%d)", (int)res);
    return res;
    }

/*
 * Clears the key filter
 */
XAresult XAMetadataExtractionItfImpl_ClearKeyFilter(
        XAMetadataExtractionItf self)
    {
    XAMetadataExtractionItfImpl *impl = NULL;
    XAresult res = XA_RESULT_SUCCESS;

    XAuint32 idx = 0;

    DEBUG_API("->XAMetadataExtractionItfImpl_ClearKeyFilter");
    impl = GetImpl(self);
    if (!impl)
        {
        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
        res = XA_RESULT_PARAMETER_INVALID;
        }
    else
        {

        if (impl->adaptCtx && impl->adaptCtx->fwtype == FWMgrFWMMF)
            {
            DEBUG_API("<-XAMetadataExtractionItfImpl_ClearKeyFilter Not Supported in MMF");
            res = XA_RESULT_PARAMETER_INVALID;
            }
        else
            {
            if (impl->tagmatchesfilter)
                {

                for (idx = 0; idx < impl->currentTags.itemcount; idx++)
                    {
                    impl->tagmatchesfilter[idx] = XA_BOOLEAN_FALSE;
                    }

                }
            impl->filteredcount = 0;
            impl->filteringOn = XA_BOOLEAN_FALSE;
            }
        }

    DEBUG_API_A1("<-XAMetadataExtractionItfImpl_ClearKeyFilter (%d)", (int)res);
    return res;
    }

/*****************************************************************************
 * XAMetadataExtractionItfImpl -specific methods
 *****************************************************************************/

/* XAMetadataExtractionItfImpl* XAMetadataExtractionItfImpl_Create()
 * Description: Allocate and initialize XAMetadataExtractionItfImpl
 */
XAMetadataExtractionItfImpl* XAMetadataExtractionItfImpl_Create(
        XAAdaptationBaseCtx *adaptCtx)
    {
    XAMetadataExtractionItfImpl *self = NULL;
    DEBUG_API("->XAMetadataExtractionItfImpl_Create");

    self = (XAMetadataExtractionItfImpl*) calloc(1,
            sizeof(XAMetadataExtractionItfImpl));

    if (self)
        {
        /* init itf default implementation */
        self->itf.GetItemCount = XAMetadataExtractionItfImpl_GetItemCount;
        self->itf.GetKeySize = XAMetadataExtractionItfImpl_GetKeySize;
        self->itf.GetKey = XAMetadataExtractionItfImpl_GetKey;
        self->itf.GetValueSize = XAMetadataExtractionItfImpl_GetValueSize;
        self->itf.GetValue = XAMetadataExtractionItfImpl_GetValue;
        self->itf.AddKeyFilter = XAMetadataExtractionItfImpl_AddKeyFilter;
        self->itf.ClearKeyFilter = XAMetadataExtractionItfImpl_ClearKeyFilter;

        /* init variables */
        self->filteredcount = 0;
        self->filteringOn = XA_BOOLEAN_FALSE;

        self->adaptCtx = adaptCtx;

        if (self->adaptCtx->fwtype != FWMgrFWMMF)
            {
            XAAdaptationBase_AddEventHandler(adaptCtx,
                    &XAMetadataExtractionItfImp_AdaptCb, XA_METADATAEVENTS,
                    self);
            }

        self->self = self;
        }

    DEBUG_API("<-XAMetadataExtractionItfImpl_Create");
    return self;
    }

/* void XAMetadataExtractionItfImpl_Free(XAMetadataExtractionItfImpl* self)
 * Description: Free all resources reserved at XAMetadataExtractionItfImpl_Create
 */
void XAMetadataExtractionItfImpl_Free(XAMetadataExtractionItfImpl* self)
    {
    DEBUG_API("->XAMetadataExtractionItfImpl_Free");
    assert(self==self->self);

    if (self->adaptCtx->fwtype != FWMgrFWMMF)
        {
        XAAdaptationBase_RemoveEventHandler(self->adaptCtx,
                &XAMetadataExtractionItfImp_AdaptCb);
        XAMetadataAdapt_FreeImplTagList(&(self->currentTags), XA_BOOLEAN_TRUE);

        if (self->tagmatchesfilter)
            {
            free(self->tagmatchesfilter);
            }
        }

    free(self);
    DEBUG_API("<-XAMetadataExtractionItfImpl_Free");
    }

/* With this method, adaptation infroms that new tags are found (e.g. if source,
 * has changed, live stream contains metadata...)
 */
void XAMetadataExtractionItfImp_AdaptCb(void *pHandlerCtx,
        XAAdaptEvent *event)
    {
    XAMetadataExtractionItfImpl* impl = NULL;
    DEBUG_API("->XAMetadataExtractionItfImp_AdaptCb");
    impl = (XAMetadataExtractionItfImpl*) pHandlerCtx;
    if (!impl)
        {
        DEBUG_ERR("XAMetadataExtractionItfImp_AdaptCb, invalid context pointer!");
        DEBUG_API("<-XAMetadataExtractionItfImp_AdaptCb");
        return;
        }
    if (event && event->eventid == XA_ADAPT_MDE_TAGS_AVAILABLE)
        {
        /* get the tag list */
        XAMetadataExtractionItfAdapt_FillTagList(
                (XAAdaptationGstCtx*) impl->adaptCtx, &(impl->currentTags));
        if (impl->tagmatchesfilter)
            {
            free(impl->tagmatchesfilter);
            }
        impl->tagmatchesfilter = calloc(impl->currentTags.itemcount,
                sizeof(XAboolean));
        impl->filteredcount = 0;
        }
    else
        {
        DEBUG_INFO("unhandled");
        }
    DEBUG_API("<-XAMetadataExtractionItfImp_AdaptCb");
    }

/* For given index over filtered array, return index over whole array
 */
XAresult CheckAndUnfilterIndex(XAMetadataExtractionItfImpl *impl,
        XAuint32 oldidx, XAuint32 *newidx)
    {
    DEBUG_API("->CheckAndUnfilterIndex");

    if (impl->filteringOn)
        {
        XAint16 i = -1;
        if (oldidx >= impl->filteredcount)
            {
            DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
            DEBUG_API("<-CheckAndUnfilterIndex");
            return XA_RESULT_PARAMETER_INVALID;
            }
        *newidx = 0;
        while (*newidx < impl->currentTags.itemcount)
            {
            if (impl->tagmatchesfilter[*newidx])
                i++;
            if (i < oldidx)
                (*newidx)++;
            else
                break;
            }
        if (*newidx == impl->currentTags.itemcount)
            {
            /* should not end up here */
            *newidx = 0;
            DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
            DEBUG_API("<-CheckAndUnfilterIndex");
            return XA_RESULT_PARAMETER_INVALID;
            }
        }
    else
        {
        if (oldidx >= impl->currentTags.itemcount)
            {
            DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
            DEBUG_API("<-CheckAndUnfilterIndex");
            return XA_RESULT_PARAMETER_INVALID;
            }
        *newidx = oldidx;
        }

    DEBUG_API("<-CheckAndUnfilterIndex");
    return XA_RESULT_SUCCESS;
    }