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;
69 delete[] fBufferSpace;
72std::unique_ptr<ROOT::Internal::RRawFile>
75 std::string transport = GetTransport(url);
76 if (transport ==
"file") {
78 return std::unique_ptr<RRawFile>(
new RRawFileWin(url, options));
80 return std::unique_ptr<RRawFile>(
new RRawFileUnix(url, options));
83 if (transport ==
"http" || transport ==
"https" ||
84 transport ==
"root" || transport ==
"roots" ) {
85 std::string plgclass = transport.compare( 0, 4,
"http" ) == 0 ?
86 "RRawFileDavix" :
"RRawFileNetXNG";
88 FindHandler(
"ROOT::Internal::RRawFile", std::string(url).c_str())) {
89 if (
h->LoadPlugin() == 0) {
90 return std::unique_ptr<RRawFile>(
reinterpret_cast<RRawFile *
>(
h->ExecPlugin(2, &url, &options)));
92 throw std::runtime_error(
"Cannot load plugin handler for " + plgclass);
94 throw std::runtime_error(
"Cannot find plugin handler for " + plgclass);
96 throw std::runtime_error(
"Unsupported transport protocol: " + transport);
111 throw std::runtime_error(
"Memory mapping unsupported");
116 for (
unsigned i = 0; i < nReq; ++i) {
123 throw std::runtime_error(
"Memory mapping unsupported");
128 auto idx = url.find(kTransportSeparator);
129 if (idx == std::string_view::npos)
130 return std::string(url);
131 return std::string(url.substr(idx + strlen(kTransportSeparator)));
136 if (fFileSize != kUnknownFileSize)
140 fFileSize = GetSizeImpl();
150 auto idx = url.find(kTransportSeparator);
151 if (idx == std::string_view::npos)
153 std::string transport(url.substr(0, idx));
154 std::transform(transport.begin(), transport.end(), transport.begin(), ::tolower);
161 return MapImpl(nbytes,
offset, mapdOffset);
166 size_t res = ReadAt(buffer, nbytes, fFilePos);
177 if (nbytes >
static_cast<unsigned int>(fOptions.fBlockSize))
178 return ReadAtImpl(buffer, nbytes,
offset);
180 if (fBufferSpace ==
nullptr) {
181 fBufferSpace =
new unsigned char[kNumBlockBuffers * fOptions.fBlockSize];
182 for (
unsigned int i = 0; i < kNumBlockBuffers; ++i)
183 fBlockBuffers[i].
fBuffer = fBufferSpace + i * fOptions.fBlockSize;
186 size_t totalBytes = 0;
187 size_t copiedBytes = 0;
189 for (
unsigned int idx = fBlockBufferIdx; idx < fBlockBufferIdx + kNumBlockBuffers; ++idx) {
190 copiedBytes = fBlockBuffers[idx % kNumBlockBuffers].CopyTo(buffer, nbytes,
offset);
191 buffer =
reinterpret_cast<unsigned char *
>(buffer) + copiedBytes;
192 nbytes -= copiedBytes;
194 totalBytes += copiedBytes;
196 fBlockBufferIdx = idx;
205 RBlockBuffer *thisBuffer = &fBlockBuffers[fBlockBufferIdx % kNumBlockBuffers];
206 size_t res = ReadAtImpl(thisBuffer->
fBuffer, fOptions.fBlockSize,
offset);
209 size_t remainingBytes = std::min(res, nbytes);
210 memcpy(buffer, thisBuffer->
fBuffer, remainingBytes);
211 totalBytes += remainingBytes;
218 ReadVImpl(ioVec, nReq);
223 if (fOptions.fLineBreak == ELineBreaks::kAuto) {
225 fOptions.fLineBreak = ELineBreaks::kUnix;
226 bool res = Readln(
line);
227 if ((
line.length() > 0) && (*
line.rbegin() ==
'\r')) {
228 fOptions.fLineBreak = ELineBreaks::kWindows;
235 char buffer[kLineBuffer];
238 nbytes = Read(buffer,
sizeof(buffer));
239 std::string_view bufferView(buffer, nbytes);
240 auto idx = bufferView.find(kLineBreakTokens[
static_cast<int>(fOptions.fLineBreak)]);
241 if (idx != std::string_view::npos) {
243 line.append(buffer, idx);
244 fFilePos -= nbytes - idx;
245 fFilePos += kLineBreakTokenSizes[
static_cast<int>(fOptions.fLineBreak)];
248 line.append(buffer, nbytes);
249 }
while (nbytes > 0);
251 return !
line.empty();
262 throw std::runtime_error(
"Cannot unmap, file not open");
263 UnmapImpl(region, nbytes);
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
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.
unsigned char * fBufferSpace
Memory block containing the block buffers consecutively.
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 * MapImpl(size_t nbytes, std::uint64_t offset, std::uint64_t &mapdOffset)
If a derived class supports mmap, the MapImpl and UnmapImpl calls are supposed to be implemented,...
void Unmap(void *region, size_t nbytes)
Receives a pointer returned by Map() and should have nbytes set to the full length of the mapping.
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.
static constexpr std::uint64_t kUnknownFileSize
Derived classes do not necessarily need to provide file size information but they can return "not kno...
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.
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.
std::string GetUrl() const
Returns the url of the file.
std::uint64_t fFileSize
The cached file size.
virtual void UnmapImpl(void *region, size_t nbytes)
Derived classes with mmap support must be able to unmap the memory area handed out by Map()
void * Map(size_t nbytes, std::uint64_t offset, std::uint64_t &mapdOffset)
Memory mapping according to POSIX standard; in particular, new mappings of the same range replace old...
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.