Fix nits in CPDF_PageOrganizer.

Review-Url: https://codereview.chromium.org/2493283003
diff --git a/fpdfsdk/fpdfppo.cpp b/fpdfsdk/fpdfppo.cpp
index 786bc46..705c7e2 100644
--- a/fpdfsdk/fpdfppo.cpp
+++ b/fpdfsdk/fpdfppo.cpp
@@ -18,159 +18,13 @@
 #include "core/fpdfapi/parser/cpdf_stream.h"
 #include "core/fpdfapi/parser/cpdf_string.h"
 #include "fpdfsdk/fsdk_define.h"
+#include "third_party/base/ptr_util.h"
 #include "third_party/base/stl_util.h"
 
-class CPDF_PageOrganizer {
- public:
-  using ObjectNumberMap = std::map<uint32_t, uint32_t>;
-  CPDF_PageOrganizer();
-  ~CPDF_PageOrganizer();
+namespace {
 
-  bool PDFDocInit(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc);
-  bool ExportPage(CPDF_Document* pSrcPDFDoc,
-                  std::vector<uint16_t>* pPageNums,
-                  CPDF_Document* pDestPDFDoc,
-                  int nIndex);
-  CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict,
-                                         const CFX_ByteString& bsSrctag);
-  bool UpdateReference(CPDF_Object* pObj,
-                       CPDF_Document* pDoc,
-                       ObjectNumberMap* pObjNumberMap);
-  uint32_t GetNewObjId(CPDF_Document* pDoc,
-                       ObjectNumberMap* pObjNumberMap,
-                       CPDF_Reference* pRef);
-};
-
-CPDF_PageOrganizer::CPDF_PageOrganizer() {}
-
-CPDF_PageOrganizer::~CPDF_PageOrganizer() {}
-
-bool CPDF_PageOrganizer::PDFDocInit(CPDF_Document* pDestPDFDoc,
-                                    CPDF_Document* pSrcPDFDoc) {
-  if (!pDestPDFDoc || !pSrcPDFDoc)
-    return false;
-
-  CPDF_Dictionary* pNewRoot = pDestPDFDoc->GetRoot();
-  if (!pNewRoot)
-    return false;
-
-  CPDF_Dictionary* DInfoDict = pDestPDFDoc->GetInfo();
-  if (!DInfoDict)
-    return false;
-
-  CFX_ByteString producerstr;
-  producerstr.Format("PDFium");
-  DInfoDict->SetFor("Producer", new CPDF_String(producerstr, false));
-
-  CFX_ByteString cbRootType = pNewRoot->GetStringFor("Type", "");
-  if (cbRootType.IsEmpty())
-    pNewRoot->SetFor("Type", new CPDF_Name("Catalog"));
-
-  CPDF_Object* pElement = pNewRoot->GetObjectFor("Pages");
-  CPDF_Dictionary* pNewPages =
-      pElement ? ToDictionary(pElement->GetDirect()) : nullptr;
-  if (!pNewPages) {
-    pNewPages = new CPDF_Dictionary(pDestPDFDoc->GetByteStringPool());
-    pNewRoot->SetReferenceFor("Pages", pDestPDFDoc,
-                              pDestPDFDoc->AddIndirectObject(pNewPages));
-  }
-
-  CFX_ByteString cbPageType = pNewPages->GetStringFor("Type", "");
-  if (cbPageType == "") {
-    pNewPages->SetFor("Type", new CPDF_Name("Pages"));
-  }
-
-  if (!pNewPages->GetArrayFor("Kids")) {
-    pNewPages->SetIntegerFor("Count", 0);
-    pNewPages->SetReferenceFor("Kids", pDestPDFDoc,
-                               pDestPDFDoc->AddIndirectObject(new CPDF_Array));
-  }
-
-  return true;
-}
-
-bool CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc,
-                                    std::vector<uint16_t>* pPageNums,
-                                    CPDF_Document* pDestPDFDoc,
-                                    int nIndex) {
-  int curpage = nIndex;
-  std::unique_ptr<ObjectNumberMap> pObjNumberMap(new ObjectNumberMap);
-  int nSize = pdfium::CollectionSize<int>(*pPageNums);
-  for (int i = 0; i < nSize; ++i) {
-    CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage);
-    CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(pPageNums->at(i) - 1);
-    if (!pSrcPageDict || !pCurPageDict)
-      return false;
-
-    // Clone the page dictionary
-    for (const auto& it : *pSrcPageDict) {
-      const CFX_ByteString& cbSrcKeyStr = it.first;
-      CPDF_Object* pObj = it.second;
-      if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) {
-        if (pCurPageDict->KeyExist(cbSrcKeyStr))
-          pCurPageDict->RemoveFor(cbSrcKeyStr);
-        pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone().release());
-      }
-    }
-
-    // inheritable item
-    CPDF_Object* pInheritable = nullptr;
-    // 1 MediaBox  //required
-    if (!pCurPageDict->KeyExist("MediaBox")) {
-      pInheritable = PageDictGetInheritableTag(pSrcPageDict, "MediaBox");
-      if (!pInheritable) {
-        // Search the "CropBox" from source page dictionary,
-        // if not exists,we take the letter size.
-        pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox");
-        if (pInheritable) {
-          pCurPageDict->SetFor("MediaBox", pInheritable->Clone().release());
-        } else {
-          // Make the default size to be letter size (8.5'x11')
-          CPDF_Array* pArray = new CPDF_Array;
-          pArray->AddNumber(0);
-          pArray->AddNumber(0);
-          pArray->AddNumber(612);
-          pArray->AddNumber(792);
-          pCurPageDict->SetFor("MediaBox", pArray);
-        }
-      } else {
-        pCurPageDict->SetFor("MediaBox", pInheritable->Clone().release());
-      }
-    }
-    // 2 Resources //required
-    if (!pCurPageDict->KeyExist("Resources")) {
-      pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Resources");
-      if (!pInheritable)
-        return false;
-      pCurPageDict->SetFor("Resources", pInheritable->Clone().release());
-    }
-    // 3 CropBox  //Optional
-    if (!pCurPageDict->KeyExist("CropBox")) {
-      pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox");
-      if (pInheritable)
-        pCurPageDict->SetFor("CropBox", pInheritable->Clone().release());
-    }
-    // 4 Rotate  //Optional
-    if (!pCurPageDict->KeyExist("Rotate")) {
-      pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate");
-      if (pInheritable)
-        pCurPageDict->SetFor("Rotate", pInheritable->Clone().release());
-    }
-
-    // Update the reference
-    uint32_t dwOldPageObj = pSrcPageDict->GetObjNum();
-    uint32_t dwNewPageObj = pCurPageDict->GetObjNum();
-    (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj;
-    UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get());
-    ++curpage;
-  }
-
-  return true;
-}
-
-CPDF_Object* CPDF_PageOrganizer::PageDictGetInheritableTag(
-    CPDF_Dictionary* pDict,
-    const CFX_ByteString& bsSrcTag) {
+CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict,
+                                       const CFX_ByteString& bsSrcTag) {
   if (!pDict || bsSrcTag.IsEmpty())
     return nullptr;
   if (!pDict->KeyExist("Parent") || !pDict->KeyExist("Type"))
@@ -200,16 +54,211 @@
   return nullptr;
 }
 
+bool CopyInheritable(CPDF_Dictionary* pCurPageDict,
+                     CPDF_Dictionary* pSrcPageDict,
+                     const CFX_ByteString& key) {
+  if (pCurPageDict->KeyExist(key))
+    return true;
+
+  CPDF_Object* pInheritable = PageDictGetInheritableTag(pSrcPageDict, key);
+  if (!pInheritable)
+    return false;
+
+  pCurPageDict->SetFor(key, pInheritable->Clone().release());
+  return true;
+}
+
+bool ParserPageRangeString(CFX_ByteString rangstring,
+                           std::vector<uint16_t>* pageArray,
+                           int nCount) {
+  if (rangstring.IsEmpty())
+    return true;
+
+  rangstring.Remove(' ');
+  int nLength = rangstring.GetLength();
+  CFX_ByteString cbCompareString("0123456789-,");
+  for (int i = 0; i < nLength; ++i) {
+    if (cbCompareString.Find(rangstring[i]) == -1)
+      return false;
+  }
+
+  CFX_ByteString cbMidRange;
+  int nStringFrom = 0;
+  int nStringTo = 0;
+  while (nStringTo < nLength) {
+    nStringTo = rangstring.Find(',', nStringFrom);
+    if (nStringTo == -1)
+      nStringTo = nLength;
+    cbMidRange = rangstring.Mid(nStringFrom, nStringTo - nStringFrom);
+    int nMid = cbMidRange.Find('-');
+    if (nMid == -1) {
+      long lPageNum = atol(cbMidRange.c_str());
+      if (lPageNum <= 0 || lPageNum > nCount)
+        return false;
+      pageArray->push_back((uint16_t)lPageNum);
+    } else {
+      int nStartPageNum = atol(cbMidRange.Mid(0, nMid).c_str());
+      if (nStartPageNum == 0)
+        return false;
+
+      ++nMid;
+      int nEnd = cbMidRange.GetLength() - nMid;
+      if (nEnd == 0)
+        return false;
+
+      int nEndPageNum = atol(cbMidRange.Mid(nMid, nEnd).c_str());
+      if (nStartPageNum < 0 || nStartPageNum > nEndPageNum ||
+          nEndPageNum > nCount) {
+        return false;
+      }
+      for (int i = nStartPageNum; i <= nEndPageNum; ++i) {
+        pageArray->push_back(i);
+      }
+    }
+    nStringFrom = nStringTo + 1;
+  }
+  return true;
+}
+
+}  // namespace
+
+class CPDF_PageOrganizer {
+ public:
+  CPDF_PageOrganizer(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc);
+  ~CPDF_PageOrganizer();
+
+  bool PDFDocInit();
+  bool ExportPage(const std::vector<uint16_t>& pageNums, int nIndex);
+
+ private:
+  using ObjectNumberMap = std::map<uint32_t, uint32_t>;
+
+  bool UpdateReference(CPDF_Object* pObj, ObjectNumberMap* pObjNumberMap);
+  uint32_t GetNewObjId(ObjectNumberMap* pObjNumberMap, CPDF_Reference* pRef);
+
+  CPDF_Document* m_pDestPDFDoc;
+  CPDF_Document* m_pSrcPDFDoc;
+};
+
+CPDF_PageOrganizer::CPDF_PageOrganizer(CPDF_Document* pDestPDFDoc,
+                                       CPDF_Document* pSrcPDFDoc)
+    : m_pDestPDFDoc(pDestPDFDoc), m_pSrcPDFDoc(pSrcPDFDoc) {}
+
+CPDF_PageOrganizer::~CPDF_PageOrganizer() {}
+
+bool CPDF_PageOrganizer::PDFDocInit() {
+  ASSERT(m_pDestPDFDoc);
+  ASSERT(m_pSrcPDFDoc);
+
+  CPDF_Dictionary* pNewRoot = m_pDestPDFDoc->GetRoot();
+  if (!pNewRoot)
+    return false;
+
+  CPDF_Dictionary* pDocInfoDict = m_pDestPDFDoc->GetInfo();
+  if (!pDocInfoDict)
+    return false;
+
+  CFX_ByteString producerstr;
+  producerstr.Format("PDFium");
+  pDocInfoDict->SetFor("Producer", new CPDF_String(producerstr, false));
+
+  CFX_ByteString cbRootType = pNewRoot->GetStringFor("Type", "");
+  if (cbRootType.IsEmpty())
+    pNewRoot->SetFor("Type", new CPDF_Name("Catalog"));
+
+  CPDF_Object* pElement = pNewRoot->GetObjectFor("Pages");
+  CPDF_Dictionary* pNewPages =
+      pElement ? ToDictionary(pElement->GetDirect()) : nullptr;
+  if (!pNewPages) {
+    pNewPages = new CPDF_Dictionary(m_pDestPDFDoc->GetByteStringPool());
+    pNewRoot->SetReferenceFor("Pages", m_pDestPDFDoc,
+                              m_pDestPDFDoc->AddIndirectObject(pNewPages));
+  }
+
+  CFX_ByteString cbPageType = pNewPages->GetStringFor("Type", "");
+  if (cbPageType.IsEmpty())
+    pNewPages->SetFor("Type", new CPDF_Name("Pages"));
+
+  if (!pNewPages->GetArrayFor("Kids")) {
+    pNewPages->SetIntegerFor("Count", 0);
+    pNewPages->SetReferenceFor(
+        "Kids", m_pDestPDFDoc,
+        m_pDestPDFDoc->AddIndirectObject(new CPDF_Array));
+  }
+
+  return true;
+}
+
+bool CPDF_PageOrganizer::ExportPage(const std::vector<uint16_t>& pageNums,
+                                    int nIndex) {
+  int curpage = nIndex;
+  auto pObjNumberMap = pdfium::MakeUnique<ObjectNumberMap>();
+  int nSize = pdfium::CollectionSize<int>(pageNums);
+  for (int i = 0; i < nSize; ++i) {
+    CPDF_Dictionary* pCurPageDict = m_pDestPDFDoc->CreateNewPage(curpage);
+    CPDF_Dictionary* pSrcPageDict = m_pSrcPDFDoc->GetPage(pageNums[i] - 1);
+    if (!pSrcPageDict || !pCurPageDict)
+      return false;
+
+    // Clone the page dictionary
+    for (const auto& it : *pSrcPageDict) {
+      const CFX_ByteString& cbSrcKeyStr = it.first;
+      CPDF_Object* pObj = it.second;
+      if (cbSrcKeyStr == "Type" || cbSrcKeyStr == "Parent")
+        continue;
+
+      pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone().release());
+    }
+
+    // inheritable item
+    // 1 MediaBox - required
+    if (!CopyInheritable(pCurPageDict, pSrcPageDict, "MediaBox")) {
+      // Search for "CropBox" in the source page dictionary,
+      // if it does not exists, use the default letter size.
+      CPDF_Object* pInheritable =
+          PageDictGetInheritableTag(pSrcPageDict, "CropBox");
+      if (pInheritable) {
+        pCurPageDict->SetFor("MediaBox", pInheritable->Clone().release());
+      } else {
+        // Make the default size to be letter size (8.5'x11')
+        CPDF_Array* pArray = new CPDF_Array;
+        pArray->AddNumber(0);
+        pArray->AddNumber(0);
+        pArray->AddNumber(612);
+        pArray->AddNumber(792);
+        pCurPageDict->SetFor("MediaBox", pArray);
+      }
+    }
+
+    // 2 Resources - required
+    if (!CopyInheritable(pCurPageDict, pSrcPageDict, "Resources"))
+      return false;
+
+    // 3 CropBox - optional
+    CopyInheritable(pCurPageDict, pSrcPageDict, "CropBox");
+    // 4 Rotate - optional
+    CopyInheritable(pCurPageDict, pSrcPageDict, "Rotate");
+
+    // Update the reference
+    uint32_t dwOldPageObj = pSrcPageDict->GetObjNum();
+    uint32_t dwNewPageObj = pCurPageDict->GetObjNum();
+    (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj;
+    UpdateReference(pCurPageDict, pObjNumberMap.get());
+    ++curpage;
+  }
+
+  return true;
+}
+
 bool CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj,
-                                         CPDF_Document* pDoc,
                                          ObjectNumberMap* pObjNumberMap) {
   switch (pObj->GetType()) {
     case CPDF_Object::REFERENCE: {
       CPDF_Reference* pReference = pObj->AsReference();
-      uint32_t newobjnum = GetNewObjId(pDoc, pObjNumberMap, pReference);
+      uint32_t newobjnum = GetNewObjId(pObjNumberMap, pReference);
       if (newobjnum == 0)
         return false;
-      pReference->SetRef(pDoc, newobjnum);
+      pReference->SetRef(m_pDestPDFDoc, newobjnum);
       break;
     }
     case CPDF_Object::DICTIONARY: {
@@ -223,7 +272,7 @@
           continue;
         if (!pNextObj)
           return false;
-        if (!UpdateReference(pNextObj, pDoc, pObjNumberMap))
+        if (!UpdateReference(pNextObj, pObjNumberMap))
           pDict->RemoveFor(key);
       }
       break;
@@ -234,7 +283,7 @@
         CPDF_Object* pNextObj = pArray->GetObjectAt(i);
         if (!pNextObj)
           return false;
-        if (!UpdateReference(pNextObj, pDoc, pObjNumberMap))
+        if (!UpdateReference(pNextObj, pObjNumberMap))
           return false;
       }
       break;
@@ -242,12 +291,10 @@
     case CPDF_Object::STREAM: {
       CPDF_Stream* pStream = pObj->AsStream();
       CPDF_Dictionary* pDict = pStream->GetDict();
-      if (pDict) {
-        if (!UpdateReference(pDict, pDoc, pObjNumberMap))
-          return false;
-      } else {
+      if (!pDict)
         return false;
-      }
+      if (!UpdateReference(pDict, pObjNumberMap))
+        return false;
       break;
     }
     default:
@@ -257,8 +304,7 @@
   return true;
 }
 
-uint32_t CPDF_PageOrganizer::GetNewObjId(CPDF_Document* pDoc,
-                                         ObjectNumberMap* pObjNumberMap,
+uint32_t CPDF_PageOrganizer::GetNewObjId(ObjectNumberMap* pObjNumberMap,
                                          CPDF_Reference* pRef) {
   if (!pRef)
     return 0;
@@ -286,64 +332,14 @@
     }
   }
   CPDF_Object* pUnownedClone = pClone.get();
-  dwNewObjNum = pDoc->AddIndirectObject(pClone.release());
+  dwNewObjNum = m_pDestPDFDoc->AddIndirectObject(pClone.release());
   (*pObjNumberMap)[dwObjnum] = dwNewObjNum;
-  if (!UpdateReference(pUnownedClone, pDoc, pObjNumberMap))
+  if (!UpdateReference(pUnownedClone, pObjNumberMap))
     return 0;
 
   return dwNewObjNum;
 }
 
-FPDF_BOOL ParserPageRangeString(CFX_ByteString rangstring,
-                                std::vector<uint16_t>* pageArray,
-                                int nCount) {
-  if (rangstring.GetLength() != 0) {
-    rangstring.Remove(' ');
-    int nLength = rangstring.GetLength();
-    CFX_ByteString cbCompareString("0123456789-,");
-    for (int i = 0; i < nLength; ++i) {
-      if (cbCompareString.Find(rangstring[i]) == -1)
-        return false;
-    }
-    CFX_ByteString cbMidRange;
-    int nStringFrom = 0;
-    int nStringTo = 0;
-    while (nStringTo < nLength) {
-      nStringTo = rangstring.Find(',', nStringFrom);
-      if (nStringTo == -1)
-        nStringTo = nLength;
-      cbMidRange = rangstring.Mid(nStringFrom, nStringTo - nStringFrom);
-      int nMid = cbMidRange.Find('-');
-      if (nMid == -1) {
-        long lPageNum = atol(cbMidRange.c_str());
-        if (lPageNum <= 0 || lPageNum > nCount)
-          return false;
-        pageArray->push_back((uint16_t)lPageNum);
-      } else {
-        int nStartPageNum = atol(cbMidRange.Mid(0, nMid).c_str());
-        if (nStartPageNum == 0)
-          return false;
-
-        ++nMid;
-        int nEnd = cbMidRange.GetLength() - nMid;
-        if (nEnd == 0)
-          return false;
-
-        int nEndPageNum = atol(cbMidRange.Mid(nMid, nEnd).c_str());
-        if (nStartPageNum < 0 || nStartPageNum > nEndPageNum ||
-            nEndPageNum > nCount) {
-          return false;
-        }
-        for (int i = nStartPageNum; i <= nEndPageNum; ++i) {
-          pageArray->push_back(i);
-        }
-      }
-      nStringFrom = nStringTo + 1;
-    }
-  }
-  return true;
-}
-
 DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc,
                                              FPDF_DOCUMENT src_doc,
                                              FPDF_BYTESTRING pagerange,
@@ -367,9 +363,8 @@
     }
   }
 
-  CPDF_PageOrganizer pageOrg;
-  pageOrg.PDFDocInit(pDestDoc, pSrcDoc);
-  return pageOrg.ExportPage(pSrcDoc, &pageArray, pDestDoc, index);
+  CPDF_PageOrganizer pageOrg(pDestDoc, pSrcDoc);
+  return pageOrg.PDFDocInit() && pageOrg.ExportPage(pageArray, index);
 }
 
 DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc,