diff --git a/fc-arch/fc-arch.c b/fc-arch/fc-arch.c index 0179034..2fa6b18 100644 --- a/fc-arch/fc-arch.c +++ b/fc-arch/fc-arch.c @@ -26,9 +26,6 @@ #define ENDIAN_TEST 0x12345678 #define MACHINE_SIGNATURE_SIZE (9*21 + 1) -#define MACHINE_ARCH_SIZE 32 -/* for when we don't have sysconf: */ -#define FC_HARDCODED_PAGESIZE 8192 static char * FcCacheMachineSignature (void) @@ -44,11 +41,12 @@ FcCacheMachineSignature (void) (unsigned int)sizeof (char), (unsigned int)sizeof (char *), (unsigned int)sizeof (int), + (unsigned int)sizeof (intptr_t), (unsigned int)sizeof (FcPattern), (unsigned int)sizeof (FcPatternEltPtr), (unsigned int)sizeof (struct FcPatternElt *), (unsigned int)sizeof (FcPatternElt), - (unsigned int)sizeof (FcObjectPtr), + (unsigned int)sizeof (FcObject), (unsigned int)sizeof (FcValueListPtr), (unsigned int)sizeof (FcValue), (unsigned int)sizeof (FcValueBinding), @@ -59,13 +57,7 @@ FcCacheMachineSignature (void) (unsigned int)sizeof (FcChar16), (unsigned int)sizeof (FcCharLeaf), (unsigned int)sizeof (FcChar32), - (unsigned int)sizeof (FcCache), -#if defined (HAVE_SYSCONF) - (unsigned int)sysconf(_SC_PAGESIZE) -#else - (unsigned int)FC_HARDCODED_PAGESIZE -#endif - ); + (unsigned int)sizeof (FcCache)); return buf; } diff --git a/fc-arch/fcarch.tmpl.h b/fc-arch/fcarch.tmpl.h index 4cf483f..b0712e5 100644 --- a/fc-arch/fcarch.tmpl.h +++ b/fc-arch/fcarch.tmpl.h @@ -28,8 +28,8 @@ @@@ name. Architecture names are used to construct file names, so @@@ use something reasonable and don't include any spaces @@@ -@@@ name endian char char* int Pattern EltPtr Elt * Elt ObjPtr VLPtr Value Binding VL * CharSet Leaf** Char16 * Char16 Leaf Char32 Cache PageSize -x86 78563412_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_0000000c_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000 +@@@ name endian char char* int intptr_t Pattern EltPtr Elt * Elt ObjPtr VLPtr Value Binding VL * CharSet Leaf** Char16 * Char16 Leaf Char32 Cache +x86 78563412_00000001_00000004_00000004_00000004_00000010_00000004_00000004_00000008_00000004_00000004_0000000c_00000004_00000004_00000010_00000004_00000004_00000002_00000020_00000004_00000018 x86-64 78563412_00000001_00000008_00000004_00000020_00000010_00000008_00000018_00000004_00000010_00000010_00000004_00000008_00000020_00000008_00000008_00000002_00000020_00000004_00000040_00001000 ppc-4k 12345678_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_00000010_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000 ppc-64k 12345678_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_00000010_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00010000 diff --git a/fc-lang/fc-lang.c b/fc-lang/fc-lang.c index 631411d..324a0b2 100644 --- a/fc-lang/fc-lang.c +++ b/fc-lang/fc-lang.c @@ -25,6 +25,7 @@ #include "fcint.h" #include "fccharset.c" #include "fcstr.c" +#include "fcserialize.c" /* * fc-lang diff --git a/src/fcserialize.c b/src/fcserialize.c new file mode 100644 index 0000000..5a4b4af --- /dev/null +++ b/src/fcserialize.c @@ -0,0 +1,159 @@ +/* + * Copyright © 2006 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "fcint.h" + +typedef union _FcAlign { + double d; + int i; + intptr_t ip; + off_t o; + FcBool b; + void *p; +} FcAlign; + +intptr_t +FcAlignSize (intptr_t size) +{ + intptr_t rem = size % sizeof (FcAlign); + if (rem) + size += sizeof (FcAlign) - rem; + return size; +} + +/* + * Serialization helper object -- allocate space in the + * yet-to-be-created linear array for a serialized font set + */ + +FcSerialize * +FcSerializeCreate (void) +{ + FcSerialize *serialize; + + serialize = malloc (sizeof (FcSerialize)); + if (!serialize) + return NULL; + serialize->size = 0; + serialize->linear = NULL; + memset (serialize->buckets, '\0', sizeof (serialize->buckets)); + return serialize; +} + +void +FcSerializeDestroy (FcSerialize *serialize) +{ + uintptr_t bucket; + + for (bucket = 0; bucket < FC_SERIALIZE_HASH_SIZE; bucket++) + { + FcSerializeBucket *buck, *next; + + for (buck = serialize->buckets[bucket]; buck; buck = next) { + next = buck->next; + free (buck); + } + } + free (serialize); +} + +/* + * Allocate space for an object in the serialized array. Keep track + * of where the object is placed and only allocate one copy of each object + */ + +FcBool +FcSerializeAlloc (FcSerialize *serialize, const void *object, int size) +{ + uintptr_t bucket = ((uintptr_t) object) % FC_SERIALIZE_HASH_SIZE; + FcSerializeBucket *buck; + + for (buck = serialize->buckets[bucket]; buck; buck = buck->next) + if (buck->object == object) + return FcTrue; + buck = malloc (sizeof (FcSerializeBucket)); + if (!buck) + return FcFalse; + buck->object = object; + buck->offset = serialize->size; + buck->next = serialize->buckets[bucket]; + serialize->buckets[bucket] = buck; + serialize->size += FcAlignSize (size); + return FcTrue; +} + +/* + * Reserve space in the serialization array + */ +intptr_t +FcSerializeReserve (FcSerialize *serialize, int size) +{ + intptr_t offset = serialize->size; + serialize->size += FcAlignSize (size); + return offset; +} + +/* + * Given an object, return the offset in the serialized array where + * the serialized copy of the object is stored + */ +intptr_t +FcSerializeOffset (FcSerialize *serialize, const void *object) +{ + uintptr_t bucket = ((uintptr_t) object) % FC_SERIALIZE_HASH_SIZE; + FcSerializeBucket *buck; + + for (buck = serialize->buckets[bucket]; buck; buck = buck->next) + if (buck->object == object) + return buck->offset; + return 0; +} + +/* + * Given a cache and an object, return a pointer to where + * the serialized copy of the object is stored + */ +void * +FcSerializePtr (FcSerialize *serialize, const void *object) +{ + intptr_t offset = FcSerializeOffset (serialize, object); + + if (!offset) + return NULL; + return (void *) ((char *) serialize->linear + offset); +} + +FcBool +FcStrSerializeAlloc (FcSerialize *serialize, const FcChar8 *str) +{ + return FcSerializeAlloc (serialize, str, strlen ((const char *) str) + 1); +} + +FcChar8 * +FcStrSerialize (FcSerialize *serialize, const FcChar8 *str) +{ + FcChar8 *str_serialize = FcSerializePtr (serialize, str); + if (!str_serialize) + return NULL; + strcpy ((char *) str_serialize, (const char *) str); + return str_serialize; +}