/*
 * 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"
#include "fcftint.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

static FcBool
FcHashOwnsName(const FcChar8 *name);

FcPattern *
FcPatternCreate (void)
{
    FcPattern	*p;

    p = (FcPattern *) malloc (sizeof (FcPattern));
    if (!p)
	return 0;
    FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern));
    p->num = 0;
    p->size = 0;
    p->elts_offset = FcPtrToOffset (p, NULL);
    p->ref = 1;
    return p;
}

void
FcValueDestroy (FcValue v)
{
    switch (v.type) {
    case FcTypeString:
        if (!FcHashOwnsName(v.u.s))
            FcStrFree ((FcChar8 *) v.u.s);
	break;
    case FcTypeMatrix:
	FcMatrixFree ((FcMatrix *) v.u.m);
	break;
    case FcTypeCharSet:
	FcCharSetDestroy ((FcCharSet *) v.u.c);
	break;
    case FcTypeLangSet:
	FcLangSetDestroy ((FcLangSet *) v.u.l);
	break;
    default:
	break;
    }
}

FcValue
FcValueCanonicalize (const FcValue *v)
{
    FcValue new;

    switch (v->type)
    {
    case FcTypeString:
	new.u.s = FcValueString(v);
	new.type = FcTypeString;
	break;
    case FcTypeCharSet:
	new.u.c = FcValueCharSet(v);
	new.type = FcTypeCharSet;
	break;
    case FcTypeLangSet:
	new.u.l = FcValueLangSet(v);
	new.type = FcTypeLangSet;
	break;
    default:
	new = *v;
	break;
    }
    return new;
}

FcValue
FcValueSave (FcValue v)
{
    switch (v.type) {
    case FcTypeString:
	v.u.s = FcStrStaticName (v.u.s);
	if (!v.u.s)
	    v.type = FcTypeVoid;
	break;
    case FcTypeMatrix:
	v.u.m = FcMatrixCopy (v.u.m);
	if (!v.u.m)
	    v.type = FcTypeVoid;
	break;
    case FcTypeCharSet:
	v.u.c = FcCharSetCopy ((FcCharSet *) v.u.c);
	if (!v.u.c)
	    v.type = FcTypeVoid;
	break;
    case FcTypeLangSet:
	v.u.l = FcLangSetCopy (v.u.l);
	if (!v.u.l)
	    v.type = FcTypeVoid;
	break;
    default:
	break;
    }
    return v;
}

void
FcValueListDestroy (FcValueListPtr l)
{
    FcValueListPtr next;
    for (; l; l = next)
    {
	switch (l->value.type) {
	case FcTypeString:
            if (!FcHashOwnsName((FcChar8 *)l->value.u.s))
                FcStrFree ((FcChar8 *)l->value.u.s);
	    break;
	case FcTypeMatrix:
	    FcMatrixFree ((FcMatrix *)l->value.u.m);
	    break;
	case FcTypeCharSet:
	    FcCharSetDestroy
		((FcCharSet *) (l->value.u.c));
	    break;
	case FcTypeLangSet:
	    FcLangSetDestroy
		((FcLangSet *) (l->value.u.l));
	    break;
	default:
	    break;
	}
	next = FcValueListNext(l);
	FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
	free(l);
    }
}

FcBool
FcValueEqual (FcValue va, FcValue vb)
{
    if (va.type != vb.type)
    {
	if (va.type == FcTypeInteger)
	{
	    va.type = FcTypeDouble;
	    va.u.d = va.u.i;
	}
	if (vb.type == FcTypeInteger)
	{
	    vb.type = FcTypeDouble;
	    vb.u.d = vb.u.i;
	}
	if (va.type != vb.type)
	    return FcFalse;
    }
    switch (va.type) {
    case FcTypeVoid:
	return FcTrue;
    case FcTypeInteger:
	return va.u.i == vb.u.i;
    case FcTypeDouble:
	return va.u.d == vb.u.d;
    case FcTypeString:
	return FcStrCmpIgnoreCase (va.u.s, vb.u.s) == 0;
    case FcTypeBool:
	return va.u.b == vb.u.b;
    case FcTypeMatrix:
	return FcMatrixEqual (va.u.m, vb.u.m);
    case FcTypeCharSet:
	return FcCharSetEqual (va.u.c, vb.u.c);
    case FcTypeFTFace:
	return va.u.f == vb.u.f;
    case FcTypeLangSet:
	return FcLangSetEqual (va.u.l, vb.u.l);
    }
    return FcFalse;
}

static FcChar32
FcDoubleHash (double d)
{
    if (d < 0)
	d = -d;
    if (d > 0xffffffff)
	d = 0xffffffff;
    return (FcChar32) d;
}

FcChar32
FcStringHash (const FcChar8 *s)
{
    FcChar8	c;
    FcChar32	h = 0;

    if (s)
	while ((c = *s++))
	    h = ((h << 1) | (h >> 31)) ^ c;
    return h;
}

static FcChar32
FcValueHash (const FcValue *v)
{
    switch (v->type) {
    case FcTypeVoid:
	return 0;
    case FcTypeInteger:
	return (FcChar32) v->u.i;
    case FcTypeDouble:
	return FcDoubleHash (v->u.d);
    case FcTypeString:
	return FcStringHash (FcValueString(v));
    case FcTypeBool:
	return (FcChar32) v->u.b;
    case FcTypeMatrix:
	return (FcDoubleHash (v->u.m->xx) ^
		FcDoubleHash (v->u.m->xy) ^
		FcDoubleHash (v->u.m->yx) ^
		FcDoubleHash (v->u.m->yy));
    case FcTypeCharSet:
	return (FcChar32) FcValueCharSet(v)->num;
    case FcTypeFTFace:
	return FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->family_name) ^
	       FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->style_name);
    case FcTypeLangSet:
	return FcLangSetHash (FcValueLangSet(v));
    }
    return FcFalse;
}

static FcBool
FcValueListEqual (FcValueListPtr la, FcValueListPtr lb)
{
    if (la == lb)
	return FcTrue;

    while (la && lb)
    {
	if (!FcValueEqual (la->value, lb->value))
	    return FcFalse;
	la = FcValueListNext(la);
	lb = FcValueListNext(lb);
    }
    if (la || lb)
	return FcFalse;
    return FcTrue;
}

static FcChar32
FcValueListHash (FcValueListPtr l)
{
    FcChar32	hash = 0;

    for (; l; l = FcValueListNext(l))
    {
	hash = ((hash << 1) | (hash >> 31)) ^ FcValueHash (&l->value);
    }
    return hash;
}

void
FcPatternDestroy (FcPattern *p)
{
    int		    i;
    FcPatternElt    *elts;

    if (p->ref == FC_REF_CONSTANT)
    {
	FcCacheObjectDereference (p);
	return;
    }
	
    if (--p->ref > 0)
	return;

    elts = FcPatternElts (p);
    for (i = 0; i < p->num; i++)
	FcValueListDestroy (FcPatternEltValues(&elts[i]));

    FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
    free (elts);
    FcMemFree (FC_MEM_PATTERN, sizeof (FcPattern));
    free (p);
}

static int
FcPatternObjectPosition (const FcPattern *p, FcObject object)
{
    int	    low, high, mid, c;
    FcPatternElt    *elts = FcPatternElts(p);

    low = 0;
    high = p->num - 1;
    c = 1;
    mid = 0;
    while (low <= high)
    {
	mid = (low + high) >> 1;
	c = elts[mid].object - object;
	if (c == 0)
	    return mid;
	if (c < 0)
	    low = mid + 1;
	else
	    high = mid - 1;
    }
    if (c < 0)
	mid++;
    return -(mid + 1);
}

FcPatternElt *
FcPatternObjectFindElt (const FcPattern *p, FcObject object)
{
    int	    i = FcPatternObjectPosition (p, object);
    if (i < 0)
	return 0;
    return &FcPatternElts(p)[i];
}

FcPatternElt *
FcPatternObjectInsertElt (FcPattern *p, FcObject object)
{
    int		    i;
    FcPatternElt   *e;

    i = FcPatternObjectPosition (p, object);
    if (i < 0)
    {
	i = -i - 1;

	/* reallocate array */
	if (p->num + 1 >= p->size)
	{
	    int s = p->size + 16;
	    if (p->size)
	    {
		FcPatternElt *e0 = FcPatternElts(p);
		e = (FcPatternElt *) realloc (e0, s * sizeof (FcPatternElt));
		if (!e) /* maybe it was mmapped */
		{
		    e = malloc(s * sizeof (FcPatternElt));
		    if (e)
			memcpy(e, e0, p->num * sizeof (FcPatternElt));
		}
	    }
	    else
		e = (FcPatternElt *) malloc (s * sizeof (FcPatternElt));
	    if (!e)
		return FcFalse;
	    p->elts_offset = FcPtrToOffset (p, e);
	    if (p->size)
		FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
	    FcMemAlloc (FC_MEM_PATELT, s * sizeof (FcPatternElt));
	    while (p->size < s)
	    {
		e[p->size].object = 0;
		e[p->size].values = NULL;
		p->size++;
	    }
	}
	
	e = FcPatternElts(p);
	/* move elts up */
	memmove (e + i + 1,
		 e + i,
		 sizeof (FcPatternElt) *
		 (p->num - i));
		
	/* bump count */
	p->num++;
	
	e[i].object = object;
	e[i].values = NULL;
    }

    return FcPatternElts(p) + i;
}

FcBool
FcPatternEqual (const FcPattern *pa, const FcPattern *pb)
{
    int	i;
    FcPatternElt   *pae, *pbe;

    if (pa == pb)
	return FcTrue;

    if (pa->num != pb->num)
	return FcFalse;
    pae = FcPatternElts(pa);
    pbe = FcPatternElts(pb);
    for (i = 0; i < pa->num; i++)
    {
	if (pae[i].object != pbe[i].object)
	    return FcFalse;
	if (!FcValueListEqual (FcPatternEltValues(&pae[i]),
			       FcPatternEltValues(&pbe[i])))
	    return FcFalse;
    }
    return FcTrue;
}

FcChar32
FcPatternHash (const FcPattern *p)
{
    int		i;
    FcChar32	h = 0;
    FcPatternElt    *pe = FcPatternElts(p);

    for (i = 0; i < p->num; i++)
    {
	h = (((h << 1) | (h >> 31)) ^
	     pe[i].object ^
	     FcValueListHash (FcPatternEltValues(&pe[i])));
    }
    return h;
}

FcBool
FcPatternEqualSubset (const FcPattern *pai, const FcPattern *pbi, const FcObjectSet *os)
{
    FcPatternElt    *ea, *eb;
    int		    i;

    for (i = 0; i < os->nobject; i++)
    {
	FcObject    object = FcObjectFromName (os->objects[i]);
	ea = FcPatternObjectFindElt (pai, object);
	eb = FcPatternObjectFindElt (pbi, object);
	if (ea)
	{
	    if (!eb)
		return FcFalse;
	    if (!FcValueListEqual (FcPatternEltValues(ea), FcPatternEltValues(eb)))
		return FcFalse;
	}
	else
	{
	    if (eb)
		return FcFalse;
	}
    }
    return FcTrue;
}

FcBool
FcPatternObjectAddWithBinding  (FcPattern	*p,
				FcObject	object,
				FcValue		value,
				FcValueBinding  binding,
				FcBool		append)
{
    FcPatternElt   *e;
    FcValueListPtr new, *prev;

    if (p->ref == FC_REF_CONSTANT)
	goto bail0;

    new = malloc (sizeof (FcValueList));
    if (!new)
	goto bail0;

    memset(new, 0, sizeof (FcValueList));
    FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList));
    value = FcValueSave (value);
    if (value.type == FcTypeVoid)
	goto bail1;

    /*
     * Make sure the stored type is valid for built-in objects
     */
    if (!FcObjectValidType (object, value.type))
    {
	if (FcDebug() & FC_DBG_OBJTYPES)
	{
	    printf ("FcPattern object %s does not accept value ",
		    FcObjectName (object));
	    FcValuePrint (value);
	}
	goto bail1;
    }

    new->value = value;
    new->binding = binding;
    new->next = NULL;

    e = FcPatternObjectInsertElt (p, object);
    if (!e)
	goto bail2;

    if (append)
    {
	for (prev = &e->values; *prev; prev = &(*prev)->next)
	    ;
	*prev = new;
    }
    else
    {
	new->next = e->values;
	e->values = new;
    }

    return FcTrue;

bail2:
    FcValueDestroy (value);
bail1:
    FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
    free (new);
bail0:
    return FcFalse;
}

FcBool
FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append)
{
    return FcPatternObjectAddWithBinding (p, object,
					  value, FcValueBindingStrong, append);
}

FcBool
FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append)
{
    return FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
					  value, FcValueBindingStrong, append);
}

FcBool
FcPatternAddWeak  (FcPattern *p, const char *object, FcValue value, FcBool append)
{
    return FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
					  value, FcValueBindingWeak, append);
}

FcBool
FcPatternObjectDel (FcPattern *p, FcObject object)
{
    FcPatternElt   *e;

    e = FcPatternObjectFindElt (p, object);
    if (!e)
	return FcFalse;

    /* destroy value */
    FcValueListDestroy (e->values);

    /* shuffle existing ones down */
    memmove (e, e+1,
	     (FcPatternElts(p) + p->num - (e + 1)) *
	     sizeof (FcPatternElt));
    p->num--;
    e = FcPatternElts(p) + p->num;
    e->object = 0;
    e->values = NULL;
    return FcTrue;
}

FcBool
FcPatternDel (FcPattern *p, const char *object)
{
    return FcPatternObjectDel (p, FcObjectFromName (object));
}

FcBool
FcPatternRemove (FcPattern *p, const char *object, int id)
{
    FcPatternElt    *e;
    FcValueListPtr  *prev, l;

    e = FcPatternObjectFindElt (p, FcObjectFromName (object));
    if (!e)
	return FcFalse;
    for (prev = &e->values; (l = *prev); prev = &l->next)
    {
	if (!id)
	{
	    *prev = l->next;
	    l->next = NULL;
	    FcValueListDestroy (l);
	    if (!e->values)
		FcPatternDel (p, object);
	    return FcTrue;
	}
	id--;
    }
    return FcFalse;
}

FcBool
FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i)
{
    FcValue	v;

    v.type = FcTypeInteger;
    v.u.i = i;
    return FcPatternObjectAdd (p, object, v, FcTrue);
}

FcBool
FcPatternAddInteger (FcPattern *p, const char *object, int i)
{
    return FcPatternObjectAddInteger (p, FcObjectFromName (object), i);
}

FcBool
FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d)
{
    FcValue	v;

    v.type = FcTypeDouble;
    v.u.d = d;
    return FcPatternObjectAdd (p, object, v, FcTrue);
}


FcBool
FcPatternAddDouble (FcPattern *p, const char *object, double d)
{
    return FcPatternObjectAddDouble (p, FcObjectFromName (object), d);
}

FcBool
FcPatternObjectAddString (FcPattern *p, FcObject object, const FcChar8 *s)
{
    FcValue	v;

    if (!s)
    {
	v.type = FcTypeVoid;
	v.u.s = 0;
	return FcPatternObjectAdd (p, object, v, FcTrue);
    }

    v.type = FcTypeString;
    v.u.s = FcStrStaticName(s);
    return FcPatternObjectAdd (p, object, v, FcTrue);
}

FcBool
FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
{
    return FcPatternObjectAddString (p, FcObjectFromName (object), s);
}

FcBool
FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s)
{
    FcValue	v;

    v.type = FcTypeMatrix;
    v.u.m = s;
    return FcPatternAdd (p, object, v, FcTrue);
}


FcBool
FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b)
{
    FcValue	v;

    v.type = FcTypeBool;
    v.u.b = b;
    return FcPatternObjectAdd (p, object, v, FcTrue);
}

FcBool
FcPatternAddBool (FcPattern *p, const char *object, FcBool b)
{
    return FcPatternObjectAddBool (p, FcObjectFromName (object), b);
}

FcBool
FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c)
{
    FcValue	v;

    v.type = FcTypeCharSet;
    v.u.c = (FcCharSet *)c;
    return FcPatternAdd (p, object, v, FcTrue);
}

FcBool
FcPatternAddFTFace (FcPattern *p, const char *object, const FT_Face f)
{
    FcValue	v;

    v.type = FcTypeFTFace;
    v.u.f = (void *) f;
    return FcPatternAdd (p, object, v, FcTrue);
}

FcBool
FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls)
{
    FcValue	v;

    v.type = FcTypeLangSet;
    v.u.l = (FcLangSet *)ls;
    return FcPatternAdd (p, object, v, FcTrue);
}

FcResult
FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v)
{
    FcPatternElt   *e;
    FcValueListPtr l;

    e = FcPatternObjectFindElt (p, object);
    if (!e)
	return FcResultNoMatch;
    for (l = FcPatternEltValues(e); l; l = FcValueListNext(l))
    {
	if (!id)
	{
	    *v = FcValueCanonicalize(&l->value);
	    return FcResultMatch;
	}
	id--;
    }
    return FcResultNoId;
}

FcResult
FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v)
{
    return FcPatternObjectGet (p, FcObjectFromName (object), id, v);
}

FcResult
FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int id, int *i)
{
    FcValue	v;
    FcResult	r;

    r = FcPatternObjectGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    switch (v.type) {
    case FcTypeDouble:
	*i = (int) v.u.d;
	break;
    case FcTypeInteger:
	*i = v.u.i;
	break;
    default:
        return FcResultTypeMismatch;
    }
    return FcResultMatch;
}

FcResult
FcPatternGetInteger (const FcPattern *p, const char *object, int id, int *i)
{
    return FcPatternObjectGetInteger (p, FcObjectFromName (object), id, i);
}


FcResult
FcPatternObjectGetDouble (const FcPattern *p, FcObject object, int id, double *d)
{
    FcValue	v;
    FcResult	r;

    r = FcPatternObjectGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    switch (v.type) {
    case FcTypeDouble:
	*d = v.u.d;
	break;
    case FcTypeInteger:
	*d = (double) v.u.i;
	break;
    default:
        return FcResultTypeMismatch;
    }
    return FcResultMatch;
}

FcResult
FcPatternGetDouble (const FcPattern *p, const char *object, int id, double *d)
{
    return FcPatternObjectGetDouble (p, FcObjectFromName (object), id, d);
}

FcResult
FcPatternObjectGetString (const FcPattern *p, FcObject object, int id, FcChar8 ** s)
{
    FcValue	v;
    FcResult	r;

    r = FcPatternObjectGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    if (v.type != FcTypeString)
        return FcResultTypeMismatch;

    *s = (FcChar8 *) v.u.s;
    return FcResultMatch;
}

FcResult
FcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s)
{
    return FcPatternObjectGetString (p, FcObjectFromName (object), id, s);
}

FcResult
FcPatternGetMatrix(const FcPattern *p, const char *object, int id, FcMatrix **m)
{
    FcValue	v;
    FcResult	r;

    r = FcPatternGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    if (v.type != FcTypeMatrix)
        return FcResultTypeMismatch;
    *m = (FcMatrix *)v.u.m;
    return FcResultMatch;
}


FcResult
FcPatternGetBool(const FcPattern *p, const char *object, int id, FcBool *b)
{
    FcValue	v;
    FcResult	r;

    r = FcPatternGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    if (v.type != FcTypeBool)
        return FcResultTypeMismatch;
    *b = v.u.b;
    return FcResultMatch;
}

FcResult
FcPatternGetCharSet(const FcPattern *p, const char *object, int id, FcCharSet **c)
{
    FcValue	v;
    FcResult	r;

    r = FcPatternGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    if (v.type != FcTypeCharSet)
        return FcResultTypeMismatch;
    *c = (FcCharSet *)v.u.c;
    return FcResultMatch;
}

FcResult
FcPatternGetFTFace(const FcPattern *p, const char *object, int id, FT_Face *f)
{
    FcValue	v;
    FcResult	r;

    r = FcPatternGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    if (v.type != FcTypeFTFace)
	return FcResultTypeMismatch;
    *f = (FT_Face) v.u.f;
    return FcResultMatch;
}

FcResult
FcPatternGetLangSet(const FcPattern *p, const char *object, int id, FcLangSet **ls)
{
    FcValue	v;
    FcResult	r;

    r = FcPatternGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    if (v.type != FcTypeLangSet)
        return FcResultTypeMismatch;
    *ls = (FcLangSet *)v.u.l;
    return FcResultMatch;
}

FcPattern *
FcPatternDuplicate (const FcPattern *orig)
{
    FcPattern	    *new;
    FcPatternElt    *e;
    int		    i;
    FcValueListPtr  l;

    new = FcPatternCreate ();
    if (!new)
	goto bail0;

    e = FcPatternElts(orig);

    for (i = 0; i < orig->num; i++)
    {
	for (l = FcPatternEltValues(e + i); l; l = FcValueListNext(l))
	{
	    if (!FcPatternObjectAddWithBinding (new, e[i].object,
						FcValueCanonicalize(&l->value),
						l->binding,
						FcTrue))
		goto bail1;
	
	}
    }

    return new;

bail1:
    FcPatternDestroy (new);
bail0:
    return 0;
}

void
FcPatternReference (FcPattern *p)
{
    if (p->ref != FC_REF_CONSTANT)
	p->ref++;
    else
	FcCacheObjectReference (p);
}

FcPattern *
FcPatternVaBuild (FcPattern *p, va_list va)
{
    FcPattern	*ret;

    FcPatternVapBuild (ret, p, va);
    return ret;
}

FcPattern *
FcPatternBuild (FcPattern *p, ...)
{
    va_list	va;

    va_start (va, p);
    FcPatternVapBuild (p, p, va);
    va_end (va);
    return p;
}

/*
 * Add all of the elements in 's' to 'p'
 */
FcBool
FcPatternAppend (FcPattern *p, FcPattern *s)
{
    int		    i;
    FcPatternElt    *e;
    FcValueListPtr  v;

    for (i = 0; i < s->num; i++)
    {
	e = FcPatternElts(s)+i;
	for (v = FcPatternEltValues(e); v; v = FcValueListNext(v))
	{
	    if (!FcPatternObjectAddWithBinding (p, e->object,
						FcValueCanonicalize(&v->value),
						v->binding, FcTrue))
		return FcFalse;
	}
    }
    return FcTrue;
}

FcPattern *
FcPatternFilter (FcPattern *p, const FcObjectSet *os)
{
    int		    i;
    FcPattern	    *ret;
    FcPatternElt    *e;
    FcValueListPtr  v;

    if (!os)
	return FcPatternDuplicate (p);

    ret = FcPatternCreate ();
    if (!ret)
	return NULL;

    for (i = 0; i < os->nobject; i++)
    {
	FcObject object = FcObjectFromName (os->objects[i]);
	e = FcPatternObjectFindElt (p, object);
	if (e)
	{
	    for (v = FcPatternEltValues(e); v; v = FcValueListNext(v))
	    {
		if (!FcPatternObjectAddWithBinding (ret, e->object,
						    FcValueCanonicalize(&v->value),
						    v->binding, FcTrue))
		    goto bail0;
	    }
	}
    }
    return ret;

bail0:
    FcPatternDestroy (ret);
    return NULL;
}

#define OBJECT_HASH_SIZE    31
static struct objectBucket {
    struct objectBucket	*next;
    FcChar32		hash;
} *FcObjectBuckets[OBJECT_HASH_SIZE];

static FcBool
FcHashOwnsName (const FcChar8 *name)
{
    FcChar32		hash = FcStringHash (name);
    struct objectBucket	**p;
    struct objectBucket	*b;

    for (p = &FcObjectBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
	if (b->hash == hash && ((char *)name == (char *) (b + 1)))
            return FcTrue;
    return FcFalse;
}

const FcChar8 *
FcStrStaticName (const FcChar8 *name)
{
    FcChar32		hash = FcStringHash (name);
    struct objectBucket	**p;
    struct objectBucket	*b;
    int			size;

    for (p = &FcObjectBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
	if (b->hash == hash && !strcmp ((char *)name, (char *) (b + 1)))
	    return (FcChar8 *) (b + 1);
    size = sizeof (struct objectBucket) + strlen ((char *)name) + 1;
    /*
     * workaround valgrind warning because glibc takes advantage of how it knows memory is
     * allocated to implement strlen by reading in groups of 4
     */
    size = (size + 3) & ~3;
    b = malloc (size);
    FcMemAlloc (FC_MEM_STATICSTR, size);
    if (!b)
        return NULL;
    b->next = 0;
    b->hash = hash;
    strcpy ((char *) (b + 1), (char *)name);
    *p = b;
    return (FcChar8 *) (b + 1);
}

static void
FcStrStaticNameFini (void)
{
    int i, size;
    struct objectBucket *b, *next;
    char *name;

    for (i = 0; i < OBJECT_HASH_SIZE; i++)
    {
	for (b = FcObjectBuckets[i]; b; b = next)
	{
	    next = b->next;
	    name = (char *) (b + 1);
	    size = sizeof (struct objectBucket) + strlen (name) + 1;
	    FcMemFree (FC_MEM_STATICSTR, size + sizeof (int));
	    free (b);
	}
	FcObjectBuckets[i] = 0;
    }
}

void
FcPatternFini (void)
{
    FcStrStaticNameFini ();
    FcObjectFini ();
}

FcBool
FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat)
{
    int	i;
    FcPatternElt    *elts = FcPatternElts(pat);

    if (!FcSerializeAlloc (serialize, pat, sizeof (FcPattern)))
	return FcFalse;
    if (!FcSerializeAlloc (serialize, elts, pat->num * sizeof (FcPatternElt)))
	return FcFalse;
    for (i = 0; i < pat->num; i++)
	if (!FcValueListSerializeAlloc (serialize, FcPatternEltValues(elts+i)))
	    return FcFalse;
    return FcTrue;
}

FcPattern *
FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat)
{
    FcPattern	    *pat_serialized;
    FcPatternElt    *elts = FcPatternElts (pat);
    FcPatternElt    *elts_serialized;
    FcValueList	    *values_serialized;
    int		    i;

    pat_serialized = FcSerializePtr (serialize, pat);
    if (!pat_serialized)
	return NULL;
    *pat_serialized = *pat;
    pat_serialized->size = pat->num;
    pat_serialized->ref = FC_REF_CONSTANT;

    elts_serialized = FcSerializePtr (serialize, elts);
    if (!elts_serialized)
	return NULL;

    pat_serialized->elts_offset = FcPtrToOffset (pat_serialized,
						 elts_serialized);

    for (i = 0; i < pat->num; i++)
    {
	values_serialized = FcValueListSerialize (serialize, FcPatternEltValues (elts+i));
	if (!values_serialized)
	    return NULL;
	elts_serialized[i].object = elts[i].object;
	elts_serialized[i].values = FcPtrToEncodedOffset (&elts_serialized[i],
							  values_serialized,
							  FcValueList);
    }
    if (FcDebug() & FC_DBG_CACHEV) {
	printf ("Raw pattern:\n");
	FcPatternPrint (pat);
	printf ("Serialized pattern:\n");
	FcPatternPrint (pat_serialized);
	printf ("\n");
    }
    return pat_serialized;
}

FcBool
FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *vl)
{
    while (vl)
    {
	if (!FcSerializeAlloc (serialize, vl, sizeof (FcValueList)))
	    return FcFalse;
	switch (vl->value.type) {
	case FcTypeString:
	    if (!FcStrSerializeAlloc (serialize, vl->value.u.s))
		return FcFalse;
	    break;
	case FcTypeCharSet:
	    if (!FcCharSetSerializeAlloc (serialize, vl->value.u.c))
		return FcFalse;
	    break;
	case FcTypeLangSet:
	    if (!FcLangSetSerializeAlloc (serialize, vl->value.u.l))
		return FcFalse;
	    break;
	default:
	    break;
	}
	vl = vl->next;
    }
    return FcTrue;
}

FcValueList *
FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl)
{
    FcValueList	*vl_serialized;
    FcChar8	*s_serialized;
    FcCharSet	*c_serialized;
    FcLangSet	*l_serialized;
    FcValueList	*head_serialized = NULL;
    FcValueList	*prev_serialized = NULL;

    while (vl)
    {
	vl_serialized = FcSerializePtr (serialize, vl);
	if (!vl_serialized)
	    return NULL;

	if (prev_serialized)
	    prev_serialized->next = FcPtrToEncodedOffset (prev_serialized,
							  vl_serialized,
							  FcValueList);
	else
	    head_serialized = vl_serialized;
	
	vl_serialized->next = NULL;
	vl_serialized->value.type = vl->value.type;
	switch (vl->value.type) {
	case FcTypeInteger:
	    vl_serialized->value.u.i = vl->value.u.i;
	    break;
	case FcTypeDouble:
	    vl_serialized->value.u.d = vl->value.u.d;
	    break;
	case FcTypeString:
	    s_serialized = FcStrSerialize (serialize, vl->value.u.s);
	    if (!s_serialized)
		return NULL;
	    vl_serialized->value.u.s = FcPtrToEncodedOffset (&vl_serialized->value,
							     s_serialized,
							     FcChar8);
	    break;
	case FcTypeBool:
	    vl_serialized->value.u.b = vl->value.u.b;
	    break;
	case FcTypeMatrix:
	    /* can't happen */
	    break;
	case FcTypeCharSet:
	    c_serialized = FcCharSetSerialize (serialize, vl->value.u.c);
	    if (!c_serialized)
		return NULL;
	    vl_serialized->value.u.c = FcPtrToEncodedOffset (&vl_serialized->value,
							     c_serialized,
							     FcCharSet);
	    break;
	case FcTypeFTFace:
	    /* can't happen */
	    break;
	case FcTypeLangSet:
	    l_serialized = FcLangSetSerialize (serialize, vl->value.u.l);
	    if (!l_serialized)
		return NULL;
	    vl_serialized->value.u.l = FcPtrToEncodedOffset (&vl_serialized->value,
							     l_serialized,
							     FcLangSet);
	    break;
	default:
	    break;
	}
	prev_serialized = vl_serialized;
	vl = vl->next;
    }
    return head_serialized;
}
#define __fcpat__
#include "fcaliastail.h"
#include "fcftaliastail.h"
#undef __fcpat__
