34enum class ENameCycleError {
43struct RNameCycleResult {
45 std::optional<std::int16_t> fCycle;
46 ENameCycleError fError;
50static const char *
ToString(ENameCycleError err)
52 static const char *
const kErrorStr[] = {
"",
"",
"invalid syntax",
"cycle is too large",
"name is empty"};
53 static_assert(std::size(
kErrorStr) ==
static_cast<std::size_t
>(ENameCycleError::kCOUNT));
54 return kErrorStr[
static_cast<std::size_t
>(err)];
62 return ENameCycleError::kInvalidSyntax;
63 if (res * 10 > std::numeric_limits<std::int16_t>::max())
64 return ENameCycleError::kCycleTooLarge;
69 assert(res < std::numeric_limits<std::int16_t>::max());
70 out =
static_cast<std::int16_t
>(res);
72 return ENameCycleError::kNoError;
86 result.fError = ENameCycleError::kNameEmpty;
92 result.fError = ENameCycleError::kInvalidSyntax;
99 result.fError = ENameCycleError::kAnyCycle;
133 return "path cannot be empty";
135 if (path.back() ==
'/')
136 return "path cannot end with a '/'";
139 for (
char ch : path) {
142 valid &= !(ch < 33 || ch ==
'.');
145 return "path cannot contain control characters, whitespaces or dots";
152 const auto len = path.length();
161 const auto it = std::unique(path.begin(), path.end(), [](
char a,
char b) { return (a ==
'/' && b ==
'/'); });
162 path.erase(it, path.end());
165 const auto nesting = std::count(path.begin(), path.end(),
'/');
166 if (
nesting > RFile::kMaxPathNesting)
167 return "pathView contains too many levels of nesting";
183 std::string path = key.
GetName();
186 path = std::string(parent->
GetName()) +
"/" + path;
204std::unique_ptr<RFile> RFile::Open(std::string_view path)
207 auto tfile = std::unique_ptr<TFile>(
TFile::Open(std::string(path).c_str(),
"READ_WITHOUT_GLOBALREGISTRATION"));
210 auto rfile = std::unique_ptr<RFile>(
new RFile(std::move(tfile)));
217 auto tfile = std::unique_ptr<TFile>(
TFile::Open(std::string(path).c_str(),
"UPDATE_WITHOUT_GLOBALREGISTRATION"));
220 auto rfile = std::unique_ptr<RFile>(
new RFile(std::move(tfile)));
227 auto tfile = std::unique_ptr<TFile>(
TFile::Open(std::string(path).c_str(),
"RECREATE_WITHOUT_GLOBALREGISTRATION"));
230 auto rfile = std::unique_ptr<RFile>(
new RFile(std::move(tfile)));
243 std::string
fullPath = std::string(path);
271 if (res.fError != ENameCycleError::kAnyCycle) {
272 if (res.fError != ENameCycleError::kNoError) {
275 }
else if (res.fCycle && *res.fCycle != key->
GetCycle()) {
284 std::variant<
const char *, std::reference_wrapper<const std::type_info>>
type)
const
312 R__LOG_INFO(RFileLog()) <<
"Tried to get object '" << path <<
"' of type " <<
cls->GetName()
313 <<
" but that path contains an object of type " << key->
GetClassName();
329 if (path.find_first_of(
';') != std::string_view::npos) {
331 R__FAIL(
"Invalid object path '" + path +
332 "': character ';' is used to specify an object cycle, which only makes sense when reading."));
338 if (!
fFile->IsWritable())
349 return ROOT::Join(
"/", std::span<const std::string>{
tokens.data(), idx + 1});
377 existing->GetClassName() +
" with another object of type " +
cls->GetName()));
391 : fIter(it), fDirPath(path)
403 if (!pattern.empty()) {
436 while (!fIterStack.empty()) {
437 auto &[iter,
dirPath] = fIterStack.back();
442 fIterStack.pop_back();
465 assert(!fIterStack.empty());
466 const std::size_t
nesting = fIterStack.size() - 1;
475 (!
isDir ||
nesting !=
static_cast<std::size_t
>(fRootDirNesting + 1)))
487 if (fIterStack.empty())
490 const TKey *key = fCurKey;
496 const auto &
dirPath = fIterStack.back().fDirPath;
511 std::vector<RKeyInfo> keys;
514 keys.emplace_back(key);
517 std::sort(keys.begin(), keys.end(), [](
const auto &
a,
const auto &
b) { return a.GetPath() < b.GetPath(); });
518 for (
const auto &key : keys) {
519 out << key.GetClassName() <<
" " << key.GetPath() <<
";" << key.GetCycle() <<
": \"" << key.GetTitle() <<
"\"\n";
536 const TKey *key = GetTKey(path);
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
static const char * ToString(ENameCycleError err)
static ENameCycleError DecodeNumericCycle(const char *str, std::optional< std::int16_t > &out)
static void EnsureFileOpenAndBinary(const TFile *tfile, std::string_view path)
static std::string ReconstructFullKeyPath(const TKey &key)
static RNameCycleResult DecodeNameCycle(std::string_view nameCycleRaw)
static std::string ValidateAndNormalizePath(std::string &path)
This function first validates, then normalizes the given path in place.
#define R__LOG_ERROR(...)
const char Option_t
Option string (const char)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
TRObject operator()(const T1 &t1) const
std::uint16_t fRootDirNesting
std::deque< RIterStackElem > fIterStack
RIterator(TIterator *iter, Pattern_t pattern, std::uint32_t flags)
An interface to read from, or write to, a ROOT file, as well as performing other common operations.
void Close()
Flushes the RFile if needed and closes it, disallowing any further reading or writing.
static std::unique_ptr< RFile > Recreate(std::string_view path)
Opens the file for reading/writing, overwriting it if it already exists.
std::unique_ptr< TFile > fFile
size_t Flush()
Writes all objects and the file structure to disk.
static std::unique_ptr< RFile > Update(std::string_view path)
Opens the file for updating, creating a new one if it doesn't exist.
void Print(std::ostream &out=std::cout) const
Prints the internal structure of this RFile to the given stream.
TKey * GetTKey(std::string_view path) const
Given path, returns the TKey corresponding to the object at that path (assuming the path is fully spl...
std::optional< RKeyInfo > GetKeyInfo(std::string_view path) const
Retrieves information about the key of object at path, if one exists.
void * GetUntyped(std::string_view path, std::variant< const char *, std::reference_wrapper< const std::type_info > > type) const
Gets object path from the file and returns an owning pointer to it.
void PutUntyped(std::string_view path, const std::type_info &type, const void *obj, std::uint32_t flags)
Writes obj to file, without taking its ownership.
@ kPutOverwriteKeepCycle
When overwriting an object, preserve the existing one and create a new cycle, rather than removing it...
@ kPutAllowOverwrite
When encountering an object at the specified path, overwrite it with the new one instead of erroring ...
RFile(std::unique_ptr< TFile > file)
Information about an RFile object's Key.
const std::string & GetClassName() const
const std::string & GetPath() const
Returns the absolute path of this key, i.e. the directory part plus the object name.
Base class for all ROOT issued exceptions.
A log configuration for a channel, e.g.
TClass instances represent classes, structs and namespaces in the ROOT type system.
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
TList * GetListOfKeys() const override
TDirectory::TContext keeps track and restore the current directory.
Describe directory structure in memory.
virtual TDirectory * GetDirectory(const char *namecycle, Bool_t printError=false, const char *funcname="GetDirectory")
Find a directory using apath.
virtual Int_t WriteObjectAny(const void *, const char *, const char *, Option_t *="", Int_t=0)
virtual TKey * GetKey(const char *, Short_t=9999) const
virtual TKey * FindKey(const char *) const
virtual TDirectory * mkdir(const char *name, const char *title="", Bool_t returnExistingDirectory=kFALSE)
Create a sub-directory "a" or a hierarchy of sub-directories "a/b/c/...".
virtual TList * GetListOfKeys() const
TDirectory * GetMotherDir() const
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
Int_t Write(const char *name=nullptr, Int_t opt=0, Int_t bufsize=0) override
Write memory objects to this file.
virtual Bool_t IsArchive() const
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Iterator abstract base class.
Book space in a file, create I/O buffers, to fill them, (un)compress them.
const char * GetTitle() const override
Returns title (title can contain 32x32 xpm thumbnail/icon).
virtual const char * GetClassName() const
virtual void * ReadObjectAny(const TClass *expectedClass)
To read an object (non deriving from TObject) from the file.
TDirectory * GetMotherDir() const
Short_t GetCycle() const
Return cycle number associated to this key.
TIterator * MakeIterator(Bool_t dir=kIterForward) const override
Return a list iterator.
const char * GetName() const override
Returns name of object.
Mother of all ROOT objects.
R__ALWAYS_INLINE Bool_t IsZombie() const
std::pair< std::string_view, std::string_view > DecomposePath(std::string_view path)
Given a "path-like" string (like foo/bar/baz), returns a pair { dirName, baseName }.
ROOT::RLogChannel & RFileLog()
void * RFile_GetObjectFromKey(RFile &file, const RKeyInfo &key)
Returns an owning pointer to the object referenced by key.
std::string Join(const std::string &sep, StringCollection_t &&strings)
Concatenate a list of strings with a separator.
bool StartsWith(std::string_view string, std::string_view prefix)
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
RIterStackElem(TIterator *it, const std::string &path="")