/*
 * fontconfig/src/fclist.c
 *
 * Copyright © 2000 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of the author(s) not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  The authors make no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include "fcint.h"

static unsigned int
FcObjectTypeHash (register const char *str, register unsigned int len);

static const struct FcObjectTypeInfo *
FcObjectTypeLookup (register const char *str, register unsigned int len);

#include "fcobjshash.h"

#include <string.h>

/* The 1000 is to leave some room for future added internal objects, such
 * that caches from newer fontconfig can still be used with older fontconfig
 * without getting confused. */
static fc_atomic_int_t next_id = FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX;
struct FcObjectOtherTypeInfo {
    struct FcObjectOtherTypeInfo *next;
    FcObjectType object;
    FcObject id;
} *other_types;

static FcObjectType *
_FcObjectLookupOtherTypeByName (const char *str, FcObject *id)
{
    struct FcObjectOtherTypeInfo *ots, *ot;

retry:
    ots = fc_atomic_ptr_get (&other_types);

    for (ot = ots; ot; ot = ot->next)
	if (0 == strcmp (ot->object.object, str))
	    break;

    if (!ot)
    {
	ot = malloc (sizeof (*ot));
	if (!ot)
	    return NULL;

	ot->object.object = (const char *) FcStrdup (str);
	ot->object.type = FcTypeUnknown;
	ot->id = fc_atomic_int_add (next_id, +1);
	ot->next = ots;

	if (!fc_atomic_ptr_cmpexch (&other_types, ots, ot)) {
	    free (ot);
	    goto retry;
	}
    }

    if (id)
      *id = ot->id;

    return &ot->object;
}

FcObject
FcObjectLookupBuiltinIdByName (const char *str)
{
    const struct FcObjectTypeInfo *o = FcObjectTypeLookup (str, strlen (str));

    if (o)
	return o->id;

    return 0;
}

FcObject
FcObjectLookupIdByName (const char *str)
{
    const struct FcObjectTypeInfo *o = FcObjectTypeLookup (str, strlen (str));
    FcObject id;
    if (o)
	return o->id;

    if (_FcObjectLookupOtherTypeByName (str, &id))
	return id;

    return 0;
}

const char *
FcObjectLookupOtherNameById (FcObject id)
{
    struct FcObjectOtherTypeInfo *ot;

    for (ot = fc_atomic_ptr_get (&other_types); ot; ot = ot->next)
	if (ot->id == id)
	    return ot->object.object;

    return NULL;
}

const FcObjectType *
FcObjectLookupOtherTypeByName (const char *str)
{
    return _FcObjectLookupOtherTypeByName (str, NULL);
}

FcPrivate const FcObjectType *
FcObjectLookupOtherTypeById (FcObject id)
{
    struct FcObjectOtherTypeInfo *ot;

    for (ot = fc_atomic_ptr_get (&other_types); ot; ot = ot->next)
	if (ot->id == id)
	    return &ot->object;

    return NULL;
}


#include "fcaliastail.h"
#undef __fcobjs__
