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>
66 std::string transport = GetTransport(url);
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" ||
75 transport ==
"root" || transport ==
"roots" ) {
76 std::string plgclass = transport.compare( 0, 4,
"http" ) == 0 ?
77 "RRawFileDavix" :
"RRawFileNetXNG";
79 FindHandler(
"ROOT::Internal::RRawFile", std::string(url).c_str())) {
80 if (
h->LoadPlugin() == 0) {
81 return std::unique_ptr<RRawFile>(
reinterpret_cast<RRawFile *
>(
h->ExecPlugin(2, &url, &options)));
83 throw std::runtime_error(
"Cannot load plugin handler for " + plgclass);
85 throw std::runtime_error(
"Cannot find plugin handler for " + plgclass);
87 throw std::runtime_error(
"Unsupported transport protocol: " + transport);
101 for (
unsigned i = 0; i < nReq; ++i) {
108 auto idx = url.find(kTransportSeparator);
109 if (idx == std::string_view::npos)
110 return std::string(url);
111 return std::string(url.substr(idx + strlen(kTransportSeparator)));
116 if (fFileSize != kUnknownFileSize)
120 fFileSize = GetSizeImpl();
130 auto idx = url.find(kTransportSeparator);
131 if (idx == std::string_view::npos)
133 std::string transport(url.substr(0, idx));
134 std::transform(transport.begin(), transport.end(), transport.begin(), ::tolower);
140 size_t res = ReadAt(buffer, nbytes, fFilePos);
154 if (!fIsBuffering || nbytes >
static_cast<unsigned int>(fOptions.fBlockSize))
155 return ReadAtImpl(buffer, nbytes,
offset);
158 fBufferSpace.reset(
new unsigned char[kNumBlockBuffers * fOptions.fBlockSize]);
159 for (
unsigned int i = 0; i < kNumBlockBuffers; ++i) {
160 fBlockBuffers[i].fBuffer = fBufferSpace.get() + i * fOptions.fBlockSize;
161 fBlockBuffers[i].fBufferSize = 0;
165 size_t totalBytes = 0;
166 size_t copiedBytes = 0;
168 for (
unsigned int idx = fBlockBufferIdx; idx < fBlockBufferIdx + kNumBlockBuffers; ++idx) {
169 copiedBytes = fBlockBuffers[idx % kNumBlockBuffers].CopyTo(buffer, nbytes,
offset);
170 buffer =
reinterpret_cast<unsigned char *
>(buffer) + copiedBytes;
171 nbytes -= copiedBytes;
173 totalBytes += copiedBytes;
175 fBlockBufferIdx = idx;
184 RBlockBuffer *thisBuffer = &fBlockBuffers[fBlockBufferIdx % kNumBlockBuffers];
185 size_t res = ReadAtImpl(thisBuffer->
fBuffer, fOptions.fBlockSize,
offset);
188 size_t remainingBytes = std::min(res, nbytes);
189 memcpy(buffer, thisBuffer->
fBuffer, remainingBytes);
190 totalBytes += remainingBytes;
197 ReadVImpl(ioVec, nReq);
202 fIsBuffering =
value;
204 fBufferSpace.reset();
209 if (fOptions.fLineBreak == ELineBreaks::kAuto) {
211 fOptions.fLineBreak = ELineBreaks::kUnix;
212 bool res = Readln(
line);
213 if ((
line.length() > 0) && (*
line.rbegin() ==
'\r')) {
214 fOptions.fLineBreak = ELineBreaks::kWindows;
221 char buffer[kLineBuffer];
224 nbytes = Read(buffer,
sizeof(buffer));
225 std::string_view bufferView(buffer, nbytes);
226 auto idx = bufferView.find(kLineBreakTokens[
static_cast<int>(fOptions.fLineBreak)]);
227 if (idx != std::string_view::npos) {
229 line.append(buffer, idx);
230 fFilePos -= nbytes - idx;
231 fFilePos += kLineBreakTokenSizes[
static_cast<int>(fOptions.fLineBreak)];
234 line.append(buffer, nbytes);
235 }
while (nbytes > 0);
237 return !
line.empty();
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 offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
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.
The RRawFile provides read-only access to local and remote files.
static std::string GetLocation(std::string_view url)
Returns only the file location, e.g. "server/file" for http://server/file.
RRawFile(std::string_view url, ROptions options)
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.
std::uint64_t GetSize()
Returns the size of the file.
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.
size_t ReadAt(void *buffer, size_t nbytes, std::uint64_t offset)
Buffered read from a random position.
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.
void ReadV(RIOVec *ioVec, unsigned int nReq)
Opens the file if necessary and calls ReadVImpl.
size_t Read(void *buffer, size_t nbytes)
Read from fFilePos offset. Returns the actual number of bytes read.
void SetBuffering(bool value)
Turn off buffered reads; all scalar read requests go directly to the implementation.
std::string GetUrl() const
Returns the url of the file.
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.