Make FcCacheIsMmapSafe() threadsafe
[platform/upstream/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 intptr_t
26 FcAlignSize (intptr_t size)
27 {
28     intptr_t    rem = size % sizeof (FcAlign);
29     if (rem)
30         size += sizeof (FcAlign) - rem;
31     return size;
32 }
33
34 /*
35  * Serialization helper object -- allocate space in the
36  * yet-to-be-created linear array for a serialized font set
37  */
38
39 FcSerialize *
40 FcSerializeCreate (void)
41 {
42     FcSerialize *serialize;
43
44     serialize = malloc (sizeof (FcSerialize));
45     if (!serialize)
46         return NULL;
47     serialize->size = 0;
48     serialize->linear = NULL;
49     serialize->cs_freezer = NULL;
50     memset (serialize->buckets, '\0', sizeof (serialize->buckets));
51     return serialize;
52 }
53
54 void
55 FcSerializeDestroy (FcSerialize *serialize)
56 {
57     uintptr_t   bucket;
58
59     for (bucket = 0; bucket < FC_SERIALIZE_HASH_SIZE; bucket++)
60     {
61         FcSerializeBucket   *buck, *next;
62
63         for (buck = serialize->buckets[bucket]; buck; buck = next) {
64             next = buck->next;
65             free (buck);
66         }
67     }
68     if (serialize->cs_freezer)
69         FcCharSetFreezerDestroy (serialize->cs_freezer);
70     free (serialize);
71 }
72
73 /*
74  * Allocate space for an object in the serialized array. Keep track
75  * of where the object is placed and only allocate one copy of each object
76  */
77
78 FcBool
79 FcSerializeAlloc (FcSerialize *serialize, const void *object, int size)
80 {
81     uintptr_t   bucket = ((uintptr_t) object) % FC_SERIALIZE_HASH_SIZE;
82     FcSerializeBucket  *buck;
83
84     for (buck = serialize->buckets[bucket]; buck; buck = buck->next)
85         if (buck->object == object)
86             return FcTrue;
87     buck = malloc (sizeof (FcSerializeBucket));
88     if (!buck)
89         return FcFalse;
90     buck->object = object;
91     buck->offset = serialize->size;
92     buck->next = serialize->buckets[bucket];
93     serialize->buckets[bucket] = buck;
94     serialize->size += FcAlignSize (size);
95     return FcTrue;
96 }
97
98 /*
99  * Reserve space in the serialization array
100  */
101 intptr_t
102 FcSerializeReserve (FcSerialize *serialize, int size)
103 {
104     intptr_t    offset = serialize->size;
105     serialize->size += FcAlignSize (size);
106     return offset;
107 }
108
109 /*
110  * Given an object, return the offset in the serialized array where
111  * the serialized copy of the object is stored
112  */
113 intptr_t
114 FcSerializeOffset (FcSerialize *serialize, const void *object)
115 {
116     uintptr_t   bucket = ((uintptr_t) object) % FC_SERIALIZE_HASH_SIZE;
117     FcSerializeBucket  *buck;
118
119     for (buck = serialize->buckets[bucket]; buck; buck = buck->next)
120         if (buck->object == object)
121             return buck->offset;
122     return 0;
123 }
124
125 /*
126  * Given a cache and an object, return a pointer to where
127  * the serialized copy of the object is stored
128  */
129 void *
130 FcSerializePtr (FcSerialize *serialize, const void *object)
131 {
132     intptr_t    offset = FcSerializeOffset (serialize, object);
133
134     if (!offset)
135         return NULL;
136     return (void *) ((char *) serialize->linear + offset);
137 }
138
139 FcBool
140 FcStrSerializeAlloc (FcSerialize *serialize, const FcChar8 *str)
141 {
142     return FcSerializeAlloc (serialize, str, strlen ((const char *) str) + 1);
143 }
144
145 FcChar8 *
146 FcStrSerialize (FcSerialize *serialize, const FcChar8 *str)
147 {
148     FcChar8 *str_serialize = FcSerializePtr (serialize, str);
149     if (!str_serialize)
150         return NULL;
151     strcpy ((char *) str_serialize, (const char *) str);
152     return str_serialize;
153 }
154 #include "fcaliastail.h"
155 #undef __fcserialize__