// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../../include/fpdfapi/fpdf_parser.h"
#include "../../../include/fxcrt/fx_string.h"

// static
int CPDF_Object::s_nCurRefDepth = 0;

void CPDF_Object::Release() {
  if (m_ObjNum) {
    return;
  }
  Destroy();
}
void CPDF_Object::Destroy() {
  switch (m_Type) {
    case PDFOBJ_STRING:
      delete (CPDF_String*)this;
      break;
    case PDFOBJ_NAME:
      delete (CPDF_Name*)this;
      break;
    case PDFOBJ_ARRAY:
      delete (CPDF_Array*)this;
      break;
    case PDFOBJ_DICTIONARY:
      delete (CPDF_Dictionary*)this;
      break;
    case PDFOBJ_STREAM:
      delete (CPDF_Stream*)this;
      break;
    default:
      delete this;
  }
}
CFX_ByteString CPDF_Object::GetString() const {
  switch (m_Type) {
    case PDFOBJ_BOOLEAN:
      return ((CPDF_Boolean*)this)->m_bValue ? "true" : "false";
    case PDFOBJ_NUMBER:
      return ((CPDF_Number*)this)->GetString();
    case PDFOBJ_STRING:
      return ((CPDF_String*)this)->m_String;
    case PDFOBJ_NAME:
      return ((CPDF_Name*)this)->m_Name;
    case PDFOBJ_REFERENCE: {
      CPDF_Reference* pRef = (CPDF_Reference*)(void*)this;
      if (pRef->m_pObjList == NULL) {
        break;
      }
      CPDF_Object* pObj =
          pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum);
      if (pObj == NULL) {
        return CFX_ByteString();
      }
      return pObj->GetString();
    }
  }
  return CFX_ByteString();
}
CFX_ByteStringC CPDF_Object::GetConstString() const {
  switch (m_Type) {
    case PDFOBJ_STRING:
      return CFX_ByteStringC((const uint8_t*)((CPDF_String*)this)->m_String,
                             ((CPDF_String*)this)->m_String.GetLength());
    case PDFOBJ_NAME:
      return CFX_ByteStringC((const uint8_t*)((CPDF_Name*)this)->m_Name,
                             ((CPDF_Name*)this)->m_Name.GetLength());
    case PDFOBJ_REFERENCE: {
      CPDF_Reference* pRef = (CPDF_Reference*)(void*)this;
      if (pRef->m_pObjList == NULL) {
        break;
      }
      CPDF_Object* pObj =
          pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum);
      if (pObj == NULL) {
        return CFX_ByteStringC();
      }
      return pObj->GetConstString();
    }
  }
  return CFX_ByteStringC();
}
FX_FLOAT CPDF_Object::GetNumber() const {
  switch (m_Type) {
    case PDFOBJ_NUMBER:
      return ((CPDF_Number*)this)->GetNumber();
    case PDFOBJ_REFERENCE: {
      CPDF_Reference* pRef = (CPDF_Reference*)(void*)this;
      if (pRef->m_pObjList == NULL) {
        break;
      }
      CPDF_Object* pObj =
          pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum);
      if (pObj == NULL) {
        return 0;
      }
      return pObj->GetNumber();
    }
  }
  return 0;
}
FX_FLOAT CPDF_Object::GetNumber16() const {
  return GetNumber();
}
int CPDF_Object::GetInteger() const {
  CFX_AutoRestorer<int> restorer(&s_nCurRefDepth);
  if (++s_nCurRefDepth > OBJECT_REF_MAX_DEPTH) {
    return 0;
  }
  switch (m_Type) {
    case PDFOBJ_BOOLEAN:
      return ((CPDF_Boolean*)this)->m_bValue;
    case PDFOBJ_NUMBER:
      return ((CPDF_Number*)this)->GetInteger();
    case PDFOBJ_REFERENCE: {
      CPDF_Reference* pRef = (CPDF_Reference*)(void*)this;
      PARSE_CONTEXT context;
      FXSYS_memset(&context, 0, sizeof(PARSE_CONTEXT));
      if (pRef->m_pObjList == NULL) {
        return 0;
      }
      CPDF_Object* pObj =
          pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum, &context);
      if (pObj == NULL) {
        return 0;
      }
      return pObj->GetInteger();
    }
  }
  return 0;
}
CPDF_Dictionary* CPDF_Object::GetDict() const {
  switch (m_Type) {
    case PDFOBJ_DICTIONARY:
      return (CPDF_Dictionary*)this;
    case PDFOBJ_STREAM:
      return ((CPDF_Stream*)this)->GetDict();
    case PDFOBJ_REFERENCE: {
      CPDF_Reference* pRef = (CPDF_Reference*)this;
      if (pRef->m_pObjList == NULL) {
        break;
      }
      CPDF_Object* pObj =
          pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum);
      if (pObj == NULL) {
        return NULL;
      }
      return pObj->GetDict();
    }
  }
  return NULL;
}
CPDF_Array* CPDF_Object::GetArray() const {
  if (m_Type == PDFOBJ_ARRAY)
    return (CPDF_Array*)this;

  return NULL;
}
void CPDF_Object::SetString(const CFX_ByteString& str) {
  ASSERT(this != NULL);
  switch (m_Type) {
    case PDFOBJ_BOOLEAN:
      ((CPDF_Boolean*)this)->m_bValue = str == FX_BSTRC("true") ? 1 : 0;
      return;
    case PDFOBJ_NUMBER:
      ((CPDF_Number*)this)->SetString(str);
      return;
    case PDFOBJ_STRING:
      ((CPDF_String*)this)->m_String = str;
      return;
    case PDFOBJ_NAME:
      ((CPDF_Name*)this)->m_Name = str;
      return;
  }
  ASSERT(FALSE);
}
int CPDF_Object::GetDirectType() const {
  if (m_Type != PDFOBJ_REFERENCE) {
    return m_Type;
  }
  CPDF_Reference* pRef = (CPDF_Reference*)this;
  return pRef->m_pObjList->GetIndirectType(pRef->m_RefObjNum);
}
FX_BOOL CPDF_Object::IsIdentical(CPDF_Object* pOther) const {
  if (this == pOther) {
    return TRUE;
  }
  if (pOther == NULL) {
    return FALSE;
  }
  if (pOther->m_Type != m_Type) {
    if (m_Type == PDFOBJ_REFERENCE && GetDirect()) {
      return GetDirect()->IsIdentical(pOther);
    }
    if (pOther->m_Type == PDFOBJ_REFERENCE) {
      return IsIdentical(pOther->GetDirect());
    }
    return FALSE;
  }
  switch (m_Type) {
    case PDFOBJ_BOOLEAN:
      return (((CPDF_Boolean*)this)->Identical((CPDF_Boolean*)pOther));
    case PDFOBJ_NUMBER:
      return (((CPDF_Number*)this)->Identical((CPDF_Number*)pOther));
    case PDFOBJ_STRING:
      return (((CPDF_String*)this)->Identical((CPDF_String*)pOther));
    case PDFOBJ_NAME:
      return (((CPDF_Name*)this)->Identical((CPDF_Name*)pOther));
    case PDFOBJ_ARRAY:
      return (((CPDF_Array*)this)->Identical((CPDF_Array*)pOther));
    case PDFOBJ_DICTIONARY:
      return (((CPDF_Dictionary*)this)->Identical((CPDF_Dictionary*)pOther));
    case PDFOBJ_NULL:
      return TRUE;
    case PDFOBJ_STREAM:
      return (((CPDF_Stream*)this)->Identical((CPDF_Stream*)pOther));
    case PDFOBJ_REFERENCE:
      return (((CPDF_Reference*)this)->Identical((CPDF_Reference*)pOther));
  }
  return FALSE;
}
CPDF_Object* CPDF_Object::GetDirect() const {
  if (m_Type != PDFOBJ_REFERENCE) {
    return (CPDF_Object*)this;
  }
  CPDF_Reference* pRef = (CPDF_Reference*)(void*)this;
  if (pRef->m_pObjList == NULL) {
    return NULL;
  }
  return pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum);
}
CPDF_Object* CPDF_Object::Clone(FX_BOOL bDirect) const {
  CFX_MapPtrToPtr visited;
  return CloneInternal(bDirect, &visited);
}
CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect,
                                        CFX_MapPtrToPtr* visited) const {
  switch (m_Type) {
    case PDFOBJ_BOOLEAN:
      return new CPDF_Boolean(((CPDF_Boolean*)this)->m_bValue);
    case PDFOBJ_NUMBER:
      return new CPDF_Number(((CPDF_Number*)this)->m_bInteger,
                             &((CPDF_Number*)this)->m_Integer);
    case PDFOBJ_STRING:
      return new CPDF_String(((CPDF_String*)this)->m_String,
                             ((CPDF_String*)this)->IsHex());
    case PDFOBJ_NAME:
      return new CPDF_Name(((CPDF_Name*)this)->m_Name);
    case PDFOBJ_ARRAY: {
      CPDF_Array* pCopy = new CPDF_Array();
      CPDF_Array* pThis = (CPDF_Array*)this;
      int n = pThis->GetCount();
      for (int i = 0; i < n; i++) {
        CPDF_Object* value = (CPDF_Object*)pThis->m_Objects.GetAt(i);
        pCopy->m_Objects.Add(value->CloneInternal(bDirect, visited));
      }
      return pCopy;
    }
    case PDFOBJ_DICTIONARY: {
      CPDF_Dictionary* pCopy = new CPDF_Dictionary();
      CPDF_Dictionary* pThis = (CPDF_Dictionary*)this;
      FX_POSITION pos = pThis->m_Map.GetStartPosition();
      while (pos) {
        CFX_ByteString key;
        CPDF_Object* value;
        pThis->m_Map.GetNextAssoc(pos, key, (void*&)value);
        pCopy->m_Map.SetAt(key, value->CloneInternal(bDirect, visited));
      }
      return pCopy;
    }
    case PDFOBJ_NULL: {
      return new CPDF_Null;
    }
    case PDFOBJ_STREAM: {
      CPDF_Stream* pThis = (CPDF_Stream*)this;
      CPDF_StreamAcc acc;
      acc.LoadAllData(pThis, TRUE);
      FX_DWORD streamSize = acc.GetSize();
      CPDF_Dictionary* pDict = pThis->GetDict();
      if (pDict)
        pDict = (CPDF_Dictionary*)((CPDF_Object*)pDict)
                    ->CloneInternal(bDirect, visited);
      return new CPDF_Stream(acc.DetachData(), streamSize, pDict);
    }
    case PDFOBJ_REFERENCE: {
      CPDF_Reference* pRef = (CPDF_Reference*)this;
      FX_DWORD obj_num = pRef->m_RefObjNum;
      if (bDirect && !visited->GetValueAt((void*)(uintptr_t)obj_num)) {
        visited->SetAt((void*)(uintptr_t)obj_num, (void*)1);
        if (!pRef->GetDirect())
          return nullptr;

        return pRef->GetDirect()->CloneInternal(TRUE, visited);
      }
      return new CPDF_Reference(pRef->m_pObjList, obj_num);
    }
  }
  return NULL;
}
CPDF_Object* CPDF_Object::CloneRef(CPDF_IndirectObjects* pDoc) const {
  if (m_ObjNum) {
    return new CPDF_Reference(pDoc, m_ObjNum);
  }
  return Clone();
}
CFX_WideString CPDF_Object::GetUnicodeText(CFX_CharMap* pCharMap) const {
  if (m_Type == PDFOBJ_STRING) {
    return PDF_DecodeText(((CPDF_String*)this)->m_String, pCharMap);
  }
  if (m_Type == PDFOBJ_STREAM) {
    CPDF_StreamAcc stream;
    stream.LoadAllData((CPDF_Stream*)this, FALSE);
    CFX_WideString result =
        PDF_DecodeText(stream.GetData(), stream.GetSize(), pCharMap);
    return result;
  }
  if (m_Type == PDFOBJ_NAME) {
    return PDF_DecodeText(((CPDF_Name*)this)->m_Name, pCharMap);
  }
  return CFX_WideString();
}
void CPDF_Object::SetUnicodeText(const FX_WCHAR* pUnicodes, int len) {
  if (m_Type == PDFOBJ_STRING) {
    ((CPDF_String*)this)->m_String = PDF_EncodeText(pUnicodes, len);
  } else if (m_Type == PDFOBJ_STREAM) {
    CFX_ByteString result = PDF_EncodeText(pUnicodes, len);
    ((CPDF_Stream*)this)
        ->SetData((uint8_t*)result.c_str(), result.GetLength(), FALSE, FALSE);
  }
}

CPDF_Number::CPDF_Number(int value)
    : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(TRUE), m_Integer(value) {}

CPDF_Number::CPDF_Number(FX_FLOAT value)
    : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(FALSE), m_Float(value) {}

CPDF_Number::CPDF_Number(FX_BOOL bInteger, void* pData)
    : CPDF_Object(PDFOBJ_NUMBER),
      m_bInteger(bInteger),
      m_Integer(*(int*)pData) {}

CPDF_Number::CPDF_Number(const CFX_ByteStringC& str)
    : CPDF_Object(PDFOBJ_NUMBER) {
  FX_atonum(str, m_bInteger, &m_Integer);
}

void CPDF_Number::SetString(const CFX_ByteStringC& str) {
  FX_atonum(str, m_bInteger, &m_Integer);
}
FX_BOOL CPDF_Number::Identical(CPDF_Number* pOther) const {
  return m_bInteger == pOther->m_bInteger && m_Integer == pOther->m_Integer;
}
CFX_ByteString CPDF_Number::GetString() const {
  return m_bInteger ? CFX_ByteString::FormatInteger(m_Integer, FXFORMAT_SIGNED)
                    : CFX_ByteString::FormatFloat(m_Float);
}
void CPDF_Number::SetNumber(FX_FLOAT value) {
  m_bInteger = FALSE;
  m_Float = value;
}
CPDF_String::CPDF_String(const CFX_WideString& str)
    : CPDF_Object(PDFOBJ_STRING), m_bHex(FALSE) {
  m_String = PDF_EncodeText(str);
}
CPDF_Array::~CPDF_Array() {
  int size = m_Objects.GetSize();
  CPDF_Object** pList = (CPDF_Object**)m_Objects.GetData();
  for (int i = 0; i < size; i++) {
    if (pList[i])
      pList[i]->Release();
  }
}
CFX_FloatRect CPDF_Array::GetRect() {
  CFX_FloatRect rect;
  if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 4) {
    return rect;
  }
  rect.left = GetNumber(0);
  rect.bottom = GetNumber(1);
  rect.right = GetNumber(2);
  rect.top = GetNumber(3);
  return rect;
}
CFX_AffineMatrix CPDF_Array::GetMatrix() {
  CFX_AffineMatrix matrix;
  if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 6) {
    return matrix;
  }
  matrix.Set(GetNumber(0), GetNumber(1), GetNumber(2), GetNumber(3),
             GetNumber(4), GetNumber(5));
  return matrix;
}
CPDF_Object* CPDF_Array::GetElement(FX_DWORD i) const {
  if (i >= (FX_DWORD)m_Objects.GetSize()) {
    return NULL;
  }
  return (CPDF_Object*)m_Objects.GetAt(i);
}
CPDF_Object* CPDF_Array::GetElementValue(FX_DWORD i) const {
  if (i >= (FX_DWORD)m_Objects.GetSize()) {
    return NULL;
  }
  return ((CPDF_Object*)m_Objects.GetAt(i))->GetDirect();
}
CFX_ByteString CPDF_Array::GetString(FX_DWORD i) const {
  if (i < (FX_DWORD)m_Objects.GetSize()) {
    CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
    return p->GetString();
  }
  return CFX_ByteString();
}
CFX_ByteStringC CPDF_Array::GetConstString(FX_DWORD i) const {
  if (i < (FX_DWORD)m_Objects.GetSize()) {
    CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
    return p->GetConstString();
  }
  return CFX_ByteStringC();
}
int CPDF_Array::GetInteger(FX_DWORD i) const {
  if (i >= (FX_DWORD)m_Objects.GetSize()) {
    return 0;
  }
  CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
  return p->GetInteger();
}
FX_FLOAT CPDF_Array::GetNumber(FX_DWORD i) const {
  if (i >= (FX_DWORD)m_Objects.GetSize()) {
    return 0;
  }
  CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
  return p->GetNumber();
}
CPDF_Dictionary* CPDF_Array::GetDict(FX_DWORD i) const {
  CPDF_Object* p = GetElementValue(i);
  if (!p) {
    return NULL;
  }
  if (p->GetType() == PDFOBJ_DICTIONARY) {
    return (CPDF_Dictionary*)p;
  }
  if (p->GetType() == PDFOBJ_STREAM) {
    return ((CPDF_Stream*)p)->GetDict();
  }
  return NULL;
}
CPDF_Stream* CPDF_Array::GetStream(FX_DWORD i) const {
  CPDF_Object* p = GetElementValue(i);
  if (p == NULL || p->GetType() != PDFOBJ_STREAM) {
    return NULL;
  }
  return (CPDF_Stream*)p;
}
CPDF_Array* CPDF_Array::GetArray(FX_DWORD i) const {
  CPDF_Object* p = GetElementValue(i);
  if (p == NULL || p->GetType() != PDFOBJ_ARRAY) {
    return NULL;
  }
  return (CPDF_Array*)p;
}
void CPDF_Array::RemoveAt(FX_DWORD i) {
  ASSERT(m_Type == PDFOBJ_ARRAY);
  if (i >= (FX_DWORD)m_Objects.GetSize()) {
    return;
  }
  CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
  if (p)
    p->Release();
  m_Objects.RemoveAt(i);
}
void CPDF_Array::SetAt(FX_DWORD i,
                       CPDF_Object* pObj,
                       CPDF_IndirectObjects* pObjs) {
  ASSERT(m_Type == PDFOBJ_ARRAY);
  ASSERT(i < (FX_DWORD)m_Objects.GetSize());
  if (i >= (FX_DWORD)m_Objects.GetSize()) {
    return;
  }
  CPDF_Object* pOld = (CPDF_Object*)m_Objects.GetAt(i);
  if (pOld)
    pOld->Release();
  if (pObj->GetObjNum()) {
    ASSERT(pObjs != NULL);
    pObj = new CPDF_Reference(pObjs, pObj->GetObjNum());
  }
  m_Objects.SetAt(i, pObj);
}
void CPDF_Array::InsertAt(FX_DWORD index,
                          CPDF_Object* pObj,
                          CPDF_IndirectObjects* pObjs) {
  ASSERT(pObj != NULL);
  if (pObj->GetObjNum()) {
    ASSERT(pObjs != NULL);
    pObj = new CPDF_Reference(pObjs, pObj->GetObjNum());
  }
  m_Objects.InsertAt(index, pObj);
}
void CPDF_Array::Add(CPDF_Object* pObj, CPDF_IndirectObjects* pObjs) {
  ASSERT(pObj != NULL);
  if (pObj->GetObjNum()) {
    ASSERT(pObjs != NULL);
    pObj = new CPDF_Reference(pObjs, pObj->GetObjNum());
  }
  m_Objects.Add(pObj);
}
void CPDF_Array::AddName(const CFX_ByteString& str) {
  ASSERT(m_Type == PDFOBJ_ARRAY);
  Add(new CPDF_Name(str));
}
void CPDF_Array::AddString(const CFX_ByteString& str) {
  ASSERT(m_Type == PDFOBJ_ARRAY);
  Add(new CPDF_String(str));
}
void CPDF_Array::AddInteger(int i) {
  ASSERT(m_Type == PDFOBJ_ARRAY);
  Add(new CPDF_Number(i));
}
void CPDF_Array::AddNumber(FX_FLOAT f) {
  ASSERT(m_Type == PDFOBJ_ARRAY);
  CPDF_Number* pNumber = new CPDF_Number;
  pNumber->SetNumber(f);
  Add(pNumber);
}
void CPDF_Array::AddReference(CPDF_IndirectObjects* pDoc, FX_DWORD objnum) {
  ASSERT(m_Type == PDFOBJ_ARRAY);
  Add(new CPDF_Reference(pDoc, objnum));
}
FX_BOOL CPDF_Array::Identical(CPDF_Array* pOther) const {
  if (m_Objects.GetSize() != pOther->m_Objects.GetSize()) {
    return FALSE;
  }
  for (int i = 0; i < m_Objects.GetSize(); i++)
    if (!((CPDF_Object*)m_Objects[i])
             ->IsIdentical((CPDF_Object*)pOther->m_Objects[i])) {
      return FALSE;
    }
  return TRUE;
}
CPDF_Dictionary::~CPDF_Dictionary() {
  FX_POSITION pos = m_Map.GetStartPosition();
  while (pos) {
    void* value = m_Map.GetNextValue(pos);
    if (value)
      ((CPDF_Object*)value)->Release();
  }
}
FX_POSITION CPDF_Dictionary::GetStartPos() const {
  return m_Map.GetStartPosition();
}
CPDF_Object* CPDF_Dictionary::GetNextElement(FX_POSITION& pos,
                                             CFX_ByteString& key) const {
  if (pos == NULL) {
    return NULL;
  }
  CPDF_Object* p;
  m_Map.GetNextAssoc(pos, key, (void*&)p);
  return p;
}
CPDF_Object* CPDF_Dictionary::GetElement(const CFX_ByteStringC& key) const {
  CPDF_Object* p = NULL;
  m_Map.Lookup(key, (void*&)p);
  return p;
}
CPDF_Object* CPDF_Dictionary::GetElementValue(
    const CFX_ByteStringC& key) const {
  CPDF_Object* p = NULL;
  m_Map.Lookup(key, (void*&)p);
  return p ? p->GetDirect() : NULL;
}
CFX_ByteString CPDF_Dictionary::GetString(const CFX_ByteStringC& key) const {
  CPDF_Object* p = NULL;
  m_Map.Lookup(key, (void*&)p);
  if (p) {
    return p->GetString();
  }
  return CFX_ByteString();
}
CFX_ByteStringC CPDF_Dictionary::GetConstString(
    const CFX_ByteStringC& key) const {
  CPDF_Object* p = NULL;
  m_Map.Lookup(key, (void*&)p);
  if (p) {
    return p->GetConstString();
  }
  return CFX_ByteStringC();
}
CFX_WideString CPDF_Dictionary::GetUnicodeText(const CFX_ByteStringC& key,
                                               CFX_CharMap* pCharMap) const {
  CPDF_Object* p = NULL;
  m_Map.Lookup(key, (void*&)p);
  if (p) {
    if (p->GetType() == PDFOBJ_REFERENCE) {
      p = ((CPDF_Reference*)p)->GetDirect();
      if (p) {
        return p->GetUnicodeText(pCharMap);
      }
    } else {
      return p->GetUnicodeText(pCharMap);
    }
  }
  return CFX_WideString();
}
CFX_ByteString CPDF_Dictionary::GetString(const CFX_ByteStringC& key,
                                          const CFX_ByteStringC& def) const {
  CPDF_Object* p = NULL;
  m_Map.Lookup(key, (void*&)p);
  if (p) {
    return p->GetString();
  }
  return CFX_ByteString(def);
}
CFX_ByteStringC CPDF_Dictionary::GetConstString(
    const CFX_ByteStringC& key,
    const CFX_ByteStringC& def) const {
  CPDF_Object* p = NULL;
  m_Map.Lookup(key, (void*&)p);
  if (p) {
    return p->GetConstString();
  }
  return CFX_ByteStringC(def);
}
int CPDF_Dictionary::GetInteger(const CFX_ByteStringC& key) const {
  CPDF_Object* p = NULL;
  m_Map.Lookup(key, (void*&)p);
  if (p) {
    return p->GetInteger();
  }
  return 0;
}
int CPDF_Dictionary::GetInteger(const CFX_ByteStringC& key, int def) const {
  CPDF_Object* p = NULL;
  m_Map.Lookup(key, (void*&)p);
  if (p) {
    return p->GetInteger();
  }
  return def;
}
FX_FLOAT CPDF_Dictionary::GetNumber(const CFX_ByteStringC& key) const {
  CPDF_Object* p = NULL;
  m_Map.Lookup(key, (void*&)p);
  if (p) {
    return p->GetNumber();
  }
  return 0;
}
FX_BOOL CPDF_Dictionary::GetBoolean(const CFX_ByteStringC& key,
                                    FX_BOOL bDefault) const {
  CPDF_Object* p = NULL;
  m_Map.Lookup(key, (void*&)p);
  if (p && p->GetType() == PDFOBJ_BOOLEAN) {
    return p->GetInteger();
  }
  return bDefault;
}
CPDF_Dictionary* CPDF_Dictionary::GetDict(const CFX_ByteStringC& key) const {
  CPDF_Object* p = GetElementValue(key);
  if (!p) {
    return nullptr;
  }
  if (p->GetType() == PDFOBJ_DICTIONARY) {
    return (CPDF_Dictionary*)p;
  }
  if (p->GetType() == PDFOBJ_STREAM) {
    return ((CPDF_Stream*)p)->GetDict();
  }
  return nullptr;
}
CPDF_Array* CPDF_Dictionary::GetArray(const CFX_ByteStringC& key) const {
  CPDF_Object* p = GetElementValue(key);
  if (p == NULL || p->GetType() != PDFOBJ_ARRAY) {
    return NULL;
  }
  return (CPDF_Array*)p;
}
CPDF_Stream* CPDF_Dictionary::GetStream(const CFX_ByteStringC& key) const {
  CPDF_Object* p = GetElementValue(key);
  if (p == NULL || p->GetType() != PDFOBJ_STREAM) {
    return NULL;
  }
  return (CPDF_Stream*)p;
}
CFX_FloatRect CPDF_Dictionary::GetRect(const CFX_ByteStringC& key) const {
  CFX_FloatRect rect;
  CPDF_Array* pArray = GetArray(key);
  if (pArray) {
    rect = pArray->GetRect();
  }
  return rect;
}
CFX_AffineMatrix CPDF_Dictionary::GetMatrix(const CFX_ByteStringC& key) const {
  CFX_AffineMatrix matrix;
  CPDF_Array* pArray = GetArray(key);
  if (pArray) {
    matrix = pArray->GetMatrix();
  }
  return matrix;
}
FX_BOOL CPDF_Dictionary::KeyExist(const CFX_ByteStringC& key) const {
  void* value;
  return m_Map.Lookup(key, value);
}
void CPDF_Dictionary::SetAt(const CFX_ByteStringC& key,
                            CPDF_Object* pObj,
                            CPDF_IndirectObjects* pObjs) {
  ASSERT(m_Type == PDFOBJ_DICTIONARY);
  CPDF_Object* p = NULL;
  m_Map.Lookup(key, (void*&)p);
  if (p == pObj) {
    return;
  }
  if (p)
    p->Release();
  if (pObj) {
    if (pObj->GetObjNum()) {
      ASSERT(pObjs != NULL);
      pObj = new CPDF_Reference(pObjs, pObj->GetObjNum());
    }
    m_Map.SetAt(key, pObj);
  } else {
    m_Map.RemoveKey(key);
  }
}
void CPDF_Dictionary::AddValue(const CFX_ByteStringC& key, CPDF_Object* pObj) {
  ASSERT(m_Type == PDFOBJ_DICTIONARY);
  m_Map.AddValue(key, pObj);
}
void CPDF_Dictionary::RemoveAt(const CFX_ByteStringC& key) {
  ASSERT(m_Type == PDFOBJ_DICTIONARY);
  CPDF_Object* p = NULL;
  m_Map.Lookup(key, (void*&)p);
  if (p == NULL) {
    return;
  }
  p->Release();
  m_Map.RemoveKey(key);
}
void CPDF_Dictionary::ReplaceKey(const CFX_ByteStringC& oldkey,
                                 const CFX_ByteStringC& newkey) {
  ASSERT(m_Type == PDFOBJ_DICTIONARY);
  CPDF_Object* p = NULL;
  m_Map.Lookup(oldkey, (void*&)p);
  if (p == NULL) {
    return;
  }
  m_Map.RemoveKey(oldkey);
  m_Map.SetAt(newkey, p);
}
FX_BOOL CPDF_Dictionary::Identical(CPDF_Dictionary* pOther) const {
  if (pOther == NULL) {
    return FALSE;
  }
  if (m_Map.GetCount() != pOther->m_Map.GetCount()) {
    return FALSE;
  }
  FX_POSITION pos = m_Map.GetStartPosition();
  while (pos) {
    CFX_ByteString key;
    void* value;
    m_Map.GetNextAssoc(pos, key, value);
    if (!value)
      return FALSE;
    if (!((CPDF_Object*)value)->IsIdentical(pOther->GetElement(key))) {
      return FALSE;
    }
  }
  return TRUE;
}
void CPDF_Dictionary::SetAtInteger(const CFX_ByteStringC& key, int i) {
  SetAt(key, new CPDF_Number(i));
}
void CPDF_Dictionary::SetAtName(const CFX_ByteStringC& key,
                                const CFX_ByteString& name) {
  SetAt(key, new CPDF_Name(name));
}
void CPDF_Dictionary::SetAtString(const CFX_ByteStringC& key,
                                  const CFX_ByteString& str) {
  SetAt(key, new CPDF_String(str));
}
void CPDF_Dictionary::SetAtReference(const CFX_ByteStringC& key,
                                     CPDF_IndirectObjects* pDoc,
                                     FX_DWORD objnum) {
  SetAt(key, new CPDF_Reference(pDoc, objnum));
}
void CPDF_Dictionary::AddReference(const CFX_ByteStringC& key,
                                   CPDF_IndirectObjects* pDoc,
                                   FX_DWORD objnum) {
  AddValue(key, new CPDF_Reference(pDoc, objnum));
}
void CPDF_Dictionary::SetAtNumber(const CFX_ByteStringC& key, FX_FLOAT f) {
  CPDF_Number* pNumber = new CPDF_Number;
  pNumber->SetNumber(f);
  SetAt(key, pNumber);
}
void CPDF_Dictionary::SetAtBoolean(const CFX_ByteStringC& key, FX_BOOL bValue) {
  SetAt(key, new CPDF_Boolean(bValue));
}
void CPDF_Dictionary::SetAtRect(const CFX_ByteStringC& key,
                                const CFX_FloatRect& rect) {
  CPDF_Array* pArray = new CPDF_Array;
  pArray->AddNumber(rect.left);
  pArray->AddNumber(rect.bottom);
  pArray->AddNumber(rect.right);
  pArray->AddNumber(rect.top);
  SetAt(key, pArray);
}
void CPDF_Dictionary::SetAtMatrix(const CFX_ByteStringC& key,
                                  const CFX_AffineMatrix& matrix) {
  CPDF_Array* pArray = new CPDF_Array;
  pArray->AddNumber16(matrix.a);
  pArray->AddNumber16(matrix.b);
  pArray->AddNumber16(matrix.c);
  pArray->AddNumber16(matrix.d);
  pArray->AddNumber(matrix.e);
  pArray->AddNumber(matrix.f);
  SetAt(key, pArray);
}
CPDF_Stream::CPDF_Stream(uint8_t* pData, FX_DWORD size, CPDF_Dictionary* pDict)
    : CPDF_Object(PDFOBJ_STREAM) {
  m_pDict = pDict;
  m_dwSize = size;
  m_GenNum = (FX_DWORD)-1;
  m_pDataBuf = pData;
  m_pCryptoHandler = NULL;
}
CPDF_Stream::~CPDF_Stream() {
  if (m_GenNum == (FX_DWORD)-1) {
    FX_Free(m_pDataBuf);
  }
  if (m_pDict) {
    m_pDict->Release();
  }
}
void CPDF_Stream::InitStream(CPDF_Dictionary* pDict) {
  if (pDict) {
    if (m_pDict) {
      m_pDict->Release();
    }
    m_pDict = pDict;
  }
  if (m_GenNum == (FX_DWORD)-1) {
    FX_Free(m_pDataBuf);
  }
  m_GenNum = 0;
  m_pFile = NULL;
  m_pCryptoHandler = NULL;
  m_FileOffset = 0;
}
void CPDF_Stream::InitStream(uint8_t* pData,
                             FX_DWORD size,
                             CPDF_Dictionary* pDict) {
  InitStream(pDict);
  m_GenNum = (FX_DWORD)-1;
  m_pDataBuf = FX_Alloc(uint8_t, size);
  if (pData) {
    FXSYS_memcpy(m_pDataBuf, pData, size);
  }
  m_dwSize = size;
  if (m_pDict) {
    m_pDict->SetAtInteger(FX_BSTRC("Length"), size);
  }
}
void CPDF_Stream::SetData(const uint8_t* pData,
                          FX_DWORD size,
                          FX_BOOL bCompressed,
                          FX_BOOL bKeepBuf) {
  if (m_GenNum == (FX_DWORD)-1) {
    FX_Free(m_pDataBuf);
  } else {
    m_GenNum = (FX_DWORD)-1;
    m_pCryptoHandler = NULL;
  }
  if (bKeepBuf) {
    m_pDataBuf = (uint8_t*)pData;
  } else {
    m_pDataBuf = FX_Alloc(uint8_t, size);
    if (pData) {
      FXSYS_memcpy(m_pDataBuf, pData, size);
    }
  }
  m_dwSize = size;
  if (m_pDict == NULL) {
    m_pDict = new CPDF_Dictionary;
  }
  m_pDict->SetAtInteger(FX_BSTRC("Length"), size);
  if (!bCompressed) {
    m_pDict->RemoveAt(FX_BSTRC("Filter"));
    m_pDict->RemoveAt(FX_BSTRC("DecodeParms"));
  }
}
FX_BOOL CPDF_Stream::ReadRawData(FX_FILESIZE offset,
                                 uint8_t* buf,
                                 FX_DWORD size) const {
  if ((m_GenNum != (FX_DWORD)-1) && m_pFile) {
    return m_pFile->ReadBlock(buf, m_FileOffset + offset, size);
  }
  if (m_pDataBuf) {
    FXSYS_memcpy(buf, m_pDataBuf + offset, size);
  }
  return TRUE;
}
void CPDF_Stream::InitStream(IFX_FileRead* pFile, CPDF_Dictionary* pDict) {
  InitStream(pDict);
  m_pFile = pFile;
  m_dwSize = (FX_DWORD)pFile->GetSize();
  if (m_pDict) {
    m_pDict->SetAtInteger(FX_BSTRC("Length"), m_dwSize);
  }
}

FX_BOOL CPDF_Stream::Identical(CPDF_Stream* pOther) const {
  if (!m_pDict)
    return pOther->m_pDict ? FALSE : TRUE;

  if (!m_pDict->Identical(pOther->m_pDict)) {
    return FALSE;
  }
  if (m_dwSize != pOther->m_dwSize) {
    return FALSE;
  }
  if (m_GenNum != (FX_DWORD)-1 && pOther->m_GenNum != (FX_DWORD)-1) {
    if (m_pFile == pOther->m_pFile && m_pFile == NULL) {
      return TRUE;
    }
    if (!m_pFile || !pOther->m_pFile) {
      return FALSE;
    }
    uint8_t srcBuf[1024];
    uint8_t destBuf[1024];
    FX_DWORD size = m_dwSize;
    FX_DWORD srcOffset = m_FileOffset;
    FX_DWORD destOffset = pOther->m_FileOffset;
    if (m_pFile == pOther->m_pFile && srcOffset == destOffset) {
      return TRUE;
    }
    while (size > 0) {
      FX_DWORD actualSize = size > 1024 ? 1024 : size;
      m_pFile->ReadBlock(srcBuf, srcOffset, actualSize);
      pOther->m_pFile->ReadBlock(destBuf, destOffset, actualSize);
      if (FXSYS_memcmp(srcBuf, destBuf, actualSize) != 0) {
        return FALSE;
      }
      size -= actualSize;
      srcOffset += actualSize;
      destOffset += actualSize;
    }
    return TRUE;
  }
  if (m_GenNum != (FX_DWORD)-1 || pOther->m_GenNum != (FX_DWORD)-1) {
    IFX_FileRead* pFile = NULL;
    uint8_t* pBuf = NULL;
    FX_DWORD offset = 0;
    if (pOther->m_GenNum != (FX_DWORD)-1) {
      pFile = pOther->m_pFile;
      pBuf = m_pDataBuf;
      offset = pOther->m_FileOffset;
    } else if (m_GenNum != (FX_DWORD)-1) {
      pFile = m_pFile;
      pBuf = pOther->m_pDataBuf;
      offset = m_FileOffset;
    }
    if (NULL == pBuf) {
      return FALSE;
    }
    uint8_t srcBuf[1024];
    FX_DWORD size = m_dwSize;
    while (size > 0) {
      FX_DWORD actualSize = std::min(size, 1024U);
      pFile->ReadBlock(srcBuf, offset, actualSize);
      if (FXSYS_memcmp(srcBuf, pBuf, actualSize) != 0) {
        return FALSE;
      }
      pBuf += actualSize;
      size -= actualSize;
      offset += actualSize;
    }
    return TRUE;
  }
  return FXSYS_memcmp(m_pDataBuf, pOther->m_pDataBuf, m_dwSize) == 0;
}

extern FX_BOOL PDF_DataDecode(const uint8_t* src_buf,
                              FX_DWORD src_size,
                              const CPDF_Dictionary* pDict,
                              uint8_t*& dest_buf,
                              FX_DWORD& dest_size,
                              CFX_ByteString& ImageEncoding,
                              CPDF_Dictionary*& pImageParms,
                              FX_DWORD estimated_size,
                              FX_BOOL bImageAcc);
CPDF_StreamAcc::CPDF_StreamAcc() {
  m_bNewBuf = FALSE;
  m_pData = NULL;
  m_dwSize = 0;
  m_pImageParam = NULL;
  m_pStream = NULL;
  m_pSrcData = NULL;
}
void CPDF_StreamAcc::LoadAllData(const CPDF_Stream* pStream,
                                 FX_BOOL bRawAccess,
                                 FX_DWORD estimated_size,
                                 FX_BOOL bImageAcc) {
  if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {
    return;
  }
  m_pStream = pStream;
  if (pStream->IsMemoryBased() &&
      (!pStream->GetDict()->KeyExist(FX_BSTRC("Filter")) || bRawAccess)) {
    m_dwSize = pStream->m_dwSize;
    m_pData = (uint8_t*)pStream->m_pDataBuf;
    return;
  }
  uint8_t* pSrcData;
  FX_DWORD dwSrcSize = pStream->m_dwSize;
  if (dwSrcSize == 0) {
    return;
  }
  if (!pStream->IsMemoryBased()) {
    pSrcData = m_pSrcData = FX_Alloc(uint8_t, dwSrcSize);
    if (!pStream->ReadRawData(0, pSrcData, dwSrcSize)) {
      return;
    }
  } else {
    pSrcData = pStream->m_pDataBuf;
  }
  uint8_t* pDecryptedData;
  FX_DWORD dwDecryptedSize;
  if (pStream->m_pCryptoHandler) {
    CFX_BinaryBuf dest_buf;
    dest_buf.EstimateSize(pStream->m_pCryptoHandler->DecryptGetSize(dwSrcSize));
    void* context = pStream->m_pCryptoHandler->DecryptStart(
        pStream->GetObjNum(), pStream->m_GenNum);
    pStream->m_pCryptoHandler->DecryptStream(context, pSrcData, dwSrcSize,
                                             dest_buf);
    pStream->m_pCryptoHandler->DecryptFinish(context, dest_buf);
    pDecryptedData = dest_buf.GetBuffer();
    dwDecryptedSize = dest_buf.GetSize();
    dest_buf.DetachBuffer();
  } else {
    pDecryptedData = pSrcData;
    dwDecryptedSize = dwSrcSize;
  }
  if (!pStream->GetDict()->KeyExist(FX_BSTRC("Filter")) || bRawAccess) {
    m_pData = pDecryptedData;
    m_dwSize = dwDecryptedSize;
  } else {
    FX_BOOL bRet = PDF_DataDecode(
        pDecryptedData, dwDecryptedSize, m_pStream->GetDict(), m_pData,
        m_dwSize, m_ImageDecoder, m_pImageParam, estimated_size, bImageAcc);
    if (!bRet) {
      m_pData = pDecryptedData;
      m_dwSize = dwDecryptedSize;
    }
  }
  if (pSrcData != pStream->m_pDataBuf && pSrcData != m_pData) {
    FX_Free(pSrcData);
  }
  if (pDecryptedData != pSrcData && pDecryptedData != m_pData) {
    FX_Free(pDecryptedData);
  }
  m_pSrcData = NULL;
  m_bNewBuf = m_pData != pStream->m_pDataBuf;
}
CPDF_StreamAcc::~CPDF_StreamAcc() {
  if (m_bNewBuf) {
    FX_Free(m_pData);
  }
  FX_Free(m_pSrcData);
}
const uint8_t* CPDF_StreamAcc::GetData() const {
  if (m_bNewBuf) {
    return m_pData;
  }
  if (!m_pStream) {
    return NULL;
  }
  return m_pStream->m_pDataBuf;
}
FX_DWORD CPDF_StreamAcc::GetSize() const {
  if (m_bNewBuf) {
    return m_dwSize;
  }
  if (!m_pStream) {
    return 0;
  }
  return m_pStream->m_dwSize;
}
uint8_t* CPDF_StreamAcc::DetachData() {
  if (m_bNewBuf) {
    uint8_t* p = m_pData;
    m_pData = NULL;
    m_dwSize = 0;
    return p;
  }
  uint8_t* p = FX_Alloc(uint8_t, m_dwSize);
  FXSYS_memcpy(p, m_pData, m_dwSize);
  return p;
}
void CPDF_Reference::SetRef(CPDF_IndirectObjects* pDoc, FX_DWORD objnum) {
  m_pObjList = pDoc;
  m_RefObjNum = objnum;
}
CPDF_IndirectObjects::CPDF_IndirectObjects(CPDF_Parser* pParser) {
  m_pParser = pParser;
  m_IndirectObjs.InitHashTable(1013);
  if (pParser) {
    m_LastObjNum = m_pParser->GetLastObjNum();
  } else {
    m_LastObjNum = 0;
  }
}
CPDF_IndirectObjects::~CPDF_IndirectObjects() {
  FX_POSITION pos = m_IndirectObjs.GetStartPosition();
  while (pos) {
    void* key;
    void* value;
    m_IndirectObjs.GetNextAssoc(pos, key, value);
    ((CPDF_Object*)value)->Destroy();
  }
}
CPDF_Object* CPDF_IndirectObjects::GetIndirectObject(
    FX_DWORD objnum,
    struct PARSE_CONTEXT* pContext) {
  if (objnum == 0) {
    return NULL;
  }
  void* value;
  {
    if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) {
      if (((CPDF_Object*)value)->GetObjNum() == -1) {
        return NULL;
      }
      return (CPDF_Object*)value;
    }
  }
  CPDF_Object* pObj = NULL;
  if (m_pParser) {
    pObj = m_pParser->ParseIndirectObject(this, objnum, pContext);
  }
  if (pObj == NULL) {
    return NULL;
  }
  pObj->m_ObjNum = objnum;
  if (m_LastObjNum < objnum) {
    m_LastObjNum = objnum;
  }
  if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) {
    if (value) {
      ((CPDF_Object*)value)->Destroy();
    }
  }
  m_IndirectObjs.SetAt((void*)(uintptr_t)objnum, pObj);
  return pObj;
}
int CPDF_IndirectObjects::GetIndirectType(FX_DWORD objnum) {
  void* value;
  if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) {
    return ((CPDF_Object*)value)->GetType();
  }
  if (m_pParser) {
    PARSE_CONTEXT context;
    FXSYS_memset(&context, 0, sizeof(PARSE_CONTEXT));
    context.m_Flags = PDFPARSE_TYPEONLY;
    return (int)(uintptr_t)m_pParser->ParseIndirectObject(this, objnum,
                                                          &context);
  }
  return 0;
}
FX_DWORD CPDF_IndirectObjects::AddIndirectObject(CPDF_Object* pObj) {
  if (pObj->m_ObjNum) {
    return pObj->m_ObjNum;
  }
  m_LastObjNum++;
  m_IndirectObjs.SetAt((void*)(uintptr_t)m_LastObjNum, pObj);
  pObj->m_ObjNum = m_LastObjNum;
  return m_LastObjNum;
}
void CPDF_IndirectObjects::ReleaseIndirectObject(FX_DWORD objnum) {
  void* value;
  if (!m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) {
    return;
  }
  if (((CPDF_Object*)value)->GetObjNum() == -1) {
    return;
  }
  ((CPDF_Object*)value)->Destroy();
  m_IndirectObjs.RemoveKey((void*)(uintptr_t)objnum);
}
void CPDF_IndirectObjects::InsertIndirectObject(FX_DWORD objnum,
                                                CPDF_Object* pObj) {
  if (objnum == 0 || pObj == NULL) {
    return;
  }
  void* value = NULL;
  if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) {
    if (value) {
      if (pObj->GetGenNum() <= ((CPDF_Object*)value)->GetGenNum()) {
        return;
      }
      ((CPDF_Object*)value)->Destroy();
    }
  }
  pObj->m_ObjNum = objnum;
  m_IndirectObjs.SetAt((void*)(uintptr_t)objnum, pObj);
  if (m_LastObjNum < objnum) {
    m_LastObjNum = objnum;
  }
}
FX_DWORD CPDF_IndirectObjects::GetLastObjNum() const {
  return m_LastObjNum;
}
