//======================================================================== // // PopplerCache.h // // This file is licensed under the GPLv2 or later // // Copyright (C) 2009 Koji Otani // Copyright (C) 2009, 2010 Albert Astals Cid // Copyright (C) 2010 Carlos Garcia Campos // //======================================================================== #include "PopplerCache.h" #include "XRef.h" PopplerCacheKey::~PopplerCacheKey() { } PopplerCacheItem::~PopplerCacheItem() { } PopplerCache::PopplerCache(int cacheSizeA) { cacheSize = cacheSizeA; keys = new PopplerCacheKey*[cacheSize]; items = new PopplerCacheItem*[cacheSize]; lastValidCacheIndex = -1; } PopplerCache::~PopplerCache() { for (int i = 0; i <= lastValidCacheIndex; ++i) { delete keys[i]; delete items[i]; } delete[] keys; delete[] items; } PopplerCacheItem *PopplerCache::lookup(const PopplerCacheKey &key) { if (lastValidCacheIndex < 0) return 0; if (*keys[0] == key) { return items[0]; } for (int i = 1; i <= lastValidCacheIndex; i++) { if (*keys[i] == key) { PopplerCacheKey *keyHit = keys[i]; PopplerCacheItem *itemHit = items[i]; for (int j = i; j > 0; j--) { keys[j] = keys[j - 1]; items[j] = items[j - 1]; } keys[0] = keyHit; items[0] = itemHit; return itemHit; } } return 0; } void PopplerCache::put(PopplerCacheKey *key, PopplerCacheItem *item) { int movingStartIndex = lastValidCacheIndex + 1; if (lastValidCacheIndex == cacheSize - 1) { delete keys[lastValidCacheIndex]; delete items[lastValidCacheIndex]; movingStartIndex = cacheSize - 1; } else { lastValidCacheIndex++; } for (int i = movingStartIndex; i > 0; i--) { keys[i] = keys[i - 1]; items[i] = items[i - 1]; } keys[0] = key; items[0] = item; } int PopplerCache::size() { return cacheSize; } int PopplerCache::numberOfItems() { return lastValidCacheIndex + 1; } PopplerCacheItem *PopplerCache::item(int index) { return items[index]; } PopplerCacheKey *PopplerCache::key(int index) { return keys[index]; } class ObjectKey : public PopplerCacheKey { public: ObjectKey(int numA, int genA) : num(numA), gen(genA) { } bool operator==(const PopplerCacheKey &key) const { const ObjectKey *k = static_cast(&key); return k->num == num && k->gen == gen; } int num, gen; }; class ObjectItem : public PopplerCacheItem { public: ObjectItem(Object *obj) { obj->copy(&item); } ~ObjectItem() { item.free(); } Object item; }; PopplerObjectCache::PopplerObjectCache(int cacheSize, XRef *xrefA) { cache = new PopplerCache (cacheSize); xref = xrefA; } PopplerObjectCache::~PopplerObjectCache() { delete cache; } Object *PopplerObjectCache::put(const Ref &ref) { Object obj; xref->fetch(ref.num, ref.gen, &obj); ObjectKey *key = new ObjectKey(ref.num, ref.gen); ObjectItem *item = new ObjectItem(&obj); cache->put(key, item); obj.free(); return &item->item; } Object *PopplerObjectCache::lookup(const Ref &ref, Object *obj) { ObjectKey key(ref.num, ref.gen); ObjectItem *item = static_cast(cache->lookup(key)); return item ? item->item.copy(obj) : obj->initNull(); }