//========================================================================
//
// XRef.h
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2005 Brad Hards <bradh@frogmouth.net>
// Copyright (C) 2006, 2008, 2010-2013, 2017-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2007-2008 Julien Rebetez <julienr@svn.gnome.org>
// Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2010 Ilya Gorenbein <igorenbein@finjan.com>
// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2012, 2013, 2016 Thomas Freitag <Thomas.Freitag@kabelmail.de>
// Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2013, 2017 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com>
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
// Copyright (C) 2018 Marek Kasik <mkasik@redhat.com>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#ifndef XREF_H
#define XREF_H

#include "poppler-config.h"
#include "Object.h"
#include "Stream.h"
#include "PopplerCache.h"

class Dict;
class Stream;
class Parser;
class ObjectStream;

//------------------------------------------------------------------------
// XRef
//------------------------------------------------------------------------

enum XRefEntryType {
  xrefEntryFree,
  xrefEntryUncompressed,
  xrefEntryCompressed,
  xrefEntryNone
};

struct XRefEntry {
  Goffset offset;
  int gen;
  XRefEntryType type;
  int flags;
  Object obj; //if this entry was updated, obj will contains the updated object

  enum Flag {
    // Regular flags
    Updated,     // Entry was modified
    Parsing,     // Entry is currently being parsed

    // Special flags -- available only after xref->scanSpecialFlags() is run
    Unencrypted, // Entry is stored in unencrypted form (meaningless in unencrypted documents)
    DontRewrite  // Entry must not be written back in case of full rewrite
  };

  inline bool getFlag(Flag flag) const {
    const int mask = (1 << (int)flag);
    return (flags & mask) != 0;
  }

  inline void setFlag(Flag flag, bool value) {
    const int mask = (1 << (int)flag);
    if (value) {
      flags |= mask;
    } else {
      flags &= ~mask;
    }
  }
};

class XRef {
public:

  // Constructor, create an empty XRef, used for PDF writing
  XRef();
  // Constructor, create an empty XRef but with info dict, used for PDF writing
  XRef(const Object *trailerDictA);
  // Constructor.  Read xref table from stream.
  XRef(BaseStream *strA, Goffset pos, Goffset mainXRefEntriesOffsetA = 0, bool *wasReconstructed = nullptr, bool reconstruct = false);

  // Destructor.
  ~XRef();

  XRef(const XRef &) = delete;
  XRef& operator=(const XRef &) = delete;

  // Copy xref but with new base stream!
  XRef *copy() const;

  // Is xref table valid?
  bool isOk() const { return ok; }

  // Is the last XRef section a stream or a table?
  bool isXRefStream() const { return xRefStream; }

  // Get the error code (if isOk() returns false).
  int getErrorCode() const { return errCode; }

  // Set the encryption parameters.
  void setEncryption(int permFlagsA, bool ownerPasswordOkA,
		     const unsigned char *fileKeyA, int keyLengthA,
		     int encVersionA, int encRevisionA,
		     CryptAlgorithm encAlgorithmA);
  // Mark Encrypt entry as Unencrypted
  void markUnencrypted();

  void getEncryptionParameters(unsigned char **fileKeyA, CryptAlgorithm *encAlgorithmA, int *keyLengthA);

  // Is the file encrypted?
  bool isEncrypted() const { return encrypted; }

  // Check various permissions.
  bool okToPrint(bool ignoreOwnerPW = false) const;
  bool okToPrintHighRes(bool ignoreOwnerPW = false) const;
  bool okToChange(bool ignoreOwnerPW = false) const;
  bool okToCopy(bool ignoreOwnerPW = false) const;
  bool okToAddNotes(bool ignoreOwnerPW = false) const;
  bool okToFillForm(bool ignoreOwnerPW = false) const;
  bool okToAccessibility(bool ignoreOwnerPW = false) const;
  bool okToAssemble(bool ignoreOwnerPW = false) const;
  int getPermFlags() const { return permFlags; }

  // Get catalog object.
  Object getCatalog();

  // Fetch an indirect reference.
  Object fetch(const Ref ref, int recursion = 0);
  Object fetch(int num, int gen, int recursion = 0);

  // Return the document's Info dictionary (if any).
  Object getDocInfo();
  Object getDocInfoNF();

  // Create and return the document's Info dictionary if none exists.
  // Otherwise return the existing one.
  Object createDocInfoIfNoneExists();

  // Remove the document's Info dictionary and update the trailer dictionary.
  void removeDocInfo();

  // Return the number of objects in the xref table.
  int getNumObjects() const { return size; }

  // Return the catalog object reference.
  int getRootNum() const { return rootNum; }
  int getRootGen() const { return rootGen; }

  // Get end position for a stream in a damaged file.
  // Returns false if unknown or file is not damaged.
  bool getStreamEnd(Goffset streamStart, Goffset *streamEnd);

  // Retuns the entry that belongs to the offset
  int getNumEntry(Goffset offset);

  // Scans the document and sets special flags in all xref entries. One of those
  // flags is Unencrypted, which affects how the object is fetched. Therefore,
  // this function must be called before fetching unencrypted objects (e.g.
  // Encrypt dictionary, XRef streams). Note that the code that initializes
  // decryption doesn't need to call this function, because it runs before
  // decryption is enabled, and therefore the Unencrypted flag is ignored.
  void scanSpecialFlags();

  // Direct access.
  XRefEntry *getEntry(int i, bool complainIfMissing = true);
  Object *getTrailerDict() { return &trailerDict; }

  // Was the XRef modified?
  bool isModified() const { return modified; }
  // Set the modification flag for XRef to true.
  void setModified() { modified = true; }

  // Write access
  void setModifiedObject(const Object* o, Ref r);
  Ref addIndirectObject (const Object* o);
  void removeIndirectObject(Ref r);
  void add(int num, int gen,  Goffset offs, bool used);
  void add(Ref ref, Goffset offs, bool used);

  // Output XRef table to stream
  void writeTableToFile(OutStream* outStr, bool writeAllEntries);
  // Output XRef stream contents to GooString and fill trailerDict fields accordingly
  void writeStreamToBuffer(GooString *stmBuf, Dict *xrefDict, XRef *xref);

  // to be thread safe during write where changes are not allowed
  void lock();
  void unlock();

private:

  BaseStream *str;		// input stream
  Goffset start;		// offset in file (to allow for garbage
				//   at beginning of file)
  XRefEntry *entries;		// xref entries
  int capacity;			// size of <entries> array
  int size;			// number of entries
  int rootNum, rootGen;		// catalog dict
  bool ok;			// true if xref table is valid
  int errCode;			// error code (if <ok> is false)
  bool xrefReconstructed;	// marker, true if xref was already reconstructed
  Object trailerDict;		// trailer dictionary
  bool modified;
  Goffset *streamEnds;		// 'endstream' positions - only used in
				//   damaged files
  int streamEndsLen;		// number of valid entries in streamEnds
  PopplerCache<Goffset, ObjectStream> objStrs;	// cached object streams
  bool encrypted;		// true if file is encrypted
  int encRevision;		
  int encVersion;		// encryption algorithm
  CryptAlgorithm encAlgorithm;	// encryption algorithm
  int keyLength;		// length of key, in bytes
  int permFlags;		// permission bits
  unsigned char fileKey[32];		// file decryption key
  bool ownerPasswordOk;	// true if owner password is correct
  Goffset prevXRefOffset;		// position of prev XRef section (= next to read)
  Goffset mainXRefEntriesOffset; // offset of entries in main XRef table
  bool xRefStream;		// true if last XRef section is a stream
  Goffset mainXRefOffset;	// position of the main XRef table/stream
  bool scannedSpecialFlags;	// true if scanSpecialFlags has been called
  bool strOwner;     // true if str is owned by the instance
  mutable std::recursive_mutex mutex;

  int reserve(int newSize);
  int resize(int newSize);
  bool readXRef(Goffset *pos, std::vector<Goffset> *followedXRefStm, std::vector<int> *xrefStreamObjsNum);
  bool readXRefTable(Parser *parser, Goffset *pos, std::vector<Goffset> *followedXRefStm, std::vector<int> *xrefStreamObjsNum);
  bool readXRefStreamSection(Stream *xrefStr, int *w, int first, int n);
  bool readXRefStream(Stream *xrefStr, Goffset *pos);
  bool constructXRef(bool *wasReconstructed, bool needCatalogDict = false);
  bool parseEntry(Goffset offset, XRefEntry *entry);
  void readXRefUntil(int untilEntryNum, std::vector<int> *xrefStreamObjsNum = nullptr);
  void markUnencrypted(Object *obj);

  class XRefWriter {
  public:
    XRefWriter() = default;
    virtual void startSection(int first, int count) = 0;
    virtual void writeEntry(Goffset offset, int gen, XRefEntryType type) = 0;
    virtual ~XRefWriter() {};

    XRefWriter(const XRefWriter &) = delete;
    XRefWriter& operator=(const XRefWriter &other) = delete;
  };

  // XRefWriter subclass that writes a XRef table
  class XRefTableWriter: public XRefWriter {
  public:
    XRefTableWriter(OutStream* outStrA);
    void startSection(int first, int count) override;
    void writeEntry(Goffset offset, int gen, XRefEntryType type) override;
  private:
    OutStream* outStr;
  };

  // XRefWriter subclass that writes a XRef stream
  class XRefStreamWriter: public XRefWriter {
  public:
    XRefStreamWriter(Array *index, GooString *stmBuf, int offsetSize);
    void startSection(int first, int count) override;
    void writeEntry(Goffset offset, int gen, XRefEntryType type) override;
  private:
    Array *index;
    GooString *stmBuf;
    int offsetSize;
  };

  // Dummy XRefWriter subclass that only checks if all offsets fit in 4 bytes
  class XRefPreScanWriter: public XRefWriter {
  public:
    XRefPreScanWriter();
    void startSection(int first, int count) override;
    void writeEntry(Goffset offset, int gen, XRefEntryType type) override;

    bool hasOffsetsBeyond4GB;
  };

  void writeXRef(XRefWriter *writer, bool writeAllEntries);
};

#endif
