SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
SDDSLegacy.cc
Go to the documentation of this file.
1/**
2 * @file SDDSLegacy.cc
3 * @brief Deprecated SDDSFile method facade implemented on the C++17 SDDS API.
4 *
5 * @details Translates common historical SDDSFile calls into Layout, Page,
6 * Reader, and Writer operations without restoring the former public object ABI.
7 *
8 * @copyright
9 * - (c) 2026 The University of Chicago
10 *
11 * @license
12 * This file is distributed under the terms of the Software License Agreement
13 * found in the file LICENSE included with this distribution.
14 */
15
16#include "SDDS3Legacy.h"
17
18#include <algorithm>
19#include <cstdlib>
20#include <cstring>
21#include <iostream>
22#include <string>
23#include <type_traits>
24#include <utility>
25#include <variant>
26#include <vector>
27
28namespace {
29
30sdds::Type checkedType(std::int32_t type) {
31 if (type < static_cast<std::int32_t>(sdds::Type::LongDouble) ||
32 type > static_cast<std::int32_t>(sdds::Type::Character))
33 throw sdds::TypeError(sdds::ErrorKind::Type, "invalid SDDS type number");
34 return static_cast<sdds::Type>(type);
35}
36
37sdds::Type checkedType(const char *name) {
38 if (!name)
39 throw sdds::TypeError(sdds::ErrorKind::Type, "null SDDS type name");
40 for (std::int32_t value = 1; value <= 11; ++value) {
41 const auto type = static_cast<sdds::Type>(value);
42 if (sdds::typeName(type) == name)
43 return type;
44 }
45 throw sdds::TypeError(sdds::ErrorKind::Type, "invalid SDDS type name");
46}
47
48std::optional<std::string> optionalText(const char *text) {
49 return text ? std::optional<std::string>(text) : std::nullopt;
50}
51
52template <class T>
53sdds::Scalar convertedScalar(sdds::Type type, const T &value) {
54 if constexpr (std::is_same_v<T, std::string>) {
55 if (type != sdds::Type::String)
56 throw sdds::TypeError(sdds::ErrorKind::Type, "string value used for a non-string field");
57 return value;
58 } else {
59 switch (type) {
60 case sdds::Type::LongDouble: return static_cast<long double>(value);
61 case sdds::Type::Double: return static_cast<double>(value);
62 case sdds::Type::Float: return static_cast<float>(value);
63 case sdds::Type::Int64: return static_cast<std::int64_t>(value);
64 case sdds::Type::UInt64: return static_cast<std::uint64_t>(value);
65 case sdds::Type::Int32: return static_cast<std::int32_t>(value);
66 case sdds::Type::UInt32: return static_cast<std::uint32_t>(value);
67 case sdds::Type::Int16: return static_cast<std::int16_t>(value);
68 case sdds::Type::UInt16: return static_cast<std::uint16_t>(value);
69 case sdds::Type::Character: return static_cast<char>(value);
70 case sdds::Type::String:
71 throw sdds::TypeError(sdds::ErrorKind::Type, "numeric value used for a string field");
72 }
73 }
74 throw sdds::TypeError(sdds::ErrorKind::Type, "invalid SDDS type");
75}
76
77template <class T>
78sdds::Values convertedValues(sdds::Type type, const T *values, std::size_t count) {
79 if (!values && count)
80 throw sdds::TypeError(sdds::ErrorKind::Type, "null column data");
81 sdds::Values result;
82 switch (type) {
83 case sdds::Type::LongDouble: result = std::vector<long double>{}; break;
84 case sdds::Type::Double: result = std::vector<double>{}; break;
85 case sdds::Type::Float: result = std::vector<float>{}; break;
86 case sdds::Type::Int64: result = std::vector<std::int64_t>{}; break;
87 case sdds::Type::UInt64: result = std::vector<std::uint64_t>{}; break;
88 case sdds::Type::Int32: result = std::vector<std::int32_t>{}; break;
89 case sdds::Type::UInt32: result = std::vector<std::uint32_t>{}; break;
90 case sdds::Type::Int16: result = std::vector<std::int16_t>{}; break;
91 case sdds::Type::UInt16: result = std::vector<std::uint16_t>{}; break;
92 case sdds::Type::Character: result = std::vector<char>{}; break;
93 case sdds::Type::String:
94 throw sdds::TypeError(sdds::ErrorKind::Type, "numeric data used for a string column");
95 }
96 std::visit([&](auto &destination) {
97 using Vector = std::decay_t<decltype(destination)>;
98 using Value = typename Vector::value_type;
99 if constexpr (std::is_same_v<Value, std::string>) {
100 throw sdds::TypeError(sdds::ErrorKind::Type,
101 "numeric data used for a string column");
102 } else {
103 destination.reserve(count);
104 for (std::size_t i = 0; i < count; ++i)
105 destination.push_back(static_cast<Value>(values[i]));
106 }
107 }, result);
108 return result;
109}
110
111sdds::Values convertedStrings(char **values, std::size_t count) {
112 std::vector<std::string> result;
113 result.reserve(count);
114 for (std::size_t i = 0; i < count; ++i)
115 result.emplace_back(values && values[i] ? values[i] : "");
116 return result;
117}
118
119template <class T>
120T scalarNumber(const sdds::Scalar &value) {
121 return std::visit([](const auto &item) -> T {
122 using Value = std::decay_t<decltype(item)>;
123 if constexpr (std::is_same_v<Value, std::string>)
124 return static_cast<T>(std::strtold(item.c_str(), nullptr));
125 else
126 return static_cast<T>(item);
127 }, value);
128}
129
130template <class T>
131std::vector<T> vectorNumbers(const sdds::Values &values) {
132 return std::visit([](const auto &source) {
133 using Vector = std::decay_t<decltype(source)>;
134 using Value = typename Vector::value_type;
135 std::vector<T> result;
136 result.reserve(source.size());
137 for (const auto &item : source) {
138 if constexpr (std::is_same_v<Value, std::string>)
139 result.push_back(static_cast<T>(std::strtold(item.c_str(), nullptr)));
140 else
141 result.push_back(static_cast<T>(item));
142 }
143 return result;
144 }, values);
145}
146
147} // namespace
148
150 std::string filename;
151 std::shared_ptr<sdds::Layout> layout = std::make_shared<sdds::Layout>();
152 std::vector<sdds::Page> pages;
153 std::vector<std::string> errors;
154 std::size_t readCursor = 0;
155 sdds::RecoveryMode recovery = sdds::RecoveryMode::Automatic;
156 std::vector<std::int32_t> int32Scratch;
157 std::vector<std::uint32_t> uint32Scratch;
158 std::vector<double> doubleScratch;
159 std::string stringScratch;
160 std::vector<std::string> stringsScratch;
161 std::vector<char *> stringPointers;
162
163 int fail(const std::exception &error) {
164 errors.emplace_back(error.what());
165 return 0;
166 }
167
168 sdds::Page &page(std::uint32_t number) {
169 if (!number)
170 throw sdds::StateError(sdds::ErrorKind::State, "legacy page numbers start at one");
171 while (pages.size() < number)
172 pages.emplace_back(layout);
173 return pages[number - 1];
174 }
175
176 const sdds::Page &page(std::uint32_t number) const {
177 if (!number || number > pages.size())
178 throw sdds::StateError(sdds::ErrorKind::State, "invalid legacy page number");
179 return pages[number - 1];
180 }
181
182 void requireMutableLayout() const {
183 if (!pages.empty())
184 throw sdds::StateError(sdds::ErrorKind::State,
185 "definitions cannot be changed after page data is allocated");
186 }
187
188 template <class T>
189 int setParameter(std::uint32_t pageNumber, std::size_t index, const T &value) {
190 try {
191 page(pageNumber).setParameter(index,
192 convertedScalar(layout->parameters.at(index).type, value));
193 return 1;
194 } catch (const std::exception &error) {
195 return fail(error);
196 }
197 }
198
199 template <class T>
200 int setColumn(std::size_t index, std::uint32_t pageNumber, std::uint32_t startRow,
201 const T *values, std::uint32_t rows) {
202 try {
203 auto &targetPage = page(pageNumber);
204 sdds::Values incoming = convertedValues(layout->columns.at(index).type, values, rows);
205 if (!startRow) {
206 targetPage.setColumn(index, std::move(incoming));
207 } else {
208 sdds::Values merged = targetPage.column(index);
209 std::visit([&](auto &destination) {
210 using Vector = std::decay_t<decltype(destination)>;
211 const auto &source = std::get<Vector>(incoming);
212 if (destination.size() < startRow)
213 destination.resize(startRow);
214 if (destination.size() < static_cast<std::size_t>(startRow) + source.size())
215 destination.resize(static_cast<std::size_t>(startRow) + source.size());
216 std::copy(source.begin(), source.end(), destination.begin() + startRow);
217 }, merged);
218 targetPage.setColumn(index, std::move(merged));
219 }
220 return 1;
221 } catch (const std::exception &error) {
222 return fail(error);
223 }
224 }
225};
226
227SDDSFile::SDDSFile() : impl_(std::make_unique<Impl>()) {}
228SDDSFile::SDDSFile(char *filename) : SDDSFile(static_cast<const char *>(filename)) {}
229SDDSFile::SDDSFile(const char *filename) : SDDSFile() { setFileName(filename); }
230SDDSFile::SDDSFile(bool binary) : SDDSFile() { if (binary) setBinaryMode(); }
231SDDSFile::SDDSFile(char *filename, bool binary)
232 : SDDSFile(static_cast<const char *>(filename), binary) {}
233SDDSFile::SDDSFile(const char *filename, bool binary) : SDDSFile(binary) { setFileName(filename); }
234SDDSFile::~SDDSFile() = default;
235
236int32_t SDDSFile::initializeInput(char *filename) { return initializeInput(static_cast<const char *>(filename)); }
237int32_t SDDSFile::initializeInput(const char *filename) {
238 try {
239 setFileName(filename);
240 sdds::ReaderOptions options;
241 options.recovery = impl_->recovery;
242 auto reader = sdds::Reader::open(impl_->filename, options);
243 auto dataset = reader.readAll();
244 reader.close();
245 impl_->layout = std::make_shared<sdds::Layout>(std::move(dataset.layout));
246 impl_->pages = std::move(dataset.pages);
247 impl_->readCursor = 0;
248 return 1;
249 } catch (const std::exception &error) {
250 return impl_->fail(error);
251 }
252}
253
254int32_t SDDSFile::initializeOutput(int32_t dataMode, int32_t linesPerRow,
255 char *description, char *contents, char *filename) {
256 try {
257 impl_->layout = std::make_shared<sdds::Layout>();
258 impl_->pages.clear();
259 setFileName(filename);
260 setDataMode(static_cast<std::uint32_t>(dataMode));
261 impl_->layout->data.linesPerRow = linesPerRow;
262 setDescription(description, contents);
263 return 1;
264 } catch (const std::exception &error) {
265 return impl_->fail(error);
266 }
267}
268
269int32_t SDDSFile::openInputFile() { return initializeInput(impl_->filename.c_str()); }
270int32_t SDDSFile::openOutputFile() { return impl_->filename.empty() ? 0 : 1; }
271int32_t SDDSFile::closeFile() { return 1; }
272int32_t SDDSFile::readLayout() { return impl_->layout ? 1 : 0; }
273int32_t SDDSFile::readFile() { return impl_->filename.empty() ? 0 : initializeInput(impl_->filename.c_str()); }
274int32_t SDDSFile::readPage() {
275 if (impl_->readCursor >= impl_->pages.size())
276 return 0;
277 return static_cast<int32_t>(++impl_->readCursor);
278}
279int32_t SDDSFile::readPages() { impl_->readCursor = impl_->pages.size(); return 1; }
280int32_t SDDSFile::writeLayout() { return openOutputFile(); }
281int32_t SDDSFile::writeFile() { return writePages(); }
282int32_t SDDSFile::writePage(uint32_t page) { return writePages(page, page); }
283int32_t SDDSFile::writePages() {
284 return writePages(1, static_cast<std::uint32_t>(impl_->pages.size()));
285}
286int32_t SDDSFile::writePages(uint32_t startPage, uint32_t endPage) {
287 try {
288 if (impl_->filename.empty())
289 throw sdds::StateError(sdds::ErrorKind::State, "no output filename was specified");
290 if ((!impl_->pages.empty() && (!startPage || startPage > endPage || endPage > impl_->pages.size())) ||
291 (impl_->pages.empty() && (startPage != 1 || endPage != 0)))
292 throw sdds::StateError(sdds::ErrorKind::State, "invalid legacy output page range");
293 auto writer = sdds::Writer::create(impl_->filename, *impl_->layout);
294 for (std::uint32_t page = startPage; page <= endPage && page; ++page)
295 writer.write(impl_->pages[page - 1]);
296 writer.close();
297 return 1;
298 } catch (const std::exception &error) {
299 return impl_->fail(error);
300 }
301}
302
303int32_t SDDSFile::checkForErrors() { return static_cast<int32_t>(impl_->errors.size()); }
304void SDDSFile::clearErrors() { impl_->errors.clear(); }
305void SDDSFile::printErrors(FILE *file, int32_t) {
306 FILE *output = file ? file : stderr;
307 for (const auto &error : impl_->errors)
308 std::fprintf(output, "%s\n", error.c_str());
309}
310void SDDSFile::printErrors() { printErrors(stderr, 0); }
311void SDDSFile::setError(char *text) { impl_->errors.emplace_back(text ? text : ""); }
312int32_t SDDSFile::readRecoveryPossible() const {
313 return std::any_of(impl_->pages.begin(), impl_->pages.end(),
314 [](const auto &page) { return page.recovered(); }) ? 1 : 0;
315}
316
317void SDDSFile::setFileName(char *filename) { setFileName(static_cast<const char *>(filename)); }
318void SDDSFile::setFileName(const char *filename) { impl_->filename = filename ? filename : ""; }
319uint32_t SDDSFile::getDataMode() const {
320 return impl_->layout->data.mode == sdds::DataMode::Binary ? SDDS_BINARY : SDDS_ASCII;
321}
322void SDDSFile::setDataMode(uint32_t mode) {
323 impl_->layout->data.mode = mode == SDDS_BINARY ? sdds::DataMode::Binary : sdds::DataMode::Ascii;
324}
325void SDDSFile::setAsciiMode() { impl_->layout->data.mode = sdds::DataMode::Ascii; }
326void SDDSFile::setBinaryMode() { impl_->layout->data.mode = sdds::DataMode::Binary; }
327void SDDSFile::setColumnMajorOrder() { impl_->layout->data.majorOrder = sdds::MajorOrder::Column; }
328void SDDSFile::setRowMajorOrder() { impl_->layout->data.majorOrder = sdds::MajorOrder::Row; }
329void SDDSFile::setNativeEndian() { impl_->layout->data.byteOrder = sdds::ByteOrder::Native; }
330void SDDSFile::setNonNativeEndian() {
331 const std::uint16_t marker = 0x0102;
332 const bool big = *reinterpret_cast<const unsigned char *>(&marker) == 0x01;
333 impl_->layout->data.byteOrder = big ? sdds::ByteOrder::Little : sdds::ByteOrder::Big;
334}
335void SDDSFile::setNoRowCount() { impl_->layout->data.rowCountMode = sdds::RowCountMode::None; }
336void SDDSFile::setUseRowCount() { impl_->layout->data.rowCountMode = sdds::RowCountMode::Variable; }
337void SDDSFile::setReadRecoveryMode(int32_t mode) {
338 impl_->recovery = mode ? sdds::RecoveryMode::Recover : sdds::RecoveryMode::Strict;
339}
340void SDDSFile::setLayoutVersion(int32_t version) { impl_->layout->version = version; }
341void SDDSFile::setDescription(char *text, char *contents) {
342 impl_->layout->description = optionalText(text);
343 impl_->layout->contents = optionalText(contents);
344}
345int32_t SDDSFile::getDescription(char **text, char **contents) {
346 if (text) *text = impl_->layout->description ? impl_->layout->description->data() : nullptr;
347 if (contents) *contents = impl_->layout->contents ? impl_->layout->contents->data() : nullptr;
348 return 1;
349}
350int32_t SDDSFile::readVersion() const { return impl_->layout->version; }
351uint32_t SDDSFile::pageCount() const { return static_cast<std::uint32_t>(impl_->pages.size()); }
352uint32_t SDDSFile::rowCount(uint32_t page) const {
353 try { return static_cast<std::uint32_t>(impl_->page(page).rowCount()); }
354 catch (...) { return 0; }
355}
356void SDDSFile::freePage() { impl_->pages.clear(); impl_->readCursor = 0; }
357
358int32_t SDDSFile::defineParameter(char *name, int32_t type) {
359 return defineParameter(name, nullptr, nullptr, nullptr, nullptr, type, nullptr);
360}
361int32_t SDDSFile::defineParameter(char *name, char *type) {
362 try { return defineParameter(name, static_cast<int32_t>(checkedType(type))); }
363 catch (const std::exception &error) { return impl_->fail(error); }
364}
365int32_t SDDSFile::defineParameter(char *name, char *symbol, char *units, char *description,
366 char *formatString, int32_t type, char *fixedValue) {
367 try {
368 impl_->requireMutableLayout();
369 sdds::ParameterDefinition definition;
370 definition.name = name ? name : "";
371 definition.symbol = optionalText(symbol);
372 definition.units = optionalText(units);
373 definition.description = optionalText(description);
374 definition.format = optionalText(formatString);
375 definition.type = checkedType(type);
376 definition.fixedValue = optionalText(fixedValue);
377 impl_->layout->parameters.push_back(std::move(definition));
378 return static_cast<int32_t>(impl_->layout->parameters.size() - 1);
379 } catch (const std::exception &error) { return impl_->fail(error); }
380}
381
382int32_t SDDSFile::defineColumn(char *name, int32_t type) {
383 return defineColumn(name, nullptr, nullptr, nullptr, nullptr, type, 0);
384}
385int32_t SDDSFile::defineColumn(char *name, char *type) {
386 try { return defineColumn(name, static_cast<int32_t>(checkedType(type))); }
387 catch (const std::exception &error) { return impl_->fail(error); }
388}
389int32_t SDDSFile::defineColumn(char *name, char *symbol, char *units, char *description,
390 char *formatString, int32_t type, uint32_t fieldLength) {
391 try {
392 impl_->requireMutableLayout();
393 sdds::ColumnDefinition definition;
394 definition.name = name ? name : "";
395 definition.symbol = optionalText(symbol);
396 definition.units = optionalText(units);
397 definition.description = optionalText(description);
398 definition.format = optionalText(formatString);
399 definition.type = checkedType(type);
400 definition.fieldLength = static_cast<std::int32_t>(fieldLength);
401 impl_->layout->columns.push_back(std::move(definition));
402 return static_cast<int32_t>(impl_->layout->columns.size() - 1);
403 } catch (const std::exception &error) { return impl_->fail(error); }
404}
405
406int32_t SDDSFile::defineArray(char *name, int32_t type, uint32_t dimensions) {
407 return defineArray(name, nullptr, nullptr, nullptr, nullptr, nullptr, type, 0, dimensions);
408}
409int32_t SDDSFile::defineArray(char *name, char *type, uint32_t dimensions) {
410 try { return defineArray(name, static_cast<int32_t>(checkedType(type)), dimensions); }
411 catch (const std::exception &error) { return impl_->fail(error); }
412}
413int32_t SDDSFile::defineArray(char *name, char *symbol, char *units, char *description,
414 char *formatString, char *groupName, int32_t type,
415 uint32_t fieldLength, uint32_t dimensions) {
416 try {
417 impl_->requireMutableLayout();
418 sdds::ArrayDefinition definition;
419 definition.name = name ? name : "";
420 definition.symbol = optionalText(symbol);
421 definition.units = optionalText(units);
422 definition.description = optionalText(description);
423 definition.format = optionalText(formatString);
424 definition.groupName = optionalText(groupName);
425 definition.type = checkedType(type);
426 definition.fieldLength = static_cast<std::int32_t>(fieldLength);
427 definition.dimensions = static_cast<std::int32_t>(dimensions);
428 impl_->layout->arrays.push_back(std::move(definition));
429 return static_cast<int32_t>(impl_->layout->arrays.size() - 1);
430 } catch (const std::exception &error) { return impl_->fail(error); }
431}
432
433int32_t SDDSFile::getParameterCount() const { return static_cast<int32_t>(impl_->layout->parameters.size()); }
434int32_t SDDSFile::getColumnCount() const { return static_cast<int32_t>(impl_->layout->columns.size()); }
435int32_t SDDSFile::getArrayCount() const { return static_cast<int32_t>(impl_->layout->arrays.size()); }
436int32_t SDDSFile::getParameterIndex(char *name) const {
437 try { return static_cast<int32_t>(impl_->layout->parameterIndex(name ? name : "")); } catch (...) { return -1; }
438}
439int32_t SDDSFile::getColumnIndex(char *name) const {
440 try { return static_cast<int32_t>(impl_->layout->columnIndex(name ? name : "")); } catch (...) { return -1; }
441}
442int32_t SDDSFile::getArrayIndex(char *name) const {
443 try { return static_cast<int32_t>(impl_->layout->arrayIndex(name ? name : "")); } catch (...) { return -1; }
444}
445char *SDDSFile::getParameterName(int32_t index) { return impl_->layout->parameters.at(index).name.data(); }
446char *SDDSFile::getColumnName(int32_t index) { return impl_->layout->columns.at(index).name.data(); }
447char *SDDSFile::getArrayName(int32_t index) { return impl_->layout->arrays.at(index).name.data(); }
448int32_t SDDSFile::getParameterType(int32_t index) const { return static_cast<int32_t>(impl_->layout->parameters.at(index).type); }
449int32_t SDDSFile::getColumnType(int32_t index) const { return static_cast<int32_t>(impl_->layout->columns.at(index).type); }
450int32_t SDDSFile::getArrayType(int32_t index) const { return static_cast<int32_t>(impl_->layout->arrays.at(index).type); }
451
452int32_t SDDSFile::setParameter(uint32_t page, int32_t index, int32_t value) { return impl_->setParameter(page, index, value); }
453int32_t SDDSFile::setParameter(uint32_t page, int32_t index, uint32_t value) { return impl_->setParameter(page, index, value); }
454int32_t SDDSFile::setParameter(uint32_t page, int32_t index, double value) { return impl_->setParameter(page, index, value); }
455int32_t SDDSFile::setParameter(uint32_t page, int32_t index, char *value) { return impl_->setParameter(page, index, std::string(value ? value : "")); }
456int32_t SDDSFile::setParameter(uint32_t page, char *name, int32_t value) { return setParameter(page, getParameterIndex(name), value); }
457int32_t SDDSFile::setParameter(uint32_t page, char *name, uint32_t value) { return setParameter(page, getParameterIndex(name), value); }
458int32_t SDDSFile::setParameter(uint32_t page, char *name, double value) { return setParameter(page, getParameterIndex(name), value); }
459int32_t SDDSFile::setParameter(uint32_t page, char *name, char *value) { return setParameter(page, getParameterIndex(name), value); }
460
461#define SDDSPP_SET_COLUMN(TYPE) \
462 int32_t SDDSFile::setColumn(int32_t index, uint32_t page, uint32_t startRow, \
463 TYPE *values, uint32_t rows) { \
464 return impl_->setColumn(index, page, startRow, values, rows); \
465 }
466SDDSPP_SET_COLUMN(int16_t)
467SDDSPP_SET_COLUMN(uint16_t)
468SDDSPP_SET_COLUMN(int32_t)
469SDDSPP_SET_COLUMN(uint32_t)
470SDDSPP_SET_COLUMN(float)
471SDDSPP_SET_COLUMN(double)
472SDDSPP_SET_COLUMN(char)
473#undef SDDSPP_SET_COLUMN
474
475int32_t SDDSFile::setColumn(int32_t index, uint32_t page, uint32_t startRow,
476 char **values, uint32_t rows) {
477 try {
478 if (impl_->layout->columns.at(index).type != sdds::Type::String)
479 throw sdds::TypeError(sdds::ErrorKind::Type, "string data used for a non-string column");
480 auto &target = impl_->page(page);
481 sdds::Values incoming = convertedStrings(values, rows);
482 if (!startRow) target.setColumn(index, std::move(incoming));
483 else {
484 auto merged = target.column(index);
485 auto &destination = std::get<std::vector<std::string>>(merged);
486 const auto &source = std::get<std::vector<std::string>>(incoming);
487 if (destination.size() < startRow) destination.resize(startRow);
488 if (destination.size() < static_cast<std::size_t>(startRow) + source.size())
489 destination.resize(static_cast<std::size_t>(startRow) + source.size());
490 std::copy(source.begin(), source.end(), destination.begin() + startRow);
491 target.setColumn(index, std::move(merged));
492 }
493 return 1;
494 } catch (const std::exception &error) { return impl_->fail(error); }
495}
496int32_t SDDSFile::setColumn(char *name, uint32_t page, uint32_t startRow, int32_t *values, uint32_t rows) { return setColumn(getColumnIndex(name), page, startRow, values, rows); }
497int32_t SDDSFile::setColumn(char *name, uint32_t page, uint32_t startRow, uint32_t *values, uint32_t rows) { return setColumn(getColumnIndex(name), page, startRow, values, rows); }
498int32_t SDDSFile::setColumn(char *name, uint32_t page, uint32_t startRow, double *values, uint32_t rows) { return setColumn(getColumnIndex(name), page, startRow, values, rows); }
499int32_t SDDSFile::setColumn(char *name, uint32_t page, uint32_t startRow, char **values, uint32_t rows) { return setColumn(getColumnIndex(name), page, startRow, values, rows); }
500
501int32_t SDDSFile::getParameterInInt32(int32_t index, uint32_t page) { return scalarNumber<int32_t>(impl_->page(page).parameter(index)); }
502int32_t SDDSFile::getParameterInInt32(char *name, uint32_t page) { return getParameterInInt32(getParameterIndex(name), page); }
503uint32_t SDDSFile::getParameterInUInt32(int32_t index, uint32_t page) { return scalarNumber<uint32_t>(impl_->page(page).parameter(index)); }
504uint32_t SDDSFile::getParameterInUInt32(char *name, uint32_t page) { return getParameterInUInt32(getParameterIndex(name), page); }
505double SDDSFile::getParameterInDouble(int32_t index, uint32_t page) { return scalarNumber<double>(impl_->page(page).parameter(index)); }
506double SDDSFile::getParameterInDouble(char *name, uint32_t page) { return getParameterInDouble(getParameterIndex(name), page); }
507char *SDDSFile::getParameterInString(int32_t index, uint32_t page) {
508 const auto &value = impl_->page(page).parameter(index);
509 if (const auto *text = std::get_if<std::string>(&value)) return const_cast<char *>(text->c_str());
510 impl_->stringScratch = std::visit([](const auto &item) {
511 using Value = std::decay_t<decltype(item)>;
512 if constexpr (std::is_same_v<Value, std::string>) return item;
513 else if constexpr (std::is_same_v<Value, char>) return std::string(1, item);
514 else return std::to_string(item);
515 }, value);
516 return impl_->stringScratch.data();
517}
518char *SDDSFile::getParameterInString(char *name, uint32_t page) { return getParameterInString(getParameterIndex(name), page); }
519int32_t *SDDSFile::getColumnInInt32(int32_t index, uint32_t page) { impl_->int32Scratch = vectorNumbers<int32_t>(impl_->page(page).column(index)); return impl_->int32Scratch.data(); }
520int32_t *SDDSFile::getColumnInInt32(char *name, uint32_t page) { return getColumnInInt32(getColumnIndex(name), page); }
521uint32_t *SDDSFile::getColumnInUInt32(int32_t index, uint32_t page) { impl_->uint32Scratch = vectorNumbers<uint32_t>(impl_->page(page).column(index)); return impl_->uint32Scratch.data(); }
522uint32_t *SDDSFile::getColumnInUInt32(char *name, uint32_t page) { return getColumnInUInt32(getColumnIndex(name), page); }
523double *SDDSFile::getColumnInDouble(int32_t index, uint32_t page) { impl_->doubleScratch = vectorNumbers<double>(impl_->page(page).column(index)); return impl_->doubleScratch.data(); }
524double *SDDSFile::getColumnInDouble(char *name, uint32_t page) { return getColumnInDouble(getColumnIndex(name), page); }
525char **SDDSFile::getColumnInString(int32_t index, uint32_t page) {
526 impl_->stringsScratch = std::get<std::vector<std::string>>(impl_->page(page).column(index));
527 impl_->stringPointers.clear();
528 for (auto &text : impl_->stringsScratch) impl_->stringPointers.push_back(text.data());
529 return impl_->stringPointers.data();
530}
531char **SDDSFile::getColumnInString(char *name, uint32_t page) { return getColumnInString(getColumnIndex(name), page); }
532void *SDDSFile::getInternalColumn(int32_t index, uint32_t page) {
533 return std::visit([](const auto &values) -> void * {
534 return const_cast<typename std::decay_t<decltype(values)>::value_type *>(values.data());
535 }, impl_->page(page).column(index));
536}
537void *SDDSFile::getInternalColumn(char *name, uint32_t page) { return getInternalColumn(getColumnIndex(name), page); }