34const char *kTransportSeparator =
"://";
37const char *kLineBreakTokens[] = {
"",
"\r\n",
"\n",
"\r\n"};
38constexpr unsigned int kLineBreakTokenSizes[] = {0, 2, 1, 2};
40const char *kLineBreakTokens[] = {
"",
"\n",
"\n",
"\r\n"};
41constexpr unsigned int kLineBreakTokenSizes[] = {0, 1, 1, 2};
43constexpr unsigned int kLineBuffer = 128;
51 size_t copiedBytes = 0;
53 if (offsetInBuffer <
static_cast<std::uint64_t
>(
fBufferSize)) {
54 size_t bytesInBuffer = std::min(nbytes,
static_cast<size_t>(
fBufferSize - offsetInBuffer));
55 memcpy(buffer,
fBuffer + offsetInBuffer, bytesInBuffer);
56 copiedBytes = bytesInBuffer;
63std::unique_ptr<ROOT::Internal::RRawFile>
67 if (transport ==
"file") {
69 return std::unique_ptr<RRawFile>(
new RRawFileWin(url, options));
71 return std::unique_ptr<RRawFile>(
new RRawFileUnix(url, options));
74 if (transport ==
"http" || transport ==
"https" || transport ==
"root" || transport ==
"roots") {
75 std::string plgclass = transport.compare(0, 4,
"http") == 0 ?
"RRawFileDavix" :
"RRawFileNetXNG";
77 gROOT->GetPluginManager()->FindHandler(
"ROOT::Internal::RRawFile", std::string(url).c_str())) {
78 if (
h->LoadPlugin() == 0) {
79 return std::unique_ptr<RRawFile>(
reinterpret_cast<RRawFile *
>(
h->ExecPlugin(2, &url, &options)));
81 throw std::runtime_error(
"Cannot load plugin handler for " + plgclass);
83 throw std::runtime_error(
"Cannot find plugin handler for " + plgclass);
85 throw std::runtime_error(
"Unsupported transport protocol: " + transport);
100 for (
unsigned i = 0; i < nReq; ++i) {
107 auto idx = url.find(kTransportSeparator);
108 if (idx == std::string_view::npos)
109 return std::string(url);
110 return std::string(url.substr(idx + strlen(kTransportSeparator)));
129 auto idx = url.find(kTransportSeparator);
130 if (idx == std::string_view::npos)
132 std::string transport(url.substr(0, idx));
133 std::transform(transport.begin(), transport.end(), transport.begin(), ::tolower);
164 size_t totalBytes = 0;
165 size_t copiedBytes = 0;
169 buffer =
reinterpret_cast<unsigned char *
>(buffer) + copiedBytes;
170 nbytes -= copiedBytes;
171 offset += copiedBytes;
172 totalBytes += copiedBytes;
187 size_t remainingBytes = std::min(res, nbytes);
188 memcpy(buffer, thisBuffer->
fBuffer, remainingBytes);
189 totalBytes += remainingBytes;
214 if ((
line.length() > 0) && (*
line.rbegin() ==
'\r')) {
222 char buffer[kLineBuffer];
225 nbytes =
Read(buffer,
sizeof(buffer));
226 std::string_view bufferView(buffer, nbytes);
227 auto idx = bufferView.find(kLineBreakTokens[
static_cast<int>(
fOptions.fLineBreak)]);
228 if (idx != std::string_view::npos) {
230 line.append(buffer, idx);
235 line.append(buffer, nbytes);
236 }
while (nbytes > 0);
238 return !
line.empty();
The RRawFileUnix class uses POSIX calls to read from a mounted file system.
The RRawFileWin class uses portable C I/O calls to read from a drive.
virtual std::uint64_t GetSizeImpl()=0
Derived classes should return the file size.
static std::string GetLocation(std::string_view url)
Returns only the file location, e.g. "server/file" for http://server/file.
unsigned int fBlockBufferIdx
To be used modulo kNumBlockBuffers, points to the last used block buffer in fBlockBuffers.
RRawFile(std::string_view url, ROptions options)
std::uint64_t fFilePos
The current position in the file, which can be changed by Seek, Read, and Readln.
virtual void ReadVImpl(RIOVec *ioVec, unsigned int nReq)
By default implemented as a loop of ReadAt calls but can be overwritten, e.g. XRootD or DAVIX impleme...
static std::string GetTransport(std::string_view url)
Returns only the transport protocol in lower case, e.g. "http" for HTTP://server/file.
static constexpr unsigned int kNumBlockBuffers
Don't change without adapting ReadAt().
std::uint64_t GetSize()
Returns the size of the file.
bool fIsBuffering
Runtime switch to decide if reads are buffered or directly sent to ReadAtImpl().
static std::unique_ptr< RRawFile > Create(std::string_view url, ROptions options=ROptions())
Factory method that returns a suitable concrete implementation according to the transport in the url.
void Seek(std::uint64_t offset)
Change the cursor fFilePos.
static constexpr std::uint64_t kUnknownFileSize
Used as a marker that the file size was not yet queried.
size_t ReadAt(void *buffer, size_t nbytes, std::uint64_t offset)
Buffered read from a random position.
bool fIsOpen
Files are opened lazily and only when required; the open state is kept by this flag.
virtual size_t ReadAtImpl(void *buffer, size_t nbytes, std::uint64_t offset)=0
Derived classes should implement low-level reading without buffering.
bool Readln(std::string &line)
Read the next line starting from the current value of fFilePos. Returns false if the end of the file ...
void EnsureOpen()
Open the file if not already open. Otherwise noop.
virtual void SetDiscourageReadAheadImpl(bool)
std::unique_ptr< unsigned char[]> fBufferSpace
Memory block containing the block buffers consecutively.
void ReadV(RIOVec *ioVec, unsigned int nReq)
Opens the file if necessary and calls ReadVImpl.
virtual void OpenImpl()=0
OpenImpl() is called at most once and before any call to either DoReadAt or DoGetSize.
size_t Read(void *buffer, size_t nbytes)
Read from fFilePos offset. Returns the actual number of bytes read.
void SetBuffering(bool value)
Turn on/off buffered reads; if off, all scalar read requests go directly to the implementation.
std::string GetUrl() const
Returns the url of the file.
std::uint64_t fFileSize
The cached file size.
RBlockBuffer fBlockBuffers[kNumBlockBuffers]
An active buffer and a shadow buffer, which supports "jumping back" to a previously used location in ...
std::uint64_t fBufferOffset
Where in the open file does fBuffer start.
unsigned char * fBuffer
Points into the I/O buffer with data from the file, not owned.
size_t CopyTo(void *buffer, size_t nbytes, std::uint64_t offset)
Tries to copy up to nbytes starting at offset from fBuffer into buffer. Returns number of bytes copie...
size_t fBufferSize
The number of currently buffered bytes in fBuffer.
Used for vector reads from multiple offsets into multiple buffers.
std::size_t fOutBytes
The number of actually read bytes, set by ReadV().
On construction, an ROptions parameter can customize the RRawFile behavior.