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

#ifndef CORE_FPDFAPI_PARSER_CPDF_STREAM_H_
#define CORE_FPDFAPI_PARSER_CPDF_STREAM_H_

#include <memory>
#include <set>
#include <sstream>

#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_object.h"
#include "core/fxcrt/fx_stream.h"

class CPDF_Stream : public CPDF_Object {
 public:
  CPDF_Stream();

  // Takes ownership of |pData|.
  CPDF_Stream(std::unique_ptr<uint8_t, FxFreeDeleter> pData,
              uint32_t size,
              std::unique_ptr<CPDF_Dictionary> pDict);

  ~CPDF_Stream() override;

  // CPDF_Object:
  Type GetType() const override;
  std::unique_ptr<CPDF_Object> Clone() const override;
  CPDF_Dictionary* GetDict() const override;
  CFX_WideString GetUnicodeText() const override;
  bool IsStream() const override;
  CPDF_Stream* AsStream() override;
  const CPDF_Stream* AsStream() const override;
  bool WriteTo(IFX_ArchiveStream* archive) const override;

  uint32_t GetRawSize() const { return m_dwSize; }
  uint8_t* GetRawData() const { return m_pDataBuf.get(); }

  // Does not takes ownership of |pData|, copies into internally-owned buffer.
  void SetData(const uint8_t* pData, uint32_t size);
  void SetData(std::unique_ptr<uint8_t, FxFreeDeleter> pData, uint32_t size);
  void SetData(std::ostringstream* stream);
  // Set data and remove "Filter" and "DecodeParms" fields from stream
  // dictionary.
  void SetDataAndRemoveFilter(const uint8_t* pData, uint32_t size);
  void SetDataAndRemoveFilter(std::ostringstream* stream);

  void InitStream(const uint8_t* pData,
                  uint32_t size,
                  std::unique_ptr<CPDF_Dictionary> pDict);
  void InitStreamFromFile(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
                          std::unique_ptr<CPDF_Dictionary> pDict);

  bool ReadRawData(FX_FILESIZE start_pos,
                   uint8_t* pBuf,
                   uint32_t buf_size) const;

  bool IsMemoryBased() const { return m_bMemoryBased; }
  bool HasFilter() const;

 protected:
  std::unique_ptr<CPDF_Object> CloneNonCyclic(
      bool bDirect,
      std::set<const CPDF_Object*>* pVisited) const override;

  bool m_bMemoryBased = true;
  uint32_t m_dwSize = 0;
  std::unique_ptr<CPDF_Dictionary> m_pDict;
  std::unique_ptr<uint8_t, FxFreeDeleter> m_pDataBuf;
  CFX_RetainPtr<IFX_SeekableReadStream> m_pFile;
};

inline CPDF_Stream* ToStream(CPDF_Object* obj) {
  return obj ? obj->AsStream() : nullptr;
}

inline const CPDF_Stream* ToStream(const CPDF_Object* obj) {
  return obj ? obj->AsStream() : nullptr;
}

inline std::unique_ptr<CPDF_Stream> ToStream(std::unique_ptr<CPDF_Object> obj) {
  CPDF_Stream* pStream = ToStream(obj.get());
  if (!pStream)
    return nullptr;
  obj.release();
  return std::unique_ptr<CPDF_Stream>(pStream);
}

#endif  // CORE_FPDFAPI_PARSER_CPDF_STREAM_H_
