Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include "fitz.h"
  2. #include "mupdf.h"
  3.  
  4. typedef struct pdf_item_s pdf_item;
  5.  
  6. struct pdf_item_s
  7. {
  8.         void *drop_func;
  9.         fz_obj *key;
  10.         void *val;
  11.         int age;
  12.         pdf_item *next;
  13. };
  14.  
  15. struct refkey
  16. {
  17.         void *drop_func;
  18.         int num;
  19.         int gen;
  20. };
  21.  
  22. struct pdf_store_s
  23. {
  24.         fz_hash_table *hash;    /* hash for num/gen keys */
  25.         pdf_item *root;         /* linked list for everything else */
  26. };
  27.  
  28. pdf_store *
  29. pdf_new_store(void)
  30. {
  31.         pdf_store *store;
  32.         store = fz_malloc(sizeof(pdf_store));
  33.         store->hash = fz_new_hash_table(4096, sizeof(struct refkey));
  34.         store->root = NULL;
  35.         return store;
  36. }
  37.  
  38. void
  39. pdf_store_item(pdf_store *store, void *keepfunc, void *drop_func, fz_obj *key, void *val)
  40. {
  41.         pdf_item *item;
  42.  
  43.         if (!store)
  44.                 return;
  45.  
  46.         item = fz_malloc(sizeof(pdf_item));
  47.         item->drop_func = drop_func;
  48.         item->key = fz_keep_obj(key);
  49.         item->val = ((void*(*)(void*))keepfunc)(val);
  50.         item->age = 0;
  51.         item->next = NULL;
  52.  
  53.         if (fz_is_indirect(key))
  54.         {
  55.                 struct refkey refkey;
  56.                 refkey.drop_func = drop_func;
  57.                 refkey.num = fz_to_num(key);
  58.                 refkey.gen = fz_to_gen(key);
  59.                 fz_hash_insert(store->hash, &refkey, item);
  60.         }
  61.         else
  62.         {
  63.                 item->next = store->root;
  64.                 store->root = item;
  65.         }
  66. }
  67.  
  68. void *
  69. pdf_find_item(pdf_store *store, void *drop_func, fz_obj *key)
  70. {
  71.         struct refkey refkey;
  72.         pdf_item *item;
  73.  
  74.         if (!store)
  75.                 return NULL;
  76.  
  77.         if (key == NULL)
  78.                 return NULL;
  79.  
  80.         if (fz_is_indirect(key))
  81.         {
  82.                 refkey.drop_func = drop_func;
  83.                 refkey.num = fz_to_num(key);
  84.                 refkey.gen = fz_to_gen(key);
  85.                 item = fz_hash_find(store->hash, &refkey);
  86.                 if (item)
  87.                 {
  88.                         item->age = 0;
  89.                         return item->val;
  90.                 }
  91.         }
  92.         else
  93.         {
  94.                 for (item = store->root; item; item = item->next)
  95.                 {
  96.                         if (item->drop_func == drop_func && !fz_objcmp(item->key, key))
  97.                         {
  98.                                 item->age = 0;
  99.                                 return item->val;
  100.                         }
  101.                 }
  102.         }
  103.  
  104.         return NULL;
  105. }
  106.  
  107. void
  108. pdf_remove_item(pdf_store *store, void *drop_func, fz_obj *key)
  109. {
  110.         struct refkey refkey;
  111.         pdf_item *item, *prev, *next;
  112.  
  113.         if (fz_is_indirect(key))
  114.         {
  115.                 refkey.drop_func = drop_func;
  116.                 refkey.num = fz_to_num(key);
  117.                 refkey.gen = fz_to_gen(key);
  118.                 item = fz_hash_find(store->hash, &refkey);
  119.                 if (item)
  120.                 {
  121.                         fz_hash_remove(store->hash, &refkey);
  122.                         ((void(*)(void*))item->drop_func)(item->val);
  123.                         fz_drop_obj(item->key);
  124.                         fz_free(item);
  125.                 }
  126.         }
  127.         else
  128.         {
  129.                 prev = NULL;
  130.                 for (item = store->root; item; item = next)
  131.                 {
  132.                         next = item->next;
  133.                         if (item->drop_func == drop_func && !fz_objcmp(item->key, key))
  134.                         {
  135.                                 if (!prev)
  136.                                         store->root = next;
  137.                                 else
  138.                                         prev->next = next;
  139.                                 ((void(*)(void*))item->drop_func)(item->val);
  140.                                 fz_drop_obj(item->key);
  141.                                 fz_free(item);
  142.                         }
  143.                         else
  144.                                 prev = item;
  145.                 }
  146.         }
  147. }
  148.  
  149. void
  150. pdf_age_store(pdf_store *store, int maxage)
  151. {
  152.         struct refkey *refkey;
  153.         pdf_item *item, *prev, *next;
  154.         int i;
  155.  
  156.         for (i = 0; i < fz_hash_len(store->hash); i++)
  157.         {
  158.                 refkey = fz_hash_get_key(store->hash, i);
  159.                 item = fz_hash_get_val(store->hash, i);
  160.                 if (item && ++item->age > maxage)
  161.                 {
  162.                         fz_hash_remove(store->hash, refkey);
  163.                         ((void(*)(void*))item->drop_func)(item->val);
  164.                         fz_drop_obj(item->key);
  165.                         fz_free(item);
  166.                         i--; /* items with same hash may move into place */
  167.                 }
  168.         }
  169.  
  170.         prev = NULL;
  171.         for (item = store->root; item; item = next)
  172.         {
  173.                 next = item->next;
  174.                 if (++item->age > maxage)
  175.                 {
  176.                         if (!prev)
  177.                                 store->root = next;
  178.                         else
  179.                                 prev->next = next;
  180.                         ((void(*)(void*))item->drop_func)(item->val);
  181.                         fz_drop_obj(item->key);
  182.                         fz_free(item);
  183.                 }
  184.                 else
  185.                         prev = item;
  186.         }
  187. }
  188.  
  189. void
  190. pdf_free_store(pdf_store *store)
  191. {
  192.         pdf_age_store(store, 0);
  193.         fz_free_hash(store->hash);
  194.         fz_free(store);
  195. }
  196.  
  197. void
  198. pdf_debug_store(pdf_store *store)
  199. {
  200.         pdf_item *item;
  201.         pdf_item *next;
  202.         struct refkey *refkey;
  203.         int i;
  204.  
  205.         printf("-- resource store contents --\n");
  206.  
  207.         for (i = 0; i < fz_hash_len(store->hash); i++)
  208.         {
  209.                 refkey = fz_hash_get_key(store->hash, i);
  210.                 item = fz_hash_get_val(store->hash, i);
  211.                 if (item)
  212.                         printf("store[%d] (%d %d R) = %p\n", i, refkey->num, refkey->gen, item->val);
  213.         }
  214.  
  215.         for (item = store->root; item; item = next)
  216.         {
  217.                 next = item->next;
  218.                 printf("store[*] ");
  219.                 fz_debug_obj(item->key);
  220.                 printf(" = %p\n", item->val);
  221.         }
  222. }
  223.