fcserialize.c revision 2c393a42
1/*
2 * Copyright © 2006 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission.  The copyright holders make no representations
11 * about the suitability of this software for any purpose.  It is provided "as
12 * is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
21 */
22
23#include "fcint.h"
24
25typedef union _FcAlign {
26    double	d;
27    int		i;
28    intptr_t	ip;
29    FcBool	b;
30    void	*p;
31} FcAlign;
32
33intptr_t
34FcAlignSize (intptr_t size)
35{
36    intptr_t	rem = size % sizeof (FcAlign);
37    if (rem)
38	size += sizeof (FcAlign) - rem;
39    return size;
40}
41
42/*
43 * Serialization helper object -- allocate space in the
44 * yet-to-be-created linear array for a serialized font set
45 */
46
47FcSerialize *
48FcSerializeCreate (void)
49{
50    FcSerialize	*serialize;
51
52    serialize = malloc (sizeof (FcSerialize));
53    if (!serialize)
54	return NULL;
55    serialize->size = 0;
56    serialize->linear = NULL;
57    serialize->cs_freezer = NULL;
58    memset (serialize->buckets, '\0', sizeof (serialize->buckets));
59    return serialize;
60}
61
62void
63FcSerializeDestroy (FcSerialize *serialize)
64{
65    uintptr_t	bucket;
66
67    for (bucket = 0; bucket < FC_SERIALIZE_HASH_SIZE; bucket++)
68    {
69	FcSerializeBucket   *buck, *next;
70
71	for (buck = serialize->buckets[bucket]; buck; buck = next) {
72	    next = buck->next;
73	    free (buck);
74	}
75    }
76    if (serialize->cs_freezer)
77	FcCharSetFreezerDestroy (serialize->cs_freezer);
78    free (serialize);
79}
80
81/*
82 * Allocate space for an object in the serialized array. Keep track
83 * of where the object is placed and only allocate one copy of each object
84 */
85
86FcBool
87FcSerializeAlloc (FcSerialize *serialize, const void *object, int size)
88{
89    uintptr_t	bucket = ((uintptr_t) object) % FC_SERIALIZE_HASH_SIZE;
90    FcSerializeBucket  *buck;
91
92    for (buck = serialize->buckets[bucket]; buck; buck = buck->next)
93	if (buck->object == object)
94	    return FcTrue;
95    buck = malloc (sizeof (FcSerializeBucket));
96    if (!buck)
97	return FcFalse;
98    buck->object = object;
99    buck->offset = serialize->size;
100    buck->next = serialize->buckets[bucket];
101    serialize->buckets[bucket] = buck;
102    serialize->size += FcAlignSize (size);
103    return FcTrue;
104}
105
106/*
107 * Reserve space in the serialization array
108 */
109intptr_t
110FcSerializeReserve (FcSerialize *serialize, int size)
111{
112    intptr_t	offset = serialize->size;
113    serialize->size += FcAlignSize (size);
114    return offset;
115}
116
117/*
118 * Given an object, return the offset in the serialized array where
119 * the serialized copy of the object is stored
120 */
121intptr_t
122FcSerializeOffset (FcSerialize *serialize, const void *object)
123{
124    uintptr_t	bucket = ((uintptr_t) object) % FC_SERIALIZE_HASH_SIZE;
125    FcSerializeBucket  *buck;
126
127    for (buck = serialize->buckets[bucket]; buck; buck = buck->next)
128	if (buck->object == object)
129	    return buck->offset;
130    return 0;
131}
132
133/*
134 * Given a cache and an object, return a pointer to where
135 * the serialized copy of the object is stored
136 */
137void *
138FcSerializePtr (FcSerialize *serialize, const void *object)
139{
140    intptr_t	offset = FcSerializeOffset (serialize, object);
141
142    if (!offset)
143	return NULL;
144    return (void *) ((char *) serialize->linear + offset);
145}
146
147FcBool
148FcStrSerializeAlloc (FcSerialize *serialize, const FcChar8 *str)
149{
150    return FcSerializeAlloc (serialize, str, strlen ((const char *) str) + 1);
151}
152
153FcChar8 *
154FcStrSerialize (FcSerialize *serialize, const FcChar8 *str)
155{
156    FcChar8 *str_serialize = FcSerializePtr (serialize, str);
157    if (!str_serialize)
158	return NULL;
159    strcpy ((char *) str_serialize, (const char *) str);
160    return str_serialize;
161}
162#define __fcserialize__
163#include "fcaliastail.h"
164#undef __fcserialize__
165