[poppler] 3 commits - CMakeLists.txt poppler/Function.h poppler/Gfx.cc poppler/Gfx.h poppler/GfxState.cc poppler/GfxState.h poppler/OutputDev.cc poppler/OutputDev.h poppler/PopplerCache.cc poppler/PopplerCache.h poppler/XRef.cc poppler/XRef.h

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Oct 4 23:14:12 UTC 2018


 CMakeLists.txt          |    1 
 poppler/Function.h      |    1 
 poppler/Gfx.cc          |   16 ++--
 poppler/Gfx.h           |    3 
 poppler/GfxState.cc     |   43 -------------
 poppler/GfxState.h      |    1 
 poppler/OutputDev.cc    |   15 ++--
 poppler/OutputDev.h     |   16 ++--
 poppler/PopplerCache.cc |  156 ------------------------------------------------
 poppler/PopplerCache.h  |   96 ++++++++++-------------------
 poppler/XRef.cc         |   62 +------------------
 poppler/XRef.h          |    8 --
 12 files changed, 71 insertions(+), 347 deletions(-)

New commits:
commit 13e610fd95025804623ebfc7d134332071f5f1d5
Author: Adam Reichold <adam.reichold at t-online.de>
Date:   Fri Sep 21 18:13:04 2018 +0200

    Since the circular dependency between PopplerCache and XRef is gone now, XRef can properly embed PopplerCache without additional indirection.

diff --git a/poppler/XRef.cc b/poppler/XRef.cc
index 84914f1f..9b4b31c3 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -55,7 +55,6 @@
 #include "Error.h"
 #include "ErrorCodes.h"
 #include "XRef.h"
-#include "PopplerCache.h"
 
 //------------------------------------------------------------------------
 // Permission bits
@@ -227,7 +226,7 @@ Object ObjectStream::getObject(int objIdx, int objNum) {
 
 #define xrefLocker()   std::unique_lock<std::recursive_mutex> locker(mutex)
 
-void XRef::init() {
+XRef::XRef() : objStrs{5} {
   ok = gTrue;
   errCode = errNone;
   entries = nullptr;
@@ -236,7 +235,6 @@ void XRef::init() {
   modified = gFalse;
   streamEnds = nullptr;
   streamEndsLen = 0;
-  objStrs = new PopplerCache<Goffset, ObjectStream>(5);
   mainXRefEntriesOffset = 0;
   xRefStream = gFalse;
   scannedSpecialFlags = gFalse;
@@ -249,21 +247,14 @@ void XRef::init() {
   encAlgorithm = cryptNone;
 }
 
-XRef::XRef() {
-  init();
-}
-
-XRef::XRef(const Object *trailerDictA) {
-  init();
-
+XRef::XRef(const Object *trailerDictA) : XRef{} {
   if (trailerDictA->isDict())
     trailerDict = trailerDictA->copy();
 }
 
-XRef::XRef(BaseStream *strA, Goffset pos, Goffset mainXRefEntriesOffsetA, GBool *wasReconstructed, GBool reconstruct) {
+XRef::XRef(BaseStream *strA, Goffset pos, Goffset mainXRefEntriesOffsetA, GBool *wasReconstructed, GBool reconstruct) : XRef{} {
   Object obj;
 
-  init();
   mainXRefEntriesOffset = mainXRefEntriesOffsetA;
 
   // read the trailer
@@ -342,9 +333,6 @@ XRef::~XRef() {
   if (streamEnds) {
     gfree(streamEnds);
   }
-  if (objStrs) {
-    delete objStrs;
-  }
   if (strOwner) {
     delete str;
   }
@@ -1158,7 +1146,7 @@ Object XRef::fetch(int num, int gen, int recursion) {
       goto err;
     }
 
-    ObjectStream *objStr = objStrs->lookup(e->offset);
+    ObjectStream *objStr = objStrs.lookup(e->offset);
     if (!objStr) {
       objStr = new ObjectStream(this, e->offset, recursion + 1);
       if (!objStr->isOk()) {
@@ -1168,7 +1156,7 @@ Object XRef::fetch(int num, int gen, int recursion) {
       } else {
 	// XRef could be reconstructed in constructor of ObjectStream:
 	e = getEntry(num);
-	objStrs->put(e->offset, objStr);
+	objStrs.put(e->offset, objStr);
       }
     }
     return objStr->getObject(e->gen, num);
diff --git a/poppler/XRef.h b/poppler/XRef.h
index cd309cdf..9382e9ec 100644
--- a/poppler/XRef.h
+++ b/poppler/XRef.h
@@ -40,14 +40,11 @@
 #include "goo/gtypes.h"
 #include "Object.h"
 #include "Stream.h"
-
-#include <vector>
+#include "PopplerCache.h"
 
 class Dict;
 class Stream;
 class Parser;
-template<typename Key, typename Item>
-class PopplerCache;
 class ObjectStream;
 
 //------------------------------------------------------------------------
@@ -224,7 +221,7 @@ private:
   Goffset *streamEnds;		// 'endstream' positions - only used in
 				//   damaged files
   int streamEndsLen;		// number of valid entries in streamEnds
-  PopplerCache<Goffset, ObjectStream> *objStrs;	// cached object streams
+  PopplerCache<Goffset, ObjectStream> objStrs;	// cached object streams
   GBool encrypted;		// true if file is encrypted
   int encRevision;		
   int encVersion;		// encryption algorithm
@@ -241,7 +238,6 @@ private:
   GBool strOwner;     // true if str is owned by the instance
   mutable std::recursive_mutex mutex;
 
-  void init();
   int reserve(int newSize);
   int resize(int newSize);
   GBool readXRef(Goffset *pos, std::vector<Goffset> *followedXRefStm, std::vector<int> *xrefStreamObjsNum);
commit 70e929e682cec8b60120ae3b1320eab457bd2ea7
Author: Adam Reichold <adam.reichold at t-online.de>
Date:   Fri Sep 21 18:07:04 2018 +0200

    Remove specialized PopplerObjectCache since it has only one user and the additional abstraction actually obscures how it is used instead of simplifying it.

diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index c9a71822..22fd5764 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -319,8 +319,8 @@ static inline GBool isSameGfxColor(const GfxColor &colorA, const GfxColor &color
 // GfxResources
 //------------------------------------------------------------------------
 
-GfxResources::GfxResources(XRef *xref, Dict *resDictA, GfxResources *nextA) :
-    gStateCache(2, xref) {
+GfxResources::GfxResources(XRef *xrefA, Dict *resDictA, GfxResources *nextA) :
+    gStateCache(2), xref(xrefA) {
   Object obj1, obj2;
   Ref r;
 
@@ -504,12 +504,14 @@ Object GfxResources::lookupGState(const char *name) {
     return obj;
   
   const Ref ref = obj.getRef();
-  obj = gStateCache.lookup(ref);
-  if (!obj.isNull())
-    return obj;
 
-  obj = gStateCache.put(ref)->copy();
-  return obj;
+  if (auto *item = gStateCache.lookup(ref)) {
+    return item->copy();
+  }
+
+  auto *item = new Object{xref->fetch(ref.num, ref.gen)};
+  gStateCache.put(ref, item);
+  return item->copy();
 }
 
 Object GfxResources::lookupGStateNF(const char *name) {
diff --git a/poppler/Gfx.h b/poppler/Gfx.h
index cd6ac3d4..296a6e31 100644
--- a/poppler/Gfx.h
+++ b/poppler/Gfx.h
@@ -138,7 +138,8 @@ private:
   Object patternDict;
   Object shadingDict;
   Object gStateDict;
-  PopplerObjectCache gStateCache;
+  PopplerCache<Ref, Object> gStateCache;
+  XRef *xref;
   Object propertiesDict;
   GfxResources *next;
 };
diff --git a/poppler/PopplerCache.h b/poppler/PopplerCache.h
index 1bd039ef..3587cb91 100644
--- a/poppler/PopplerCache.h
+++ b/poppler/PopplerCache.h
@@ -15,9 +15,8 @@
 
 #include <algorithm>
 #include <memory>
-
-#include "Object.h"
-#include "XRef.h"
+#include <utility>
+#include <vector>
 
 template<typename Key, typename Item>
 class PopplerCache
@@ -60,28 +59,4 @@ private:
   std::vector<std::pair<Key, std::unique_ptr<Item>>> entries;
 };
 
-class PopplerObjectCache
-{
-public:
-  PopplerObjectCache(std::size_t cacheSizeA, XRef *xrefA) : cache{cacheSizeA}, xref{xrefA} {}
-
-  Object lookup(const Ref &ref) {
-    if (Object *item = cache.lookup(ref)) {
-      return item->copy();
-    } else {
-      return Object{objNull};
-    }
-  }
-
-  Object *put(const Ref &ref) {
-    Object *item = new Object{xref->fetch(ref.num, ref.gen)};
-    cache.put(ref, item);
-    return item;
-  }
-
-private:
-  PopplerCache<Ref, Object> cache;
-  XRef *xref;
-};
-
 #endif
commit cb8a526906687d85dfa5af1b30a585e76e2762a7
Author: Adam Reichold <adam.reichold at t-online.de>
Date:   Fri Sep 21 17:39:56 2018 +0200

    Turn PopplerCache into a template to avoid double indirection for look-up via virtual helper classes.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f2870d8b..fdf6fb45 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -370,7 +370,6 @@ set(poppler_SRCS
   poppler/PDFDoc.cc
   poppler/PDFDocEncoding.cc
   poppler/PDFDocFactory.cc
-  poppler/PopplerCache.cc
   poppler/ProfileData.cc
   poppler/PreScanOutputDev.cc
   poppler/PSTokenizer.cc
diff --git a/poppler/Function.h b/poppler/Function.h
index 5cce1b31..0607bf14 100644
--- a/poppler/Function.h
+++ b/poppler/Function.h
@@ -39,7 +39,6 @@ class Dict;
 class Stream;
 struct PSObject;
 class PSStack;
-class PopplerCache;
 
 //------------------------------------------------------------------------
 // Function
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 6cccef26..634e5731 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -1765,38 +1765,6 @@ void GfxLabColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange,
 // GfxICCBasedColorSpace
 //------------------------------------------------------------------------
 
-class GfxICCBasedColorSpaceKey : public PopplerCacheKey
-{
-  public:
-    GfxICCBasedColorSpaceKey(int numA, int genA) : num(numA), gen(genA)
-    {
-    }
-    
-    bool operator==(const PopplerCacheKey &key) const override
-    {
-      const GfxICCBasedColorSpaceKey *k = static_cast<const GfxICCBasedColorSpaceKey*>(&key);
-      return k->num == num && k->gen == gen;
-    }
-    
-    int num, gen;
-};
-
-class GfxICCBasedColorSpaceItem : public PopplerCacheItem
-{
-  public:
-    GfxICCBasedColorSpaceItem(GfxICCBasedColorSpace *csA)
-    {
-      cs = static_cast<GfxICCBasedColorSpace*>(csA->copy());
-    }
-    
-    ~GfxICCBasedColorSpaceItem()
-    {
-      delete cs;
-    }
-    
-    GfxICCBasedColorSpace *cs;
-};
-
 GfxICCBasedColorSpace::GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA,
 					     Ref *iccProfileStreamA) {
   nComps = nCompsA;
@@ -1863,11 +1831,8 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, OutputDev *out, GfxState
 #ifdef USE_CMS
   // check cache
   if (out && iccProfileStreamA.num > 0) {
-    GfxICCBasedColorSpaceKey k(iccProfileStreamA.num, iccProfileStreamA.gen);
-    GfxICCBasedColorSpaceItem *item = static_cast<GfxICCBasedColorSpaceItem *>(out->getIccColorSpaceCache()->lookup(k));
-    if (item != nullptr)
-    {
-      cs = static_cast<GfxICCBasedColorSpace*>(item->cs->copy());
+    if (auto *item = out->getIccColorSpaceCache()->lookup(iccProfileStreamA)) {
+      cs = static_cast<GfxICCBasedColorSpace*>(item->copy());
       int transformIntent = cs->getIntent();
       int cmsIntent = INTENT_RELATIVE_COLORIMETRIC;
       if (state != nullptr) {
@@ -2007,9 +1972,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, OutputDev *out, GfxState
   }
   // put this colorSpace into cache
   if (out && iccProfileStreamA.num > 0) {
-    GfxICCBasedColorSpaceKey *k = new GfxICCBasedColorSpaceKey(iccProfileStreamA.num, iccProfileStreamA.gen);
-    GfxICCBasedColorSpaceItem *item = new GfxICCBasedColorSpaceItem(cs);
-    out->getIccColorSpaceCache()->put(k, item);
+    out->getIccColorSpaceCache()->put(iccProfileStreamA, static_cast<GfxICCBasedColorSpace*>(cs->copy()));
   }
 #endif
   return cs;
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 71831d0f..b37362e0 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -51,7 +51,6 @@ class Gfx;
 class GfxFont;
 class PDFRectangle;
 class GfxShading;
-class PopplerCache;
 class GooList;
 class OutputDev;
 class GfxState;
diff --git a/poppler/OutputDev.cc b/poppler/OutputDev.cc
index 8449f9ef..a7614017 100644
--- a/poppler/OutputDev.cc
+++ b/poppler/OutputDev.cc
@@ -42,6 +42,14 @@
 // OutputDev
 //------------------------------------------------------------------------
 
+OutputDev::OutputDev()
+#ifdef USE_CMS
+ : iccColorSpaceCache(5)
+#endif
+ {}
+
+OutputDev::~OutputDev() = default;
+
 void OutputDev::setDefaultCTM(const double *ctm) {
   int i;
   double det;
@@ -185,10 +193,3 @@ void OutputDev::startProfile() {
 std::unique_ptr<std::unordered_map<std::string, ProfileData>> OutputDev::endProfile() {
   return std::move(profileHash);
 }
-
-#ifdef USE_CMS
-PopplerCache *OutputDev::getIccColorSpaceCache()
-{
-  return &iccColorSpaceCache;
-}
-#endif
diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h
index 40796c95..e9a877e8 100644
--- a/poppler/OutputDev.h
+++ b/poppler/OutputDev.h
@@ -56,6 +56,9 @@ class GfxState;
 class Gfx;
 struct GfxColor;
 class GfxColorSpace;
+#ifdef USE_CMS
+class GfxICCBasedColorSpace;
+#endif
 class GfxImageColorMap;
 class GfxFunctionShading;
 class GfxAxialShading;
@@ -79,15 +82,10 @@ class OutputDev {
 public:
 
   // Constructor.
-  OutputDev() 
-#ifdef USE_CMS
- : iccColorSpaceCache(5)
-#endif
-  {
-  }
+  OutputDev();
 
   // Destructor.
-  virtual ~OutputDev() {}
+  virtual ~OutputDev();
 
   //----- get info about output device
 
@@ -373,7 +371,7 @@ public:
 #endif
 
 #ifdef USE_CMS
-  PopplerCache *getIccColorSpaceCache();
+  PopplerCache<Ref, GfxICCBasedColorSpace> *getIccColorSpaceCache() { return &iccColorSpaceCache; }
 #endif
 
 private:
@@ -383,7 +381,7 @@ private:
   std::unique_ptr<std::unordered_map<std::string, ProfileData>> profileHash;
 
 #ifdef USE_CMS
-  PopplerCache iccColorSpaceCache;
+  PopplerCache<Ref, GfxICCBasedColorSpace> iccColorSpaceCache;
 #endif
 };
 
diff --git a/poppler/PopplerCache.cc b/poppler/PopplerCache.cc
deleted file mode 100644
index 5832d437..00000000
--- a/poppler/PopplerCache.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-//========================================================================
-//
-// PopplerCache.h
-//
-// This file is licensed under the GPLv2 or later
-//
-// Copyright (C) 2009 Koji Otani <sho at bbr.jp>
-// Copyright (C) 2009, 2010, 2017 Albert Astals Cid <aacid at kde.org>
-// Copyright (C) 2010 Carlos Garcia Campos <carlosgc at gnome.org>
-//
-//========================================================================
-
-#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 nullptr;
-
-  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 nullptr;
-}
-
-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 override
-    {
-      const ObjectKey *k = static_cast<const ObjectKey*>(&key);
-      return k->num == num && k->gen == gen;
-    }
-
-    int num, gen;
-};
-
-class ObjectItem : public PopplerCacheItem {
-  public:
-    ObjectItem(Object &&obj)
-    {
-      item = std::move(obj);
-    }
-
-    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);
-
-  ObjectKey *key = new ObjectKey(ref.num, ref.gen);
-  ObjectItem *item = new ObjectItem(std::move(obj));
-  cache->put(key, item);
-
-  return &item->item;
-}
-
-Object PopplerObjectCache::lookup(const Ref &ref) {
-  ObjectKey key(ref.num, ref.gen);
-  ObjectItem *item = static_cast<ObjectItem *>(cache->lookup(key));
-
-  return item ? item->item.copy() : Object(objNull);
-}
diff --git a/poppler/PopplerCache.h b/poppler/PopplerCache.h
index ecc983ac..1bd039ef 100644
--- a/poppler/PopplerCache.h
+++ b/poppler/PopplerCache.h
@@ -13,78 +13,75 @@
 #ifndef POPPLER_CACHE_H
 #define POPPLER_CACHE_H
 
+#include <algorithm>
+#include <memory>
+
 #include "Object.h"
+#include "XRef.h"
 
-class PopplerCacheItem
+template<typename Key, typename Item>
+class PopplerCache
 {
-  public:
-   PopplerCacheItem() = default;
-   virtual ~PopplerCacheItem();
+public:
+  PopplerCache(const PopplerCache &) = delete;
+  PopplerCache& operator=(const PopplerCache &other) = delete;
 
-   PopplerCacheItem(const PopplerCacheItem &) = delete;
-   PopplerCacheItem& operator=(const PopplerCacheItem &other) = delete;
-};
+  PopplerCache(std::size_t cacheSizeA) { entries.reserve(cacheSizeA); }
 
-class PopplerCacheKey
-{
-  public:
-    PopplerCacheKey() = default;
-    virtual ~PopplerCacheKey();
-    virtual bool operator==(const PopplerCacheKey &key) const = 0;
+  /* The item returned is owned by the cache */
+  Item *lookup(const Key &key) {
+    if (!entries.empty() && entries.front().first == key) {
+      return entries.front().second.get();
+    }
 
-    PopplerCacheKey(const PopplerCacheKey &) = delete;
-    PopplerCacheKey& operator=(const PopplerCacheKey &other) = delete;
-};
+    for (auto it = entries.begin(); it != entries.end(); ++it) {
+      if (it->first == key) {
+	auto *item = it->second.get();
 
-class PopplerCache
-{
-  public:
-    PopplerCache(int cacheSizeA);
-    ~PopplerCache();
-    
-    PopplerCache(const PopplerCache &) = delete;
-    PopplerCache& operator=(const PopplerCache &other) = delete;
+	std::rotate(entries.begin(), it, std::next(it));
 
-    /* The item returned is owned by the cache */
-    PopplerCacheItem *lookup(const PopplerCacheKey &key);
-    
-    /* The key and item pointers ownership is taken by the cache */
-    void put(PopplerCacheKey *key, PopplerCacheItem *item);
-    
-    /* The max size of the cache */
-    int size();
-    
-    /* The number of items in the cache */
-    int numberOfItems();
-    
-    /* The n-th item in the cache */
-    PopplerCacheItem *item(int index);
+	return item;
+      }
+    }
+
+    return nullptr;
+  }
     
-    /* The n-th key in the cache */
-    PopplerCacheKey *key(int index);
-  
-  private:
-    PopplerCacheKey **keys;
-    PopplerCacheItem **items;
-    int lastValidCacheIndex;
-    int cacheSize;
+  /* The key and item pointers ownership is taken by the cache */
+  void put(const Key &key, Item *item) {
+    if (entries.size() == entries.capacity()) {
+      entries.pop_back();
+    }
+
+    entries.emplace(entries.begin(), key, std::unique_ptr<Item>{item});
+  }
+
+private:
+  std::vector<std::pair<Key, std::unique_ptr<Item>>> entries;
 };
 
 class PopplerObjectCache
 {
-  public:
-    PopplerObjectCache (int cacheSizeA, XRef *xrefA);
-    ~PopplerObjectCache();
+public:
+  PopplerObjectCache(std::size_t cacheSizeA, XRef *xrefA) : cache{cacheSizeA}, xref{xrefA} {}
 
-    PopplerObjectCache(const PopplerObjectCache &) = delete;
-    PopplerObjectCache& operator=(const PopplerObjectCache &other) = delete;
+  Object lookup(const Ref &ref) {
+    if (Object *item = cache.lookup(ref)) {
+      return item->copy();
+    } else {
+      return Object{objNull};
+    }
+  }
 
-    Object *put(const Ref &ref);
-    Object lookup(const Ref &ref);
+  Object *put(const Ref &ref) {
+    Object *item = new Object{xref->fetch(ref.num, ref.gen)};
+    cache.put(ref, item);
+    return item;
+  }
 
-  private:
-    XRef *xref;
-    PopplerCache *cache;
+private:
+  PopplerCache<Ref, Object> cache;
+  XRef *xref;
 };
 
 #endif
diff --git a/poppler/XRef.cc b/poppler/XRef.cc
index 56fa2b6a..84914f1f 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -106,37 +106,6 @@ private:
   GBool ok;
 };
 
-class ObjectStreamKey : public PopplerCacheKey
-{
-  public:
-    ObjectStreamKey(int num) : objStrNum(num)
-    {
-    }
-
-    bool operator==(const PopplerCacheKey &key) const override
-    {
-      const ObjectStreamKey *k = static_cast<const ObjectStreamKey*>(&key);
-      return objStrNum == k->objStrNum;
-    }
-
-    const int objStrNum;
-};
-
-class ObjectStreamItem : public PopplerCacheItem
-{
-  public:
-    ObjectStreamItem(ObjectStream *objStr) : objStream(objStr)
-    {
-    }
-
-    ~ObjectStreamItem()
-    {
-      delete objStream;
-    }
-
-    ObjectStream *objStream;
-};
-
 ObjectStream::ObjectStream(XRef *xref, int objStrNumA, int recursion) {
   Stream *str;
   Parser *parser;
@@ -267,7 +236,7 @@ void XRef::init() {
   modified = gFalse;
   streamEnds = nullptr;
   streamEndsLen = 0;
-  objStrs = new PopplerCache(5);
+  objStrs = new PopplerCache<Goffset, ObjectStream>(5);
   mainXRefEntriesOffset = 0;
   xRefStream = gFalse;
   scannedSpecialFlags = gFalse;
@@ -1189,14 +1158,7 @@ Object XRef::fetch(int num, int gen, int recursion) {
       goto err;
     }
 
-    ObjectStream *objStr = nullptr;
-    ObjectStreamKey key(e->offset);
-    PopplerCacheItem *item = objStrs->lookup(key);
-    if (item) {
-      ObjectStreamItem *it = static_cast<ObjectStreamItem *>(item);
-      objStr = it->objStream;
-    }
-
+    ObjectStream *objStr = objStrs->lookup(e->offset);
     if (!objStr) {
       objStr = new ObjectStream(this, e->offset, recursion + 1);
       if (!objStr->isOk()) {
@@ -1206,9 +1168,7 @@ Object XRef::fetch(int num, int gen, int recursion) {
       } else {
 	// XRef could be reconstructed in constructor of ObjectStream:
 	e = getEntry(num);
-	ObjectStreamKey *newkey = new ObjectStreamKey(e->offset);
-	ObjectStreamItem *newitem = new ObjectStreamItem(objStr);
-	objStrs->put(newkey, newitem);
+	objStrs->put(e->offset, objStr);
       }
     }
     return objStr->getObject(e->gen, num);
diff --git a/poppler/XRef.h b/poppler/XRef.h
index 933930af..cd309cdf 100644
--- a/poppler/XRef.h
+++ b/poppler/XRef.h
@@ -46,7 +46,9 @@
 class Dict;
 class Stream;
 class Parser;
+template<typename Key, typename Item>
 class PopplerCache;
+class ObjectStream;
 
 //------------------------------------------------------------------------
 // XRef
@@ -222,7 +224,7 @@ private:
   Goffset *streamEnds;		// 'endstream' positions - only used in
 				//   damaged files
   int streamEndsLen;		// number of valid entries in streamEnds
-  PopplerCache *objStrs;	// cached object streams
+  PopplerCache<Goffset, ObjectStream> *objStrs;	// cached object streams
   GBool encrypted;		// true if file is encrypted
   int encRevision;		
   int encVersion;		// encryption algorithm


More information about the poppler mailing list