diff options
Diffstat (limited to 'src/bidi.c')
-rw-r--r-- | src/bidi.c | 76 |
1 files changed, 51 insertions, 25 deletions
diff --git a/src/bidi.c b/src/bidi.c index 77043d9236f..a2ba60a7baf 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -609,12 +609,15 @@ bidi_pop_it (struct bidi_it *bidi_it) bidi_cache_last_idx = -1; } +ptrdiff_t bidi_cache_total_alloc; + /* Stash away a copy of the cache and its control variables. */ void * bidi_shelve_cache (void) { unsigned char *databuf; + /* Empty cache. */ if (bidi_cache_idx == 0) return NULL; @@ -623,6 +626,12 @@ bidi_shelve_cache (void) + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx)); + bidi_cache_total_alloc += + sizeof (bidi_cache_idx) + bidi_cache_idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack) + + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) + + sizeof (bidi_cache_last_idx); + memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); memcpy (databuf + sizeof (bidi_cache_idx), bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); @@ -648,7 +657,7 @@ bidi_shelve_cache (void) /* Restore the cache state from a copy stashed away by bidi_shelve_cache. */ void -bidi_unshelve_cache (void *databuf) +bidi_unshelve_cache (void *databuf, int just_free) { unsigned char *p = databuf; @@ -661,30 +670,47 @@ bidi_unshelve_cache (void *databuf) } else { - memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx)); - bidi_cache_ensure_space (bidi_cache_idx); - memcpy (bidi_cache, p + sizeof (bidi_cache_idx), - bidi_cache_idx * sizeof (struct bidi_it)); - memcpy (bidi_cache_start_stack, - p + sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it), - sizeof (bidi_cache_start_stack)); - memcpy (&bidi_cache_sp, - p + sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it) - + sizeof (bidi_cache_start_stack), - sizeof (bidi_cache_sp)); - memcpy (&bidi_cache_start, - p + sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it) - + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), - sizeof (bidi_cache_start)); - memcpy (&bidi_cache_last_idx, - p + sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it) - + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) - + sizeof (bidi_cache_start), - sizeof (bidi_cache_last_idx)); + if (just_free) + { + ptrdiff_t idx; + + memcpy (&idx, p, sizeof (bidi_cache_idx)); + bidi_cache_total_alloc -= + sizeof (bidi_cache_idx) + idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) + + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx); + } + else + { + memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx)); + bidi_cache_ensure_space (bidi_cache_idx); + memcpy (bidi_cache, p + sizeof (bidi_cache_idx), + bidi_cache_idx * sizeof (struct bidi_it)); + memcpy (bidi_cache_start_stack, + p + sizeof (bidi_cache_idx) + + bidi_cache_idx * sizeof (struct bidi_it), + sizeof (bidi_cache_start_stack)); + memcpy (&bidi_cache_sp, + p + sizeof (bidi_cache_idx) + + bidi_cache_idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack), + sizeof (bidi_cache_sp)); + memcpy (&bidi_cache_start, + p + sizeof (bidi_cache_idx) + + bidi_cache_idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), + sizeof (bidi_cache_start)); + memcpy (&bidi_cache_last_idx, + p + sizeof (bidi_cache_idx) + + bidi_cache_idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) + + sizeof (bidi_cache_start), + sizeof (bidi_cache_last_idx)); + bidi_cache_total_alloc -= + sizeof (bidi_cache_idx) + bidi_cache_idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) + + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx); + } xfree (p); } |