* PERFORMANCE OF THIS SOFTWARE.
*/
-#include <stdlib.h>
#include "fcint.h"
+#include <stdlib.h>
/* #define CHECK */
/* #define CHATTY */
-static FcCharSet * charsets = 0;
-static FcChar16 * numbers = 0;
-static int charset_ptr, charset_count;
+static FcCharSet ** charsets = 0;
+static FcChar16 ** numbers = 0;
+static int charset_bank_count = 0, charset_ptr, charset_count;
static int charset_numbers_ptr, charset_numbers_count;
-static FcCharLeaf * leaves = 0;
+static FcCharLeaf ** leaves = 0;
static int charset_leaf_ptr, charset_leaf_count;
-static int * leaf_idx = 0;
+static int ** leaf_idx = 0;
static int charset_leaf_idx_ptr, charset_leaf_idx_count;
+extern const FcChar16 langBankNumbers[];
+extern const FcCharLeaf langBankLeaves[];
+extern const int langBankLeafIdx[];
+
+static FcBool
+FcCharSetEnsureBank (int bi);
+
void
-FcCharSetClearStatic()
+FcLangCharSetPopulate (void)
{
- charsets = 0;
- numbers = 0;
- charset_ptr = 0; charset_count = 0;
- leaves = 0;
- charset_leaf_ptr = 0; charset_leaf_count = 0;
- leaf_idx = 0;
- charset_leaf_idx_ptr = 0; charset_leaf_idx_count = 0;
+ int bi = FcCacheBankToIndexMTF (FC_BANK_LANGS);
+ FcCharSetEnsureBank (bi);
+ charsets[bi] = 0;
+ numbers[bi] = (FcChar16 *)langBankNumbers;
+ leaves[bi] = (FcCharLeaf *)langBankLeaves;
+ leaf_idx[bi] = (int *)langBankLeafIdx;
}
FcCharSet *
FcMemAlloc (FC_MEM_CHARSET, sizeof (FcCharSet));
fcs->ref = 1;
fcs->num = 0;
- fcs->storage = FcStorageDynamic;
+ fcs->bank = FC_BANK_DYNAMIC;
fcs->u.dyn.leaves = 0;
fcs->u.dyn.numbers = 0;
return fcs;
return FcCharSetCreate ();
}
-void
-FcCharSetPtrDestroy (FcCharSetPtr fcs)
-{
- FcCharSetDestroy (FcCharSetPtrU(fcs));
- if (fcs.storage == FcStorageDynamic &&
- FcCharSetPtrU(fcs)->ref != FC_REF_CONSTANT)
- {
- free (fcs.u.dyn);
- FcMemFree (FC_MEM_CHARSET, sizeof(FcCharSet));
- }
-}
-
void
FcCharSetDestroy (FcCharSet *fcs)
{
return;
if (--fcs->ref > 0)
return;
- if (fcs->storage == FcStorageDynamic)
+ if (fcs->bank == FC_BANK_DYNAMIC)
{
for (i = 0; i < fcs->num; i++)
{
ucs4 >>= 8;
if (ucs4 >= 0x10000)
return FcFalse;
- if (fcs->storage == FcStorageStatic)
+ if (fcs->bank != FC_BANK_DYNAMIC)
{
+ /* convert to dynamic */
int i;
leaves = malloc ((fcs->num + 1) * sizeof (FcCharLeaf *));
FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcCharLeaf *));
numbers = malloc ((fcs->num + 1) * sizeof (FcChar16));
if (!numbers)
+ {
+ free (leaves);
return FcFalse;
+ }
FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
for (i = 0; i < fcs->num; i++)
leaves[i] = FcCharSetGetLeaf(fcs, i);
memcpy (numbers, FcCharSetGetNumbers(fcs),
fcs->num * sizeof (FcChar16));
- fcs->storage = FcStorageDynamic;
+
+ fcs->bank = FC_BANK_DYNAMIC;
+ fcs->u.dyn.leaves = leaves;
+ fcs->u.dyn.numbers = numbers;
}
else
{
if (pos >= 0)
{
FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
- if (fcs->storage == FcStorageDynamic)
+ if (fcs->bank == FC_BANK_DYNAMIC)
{
free (fcs->u.dyn.leaves[pos]);
fcs->u.dyn.leaves[pos] = leaf;
}
else
{
- leaves[leaf_idx[fcs->u.stat.leafidx_offset]+pos] = *leaf;
+ int bi = FcCacheBankToIndex(fcs->bank);
+ leaves[bi][leaf_idx[fcs->bank][fcs->u.stat.leafidx_offset]+pos] = *leaf;
}
return FcTrue;
}
FcCharSetDump (fcs);
#endif
iter->ucs4 = 0;
+ iter->pos = 0;
FcCharSetIterSet (fcs, iter);
}
int i = 256/32;
if (ai.ucs4 == bi.ucs4)
{
- FcChar32 *bm = bi.leaf->map;;
+ FcChar32 *bm = bi.leaf->map;
while (i--)
count += FcCharSetPopCount (*am++ & ~*bm++);
}
int i;
/* hash in leaves */
- for (i = 0; i < fcs->num * sizeof (FcCharLeaf *) / sizeof (FcChar32); i++)
+ for (i = 0; i < fcs->num * (int) (sizeof (FcCharLeaf *) / sizeof (FcChar32)); i++)
hash = ((hash << 1) | (hash >> 31)) ^ (FcChar32)(FcCharSetGetLeaf(fcs, i)->map);
/* hash in numbers */
for (i = 0; i < fcs->num; i++)
ent->set.ref = FC_REF_CONSTANT;
ent->set.num = fcs->num;
- ent->set.storage = fcs->storage;
- if (fcs->storage == FcStorageDynamic)
+ ent->set.bank = fcs->bank;
+ if (fcs->bank == FC_BANK_DYNAMIC)
{
if (fcs->num)
{
}
n = FcCharSetFreezeBase (b);
bail1:
- if (b->storage == FcStorageDynamic)
+ if (b->bank == FC_BANK_DYNAMIC)
{
if (b->u.dyn.leaves)
{
#endif
n = FcCharSetFreezeBase (c);
bail1:
- if (c->storage == FcStorageDynamic)
+ if (c->bank == FC_BANK_DYNAMIC)
{
if (c->u.dyn.leaves)
{
return FcTrue;
}
-
-FcCharSet *
-FcCharSetPtrU (FcCharSetPtr ci)
+void
+FcCharSetNewBank(void)
{
- switch (ci.storage)
- {
- case FcStorageDynamic:
- return ci.u.dyn;
- case FcStorageStatic:
- return &charsets[ci.u.stat];
- default:
- return 0;
- }
+ charset_count = 0;
+ charset_numbers_count = 0;
+ charset_leaf_count = 0;
+ charset_leaf_idx_count = 0;
}
-FcCharSetPtr
-FcCharSetPtrCreateDynamic(FcCharSet *c)
+int
+FcCharSetNeededBytes (const FcCharSet *c)
{
- FcCharSetPtr new;
+ /* yes, there's redundancy */
+ charset_count++;
+ charset_leaf_idx_count += c->num;
+ charset_leaf_count += c->num;
+ charset_numbers_count += c->num;
+ return sizeof (FcCharSet) +
+ sizeof (int) * c->num + /* leaf_idx */
+ sizeof (FcCharLeaf) * c->num + /* leaf */
+ sizeof (FcChar16) * c->num; /* number */
+}
- new.storage = FcStorageDynamic;
- new.u.dyn = c;
- return new;
+int
+FcCharSetNeededBytesAlign (void)
+{
+ return fc_alignof (FcCharSet) + fc_alignof (int) +
+ fc_alignof (FcCharLeaf) + fc_alignof (FcChar16);
}
-FcBool
-FcCharSetPrepareSerialize(FcCharSet *c)
+static FcBool
+FcCharSetEnsureBank (int bi)
{
- /* note the redundancy */
- charset_count++;
- charset_leaf_idx_count++;
- charset_leaf_count += c->num;
- charset_numbers_count += c->num;
+ if (!charsets || charset_bank_count <= bi)
+ {
+ int new_count = charset_bank_count + 2;
+ FcCharSet ** cs;
+ FcChar16 ** n;
+ FcCharLeaf ** lvs;
+ int ** lvi;
+ int i;
+
+ cs = realloc(charsets, sizeof(FcCharSet*) * new_count);
+ if (!cs) return 0;
+ n = realloc(numbers, sizeof(FcChar16*) * new_count);
+ if (!n) return 0;
+ lvs = realloc(leaves, sizeof(FcCharLeaf*) * new_count);
+ if (!lvs) return 0;
+ lvi = realloc(leaf_idx, sizeof(int*) * new_count);
+ if (!lvi) return 0;
+
+ charsets = cs; numbers = n; leaves = lvs; leaf_idx = lvi;
+ for (i = charset_bank_count; i < new_count; i++)
+ {
+ charsets[i] = 0;
+ numbers[i] = 0;
+ leaves[i] = 0;
+ leaf_idx[i] = 0;
+ }
+ charset_bank_count = new_count;
+ }
return FcTrue;
}
-FcCharSetPtr
-FcCharSetSerialize(FcCharSet *c)
+void *
+FcCharSetDistributeBytes (FcCache * metadata, void * block_ptr)
+{
+ int bi = FcCacheBankToIndex(metadata->bank);
+ if (!FcCharSetEnsureBank(bi))
+ return 0;
+
+ block_ptr = ALIGN (block_ptr, FcCharSet);
+ charsets[bi] = (FcCharSet *)block_ptr;
+ block_ptr = (void *)((char *)block_ptr +
+ (sizeof (FcCharSet) * charset_count));
+ block_ptr = ALIGN (block_ptr, FcChar16);
+ numbers[bi] = (FcChar16 *)block_ptr;
+ block_ptr = (void *)((char *)block_ptr +
+ (sizeof(FcChar16) * charset_numbers_count));
+ block_ptr = ALIGN (block_ptr, FcCharLeaf);
+ leaves[bi] = (FcCharLeaf *)block_ptr;
+ block_ptr = (void *)((char *)block_ptr +
+ (sizeof(FcCharLeaf) * charset_leaf_count));
+ block_ptr = ALIGN (block_ptr, int);
+ leaf_idx[bi] = (int *)block_ptr;
+ block_ptr = (void *)((char *)block_ptr +
+ (sizeof(int) * charset_leaf_idx_count));
+
+ metadata->charset_count = charset_count;
+ metadata->charset_numbers_count = charset_numbers_count;
+ metadata->charset_leaf_count = charset_leaf_count;
+ metadata->charset_leaf_idx_count = charset_leaf_idx_count;
+ charset_ptr = 0; charset_leaf_ptr = 0;
+ charset_leaf_idx_ptr = 0; charset_numbers_ptr = 0;
+ return block_ptr;
+}
+
+FcCharSet *
+FcCharSetSerialize(int bank, FcCharSet *c)
{
int i;
- FcCharSetPtr newp;
FcCharSet new;
+ int bi = FcCacheBankToIndex(bank), cp = charset_ptr;
- if (!charsets)
- {
- charsets = malloc(sizeof(FcCharSet) * charset_count);
- if (!charsets) goto bail;
- numbers = malloc(sizeof(FcChar16) * charset_numbers_count);
- if (!numbers) goto bail1;
- leaves = malloc(sizeof(FcCharLeaf) * charset_leaf_count);
- if (!leaves) goto bail2;
- leaf_idx = malloc(sizeof(int)*charset_leaf_idx_count);
- if (!leaf_idx) goto bail3;
- }
-
- new.ref = c->ref;
- new.storage = FcStorageStatic;
- new.u.stat.leafidx_offset = charset_leaf_ptr;
+ new.ref = FC_REF_CONSTANT;
+ new.bank = bank;
+ new.u.stat.leafidx_offset = charset_leaf_idx_ptr;
new.u.stat.numbers_offset = charset_numbers_ptr;
+ new.num = c->num;
- newp.storage = FcStorageStatic;
- newp.u.stat = charset_ptr;
- charsets[charset_ptr++] = new;
+ charsets[bi][charset_ptr++] = new;
- leaf_idx[charset_leaf_idx_ptr++] = charset_leaf_ptr;
for (i = 0; i < c->num; i++)
{
- memcpy (&leaves[charset_leaf_ptr++],
+ leaf_idx[bi][charset_leaf_idx_ptr++] = charset_leaf_ptr;
+ memcpy (&leaves[bi][charset_leaf_ptr++],
c->u.dyn.leaves[i], sizeof(FcCharLeaf));
- numbers[charset_numbers_ptr++] = c->u.dyn.numbers[i];
+ numbers[bi][charset_numbers_ptr++] = c->u.dyn.numbers[i];
}
- return newp;
+ return &charsets[bi][cp];
+}
- bail3:
- free (leaves);
- bail2:
- free (numbers);
- bail1:
- free (charsets);
- bail:
- return FcCharSetPtrCreateDynamic(0);
+void *
+FcCharSetUnserialize (FcCache *metadata, void *block_ptr)
+{
+ int bi = FcCacheBankToIndex(metadata->bank);
+ if (!FcCharSetEnsureBank(bi))
+ return 0;
+
+ block_ptr = ALIGN (block_ptr, FcCharSet);
+ charsets[bi] = (FcCharSet *)block_ptr;
+ block_ptr = (void *)((char *)block_ptr +
+ (sizeof (FcCharSet) * metadata->charset_count));
+ block_ptr = ALIGN (block_ptr, FcChar16);
+ numbers[bi] = (FcChar16 *)block_ptr;
+ block_ptr = (void *)((char *)block_ptr +
+ (sizeof(FcChar16) * metadata->charset_numbers_count));
+ block_ptr = ALIGN (block_ptr, FcCharLeaf);
+ leaves[bi] = (FcCharLeaf *)block_ptr;
+ block_ptr = (void *)((char *)block_ptr +
+ (sizeof(FcCharLeaf) * metadata->charset_leaf_count));
+ block_ptr = ALIGN (block_ptr, int);
+ leaf_idx[bi] = (int *)block_ptr;
+ block_ptr = (void *)((char *)block_ptr +
+ (sizeof(int) * metadata->charset_leaf_idx_count));
+
+ return block_ptr;
}
FcCharLeaf *
FcCharSetGetLeaf(const FcCharSet *c, int i)
{
- switch (c->storage)
- {
- case FcStorageDynamic:
+ int bi;
+ if (c->bank == FC_BANK_DYNAMIC)
return c->u.dyn.leaves[i];
- case FcStorageStatic:
- return &leaves[leaf_idx[c->u.stat.leafidx_offset]+i];
- default:
- return 0;
- }
+ bi = FcCacheBankToIndex(c->bank);
+
+ return &leaves[bi][leaf_idx[bi][c->u.stat.leafidx_offset+i]];
}
FcChar16 *
FcCharSetGetNumbers(const FcCharSet *c)
{
- switch (c->storage)
- {
- case FcStorageDynamic:
+ int bi;
+ if (c->bank == FC_BANK_DYNAMIC)
return c->u.dyn.numbers;
- case FcStorageStatic:
- return &numbers[c->u.stat.numbers_offset];
- default:
- return 0;
- }
+ bi = FcCacheBankToIndex(c->bank);
+
+ return &numbers[bi][c->u.stat.numbers_offset];
}