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

#include "core/fpdfapi/parser/cpdf_object.h"

#include <algorithm>

#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
#include "core/fpdfapi/parser/cpdf_parser.h"
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fxcrt/fx_string.h"
#include "third_party/base/notreached.h"

CPDF_Object::~CPDF_Object() = default;

static_assert(sizeof(uint64_t) >= sizeof(CPDF_Object*),
              "Need a bigger type for cache keys");

static_assert(CPDF_Parser::kMaxObjectNumber < static_cast<uint32_t>(1) << 31,
              "Need a smaller kMaxObjNumber for cache keys");

uint64_t CPDF_Object::KeyForCache() const {
  if (IsInline())
    return (static_cast<uint64_t>(1) << 63) | reinterpret_cast<uint64_t>(this);

  return (static_cast<uint64_t>(m_ObjNum) << 32) |
         static_cast<uint64_t>(m_GenNum);
}

RetainPtr<CPDF_Object> CPDF_Object::GetMutableDirect() {
  return pdfium::WrapRetain(const_cast<CPDF_Object*>(GetDirect()));
}

const CPDF_Object* CPDF_Object::GetDirect() const {
  return this;
}

RetainPtr<CPDF_Object> CPDF_Object::CloneObjectNonCyclic(bool bDirect) const {
  std::set<const CPDF_Object*> visited_objs;
  return CloneNonCyclic(bDirect, &visited_objs);
}

RetainPtr<CPDF_Object> CPDF_Object::CloneDirectObject() const {
  return CloneObjectNonCyclic(true);
}

RetainPtr<CPDF_Object> CPDF_Object::CloneNonCyclic(
    bool bDirect,
    std::set<const CPDF_Object*>* pVisited) const {
  return Clone();
}

ByteString CPDF_Object::GetString() const {
  return ByteString();
}

WideString CPDF_Object::GetUnicodeText() const {
  return WideString();
}

float CPDF_Object::GetNumber() const {
  return 0;
}

int CPDF_Object::GetInteger() const {
  return 0;
}

RetainPtr<CPDF_Dictionary> CPDF_Object::GetMutableDict() {
  return pdfium::WrapRetain(const_cast<CPDF_Dictionary*>(GetDict()));
}

const CPDF_Dictionary* CPDF_Object::GetDict() const {
  return nullptr;
}

void CPDF_Object::SetString(const ByteString& str) {
  NOTREACHED();
}

CPDF_Array* CPDF_Object::AsMutableArray() {
  return nullptr;
}

const CPDF_Array* CPDF_Object::AsArray() const {
  return const_cast<CPDF_Object*>(this)->AsMutableArray();
}

CPDF_Boolean* CPDF_Object::AsMutableBoolean() {
  return nullptr;
}

const CPDF_Boolean* CPDF_Object::AsBoolean() const {
  return const_cast<CPDF_Object*>(this)->AsMutableBoolean();
}

CPDF_Dictionary* CPDF_Object::AsMutableDictionary() {
  return nullptr;
}

const CPDF_Dictionary* CPDF_Object::AsDictionary() const {
  return const_cast<CPDF_Object*>(this)->AsMutableDictionary();
}

CPDF_Name* CPDF_Object::AsMutableName() {
  return nullptr;
}

const CPDF_Name* CPDF_Object::AsName() const {
  return const_cast<CPDF_Object*>(this)->AsMutableName();
}

CPDF_Null* CPDF_Object::AsMutableNull() {
  return nullptr;
}

const CPDF_Null* CPDF_Object::AsNull() const {
  return const_cast<CPDF_Object*>(this)->AsMutableNull();
}

CPDF_Number* CPDF_Object::AsMutableNumber() {
  return nullptr;
}

const CPDF_Number* CPDF_Object::AsNumber() const {
  return const_cast<CPDF_Object*>(this)->AsMutableNumber();
}

CPDF_Reference* CPDF_Object::AsMutableReference() {
  return nullptr;
}

const CPDF_Reference* CPDF_Object::AsReference() const {
  return const_cast<CPDF_Object*>(this)->AsMutableReference();
}

CPDF_Stream* CPDF_Object::AsMutableStream() {
  return nullptr;
}

const CPDF_Stream* CPDF_Object::AsStream() const {
  return const_cast<CPDF_Object*>(this)->AsMutableStream();
}

CPDF_String* CPDF_Object::AsMutableString() {
  return nullptr;
}

const CPDF_String* CPDF_Object::AsString() const {
  return const_cast<CPDF_Object*>(this)->AsMutableString();
}

RetainPtr<CPDF_Reference> CPDF_Object::MakeReference(
    CPDF_IndirectObjectHolder* holder) const {
  if (IsInline()) {
    NOTREACHED();
    return nullptr;
  }
  return pdfium::MakeRetain<CPDF_Reference>(holder, GetObjNum());
}
