// @(#)root/io:$Id$ // Author: Philippe Canal, May 2011 /************************************************************************* * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #ifndef ROOT_TMemFile #define ROOT_TMemFile #include "TFile.h" #include #include class TMemFile : public TFile { public: using ExternalDataPtr_t = std::shared_ptr>; /// A read-only memory range which we do not control. struct ZeroCopyView_t { const char *fStart; const size_t fSize; explicit ZeroCopyView_t(const char * start, const size_t size) : fStart(start), fSize(size) {} }; protected: struct TMemBlock { private: TMemBlock(const TMemBlock&) = delete; // Not implemented TMemBlock &operator=(const TMemBlock&) = delete; // Not implemented. public: TMemBlock() = default; TMemBlock(Long64_t size, TMemBlock *previous = nullptr); TMemBlock(UChar_t* externalBuffer, Long64_t size); ~TMemBlock(); void CreateNext(Long64_t size); TMemBlock *fPrevious{nullptr}; TMemBlock *fNext{nullptr}; UChar_t *fBuffer{nullptr}; Long64_t fSize{0}; }; TMemBlock fBlockList; ///< Collection of memory blocks of size fgDefaultBlockSize ExternalDataPtr_t fExternalData; ///< shared file data / content Bool_t fIsOwnedByROOT{kFALSE}; ///< if this is a C-style memory region Long64_t fSize{0}; ///< Total file size (sum of the size of the chunks) Long64_t fSysOffset{0}; ///< Seek offset in file TMemBlock *fBlockSeek{nullptr}; ///< Pointer to the block we seeked to. Long64_t fBlockOffset{0}; ///< Seek offset within the block constexpr static Long64_t fgDefaultBlockSize = 2 * 1024 * 1024; Long64_t fDefaultBlockSize = fgDefaultBlockSize; Bool_t IsExternalData() const { return !fIsOwnedByROOT; } Long64_t MemRead(Int_t fd, void *buf, Long64_t len) const; // Overload TFile interfaces. Int_t SysOpen(const char *pathname, Int_t flags, UInt_t mode) override; Int_t SysClose(Int_t fd) override; Int_t SysReadImpl(Int_t fd, void *buf, Long64_t len); Int_t SysWriteImpl(Int_t fd, const void *buf, Long64_t len); Int_t SysRead(Int_t fd, void *buf, Int_t len) override; Int_t SysWrite(Int_t fd, const void *buf, Int_t len) override; Long64_t SysSeek(Int_t fd, Long64_t offset, Int_t whence) override; Int_t SysStat(Int_t fd, Long_t *id, Long64_t *size, Long_t *flags, Long_t *modtime) override; Int_t SysSync(Int_t fd) override; void ResetObjects(TDirectoryFile *, TFileMergeInfo *) const; enum class EMode { kCreate, kRecreate, kUpdate, kRead }; bool NeedsToWrite(EMode mode) const { return mode != EMode::kRead; } bool NeedsExistingFile(EMode mode) const { return mode == EMode::kUpdate || mode == EMode::kRead; } EMode ParseOption(Option_t *option); TMemFile &operator=(const TMemFile&) = delete; // Not implemented. public: TMemFile(const char *name, Option_t *option = "", const char *ftitle = "", Int_t compress = ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Long64_t defBlockSize = 0LL); TMemFile(const char *name, char *buffer, Long64_t size, Option_t *option = "", const char *ftitle = "", Int_t compress = ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Long64_t defBlockSize = 0LL); TMemFile(const char *name, ExternalDataPtr_t data); TMemFile(const char *name, const ZeroCopyView_t &datarange); TMemFile(const char *name, std::unique_ptr buffer); TMemFile(const TMemFile &orig); ~TMemFile() override; virtual Long64_t CopyTo(void *to, Long64_t maxsize) const; virtual void CopyTo(TBuffer &tobuf) const; Long64_t GetSize() const override; void ResetAfterMerge(TFileMergeInfo *) override; void ResetErrno() const override; void Print(Option_t *option="") const override; ClassDefOverride(TMemFile, 0) // A ROOT file that reads/writes on a chunk of memory }; #endif