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

#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif

#include "poppler-config.h"
#include "goo/gtypes.h"
#include "goo/GooMutex.h"
#include "Object.h"
#include "Stream.h"

#include <vector>

class Dict;
class Stream;
class Parser;
class PopplerCache;

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

    // 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 GBool getFlag(Flag flag) {
    const int mask = (1 << (int)flag);
    return (flags & mask) != 0;
  }

  inline void setFlag(Flag flag, GBool 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(Object *trailerDictA);
  // Constructor.  Read xref table from stream.
  XRef(BaseStream *strA, Goffset pos, Goffset mainXRefEntriesOffsetA = 0, GBool *wasReconstructed = NULL, GBool reconstruct = false);

  // Destructor.
  ~XRef();

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

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

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

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

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

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

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

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

  // Get catalog object.
  Object getCatalog();

  // Fetch an indirect reference.
  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() { return size; }

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

  // Get end position for a stream in a damaged file.
  // Returns false if unknown or file is not damaged.
  GBool 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, GBool complainIfMissing = gTrue);
  Object *getTrailerDict() { return &trailerDict; }

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

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

  // Output XRef table to stream
  void writeTableToFile(OutStream* outStr, GBool 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
  GBool ok;			// true if xref table is valid
  int errCode;			// error code (if <ok> is false)
  GBool xrefReconstructed;	// marker, true if xref was already reconstructed
  Object trailerDict;		// trailer dictionary
  GBool modified;
  Goffset *streamEnds;		// 'endstream' positions - only used in
				//   damaged files
  int streamEndsLen;		// number of valid entries in streamEnds
  PopplerCache *objStrs;	// cached object streams
  GBool 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
  Guchar fileKey[32];		// file decryption key
  GBool 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
  GBool xRefStream;		// true if last XRef section is a stream
  Goffset mainXRefOffset;	// position of the main XRef table/stream
  GBool scannedSpecialFlags;	// true if scanSpecialFlags has been called
  GBool strOwner;     // true if str is owned by the instance
#ifdef MULTITHREADED
  GooMutex mutex;
#endif

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

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

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

    GBool hasOffsetsBeyond4GB;
  };

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

#endif
