Blame src/fcserialize.c

Packit 352660
/*
Packit 352660
 * Copyright © 2006 Keith Packard
Packit 352660
 *
Packit 352660
 * Permission to use, copy, modify, distribute, and sell this software and its
Packit 352660
 * documentation for any purpose is hereby granted without fee, provided that
Packit 352660
 * the above copyright notice appear in all copies and that both that copyright
Packit 352660
 * notice and this permission notice appear in supporting documentation, and
Packit 352660
 * that the name of the copyright holders not be used in advertising or
Packit 352660
 * publicity pertaining to distribution of the software without specific,
Packit 352660
 * written prior permission.  The copyright holders make no representations
Packit 352660
 * about the suitability of this software for any purpose.  It is provided "as
Packit 352660
 * is" without express or implied warranty.
Packit 352660
 *
Packit 352660
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
Packit 352660
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
Packit 352660
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
Packit 352660
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
Packit 352660
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
Packit 352660
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
Packit 352660
 * OF THIS SOFTWARE.
Packit 352660
 */
Packit 352660
Packit 352660
#include "fcint.h"
Packit 352660
Packit 352660
intptr_t
Packit 352660
FcAlignSize (intptr_t size)
Packit 352660
{
Packit 352660
    intptr_t	rem = size % sizeof (FcAlign);
Packit 352660
    if (rem)
Packit 352660
	size += sizeof (FcAlign) - rem;
Packit 352660
    return size;
Packit 352660
}
Packit 352660
Packit 352660
/*
Packit 352660
 * Serialization helper object -- allocate space in the
Packit 352660
 * yet-to-be-created linear array for a serialized font set
Packit 352660
 */
Packit 352660
Packit 352660
FcSerialize *
Packit 352660
FcSerializeCreate (void)
Packit 352660
{
Packit 352660
    FcSerialize	*serialize;
Packit 352660
Packit 352660
    serialize = malloc (sizeof (FcSerialize));
Packit 352660
    if (!serialize)
Packit 352660
	return NULL;
Packit 352660
    serialize->size = 0;
Packit 352660
    serialize->linear = NULL;
Packit 352660
    serialize->cs_freezer = NULL;
Packit 352660
    memset (serialize->buckets, '\0', sizeof (serialize->buckets));
Packit 352660
    return serialize;
Packit 352660
}
Packit 352660
Packit 352660
void
Packit 352660
FcSerializeDestroy (FcSerialize *serialize)
Packit 352660
{
Packit 352660
    uintptr_t	bucket;
Packit 352660
Packit 352660
    for (bucket = 0; bucket < FC_SERIALIZE_HASH_SIZE; bucket++)
Packit 352660
    {
Packit 352660
	FcSerializeBucket   *buck, *next;
Packit 352660
Packit 352660
	for (buck = serialize->buckets[bucket]; buck; buck = next) {
Packit 352660
	    next = buck->next;
Packit 352660
	    free (buck);
Packit 352660
	}
Packit 352660
    }
Packit 352660
    if (serialize->cs_freezer)
Packit 352660
	FcCharSetFreezerDestroy (serialize->cs_freezer);
Packit 352660
    free (serialize);
Packit 352660
}
Packit 352660
Packit 352660
/*
Packit 352660
 * Allocate space for an object in the serialized array. Keep track
Packit 352660
 * of where the object is placed and only allocate one copy of each object
Packit 352660
 */
Packit 352660
Packit 352660
FcBool
Packit 352660
FcSerializeAlloc (FcSerialize *serialize, const void *object, int size)
Packit 352660
{
Packit 352660
    uintptr_t	bucket = ((uintptr_t) object) % FC_SERIALIZE_HASH_SIZE;
Packit 352660
    FcSerializeBucket  *buck;
Packit 352660
Packit 352660
    for (buck = serialize->buckets[bucket]; buck; buck = buck->next)
Packit 352660
	if (buck->object == object)
Packit 352660
	    return FcTrue;
Packit 352660
    buck = malloc (sizeof (FcSerializeBucket));
Packit 352660
    if (!buck)
Packit 352660
	return FcFalse;
Packit 352660
    buck->object = object;
Packit 352660
    buck->offset = serialize->size;
Packit 352660
    buck->next = serialize->buckets[bucket];
Packit 352660
    serialize->buckets[bucket] = buck;
Packit 352660
    serialize->size += FcAlignSize (size);
Packit 352660
    return FcTrue;
Packit 352660
}
Packit 352660
Packit 352660
/*
Packit 352660
 * Reserve space in the serialization array
Packit 352660
 */
Packit 352660
intptr_t
Packit 352660
FcSerializeReserve (FcSerialize *serialize, int size)
Packit 352660
{
Packit 352660
    intptr_t	offset = serialize->size;
Packit 352660
    serialize->size += FcAlignSize (size);
Packit 352660
    return offset;
Packit 352660
}
Packit 352660
Packit 352660
/*
Packit 352660
 * Given an object, return the offset in the serialized array where
Packit 352660
 * the serialized copy of the object is stored
Packit 352660
 */
Packit 352660
intptr_t
Packit 352660
FcSerializeOffset (FcSerialize *serialize, const void *object)
Packit 352660
{
Packit 352660
    uintptr_t	bucket = ((uintptr_t) object) % FC_SERIALIZE_HASH_SIZE;
Packit 352660
    FcSerializeBucket  *buck;
Packit 352660
Packit 352660
    for (buck = serialize->buckets[bucket]; buck; buck = buck->next)
Packit 352660
	if (buck->object == object)
Packit 352660
	    return buck->offset;
Packit 352660
    return 0;
Packit 352660
}
Packit 352660
Packit 352660
/*
Packit 352660
 * Given a cache and an object, return a pointer to where
Packit 352660
 * the serialized copy of the object is stored
Packit 352660
 */
Packit 352660
void *
Packit 352660
FcSerializePtr (FcSerialize *serialize, const void *object)
Packit 352660
{
Packit 352660
    intptr_t	offset = FcSerializeOffset (serialize, object);
Packit 352660
Packit 352660
    if (!offset)
Packit 352660
	return NULL;
Packit 352660
    return (void *) ((char *) serialize->linear + offset);
Packit 352660
}
Packit 352660
Packit 352660
FcBool
Packit 352660
FcStrSerializeAlloc (FcSerialize *serialize, const FcChar8 *str)
Packit 352660
{
Packit 352660
    return FcSerializeAlloc (serialize, str, strlen ((const char *) str) + 1);
Packit 352660
}
Packit 352660
Packit 352660
FcChar8 *
Packit 352660
FcStrSerialize (FcSerialize *serialize, const FcChar8 *str)
Packit 352660
{
Packit 352660
    FcChar8 *str_serialize = FcSerializePtr (serialize, str);
Packit 352660
    if (!str_serialize)
Packit 352660
	return NULL;
Packit 352660
    strcpy ((char *) str_serialize, (const char *) str);
Packit 352660
    return str_serialize;
Packit 352660
}
Packit 352660
#include "fcaliastail.h"
Packit 352660
#undef __fcserialize__