// 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(this);
}

RetainPtr<const CPDF_Object> CPDF_Object::GetDirect() const {
  return const_cast<CPDF_Object*>(this)->GetMutableDirect();
}

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());
}
