ATLAS Offline Software
Loading...
Searching...
No Matches
blobaccess.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <iostream>
8#include "zlib.h"
9#include "TMemFile.h"
10#include "TTree.h"
11#include "CoralBase/Blob.h"
12#include "CxxUtils/base64.h"
13
14namespace CoralUtilities {
15
16
17// Compression Functions
18// -------------------------------------------------
19
20bool compressBlob(const char* in, coral::Blob& out) {
21 uLongf comprLen = compressBound(strlen(in));
22 coral::Blob blob;
23 blob.resize(comprLen);
24 unsigned char* ptr = static_cast<unsigned char*>(blob.startingAddress());
25 if (compress(ptr, &comprLen, reinterpret_cast<const unsigned char*>(in), strlen(in)) != Z_OK) {
26 return false;
27 }
28 blob.resize(comprLen);
29 out = blob;
30 return true;
31}
32
33bool writeBlobFromString(const std::string_view in, coral::Blob& out) {
34 return compressBlob(in.data(), out);
35}
36
37bool writeBlobFromJson(const nlohmann::json& in, coral::Blob& out) {
38 return writeBlobFromString(in.dump(), out);
39}
40
41bool writeBlobFromTTree(TTree* tree, coral::Blob& out) {
42 TMemFile fout("buffer","recreate");
43 fout.cd();
44 tree->CloneTree(-1, "fast")->Write();
45 fout.Write();
46 uLongf comprLen = fout.GetSize();
47 unsigned char *buffer = new unsigned char[comprLen];
48 fout.CopyTo(buffer, comprLen);
49 coral::Blob blob;
50 blob.resize(comprLen);
51 char* ptr = reinterpret_cast<char*>(blob.startingAddress());
52 *ptr = *const_cast<char*>(CxxUtils::base64_encode(buffer, comprLen).c_str());
53 out = blob;
54 return true;
55}
56
57
58
59
60// Reading and Uncompressing Functions
61// -------------------------------------------------
62
63bool uncompressBlob(const coral::Blob &blob, std::unique_ptr<unsigned char[]> & out, unsigned long& len){
64 uLongf uncompLen = 50000;
65 std::unique_ptr<unsigned char[]> uncompBuf(new unsigned char[uncompLen+1]);
66 uLongf actualLen{0};
67 while(true) {
68 actualLen = uncompLen;
69 int res(uncompress(uncompBuf.get(), &actualLen, reinterpret_cast<const unsigned char*>(blob.startingAddress()), static_cast<uLongf>(blob.size())));
70 if(res == Z_OK ) break;
71 if(res == Z_BUF_ERROR) { // double buffer if it was not big enough
72 uncompLen *= 2;
73 std::cout << "ATTENTION: Increasing buffer to " << uncompLen << std::endl;
74 uncompBuf.reset(new unsigned char[uncompLen+1]);
75 continue;
76 }
77 // something else is wrong
78 uncompBuf.reset();
79 return false;
80 }
81 uncompBuf.get()[actualLen]=0; // append 0 to terminate string
82 out = std::move(uncompBuf);
83 len = actualLen;
84 return true;
85}
86
87bool readBlobAsString(const coral::Blob &blob, std::string& out){
88 std::unique_ptr<unsigned char[]> bf {};
89 uLongf len = 0;
90 if(!uncompressBlob(blob, bf, len)) return false;
91 const char* cstring = reinterpret_cast<const char*>(bf.get()); // need to cast to char*
92 out.assign(cstring, len); // copy over to C++ string
93 return true;
94}
95
96bool readBlobAsJson(const coral::Blob &blob, nlohmann::json& out){
97 std::string str = "";
98 if(!readBlobAsString(blob, str)) return false;
99 try {
100 out = nlohmann::json::parse(str);
101 }
102 catch(const std::exception& e) {
103 std::cout << "ATTENTION: Cannot unpack Blob object as JSON!" << std::endl;
104 return false;
105 }
106 return true;
107}
108
109bool readBlobAsTTree(const coral::Blob &blob, std::unique_ptr<TTree>& out,
110 const std::string_view name){
111 const char* cstring = reinterpret_cast<const char*>(blob.startingAddress());
112 std::string sb{};
113 sb.assign(cstring, blob.size());
114 std::vector<unsigned char> bdata = CxxUtils::base64_decode(sb);
115 TMemFile f("buffer", reinterpret_cast<char*>(bdata.data()), bdata.size());
116 TTree* t{nullptr};
117 f.GetObject(name.data(), t);
118 if(!t) {
119 out.reset();
120 return false;
121 }
122 t->LoadBaskets();
123 t->SetDirectory(0);
124 f.Close();
125 out.reset(t);
126 return true;
127}
128
129/*
130// keep for now; msgpack maybe used later at some point
131bool readBlobAsMsgpack(const coral::Blob &blob, std::string& out){
132 unsigned char* bf; uLongf len;
133 if(!uncompressBlob(blob, &bf, len)) return false;
134 const char* temp = reinterpret_cast<char*>(bf);
135 try {
136 auto upd = msgpack::unpack(temp, len);
137 msgpack::object obj = upd.get();
138 std::stringstream ss;
139 ss << obj;
140 out = ss.str();
141 }
142 catch(const std::exception& e) {
143 std::cout << "ATTENTION: Cannot unpack Blob object as Msgpack!" << std::endl;
144 return false;
145 }
146 return true;
147}
148*/
149
150
151
152}
std::pair< std::vector< unsigned int >, bool > res
static TFile * fout
Definition listroot.cxx:40
bool writeBlobFromJson(const nlohmann::json &, coral::Blob &)
bool readBlobAsString(const coral::Blob &, std::string &)
bool writeBlobFromTTree(TTree *, coral::Blob &)
bool uncompressBlob(const coral::Blob &, std::unique_ptr< unsigned char[]> &, unsigned long &)
bool compressBlob(const char *, coral::Blob &)
bool readBlobAsTTree(const coral::Blob &blob, std::unique_ptr< TTree > &tree, const std::string_view name="tree")
Interprets the coral::Blob as a TTree instance.
bool writeBlobFromString(const std::string_view, coral::Blob &)
bool readBlobAsJson(const coral::Blob &, nlohmann::json &)
std::vector< unsigned char > base64_decode(const std::string &)
Definition base64.cxx:97
std::string base64_encode(const unsigned char *, unsigned int)
Definition base64.cxx:55
TChain * tree