//========================================================================
//
// Object.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) 2007 Julien Rebetez <julienr@svn.gnome.org>
// Copyright (C) 2008 Kees Cook <kees@outflux.net>
// Copyright (C) 2008, 2010, 2017, 2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2009 Jakub Wilk <jwilk@jwilk.net>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2013, 2017, 2018 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2013 Adrian Perez de Castro <aperez@igalia.com>
// Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com>
// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
//
// 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 OBJECT_H
#define OBJECT_H

#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif

#include <cassert>
#include <set>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include "goo/gtypes.h"
#include "goo/gmem.h"
#include "goo/GooString.h"
#include "goo/GooLikely.h"
#include "Error.h"

#define OBJECT_TYPE_CHECK(wanted_type) \
    if (unlikely(type != wanted_type)) { \
        error(errInternal, 0, "Call to Object where the object was type {0:d}, " \
                 "not the expected type {1:d}", type, wanted_type); \
        abort(); \
    }

#define OBJECT_2TYPES_CHECK(wanted_type1, wanted_type2) \
    if (unlikely(type != wanted_type1) && unlikely(type != wanted_type2)) { \
        error(errInternal, 0, "Call to Object where the object was type {0:d}, " \
	      "not the expected type {1:d} or {2:d}", type, wanted_type1, wanted_type2); \
        abort(); \
    }

#define OBJECT_3TYPES_CHECK(wanted_type1, wanted_type2, wanted_type3)	\
    if (unlikely(type != wanted_type1) && unlikely(type != wanted_type2) && unlikely(type != wanted_type3)) { \
        error(errInternal, 0, "Call to Object where the object was type {0:d}, " \
	      "not the expected type {1:d}, {2:d} or {3:d}", type, wanted_type1, wanted_type2, wanted_type3); \
        abort(); \
    }

#define CHECK_NOT_DEAD \
  if (unlikely(type == objDead)) { \
        error(errInternal, 0, "Call to dead object"); \
        abort(); \
    }

class XRef;
class Array;
class Dict;
class Stream;

//------------------------------------------------------------------------
// Ref
//------------------------------------------------------------------------

struct Ref {
  int num;			// object number
  int gen;			// generation number
};

inline bool operator== (const Ref& lhs, const Ref& rhs) noexcept {
  return lhs.num == rhs.num && lhs.gen == rhs.gen;
}

inline bool operator< (const Ref& lhs, const Ref& rhs) noexcept {
  if (lhs.num != rhs.num)
    return lhs.num < rhs.num;
  return lhs.gen < rhs.gen;
}

namespace std
{

template<>
struct hash<Ref>
{
    using argument_type = Ref;
    using result_type = size_t;

    result_type operator() (const argument_type &ref) const noexcept
    {
	return std::hash<int>{}(ref.num) ^ (std::hash<int>{}(ref.gen) << 1);
    }
};

}

//------------------------------------------------------------------------
// object types
//------------------------------------------------------------------------

enum ObjType {
  // simple objects
  objBool,			// boolean
  objInt,			// integer
  objReal,			// real
  objString,			// string
  objName,			// name
  objNull,			// null

  // complex objects
  objArray,			// array
  objDict,			// dictionary
  objStream,			// stream
  objRef,			// indirect reference

  // special objects
  objCmd,			// command name
  objError,			// error return from Lexer
  objEOF,			// end of file return from Lexer
  objNone,			// uninitialized object

  // poppler-only objects
  objInt64,			// integer with at least 64-bits
  objDead			// and object after shallowCopy
};

#define numObjTypes 16		// total number of object types

//------------------------------------------------------------------------
// Object
//------------------------------------------------------------------------

#define initObj(t) free(); zeroUnion(); type = t
#define constructObj(t) type = t

class Object {
public:
  // clear the anonymous union as best we can -- clear at least a pointer
  void zeroUnion() { this->cString = nullptr; }

  // Default constructor.
  Object():
    type(objNone) { zeroUnion(); }
  ~Object();

  explicit Object(GBool boolnA)
    { constructObj(objBool); booln = boolnA; }
  explicit Object(int intgA)
    { constructObj(objInt); intg = intgA; }
  explicit Object(ObjType typeA)
    { constructObj(typeA); }
  explicit Object(double realA)
    { constructObj(objReal); real = realA; }
  explicit Object(GooString *stringA)
    { assert(stringA); constructObj(objString); string = stringA; }
  Object(ObjType typeA, const char *stringA)
    { assert(typeA == objName || typeA == objCmd); assert(stringA); constructObj(typeA); cString = copyString(stringA); }
  explicit Object(long long int64gA)
    { constructObj(objInt64); int64g = int64gA; }
  explicit Object(Array *arrayA)
    { assert(arrayA); constructObj(objArray); array = arrayA; }
  explicit Object(Dict *dictA)
    { assert(dictA); constructObj(objDict); dict = dictA; }
  explicit Object(Stream *streamA)
    { assert(streamA); constructObj(objStream); stream = streamA; }
  Object(int numA, int genA)
    { constructObj(objRef); ref.num = numA; ref.gen = genA; }
  template<typename T> Object(T) = delete;

  Object(Object&& other);
  Object& operator=(Object&& other);

  Object &operator=(const Object &other) = delete;
  Object(const Object &other) = delete;

  // Set object to null.
  void setToNull() { initObj(objNull); }

  // Copy this to obj
  Object copy() const;

  // If object is a Ref, fetch and return the referenced object.
  // Otherwise, return a copy of the object.
  Object fetch(XRef *xref, int recursion = 0) const;

  // Type checking.
  ObjType getType() const { CHECK_NOT_DEAD; return type; }
  GBool isBool() const { CHECK_NOT_DEAD; return type == objBool; }
  GBool isInt() const { CHECK_NOT_DEAD; return type == objInt; }
  GBool isReal() const { CHECK_NOT_DEAD; return type == objReal; }
  GBool isNum() const { CHECK_NOT_DEAD; return type == objInt || type == objReal || type == objInt64; }
  GBool isString() const { CHECK_NOT_DEAD; return type == objString; }
  GBool isName() const { CHECK_NOT_DEAD; return type == objName; }
  GBool isNull() const { CHECK_NOT_DEAD; return type == objNull; }
  GBool isArray() const { CHECK_NOT_DEAD; return type == objArray; }
  GBool isDict() const { CHECK_NOT_DEAD; return type == objDict; }
  GBool isStream() const { CHECK_NOT_DEAD; return type == objStream; }
  GBool isRef() const { CHECK_NOT_DEAD; return type == objRef; }
  GBool isCmd() const { CHECK_NOT_DEAD; return type == objCmd; }
  GBool isError() const { CHECK_NOT_DEAD; return type == objError; }
  GBool isEOF() const { CHECK_NOT_DEAD; return type == objEOF; }
  GBool isNone() const { CHECK_NOT_DEAD; return type == objNone; }
  GBool isInt64() const { CHECK_NOT_DEAD; return type == objInt64; }
  GBool isIntOrInt64() const { CHECK_NOT_DEAD; return type == objInt || type == objInt64; }

  // Special type checking.
  GBool isName(const char *nameA) const
    { return type == objName && !strcmp(cString, nameA); }
  GBool isDict(const char *dictType) const;
  GBool isStream(char *dictType) const;
  GBool isCmd(const char *cmdA) const
    { return type == objCmd && !strcmp(cString, cmdA); }

  // Accessors.
  GBool getBool() const { OBJECT_TYPE_CHECK(objBool); return booln; }
  int getInt() const { OBJECT_TYPE_CHECK(objInt); return intg; }
  double getReal() const { OBJECT_TYPE_CHECK(objReal); return real; }

  // Note: integers larger than 2^53 can not be exactly represented by a double.
  // Where the exact value of integers up to 2^63 is required, use isInt64()/getInt64().
  double getNum() const { OBJECT_3TYPES_CHECK(objInt, objInt64, objReal);
    return type == objInt ? (double)intg : type == objInt64 ? (double)int64g : real; }
  double getNum(bool *ok) const {
    if (unlikely(type != objInt && type != objInt64 && type != objReal)) {
      *ok = false;
      return 0.;
    }
    return type == objInt ? (double)intg : type == objInt64 ? (double)int64g : real;
  }
  const GooString *getString() const { OBJECT_TYPE_CHECK(objString); return string; }
  // After takeString() the only method that should be called for the object is free().
  GooString *takeString() { OBJECT_TYPE_CHECK(objString); type = objDead; return string; }
  const char *getName() const { OBJECT_TYPE_CHECK(objName); return cString; }
  Array *getArray() const { OBJECT_TYPE_CHECK(objArray); return array; }
  Dict *getDict() const { OBJECT_TYPE_CHECK(objDict); return dict; }
  Stream *getStream() const { OBJECT_TYPE_CHECK(objStream); return stream; }
  Ref getRef() const { OBJECT_TYPE_CHECK(objRef); return ref; }
  int getRefNum() const { OBJECT_TYPE_CHECK(objRef); return ref.num; }
  int getRefGen() const { OBJECT_TYPE_CHECK(objRef); return ref.gen; }
  char *getCmd() const { OBJECT_TYPE_CHECK(objCmd); return cString; }
  long long getInt64() const { OBJECT_TYPE_CHECK(objInt64); return int64g; }
  long long getIntOrInt64() const { OBJECT_2TYPES_CHECK(objInt, objInt64);
    return type == objInt ? intg : int64g; }

  // Array accessors.
  int arrayGetLength() const;
  void arrayAdd(Object &&elem);
  void arrayRemove(int i);
  Object arrayGet(int i, int recursion) const;
  Object arrayGetNF(int i) const;

  // Dict accessors.
  int dictGetLength() const;
  void dictAdd(char *key, Object &&val) = delete;
  void dictAdd(const char *key, Object &&val);
  void dictSet(const char *key, Object &&val);
  void dictRemove(const char *key);
  GBool dictIs(const char *dictType) const;
  Object dictLookup(const char *key, int recursion = 0) const;
  Object dictLookupNF(const char *key) const;
  const char *dictGetKey(int i) const;
  Object dictGetVal(int i) const;
  Object dictGetValNF(int i) const;

  // Stream accessors.
  GBool streamIs(char *dictType) const;
  void streamReset();
  void streamClose();
  int streamGetChar() const;
  int streamGetChars(int nChars, Guchar *buffer) const;
  int streamLookChar() const;
  char *streamGetLine(char *buf, int size) const;
  Goffset streamGetPos() const;
  void streamSetPos(Goffset pos, int dir = 0);
  Dict *streamGetDict() const;

  // Output.
  const char *getTypeName() const;
  void print(FILE *f = stdout) const;

private:
  friend class Array; // Needs free and initNullAfterMalloc
  friend class Dict; // Needs free and initNullAfterMalloc
  friend class XRef; // Needs free and initNullAfterMalloc

  // Free object contents.
  void free();

  // Only use if are mallocing Objects
  void initNullAfterMalloc() { constructObj(objNull); }

  ObjType type;			// object type
  union {			// value for each type:
    GBool booln;		//   boolean
    int intg;			//   integer
    long long int64g;           //   64-bit integer
    double real;		//   real
    GooString *string;		//   string
    char *cString;		//   name or command, depending on objType
    Array *array;		//   array
    Dict *dict;			//   dictionary
    Stream *stream;		//   stream
    Ref ref;			//   indirect reference
  };
};

//------------------------------------------------------------------------
// Array accessors.
//------------------------------------------------------------------------

#include "Array.h"

inline int Object::arrayGetLength() const
  { OBJECT_TYPE_CHECK(objArray); return array->getLength(); }

inline void Object::arrayAdd(Object &&elem)
  { OBJECT_TYPE_CHECK(objArray); array->add(std::move(elem)); }

inline void Object::arrayRemove(int i)
  { OBJECT_TYPE_CHECK(objArray); array->remove(i); }

inline Object Object::arrayGet(int i, int recursion = 0) const
  { OBJECT_TYPE_CHECK(objArray); return array->get(i, recursion); }

inline Object Object::arrayGetNF(int i) const
  { OBJECT_TYPE_CHECK(objArray); return array->getNF(i); }

//------------------------------------------------------------------------
// Dict accessors.
//------------------------------------------------------------------------

#include "Dict.h"

inline int Object::dictGetLength() const
  { OBJECT_TYPE_CHECK(objDict); return dict->getLength(); }

inline void Object::dictAdd(const char *key, Object &&val)
  { OBJECT_TYPE_CHECK(objDict); dict->add(key, std::move(val)); }

inline void Object::dictSet(const char *key, Object &&val)
  { OBJECT_TYPE_CHECK(objDict); dict->set(key, std::move(val)); }

inline void Object::dictRemove(const char *key)
  { OBJECT_TYPE_CHECK(objDict); dict->remove(key); }

inline GBool Object::dictIs(const char *dictType) const
  { OBJECT_TYPE_CHECK(objDict); return dict->is(dictType); }

inline GBool Object::isDict(const char *dictType) const
  { return type == objDict && dictIs(dictType); }

inline Object Object::dictLookup(const char *key, int recursion) const
  { OBJECT_TYPE_CHECK(objDict); return dict->lookup(key, recursion); }

inline Object Object::dictLookupNF(const char *key) const
  { OBJECT_TYPE_CHECK(objDict); return dict->lookupNF(key); }

inline const char *Object::dictGetKey(int i) const
  { OBJECT_TYPE_CHECK(objDict); return dict->getKey(i); }

inline Object Object::dictGetVal(int i) const
  { OBJECT_TYPE_CHECK(objDict); return dict->getVal(i); }

inline Object Object::dictGetValNF(int i) const
  { OBJECT_TYPE_CHECK(objDict); return dict->getValNF(i); }

//------------------------------------------------------------------------
// Stream accessors.
//------------------------------------------------------------------------

#include "Stream.h"

inline GBool Object::streamIs(char *dictType) const
  { OBJECT_TYPE_CHECK(objStream); return stream->getDict()->is(dictType); }

inline GBool Object::isStream(char *dictType) const
  { return type == objStream && streamIs(dictType); }

inline void Object::streamReset()
  { OBJECT_TYPE_CHECK(objStream); stream->reset(); }

inline void Object::streamClose()
  { OBJECT_TYPE_CHECK(objStream); stream->close(); }

inline int Object::streamGetChar() const
  { OBJECT_TYPE_CHECK(objStream); return stream->getChar(); }

inline int Object::streamGetChars(int nChars, Guchar *buffer) const
  { OBJECT_TYPE_CHECK(objStream); return stream->doGetChars(nChars, buffer); }

inline int Object::streamLookChar() const
  { OBJECT_TYPE_CHECK(objStream); return stream->lookChar(); }

inline char *Object::streamGetLine(char *buf, int size) const
  { OBJECT_TYPE_CHECK(objStream); return stream->getLine(buf, size); }

inline Goffset Object::streamGetPos() const
  { OBJECT_TYPE_CHECK(objStream); return stream->getPos(); }

inline void Object::streamSetPos(Goffset pos, int dir)
  { OBJECT_TYPE_CHECK(objStream); stream->setPos(pos, dir); }

inline Dict *Object::streamGetDict() const
  { OBJECT_TYPE_CHECK(objStream); return stream->getDict(); }

#endif
