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

#include <cassert>
#include <set>
#include <stdio.h>
#include <string.h>
#include <limits.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

  static constexpr Ref INVALID() { return {-1, -1}; };
};

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 {
  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
};

constexpr int numObjTypes = 16;		// total number of object types

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

class Object {
public:
  Object() : type(objNone) {}
  ~Object() { free(); }

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

  template<typename T> Object(T) = delete;

  Object(Object&& other)
  {
    std::memcpy(reinterpret_cast<void*>(this), &other, sizeof(Object));
    other.type = objDead;
  }

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

    std::memcpy(reinterpret_cast<void*>(this), &other, sizeof(Object));
    other.type = objDead;

    return *this;
  }

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

  // Set object to null.
  void setToNull() { free(); type = 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; }
  bool isBool() const { CHECK_NOT_DEAD; return type == objBool; }
  bool isInt() const { CHECK_NOT_DEAD; return type == objInt; }
  bool isReal() const { CHECK_NOT_DEAD; return type == objReal; }
  bool isNum() const { CHECK_NOT_DEAD; return type == objInt || type == objReal || type == objInt64; }
  bool isString() const { CHECK_NOT_DEAD; return type == objString; }
  bool isName() const { CHECK_NOT_DEAD; return type == objName; }
  bool isNull() const { CHECK_NOT_DEAD; return type == objNull; }
  bool isArray() const { CHECK_NOT_DEAD; return type == objArray; }
  bool isDict() const { CHECK_NOT_DEAD; return type == objDict; }
  bool isStream() const { CHECK_NOT_DEAD; return type == objStream; }
  bool isRef() const { CHECK_NOT_DEAD; return type == objRef; }
  bool isCmd() const { CHECK_NOT_DEAD; return type == objCmd; }
  bool isError() const { CHECK_NOT_DEAD; return type == objError; }
  bool isEOF() const { CHECK_NOT_DEAD; return type == objEOF; }
  bool isNone() const { CHECK_NOT_DEAD; return type == objNone; }
  bool isInt64() const { CHECK_NOT_DEAD; return type == objInt64; }
  bool isIntOrInt64() const { CHECK_NOT_DEAD; return type == objInt || type == objInt64; }

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

  // Accessors.
  bool 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; }
  const 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;
  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);
  bool dictIs(const char *dictType) const;
  Object dictLookup(const char *key, int recursion = 0) const;
  const Object &dictLookupNF(const char *key) const;
  const char *dictGetKey(int i) const;
  Object dictGetVal(int i) const;
  const Object &dictGetValNF(int i) const;

  // Stream accessors.
  bool streamIs(const char *dictType) const;
  void streamReset();
  void streamClose();
  int streamGetChar() const;
  int streamGetChars(int nChars, unsigned char *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:
  // Free object contents.
  void free();

  ObjType type;			// object type
  union {			// value for each type:
    bool 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 const 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 bool Object::dictIs(const char *dictType) const
  { OBJECT_TYPE_CHECK(objDict); return dict->is(dictType); }

inline bool 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 const 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 const Object &Object::dictGetValNF(int i) const
  { OBJECT_TYPE_CHECK(objDict); return dict->getValNF(i); }

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

#include "Stream.h"

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

inline bool Object::isStream(const 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, unsigned char *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
