]> git.wh0rd.org - fontconfig.git/blob - src/fcserialize.c
d0d35e3413a3c10834839d29e7fb48dcc04de2ea
[fontconfig.git] / src / fcserialize.c
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
25 typedef union _FcAlign {
26 double d;
27 int i;
28 intptr_t ip;
29 FcBool b;
30 void *p;
31 } FcAlign;
32
33 intptr_t
34 FcAlignSize (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
47 FcSerialize *
48 FcSerializeCreate (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
62 void
63 FcSerializeDestroy (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
86 FcBool
87 FcSerializeAlloc (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 */
109 intptr_t
110 FcSerializeReserve (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 */
121 intptr_t
122 FcSerializeOffset (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 */
137 void *
138 FcSerializePtr (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
147 FcBool
148 FcStrSerializeAlloc (FcSerialize *serialize, const FcChar8 *str)
149 {
150 return FcSerializeAlloc (serialize, str, strlen ((const char *) str) + 1);
151 }
152
153 FcChar8 *
154 FcStrSerialize (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 }