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