Project
Loading...
Searching...
No Matches
IndexJSONHelpers.cxx
Go to the documentation of this file.
1// Copyright 2019-2025 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#include "IndexJSONHelpers.h"
12
13#include <rapidjson/reader.h>
14#include <rapidjson/prettywriter.h>
15#include <rapidjson/istreamwrapper.h>
16#include <rapidjson/ostreamwrapper.h>
17#include <rapidjson/error/en.h>
18
19#include <stack>
20#include <iostream>
21
22namespace o2::framework
23{
24namespace
25{
26struct IndexRecordsReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>, IndexRecordsReader> {
27 using Ch = rapidjson::UTF8<>::Ch;
28 using SizeType = rapidjson::SizeType;
29
30 enum struct State {
32 IN_LIST,
33 IN_RECORD,
35 };
36
37 std::stack<State> states;
38 std::ostringstream debug;
39
40 std::vector<o2::soa::IndexRecord> records;
41 std::string currentKey;
42 std::string label;
43 std::string columnLabel;
45 int pos;
46
47 IndexRecordsReader()
48 {
49 debug << ">>> Start" << std::endl;
50 states.push(State::IN_START);
51 }
52
53 bool StartArray()
54 {
55 debug << "StartArray()" << std::endl;
56 if (states.top() == State::IN_START && currentKey.compare("records") == 0) {
57 states.push(State::IN_LIST);
58 return true;
59 }
60 states.push(State::IN_ERROR);
61 return false;
62 }
63
64 bool EndArray(SizeType)
65 {
66 debug << "EndArray()" << std::endl;
67 if (states.top() == State::IN_LIST) {
68 // records done
69 states.pop();
70 return true;
71 }
72 states.push(State::IN_ERROR);
73 return false;
74 }
75
76 bool Key(const Ch* str, SizeType, bool)
77 {
78 debug << "Key(" << str << ")" << std::endl;
80 if (states.top() == State::IN_START) {
81 if (currentKey.compare("records") == 0) {
82 return true;
83 }
84 }
85
86 if (states.top() == State::IN_RECORD) {
87 if (currentKey.compare("label") == 0) {
88 return true;
89 }
90 if (currentKey.compare("column") == 0) {
91 return true;
92 }
93 if (currentKey.compare("kind") == 0) {
94 return true;
95 }
96 if (currentKey.compare("pos") == 0) {
97 return true;
98 }
99 }
100
101 states.push(State::IN_ERROR);
102 return false;
103 }
104
105 bool StartObject()
106 {
107 debug << "StartObject()" << std::endl;
108 if (states.top() == State::IN_START) {
109 return true;
110 }
111
112 if (states.top() == State::IN_LIST) {
113 states.push(State::IN_RECORD);
114 label = "";
116 pos = -2;
117 return true;
118 }
119
120 states.push(State::IN_ERROR);
121 return false;
122 }
123
124 bool EndObject(SizeType)
125 {
126 debug << "EndObject()" << std::endl;
127 if (states.top() == State::IN_RECORD) {
128 states.pop();
129 // add a record
130 records.emplace_back(label, columnLabel, kind, pos);
131 return true;
132 }
133
134 if (states.top() == State::IN_START) {
135 return true;
136 }
137
138 states.push(State::IN_ERROR);
139 return false;
140 }
141
142 bool Uint(unsigned i)
143 {
144 debug << "Uint(" << i << ") passed to Int()" << std::endl;
145 return Int(i);
146 }
147
148 bool Int(int i)
149 {
150 debug << "Int(" << i << ")" << std::endl;
151 if (states.top() == State::IN_RECORD) {
152 if (currentKey.compare("kind") == 0) {
154 return true;
155 }
156 if (currentKey.compare("pos") == 0) {
157 pos = i;
158 return true;
159 }
160 }
161
162 states.push(State::IN_ERROR);
163 return false;
164 }
165
166 bool String(const Ch* str, SizeType, bool)
167 {
168 debug << "String(" << str << ")" << std::endl;
169 if (states.top() == State::IN_RECORD) {
170 if (currentKey.compare("label") == 0) {
171 label = str;
172 return true;
173 }
174 if (currentKey.compare("column") == 0) {
176 return true;
177 }
178 }
179
180 states.push(State::IN_ERROR);
181 return false;
182 }
183};
184} // namespace
185
186std::vector<o2::soa::IndexRecord> IndexJSONHelpers::read(std::istream& s)
187{
188 rapidjson::Reader reader;
189 rapidjson::IStreamWrapper isw(s);
190 IndexRecordsReader irreader;
191
192 bool ok = reader.Parse(isw, irreader);
193
194 if (!ok) {
195 throw framework::runtime_error_f("Cannot parse serialized index records vector, error: %s at offset: %d", rapidjson::GetParseError_En(reader.GetParseErrorCode()), reader.GetErrorOffset());
196 }
197 return irreader.records;
198}
199
200namespace
201{
202void writeRecords(rapidjson::Writer<rapidjson::OStreamWrapper>& w, std::vector<o2::soa::IndexRecord>& records)
203{
204 for (auto& r : records) {
205 w.StartObject();
206 w.Key("label");
207 w.String(r.label.c_str());
208 w.Key("column");
209 w.String(r.columnLabel.c_str());
210 w.Key("kind");
211 w.Int((int)r.kind);
212 w.Key("pos");
213 w.Int(r.pos);
214 w.EndObject();
215 }
216}
217} // namespace
218
219void IndexJSONHelpers::write(std::ostream& o, std::vector<o2::soa::IndexRecord>& irs)
220{
221 rapidjson::OStreamWrapper osw(o);
222 rapidjson::Writer<rapidjson::OStreamWrapper> w(osw);
223 w.StartObject();
224 w.Key("records");
225 w.StartArray();
226 writeRecords(w, irs);
227 w.EndArray();
228 w.EndObject();
229}
230} // namespace o2::framework
std::vector< o2::soa::IndexRecord > records
o2::monitoring::tags::Key Key
std::string currentKey
std::ostringstream debug
int32_t i
std::string columnLabel
uint16_t pos
Definition RawData.h:3
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLboolean r
Definition glcorearb.h:1233
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
GLuint * states
Definition glcorearb.h:4932
Defining PrimaryVertex explicitly as messageable.
RuntimeErrorRef runtime_error_f(const char *,...)
static void write(std::ostream &o, std::vector< o2::soa::IndexRecord > &irs)
static std::vector< o2::soa::IndexRecord > read(std::istream &s)
const std::string str