Skip to content

Commit f5e893e

Browse files
committed
[net] add basic TCurlFile implementation
1 parent e443855 commit f5e893e

File tree

4 files changed

+113
-2
lines changed

4 files changed

+113
-2
lines changed

net/curl/inc/LinkDef.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
#ifdef __CLING__
22

3+
#pragma link C++ class TCurlFile+;
4+
35
#endif

net/curl/inc/TCurlFile.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@
1212
#ifndef ROOT_TCurlFile
1313
#define ROOT_TCurlFile
1414

15+
#include "ROOT/RCurlConnection.hxx"
1516
#include "TFile.h"
1617

18+
#include <memory>
19+
1720
class TCurlFile : public TFile {
21+
std::unique_ptr<ROOT::Internal::RCurlConnection> fConnection;
22+
1823
public:
1924
TCurlFile(const char *url, Option_t *option = "");
2025

net/curl/src/TCurlFile.cxx

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,95 @@
1010
*************************************************************************/
1111

1212
#include "TCurlFile.h"
13+
#include "TError.h"
14+
15+
#include <cstdint>
16+
#include <cstring>
17+
#include <vector>
18+
19+
TCurlFile::TCurlFile(const char *url, Option_t *opt)
20+
: TFile(url, strstr(opt, "_WITHOUT_GLOBALREGISTRATION") != nullptr ? "WEB_WITHOUT_GLOBALREGISTRATION" : "WEB"),
21+
fConnection(new ROOT::Internal::RCurlConnection(url))
22+
{
23+
TFile::Init(kFALSE);
24+
fOffset = 0;
25+
fD = -2; // so TFile::IsOpen() will return true when in ~TFile
26+
}
27+
28+
Long64_t TCurlFile::GetSize() const
29+
{
30+
std::uint64_t size;
31+
auto status = fConnection->SendHeadReq(size);
32+
if (!status)
33+
return -1;
34+
return size;
35+
}
36+
37+
void TCurlFile::Seek(Long64_t offset, ERelativeTo pos)
38+
{
39+
switch (pos) {
40+
case kBeg: fOffset = offset + fArchiveOffset; break;
41+
case kCur: fOffset += offset; break;
42+
case kEnd:
43+
// this option is not used currently in the ROOT code
44+
if (fArchiveOffset)
45+
Error("Seek", "seeking from end in archive is not (yet) supported");
46+
fOffset = fEND - offset; // is fEND really EOF or logical EOF?
47+
break;
48+
}
49+
}
50+
51+
Bool_t TCurlFile::ReadBuffer(char *buf, Int_t len)
52+
{
53+
ROOT::Internal::RCurlConnection::RUserRange range;
54+
range.fDestination = reinterpret_cast<unsigned char *>(buf);
55+
range.fOffset = fOffset;
56+
range.fLength = len;
57+
auto status = fConnection->SendRangesReq(1, &range);
58+
if (!status) {
59+
Error("TCurlFile", "can not read data: %s", status.fStatusMsg.c_str());
60+
return kTRUE;
61+
}
62+
63+
fOffset += range.fNBytesRecv;
64+
return kFALSE;
65+
}
66+
67+
Bool_t TCurlFile::ReadBuffer(char *buf, Long64_t pos, Int_t len)
68+
{
69+
ROOT::Internal::RCurlConnection::RUserRange range;
70+
range.fDestination = reinterpret_cast<unsigned char *>(buf);
71+
range.fOffset = pos;
72+
range.fLength = len;
73+
auto status = fConnection->SendRangesReq(1, &range);
74+
if (!status) {
75+
Error("TCurlFile", "can not read data: %s", status.fStatusMsg.c_str());
76+
return kTRUE;
77+
}
78+
return kFALSE;
79+
}
80+
81+
Bool_t TCurlFile::ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
82+
{
83+
if (nbuf == 0)
84+
return kFALSE;
85+
86+
std::vector<ROOT::Internal::RCurlConnection::RUserRange> ranges;
87+
ranges.reserve(nbuf);
88+
std::size_t bufPos = 0;
89+
for (Int_t i = 0; i < nbuf; ++i) {
90+
ROOT::Internal::RCurlConnection::RUserRange r;
91+
r.fDestination = reinterpret_cast<unsigned char *>(&buf[bufPos]);
92+
r.fOffset = pos[i];
93+
r.fLength = len[i];
94+
ranges.emplace_back(r);
95+
bufPos += len[i];
96+
}
97+
98+
auto status = fConnection->SendRangesReq(nbuf, &ranges[0]);
99+
if (!status) {
100+
Error("TCurlFile", "can not read data: %s", status.fStatusMsg.c_str());
101+
return kTRUE;
102+
}
103+
return kFALSE;
104+
}

net/curl/test/tfile_curl.cxx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
#include "gtest/gtest.h"
22

33
#include "TCurlFile.h"
4+
#include "TObject.h"
5+
6+
#include <memory>
7+
#include <utility>
48

59
TEST(TCurlFile, GetSize)
610
{
7-
// TODO
8-
}
11+
auto f = std::make_unique<TCurlFile>("https://root.cern.ch/files/galaxy.root");
12+
EXPECT_LT(0, f->GetSize());
13+
}
14+
15+
TEST(TCurlFile, Read)
16+
{
17+
auto f = std::make_unique<TCurlFile>("https://root.cern.ch/files/galaxy.root");
18+
auto obj = f->Get("n4254");
19+
EXPECT_TRUE(obj != nullptr);
20+
}

0 commit comments

Comments
 (0)