// 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

#ifndef CORE_INCLUDE_FPDFAPI_FPDF_PARSER_H_
#define CORE_INCLUDE_FPDFAPI_FPDF_PARSER_H_

#include <map>
#include <memory>
#include <set>

#include "core/include/fpdfapi/fpdf_objects.h"
#include "core/include/fxcrt/fx_system.h"

class CFX_Font;
class CFX_Matrix;
class CPDF_ColorSpace;
class CPDF_CryptoHandler;
class CPDF_DocPageData;
class CPDF_DocRenderData;
class CPDF_Font;
class CPDF_FontEncoding;
class CPDF_IccProfile;
class CPDF_Image;
class CPDF_Object;
class CPDF_Parser;
class CPDF_Pattern;
class CPDF_SecurityHandler;
class CPDF_StandardSecurityHandler;
class IFX_FileRead;

#define FPDFPERM_PRINT 0x0004
#define FPDFPERM_MODIFY 0x0008
#define FPDFPERM_EXTRACT 0x0010
#define FPDFPERM_ANNOT_FORM 0x0020
#define FPDFPERM_FILL_FORM 0x0100
#define FPDFPERM_EXTRACT_ACCESS 0x0200
#define FPDFPERM_ASSEMBLE 0x0400
#define FPDFPERM_PRINT_HIGH 0x0800
#define FPDF_PAGE_MAX_NUM 0xFFFFF

// Use the accessors below instead of directly accessing PDF_CharType.
extern const char PDF_CharType[256];

inline bool PDFCharIsWhitespace(uint8_t c) {
  return PDF_CharType[c] == 'W';
}
inline bool PDFCharIsNumeric(uint8_t c) {
  return PDF_CharType[c] == 'N';
}
inline bool PDFCharIsDelimiter(uint8_t c) {
  return PDF_CharType[c] == 'D';
}
inline bool PDFCharIsOther(uint8_t c) {
  return PDF_CharType[c] == 'R';
}

inline bool PDFCharIsLineEnding(uint8_t c) {
  return c == '\r' || c == '\n';
}

// Indexed by 8-bit char code, contains unicode code points.
extern const FX_WORD PDFDocEncoding[256];

class CPDF_Document : public CFX_PrivateData, public CPDF_IndirectObjects {
 public:
  CPDF_Document();
  explicit CPDF_Document(CPDF_Parser* pParser);

  ~CPDF_Document();

  CPDF_Parser* GetParser() const { return m_pParser; }

  CPDF_Dictionary* GetRoot() const { return m_pRootDict; }

  CPDF_Dictionary* GetInfo() const { return m_pInfoDict; }

  void GetID(CFX_ByteString& id1, CFX_ByteString& id2) const {
    id1 = m_ID1;
    id2 = m_ID2;
  }

  int GetPageCount() const;

  CPDF_Dictionary* GetPage(int iPage);

  int GetPageIndex(FX_DWORD objnum);

  FX_DWORD GetUserPermissions(FX_BOOL bCheckRevision = FALSE) const;

  FX_BOOL IsOwner() const;

  CPDF_DocPageData* GetPageData() { return GetValidatePageData(); }

  void ClearPageData();

  void RemoveColorSpaceFromPageData(CPDF_Object* pObject);

  CPDF_DocRenderData* GetRenderData() { return GetValidateRenderData(); }

  void ClearRenderData();

  void ClearRenderFont();

  FX_BOOL IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) const;

  // |pFontDict| must not be null.
  CPDF_Font* LoadFont(CPDF_Dictionary* pFontDict);

  CPDF_ColorSpace* LoadColorSpace(CPDF_Object* pCSObj,
                                  CPDF_Dictionary* pResources = NULL);

  CPDF_Pattern* LoadPattern(CPDF_Object* pObj,
                            FX_BOOL bShading,
                            const CFX_Matrix* matrix = NULL);

  CPDF_Image* LoadImageF(CPDF_Object* pObj);

  CPDF_StreamAcc* LoadFontFile(CPDF_Stream* pStream);

  CPDF_IccProfile* LoadIccProfile(CPDF_Stream* pStream);

#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_

  CPDF_Font* AddWindowsFont(LOGFONTA* pLogFont,
                            FX_BOOL bVert,
                            FX_BOOL bTranslateName = FALSE);
  CPDF_Font* AddWindowsFont(LOGFONTW* pLogFont,
                            FX_BOOL bVert,
                            FX_BOOL bTranslateName = FALSE);
#endif
#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
  CPDF_Font* AddMacFont(CTFontRef pFont,
                        FX_BOOL bVert,
                        FX_BOOL bTranslateName = FALSE);
#endif

  CPDF_Font* AddStandardFont(const FX_CHAR* font, CPDF_FontEncoding* pEncoding);

  CPDF_Font* AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert);

  void CreateNewDoc();

  CPDF_Dictionary* CreateNewPage(int iPage);

  void DeletePage(int iPage);

  void LoadDoc();
  void LoadAsynDoc(CPDF_Dictionary* pLinearized);
  void LoadPages();

 protected:
  CPDF_Dictionary* m_pRootDict;

  CPDF_Dictionary* m_pInfoDict;

  CFX_ByteString m_ID1;

  CFX_ByteString m_ID2;

  FX_BOOL m_bLinearized;

  FX_DWORD m_dwFirstPageNo;

  FX_DWORD m_dwFirstPageObjNum;

  CFX_DWordArray m_PageList;

  int _GetPageCount() const;
  CPDF_Dictionary* _FindPDFPage(CPDF_Dictionary* pPages,
                                int iPage,
                                int nPagesToGo,
                                int level);
  int _FindPageIndex(CPDF_Dictionary* pNode,
                     FX_DWORD& skip_count,
                     FX_DWORD objnum,
                     int& index,
                     int level = 0);
  FX_BOOL IsContentUsedElsewhere(FX_DWORD objnum, CPDF_Dictionary* pPageDict);
  FX_BOOL CheckOCGVisible(CPDF_Dictionary* pOCG, FX_BOOL bPrinting);
  CPDF_DocPageData* GetValidatePageData();
  CPDF_DocRenderData* GetValidateRenderData();
  friend class CPDF_Creator;
  friend class CPDF_Parser;
  friend class CPDF_DataAvail;
  friend class CPDF_OCContext;

  CPDF_DocPageData* m_pDocPage;

  CPDF_DocRenderData* m_pDocRender;
};

#define PDFWORD_EOF 0
#define PDFWORD_NUMBER 1
#define PDFWORD_TEXT 2
#define PDFWORD_DELIMITER 3
#define PDFWORD_NAME 4
class CPDF_SimpleParser {
 public:
  CPDF_SimpleParser(const uint8_t* pData, FX_DWORD dwSize);

  CPDF_SimpleParser(const CFX_ByteStringC& str);

  CFX_ByteStringC GetWord();

  FX_BOOL SearchToken(const CFX_ByteStringC& token);

  FX_BOOL SkipWord(const CFX_ByteStringC& token);

  FX_BOOL FindTagPair(const CFX_ByteStringC& start_token,
                      const CFX_ByteStringC& end_token,
                      FX_DWORD& start_pos,
                      FX_DWORD& end_pos);

  FX_BOOL FindTagParam(const CFX_ByteStringC& token, int nParams);

  FX_DWORD GetPos() { return m_dwCurPos; }

  void SetPos(FX_DWORD pos) {
    ASSERT(pos <= m_dwSize);
    m_dwCurPos = pos;
  }

 private:
  void ParseWord(const uint8_t*& pStart, FX_DWORD& dwSize, int& type);

  const uint8_t* m_pData;

  FX_DWORD m_dwSize;

  FX_DWORD m_dwCurPos;
};
class CPDF_SyntaxParser {
 public:
  CPDF_SyntaxParser();
  virtual ~CPDF_SyntaxParser();

  void InitParser(IFX_FileRead* pFileAccess, FX_DWORD HeaderOffset);

  FX_FILESIZE SavePos() { return m_Pos; }

  void RestorePos(FX_FILESIZE pos) { m_Pos = pos; }

  CPDF_Object* GetObject(CPDF_IndirectObjects* pObjList,
                         FX_DWORD objnum,
                         FX_DWORD gennum,
                         PARSE_CONTEXT* pContext,
                         FX_BOOL bDecrypt);

  CPDF_Object* GetObjectByStrict(CPDF_IndirectObjects* pObjList,
                                 FX_DWORD objnum,
                                 FX_DWORD gennum,
                                 PARSE_CONTEXT* pContext);

  int GetDirectNum();

  CFX_ByteString GetString(FX_DWORD objnum, FX_DWORD gennum);

  CFX_ByteString GetName();

  CFX_ByteString GetKeyword();

  void GetBinary(uint8_t* buffer, FX_DWORD size);

  void ToNextLine();

  void ToNextWord();

  FX_BOOL SearchWord(const CFX_ByteStringC& word,
                     FX_BOOL bWholeWord,
                     FX_BOOL bForward,
                     FX_FILESIZE limit);

  int SearchMultiWord(const CFX_ByteStringC& words,
                      FX_BOOL bWholeWord,
                      FX_FILESIZE limit);

  FX_FILESIZE FindTag(const CFX_ByteStringC& tag, FX_FILESIZE limit);

  void SetEncrypt(CPDF_CryptoHandler* pCryptoHandler) {
    m_pCryptoHandler.reset(pCryptoHandler);
  }

  FX_BOOL IsEncrypted() { return m_pCryptoHandler != NULL; }

  FX_BOOL GetCharAt(FX_FILESIZE pos, uint8_t& ch);

  FX_BOOL ReadBlock(uint8_t* pBuf, FX_DWORD size);

  CFX_ByteString GetNextWord(bool* bIsNumber);

 protected:
  friend class CPDF_Parser;
  friend class CPDF_DataAvail;
  friend class fpdf_parser_parser_ReadHexString_Test;

  static const int kParserMaxRecursionDepth = 64;
  static int s_CurrentRecursionDepth;

  virtual FX_BOOL GetNextChar(uint8_t& ch);

  FX_BOOL GetCharAtBackward(FX_FILESIZE pos, uint8_t& ch);

  void GetNextWordInternal(bool* bIsNumber);

  bool IsWholeWord(FX_FILESIZE startpos,
                   FX_FILESIZE limit,
                   const CFX_ByteStringC& tag,
                   FX_BOOL checkKeyword);

  CFX_ByteString ReadString();

  CFX_ByteString ReadHexString();

  unsigned int ReadEOLMarkers(FX_FILESIZE pos);

  CPDF_Stream* ReadStream(CPDF_Dictionary* pDict,
                          PARSE_CONTEXT* pContext,
                          FX_DWORD objnum,
                          FX_DWORD gennum);

  FX_FILESIZE m_Pos;

  FX_BOOL m_bFileStream;

  int m_MetadataObjnum;

  IFX_FileRead* m_pFileAccess;

  FX_DWORD m_HeaderOffset;

  FX_FILESIZE m_FileLen;

  uint8_t* m_pFileBuf;

  FX_DWORD m_BufSize;

  FX_FILESIZE m_BufOffset;

  std::unique_ptr<CPDF_CryptoHandler> m_pCryptoHandler;

  uint8_t m_WordBuffer[257];

  FX_DWORD m_WordSize;

  FX_FILESIZE m_dwWordPos;
};

#define PDFPARSE_TYPEONLY 1
#define PDFPARSE_NOSTREAM 2
struct PARSE_CONTEXT {
  uint32_t m_Flags;
  FX_FILESIZE m_DictStart;
  FX_FILESIZE m_DictEnd;
  FX_FILESIZE m_DataStart;
  FX_FILESIZE m_DataEnd;
};

#define PDFPARSE_ERROR_SUCCESS 0
#define PDFPARSE_ERROR_FILE 1
#define PDFPARSE_ERROR_FORMAT 2
#define PDFPARSE_ERROR_PASSWORD 3
#define PDFPARSE_ERROR_HANDLER 4
#define PDFPARSE_ERROR_CERT 5

class CPDF_Parser {
 public:
  CPDF_Parser();
  ~CPDF_Parser();

  FX_DWORD StartParse(IFX_FileRead* pFile,
                      FX_BOOL bReParse = FALSE,
                      FX_BOOL bOwnFileRead = TRUE);

  void CloseParser(FX_BOOL bReParse = FALSE);

  FX_DWORD GetPermissions(FX_BOOL bCheckRevision = FALSE);

  FX_BOOL IsOwner();

  void SetPassword(const FX_CHAR* password) { m_Password = password; }

  CFX_ByteString GetPassword() { return m_Password; }

  CPDF_CryptoHandler* GetCryptoHandler() {
    return m_Syntax.m_pCryptoHandler.get();
  }

  void SetSecurityHandler(CPDF_SecurityHandler* pSecurityHandler,
                          FX_BOOL bForced = FALSE);

  CPDF_Dictionary* GetTrailer() { return m_pTrailer; }

  FX_FILESIZE GetLastXRefOffset() { return m_LastXRefOffset; }

  CPDF_Document* GetDocument() { return m_pDocument; }

  FX_DWORD GetRootObjNum();
  FX_DWORD GetInfoObjNum();
  CPDF_Array* GetIDArray();

  CPDF_Dictionary* GetEncryptDict() { return m_pEncryptDict; }

  CPDF_Object* ParseIndirectObject(CPDF_IndirectObjects* pObjList,
                                   FX_DWORD objnum,
                                   PARSE_CONTEXT* pContext = NULL);
  FX_DWORD GetLastObjNum() const;
  bool IsValidObjectNumber(FX_DWORD objnum) const;
  FX_BOOL IsFormStream(FX_DWORD objnum, FX_BOOL& bForm);

  FX_FILESIZE GetObjectOffset(FX_DWORD objnum) const;

  FX_FILESIZE GetObjectSize(FX_DWORD objnum) const;

  void GetIndirectBinary(FX_DWORD objnum, uint8_t*& pBuffer, FX_DWORD& size);

  IFX_FileRead* GetFileAccess() const { return m_Syntax.m_pFileAccess; }

  int GetFileVersion() const { return m_FileVersion; }

  FX_BOOL IsXRefStream() const { return m_bXRefStream; }
  CPDF_Object* ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList,
                                     FX_FILESIZE pos,
                                     FX_DWORD objnum,
                                     PARSE_CONTEXT* pContext);

  CPDF_Object* ParseIndirectObjectAtByStrict(CPDF_IndirectObjects* pObjList,
                                             FX_FILESIZE pos,
                                             FX_DWORD objnum,
                                             PARSE_CONTEXT* pContext,
                                             FX_FILESIZE* pResultPos);

  FX_DWORD StartAsynParse(IFX_FileRead* pFile,
                          FX_BOOL bReParse = FALSE,
                          FX_BOOL bOwnFileRead = TRUE);

  FX_DWORD GetFirstPageNo() { return m_dwFirstPageNo; }

 protected:
  CPDF_Object* ParseDirect(CPDF_Object* pObj);

  FX_BOOL LoadAllCrossRefV4(FX_FILESIZE pos);

  FX_BOOL LoadAllCrossRefV5(FX_FILESIZE pos);

  bool LoadCrossRefV4(FX_FILESIZE pos, FX_FILESIZE streampos, FX_BOOL bSkip);

  FX_BOOL LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef);

  CPDF_Dictionary* LoadTrailerV4();

  FX_BOOL RebuildCrossRef();

  FX_DWORD SetEncryptHandler();

  void ReleaseEncryptHandler();

  FX_BOOL LoadLinearizedAllCrossRefV4(FX_FILESIZE pos, FX_DWORD dwObjCount);

  FX_BOOL LoadLinearizedCrossRefV4(FX_FILESIZE pos, FX_DWORD dwObjCount);

  FX_BOOL LoadLinearizedAllCrossRefV5(FX_FILESIZE pos);

  FX_DWORD LoadLinearizedMainXRefTable();

  CPDF_StreamAcc* GetObjectStream(FX_DWORD number);

  FX_BOOL IsLinearizedFile(IFX_FileRead* pFileAccess, FX_DWORD offset);

  bool FindPosInOffsets(FX_FILESIZE pos) const;

  void SetEncryptDictionary(CPDF_Dictionary* pDict);

  FX_FILESIZE GetObjectPositionOrZero(FX_DWORD objnum) const;

  CPDF_Document* m_pDocument;

  CPDF_SyntaxParser m_Syntax;
  FX_BOOL m_bOwnFileRead;
  int m_FileVersion;

  CPDF_Dictionary* m_pTrailer;

  CPDF_Dictionary* m_pEncryptDict;

  FX_FILESIZE m_LastXRefOffset;

  FX_BOOL m_bXRefStream;

  std::unique_ptr<CPDF_SecurityHandler> m_pSecurityHandler;

  FX_BOOL m_bForceUseSecurityHandler;

  CFX_ByteString m_bsRecipient;

  CFX_ByteString m_FilePath;

  CFX_ByteString m_Password;

  struct ObjectInfo {
    ObjectInfo() : pos(0) {}

    FX_FILESIZE pos;
// TODO(thestig): Use fields below in place of |m_V5Type| and |m_ObjVersion|
#if 0
    uint8_t type;
    uint16_t gennum;
#endif
  };
  std::map<FX_DWORD, ObjectInfo> m_ObjectInfo;

  CFX_ByteArray m_V5Type;
  CFX_WordArray m_ObjVersion;

  CFX_FileSizeArray m_SortedOffset;

  CFX_ArrayTemplate<CPDF_Dictionary*> m_Trailers;

  FX_BOOL m_bVersionUpdated;

  CPDF_Object* m_pLinearized;

  FX_DWORD m_dwFirstPageNo;

  FX_DWORD m_dwXrefStartObjNum;

  // A map of object numbers to indirect streams. Map owns the streams.
  CFX_MapPtrToPtr m_ObjectStreamMap;

  // Mapping of object numbers to offsets. The offsets are relative to the first
  // object in the stream.
  using StreamObjectCache = std::map<FX_DWORD, FX_DWORD>;

  // Mapping of streams to their object caches. This is valid as long as the
  // streams in |m_ObjectStreamMap| are valid.
  std::map<CPDF_StreamAcc*, StreamObjectCache> m_ObjCache;

  // All indirect object numbers that are being parsed.
  std::set<FX_DWORD> m_ParsingObjNums;

  friend class CPDF_Creator;
  friend class CPDF_DataAvail;
};

#define FXCIPHER_NONE 0
#define FXCIPHER_RC4 1
#define FXCIPHER_AES 2
#define FXCIPHER_AES2 3
class CPDF_SecurityHandler {
 public:
  virtual ~CPDF_SecurityHandler() {}

  virtual FX_BOOL OnInit(CPDF_Parser* pParser,
                         CPDF_Dictionary* pEncryptDict) = 0;

  virtual FX_DWORD GetPermissions() = 0;

  virtual FX_BOOL IsOwner() = 0;

  virtual FX_BOOL GetCryptInfo(int& cipher,
                               const uint8_t*& buffer,
                               int& keylen) = 0;

  virtual FX_BOOL IsMetadataEncrypted() { return TRUE; }

  virtual CPDF_CryptoHandler* CreateCryptoHandler() = 0;

  virtual CPDF_StandardSecurityHandler* GetStandardHandler() { return NULL; }
};
#define PDF_ENCRYPT_CONTENT 0
class CPDF_StandardSecurityHandler : public CPDF_SecurityHandler {
 public:
  CPDF_StandardSecurityHandler();
  ~CPDF_StandardSecurityHandler() override;

  // CPDF_SecurityHandler
  FX_BOOL OnInit(CPDF_Parser* pParser, CPDF_Dictionary* pEncryptDict) override;
  FX_DWORD GetPermissions() override;
  FX_BOOL IsOwner() override { return m_bOwner; }
  FX_BOOL GetCryptInfo(int& cipher,
                       const uint8_t*& buffer,
                       int& keylen) override;
  FX_BOOL IsMetadataEncrypted() override;
  CPDF_CryptoHandler* CreateCryptoHandler() override;
  CPDF_StandardSecurityHandler* GetStandardHandler() override { return this; }

  void OnCreate(CPDF_Dictionary* pEncryptDict,
                CPDF_Array* pIdArray,
                const uint8_t* user_pass,
                FX_DWORD user_size,
                const uint8_t* owner_pass,
                FX_DWORD owner_size,
                FX_DWORD type = PDF_ENCRYPT_CONTENT);

  void OnCreate(CPDF_Dictionary* pEncryptDict,
                CPDF_Array* pIdArray,
                const uint8_t* user_pass,
                FX_DWORD user_size,
                FX_DWORD type = PDF_ENCRYPT_CONTENT);

  CFX_ByteString GetUserPassword(const uint8_t* owner_pass, FX_DWORD pass_size);
  CFX_ByteString GetUserPassword(const uint8_t* owner_pass,
                                 FX_DWORD pass_size,
                                 int32_t key_len);
  int GetVersion() { return m_Version; }
  int GetRevision() { return m_Revision; }

  int CheckPassword(const uint8_t* password,
                    FX_DWORD pass_size,
                    FX_BOOL bOwner,
                    uint8_t* key);
  int CheckPassword(const uint8_t* password,
                    FX_DWORD pass_size,
                    FX_BOOL bOwner,
                    uint8_t* key,
                    int key_len);

 private:
  int m_Version;

  int m_Revision;

  CPDF_Parser* m_pParser;

  CPDF_Dictionary* m_pEncryptDict;

  FX_BOOL LoadDict(CPDF_Dictionary* pEncryptDict);
  FX_BOOL LoadDict(CPDF_Dictionary* pEncryptDict,
                   FX_DWORD type,
                   int& cipher,
                   int& key_len);

  FX_BOOL CheckUserPassword(const uint8_t* password,
                            FX_DWORD pass_size,
                            FX_BOOL bIgnoreEncryptMeta,
                            uint8_t* key,
                            int32_t key_len);

  FX_BOOL CheckOwnerPassword(const uint8_t* password,
                             FX_DWORD pass_size,
                             uint8_t* key,
                             int32_t key_len);
  FX_BOOL AES256_CheckPassword(const uint8_t* password,
                               FX_DWORD size,
                               FX_BOOL bOwner,
                               uint8_t* key);
  void AES256_SetPassword(CPDF_Dictionary* pEncryptDict,
                          const uint8_t* password,
                          FX_DWORD size,
                          FX_BOOL bOwner,
                          const uint8_t* key);
  void AES256_SetPerms(CPDF_Dictionary* pEncryptDict,
                       FX_DWORD permission,
                       FX_BOOL bEncryptMetadata,
                       const uint8_t* key);
  void OnCreate(CPDF_Dictionary* pEncryptDict,
                CPDF_Array* pIdArray,
                const uint8_t* user_pass,
                FX_DWORD user_size,
                const uint8_t* owner_pass,
                FX_DWORD owner_size,
                FX_BOOL bDefault,
                FX_DWORD type);
  FX_BOOL CheckSecurity(int32_t key_len);

  FX_BOOL m_bOwner;

  FX_DWORD m_Permissions;

  int m_Cipher;

  uint8_t m_EncryptKey[32];

  int m_KeyLen;
};
class CPDF_CryptoHandler {
 public:
  virtual ~CPDF_CryptoHandler() {}

  virtual FX_BOOL Init(CPDF_Dictionary* pEncryptDict,
                       CPDF_SecurityHandler* pSecurityHandler) = 0;

  virtual FX_DWORD DecryptGetSize(FX_DWORD src_size) = 0;

  virtual void* DecryptStart(FX_DWORD objnum, FX_DWORD gennum) = 0;

  virtual FX_BOOL DecryptStream(void* context,
                                const uint8_t* src_buf,
                                FX_DWORD src_size,
                                CFX_BinaryBuf& dest_buf) = 0;

  virtual FX_BOOL DecryptFinish(void* context, CFX_BinaryBuf& dest_buf) = 0;

  virtual FX_DWORD EncryptGetSize(FX_DWORD objnum,
                                  FX_DWORD version,
                                  const uint8_t* src_buf,
                                  FX_DWORD src_size) = 0;

  virtual FX_BOOL EncryptContent(FX_DWORD objnum,
                                 FX_DWORD version,
                                 const uint8_t* src_buf,
                                 FX_DWORD src_size,
                                 uint8_t* dest_buf,
                                 FX_DWORD& dest_size) = 0;

  void Decrypt(FX_DWORD objnum, FX_DWORD version, CFX_ByteString& str);
};
class CPDF_StandardCryptoHandler : public CPDF_CryptoHandler {
 public:
  CPDF_StandardCryptoHandler();
  ~CPDF_StandardCryptoHandler() override;

  // CPDF_CryptoHandler
  FX_BOOL Init(CPDF_Dictionary* pEncryptDict,
               CPDF_SecurityHandler* pSecurityHandler) override;
  FX_DWORD DecryptGetSize(FX_DWORD src_size) override;
  void* DecryptStart(FX_DWORD objnum, FX_DWORD gennum) override;
  FX_BOOL DecryptStream(void* context,
                        const uint8_t* src_buf,
                        FX_DWORD src_size,
                        CFX_BinaryBuf& dest_buf) override;
  FX_BOOL DecryptFinish(void* context, CFX_BinaryBuf& dest_buf) override;
  FX_DWORD EncryptGetSize(FX_DWORD objnum,
                          FX_DWORD version,
                          const uint8_t* src_buf,
                          FX_DWORD src_size) override;
  FX_BOOL EncryptContent(FX_DWORD objnum,
                         FX_DWORD version,
                         const uint8_t* src_buf,
                         FX_DWORD src_size,
                         uint8_t* dest_buf,
                         FX_DWORD& dest_size) override;

  FX_BOOL Init(int cipher, const uint8_t* key, int keylen);

 protected:
  virtual void CryptBlock(FX_BOOL bEncrypt,
                          FX_DWORD objnum,
                          FX_DWORD gennum,
                          const uint8_t* src_buf,
                          FX_DWORD src_size,
                          uint8_t* dest_buf,
                          FX_DWORD& dest_size);
  virtual void* CryptStart(FX_DWORD objnum, FX_DWORD gennum, FX_BOOL bEncrypt);
  virtual FX_BOOL CryptStream(void* context,
                              const uint8_t* src_buf,
                              FX_DWORD src_size,
                              CFX_BinaryBuf& dest_buf,
                              FX_BOOL bEncrypt);
  virtual FX_BOOL CryptFinish(void* context,
                              CFX_BinaryBuf& dest_buf,
                              FX_BOOL bEncrypt);

  uint8_t m_EncryptKey[32];

  int m_KeyLen;

  int m_Cipher;

  uint8_t* m_pAESContext;
};
class CPDF_Point {
 public:
  CPDF_Point(FX_FLOAT xx, FX_FLOAT yy) {
    x = xx;
    y = yy;
  }

  FX_FLOAT x;

  FX_FLOAT y;
};

#define CPDF_Rect CFX_FloatRect
CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& orig);
CFX_ByteString PDF_NameDecode(const CFX_ByteString& orig);
CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig);
CFX_ByteString PDF_EncodeString(const CFX_ByteString& src,
                                FX_BOOL bHex = FALSE);
CFX_WideString PDF_DecodeText(const uint8_t* pData,
                              FX_DWORD size,
                              CFX_CharMap* pCharMap = NULL);
inline CFX_WideString PDF_DecodeText(const CFX_ByteString& bstr,
                                     CFX_CharMap* pCharMap = NULL) {
  return PDF_DecodeText((const uint8_t*)bstr.c_str(), bstr.GetLength(),
                        pCharMap);
}
CFX_ByteString PDF_EncodeText(const FX_WCHAR* pString,
                              int len = -1,
                              CFX_CharMap* pCharMap = NULL);
inline CFX_ByteString PDF_EncodeText(const CFX_WideString& str,
                                     CFX_CharMap* pCharMap = NULL) {
  return PDF_EncodeText(str.c_str(), str.GetLength(), pCharMap);
}
FX_FLOAT PDF_ClipFloat(FX_FLOAT f);
class CFDF_Document : public CPDF_IndirectObjects {
 public:
  static CFDF_Document* CreateNewDoc();
  static CFDF_Document* ParseFile(IFX_FileRead* pFile,
                                  FX_BOOL bOwnFile = FALSE);
  static CFDF_Document* ParseMemory(const uint8_t* pData, FX_DWORD size);

  ~CFDF_Document();

  FX_BOOL WriteBuf(CFX_ByteTextBuf& buf) const;

  CPDF_Dictionary* GetRoot() const { return m_pRootDict; }

  CFX_WideString GetWin32Path() const;

 protected:
  CFDF_Document();
  void ParseStream(IFX_FileRead* pFile, FX_BOOL bOwnFile);
  CPDF_Dictionary* m_pRootDict;
  IFX_FileRead* m_pFile;
  FX_BOOL m_bOwnFile;
};

CFX_WideString FPDF_FileSpec_GetWin32Path(const CPDF_Object* pFileSpec);
void FPDF_FileSpec_SetWin32Path(CPDF_Object* pFileSpec,
                                const CFX_WideString& fullpath);

void FlateEncode(const uint8_t* src_buf,
                 FX_DWORD src_size,
                 uint8_t*& dest_buf,
                 FX_DWORD& dest_size);
void FlateEncode(const uint8_t* src_buf,
                 FX_DWORD src_size,
                 int predictor,
                 int Colors,
                 int BitsPerComponent,
                 int Columns,
                 uint8_t*& dest_buf,
                 FX_DWORD& dest_size);
FX_DWORD FlateDecode(const uint8_t* src_buf,
                     FX_DWORD src_size,
                     uint8_t*& dest_buf,
                     FX_DWORD& dest_size);
FX_DWORD RunLengthDecode(const uint8_t* src_buf,
                         FX_DWORD src_size,
                         uint8_t*& dest_buf,
                         FX_DWORD& dest_size);
bool IsSignatureDict(const CPDF_Dictionary* pDict);

class CPDF_NumberTree {
 public:
  CPDF_NumberTree(CPDF_Dictionary* pRoot) { m_pRoot = pRoot; }

  CPDF_Object* LookupValue(int num);

 protected:
  CPDF_Dictionary* m_pRoot;
};

class IFX_FileAvail {
 public:
  virtual ~IFX_FileAvail() {}
  virtual FX_BOOL IsDataAvail(FX_FILESIZE offset, FX_DWORD size) = 0;
};
class IFX_DownloadHints {
 public:
  virtual ~IFX_DownloadHints() {}
  virtual void AddSegment(FX_FILESIZE offset, FX_DWORD size) = 0;
};

class IPDF_DataAvail {
 public:
  // Must match PDF_DATA_* definitions in public/fpdf_dataavail.h, but cannot
  // #include that header. fpdfsdk/src/fpdf_dataavail.cpp has static_asserts
  // to make sure the two sets of values match.
  enum DocAvailStatus {
    DataError = -1,        // PDF_DATA_ERROR
    DataNotAvailable = 0,  // PDF_DATA_NOTAVAIL
    DataAvailable = 1,     // PDF_DATA_AVAIL
  };

  // Must match PDF_*LINEAR* definitions in public/fpdf_dataavail.h, but cannot
  // #include that header. fpdfsdk/src/fpdf_dataavail.cpp has static_asserts
  // to make sure the two sets of values match.
  enum DocLinearizationStatus {
    LinearizationUnknown = -1,  // PDF_LINEARIZATION_UNKNOWN
    NotLinearized = 0,          // PDF_NOT_LINEARIZED
    Linearized = 1,             // PDF_LINEARIZED
  };

  // Must match PDF_FORM_* definitions in public/fpdf_dataavail.h, but cannot
  // #include that header. fpdfsdk/src/fpdf_dataavail.cpp has static_asserts
  // to make sure the two sets of values match.
  enum DocFormStatus {
    FormError = -1,        // PDF_FORM_ERROR
    FormNotAvailable = 0,  // PDF_FORM_NOTAVAIL
    FormAvailable = 1,     // PDF_FORM_AVAIL
    FormNotExist = 2,      // PDF_FORM_NOTEXIST
  };

  static IPDF_DataAvail* Create(IFX_FileAvail* pFileAvail,
                                IFX_FileRead* pFileRead);
  virtual ~IPDF_DataAvail() {}

  IFX_FileAvail* GetFileAvail() const { return m_pFileAvail; }
  IFX_FileRead* GetFileRead() const { return m_pFileRead; }

  virtual DocAvailStatus IsDocAvail(IFX_DownloadHints* pHints) = 0;
  virtual void SetDocument(CPDF_Document* pDoc) = 0;
  virtual int IsPageAvail(int iPage, IFX_DownloadHints* pHints) = 0;
  virtual FX_BOOL IsLinearized() = 0;
  virtual DocFormStatus IsFormAvail(IFX_DownloadHints* pHints) = 0;
  virtual DocLinearizationStatus IsLinearizedPDF() = 0;
  virtual void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos,
                                         FX_DWORD* pSize) = 0;

 protected:
  IPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead);

  IFX_FileAvail* m_pFileAvail;
  IFX_FileRead* m_pFileRead;
};

enum PDF_PAGENODE_TYPE {
  PDF_PAGENODE_UNKOWN = 0,
  PDF_PAGENODE_PAGE,
  PDF_PAGENODE_PAGES,
  PDF_PAGENODE_ARRAY,
};
class CPDF_PageNode {
 public:
  CPDF_PageNode() : m_type(PDF_PAGENODE_UNKOWN) {}
  ~CPDF_PageNode();
  PDF_PAGENODE_TYPE m_type;
  FX_DWORD m_dwPageNo;
  CFX_ArrayTemplate<CPDF_PageNode*> m_childNode;
};
enum PDF_DATAAVAIL_STATUS {
  PDF_DATAAVAIL_HEADER = 0,
  PDF_DATAAVAIL_FIRSTPAGE,
  PDF_DATAAVAIL_FIRSTPAGE_PREPARE,
  PDF_DATAAVAIL_HINTTABLE,
  PDF_DATAAVAIL_END,
  PDF_DATAAVAIL_CROSSREF,
  PDF_DATAAVAIL_CROSSREF_ITEM,
  PDF_DATAAVAIL_CROSSREF_STREAM,
  PDF_DATAAVAIL_TRAILER,
  PDF_DATAAVAIL_LOADALLCRSOSSREF,
  PDF_DATAAVAIL_ROOT,
  PDF_DATAAVAIL_INFO,
  PDF_DATAAVAIL_ACROFORM,
  PDF_DATAAVAIL_ACROFORM_SUBOBJECT,
  PDF_DATAAVAIL_PAGETREE,
  PDF_DATAAVAIL_PAGE,
  PDF_DATAAVAIL_PAGE_LATERLOAD,
  PDF_DATAAVAIL_RESOURCES,
  PDF_DATAAVAIL_DONE,
  PDF_DATAAVAIL_ERROR,
  PDF_DATAAVAIL_LOADALLFILE,
  PDF_DATAAVAIL_TRAILER_APPEND
};

// Public for testing.
FX_DWORD A85Decode(const uint8_t* src_buf,
                   FX_DWORD src_size,
                   uint8_t*& dest_buf,
                   FX_DWORD& dest_size);
// Public for testing.
FX_DWORD HexDecode(const uint8_t* src_buf,
                   FX_DWORD src_size,
                   uint8_t*& dest_buf,
                   FX_DWORD& dest_size);
// Public for testing.
FX_DWORD FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW,
                                  const uint8_t* src_buf,
                                  FX_DWORD src_size,
                                  CPDF_Dictionary* pParams,
                                  FX_DWORD estimated_size,
                                  uint8_t*& dest_buf,
                                  FX_DWORD& dest_size);
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);

#endif  // CORE_INCLUDE_FPDFAPI_FPDF_PARSER_H_
