30std::vector<char> mutablePath(
const std::filesystem::path &path);
32sdds::Layout allTypesLayout(sdds::DataMode mode = sdds::DataMode::Binary,
33 sdds::MajorOrder major = sdds::MajorOrder::Row,
34 sdds::ByteOrder order = sdds::ByteOrder::Native) {
35 sdds::DataOptions data;
37 data.majorOrder = major;
38 data.byteOrder = order;
39 sdds::LayoutBuilder builder;
40 builder.setDataOptions(data)
41 .addParameter({{
"p64", {}, {}, {}, {}, sdds::Type::Int64}, {}})
42 .addArray({{
"array", {}, {}, {}, {}, sdds::Type::Double}, 0, 1, {}})
43 .addAssociate({
"related", std::string(
"related.sdds"), std::string(
"."),
44 std::string(
"related data"), std::string(
"SDDS"),
true})
45 .addColumn({{
"longdouble", {}, {}, {}, {}, sdds::Type::LongDouble}, 0})
46 .addColumn({{
"double", {}, {}, {}, {}, sdds::Type::Double}, 0})
47 .addColumn({{
"float", {}, {}, {}, {}, sdds::Type::Float}, 0})
48 .addColumn({{
"long64", {}, {}, {}, {}, sdds::Type::Int64}, 0})
49 .addColumn({{
"ulong64", {}, {}, {}, {}, sdds::Type::UInt64}, 0})
50 .addColumn({{
"long", {}, {}, {}, {}, sdds::Type::Int32}, 0})
51 .addColumn({{
"ulong", {}, {}, {}, {}, sdds::Type::UInt32}, 0})
52 .addColumn({{
"short", {}, {}, {}, {}, sdds::Type::Int16}, 0})
53 .addColumn({{
"ushort", {}, {}, {}, {}, sdds::Type::UInt16}, 0})
54 .addColumn({{
"string", {}, {}, {}, {}, sdds::Type::String}, 0})
55 .addColumn({{
"character", {}, {}, {}, {}, sdds::Type::Character}, 0});
56 return builder.build();
59sdds::Page allTypesPage(
const std::shared_ptr<const sdds::Layout> &layout) {
60 sdds::Page page(layout);
61 page.setParameter(
"p64", std::int64_t{1234567890123});
62 page.setArray(
"array", {{3}, std::vector<double>{1.25, 2.5, 5.0}});
63 page.setColumn(
"longdouble", std::vector<long double>{1.25L, -2.5L});
64 page.setColumn(
"double", std::vector<double>{3.25, -4.5});
65 page.setColumn(
"float", std::vector<float>{5.25F, -6.5F});
66 page.setColumn(
"long64", std::vector<std::int64_t>{-7, INT64_C(5000000000)});
67 page.setColumn(
"ulong64", std::vector<std::uint64_t>{8, UINT64_C(9000000000)});
68 page.setColumn(
"long", std::vector<std::int32_t>{-9, 10});
69 page.setColumn(
"ulong", std::vector<std::uint32_t>{11, 12});
70 page.setColumn(
"short", std::vector<std::int16_t>{-13, 14});
71 page.setColumn(
"ushort", std::vector<std::uint16_t>{15, 16});
72 page.setColumn(
"string", std::vector<std::string>{
"alpha",
"space value"});
73 page.setColumn(
"character", std::vector<char>{
'A',
'!'});
77void cWrite(
const std::filesystem::path &path) {
79 auto filename = mutablePath(path);
81 const_cast<char *
>(
"C differential output"),
84 assert(
SDDS_DefineArray(&dataset,
const_cast<char *
>(
"array"),
nullptr,
nullptr,
nullptr,
86 const char *names[] = {
"longdouble",
"double",
"float",
"long64",
"ulong64",
"long",
87 "ulong",
"short",
"ushort",
"string",
"character"};
91 for (std::size_t index = 0; index <
sizeof(types) /
sizeof(types[0]); ++index)
96 "p64", INT64_C(1234567890123),
nullptr));
97 double array[] = {1.25, 2.5, 5.0};
98 std::int32_t dimensions[] = {3};
99 assert(
SDDS_SetArray(&dataset,
const_cast<char *
>(
"array"), SDDS_CONTIGUOUS_DATA,
101 long double longdoubleValues[] = {1.25L, -2.5L};
102 double doubleValues[] = {3.25, -4.5};
103 float floatValues[] = {5.25F, -6.5F};
104 std::int64_t long64Values[] = {-7, INT64_C(5000000000)};
105 std::uint64_t ulong64Values[] = {8, UINT64_C(9000000000)};
106 std::int32_t longValues[] = {-9, 10};
107 std::uint32_t ulongValues[] = {11, 12};
108 std::int16_t shortValues[] = {-13, 14};
109 std::uint16_t ushortValues[] = {15, 16};
110 char alpha[] =
"alpha";
111 char spaced[] =
"space value";
112 char *stringValues[] = {alpha, spaced};
113 char characterValues[] = {
'A',
'!'};
114 void *values[] = {longdoubleValues, doubleValues, floatValues, long64Values, ulong64Values,
115 longValues, ulongValues, shortValues, ushortValues, stringValues,
117 for (std::size_t index = 0; index <
sizeof(values) /
sizeof(values[0]); ++index)
118 assert(
SDDS_SetColumn(&dataset, SDDS_SET_BY_NAME, values[index], 2, names[index]));
123void cppRead(
const std::filesystem::path &path) {
124 sdds::ReaderOptions options;
126 options.longDoubleEncoding = sdds::LongDoubleEncoding::LegacyFloat64;
128 auto reader = sdds::Reader::open(path, options);
129 auto page = reader.next();
130 assert(page && page->rowCount() == 2);
131 assert(page->parameterAs<std::int64_t>(
"p64") == INT64_C(1234567890123));
132 assert(page->arrayAs<
double>(
"array")[2] == 5.0);
133 assert(std::fabs(page->columnAs<
long double>(
"longdouble")[1] + 2.5L) < 1e-12L);
134 assert(page->columnAs<std::uint64_t>(
"ulong64")[1] == UINT64_C(9000000000));
135 assert(page->columnAs<std::string>(
"string")[1] ==
"space value");
136 assert(page->columnAs<
char>(
"character")[1] ==
'!');
140void cppWrite(
const std::filesystem::path &path, sdds::DataMode mode,
141 sdds::MajorOrder major, sdds::ByteOrder order,
142 sdds::Compression compression = sdds::Compression::None) {
143 const auto layout = allTypesLayout(mode, major, order);
144 sdds::WriterOptions options;
145 options.compression = compression;
147 options.longDoubleEncoding = sdds::LongDoubleEncoding::LegacyFloat64;
149 auto writer = sdds::Writer::create(path, layout, options);
150 writer.write(allTypesPage(std::make_shared<const sdds::Layout>(layout)));
152 auto reader = sdds::Reader::open(path);
153 assert(reader.layout().associates.size() == 1);
154 assert(reader.layout().associates[0].name ==
"related");
155 assert(reader.layout().associates[0].isSdds);
159std::vector<char> mutablePath(
const std::filesystem::path &path) {
160 const std::string text = path.string();
161 std::vector<char> result(text.begin(), text.end());
162 result.push_back(
'\0');
166void cRead(
const std::filesystem::path &path) {
168 auto filename = mutablePath(path);
172 std::int64_t parameter = 0;
174 assert(parameter == INT64_C(1234567890123));
175 auto *long64Values =
static_cast<std::int64_t *
>(
177 assert(long64Values && long64Values[1] == INT64_C(5000000000));
180 assert(strings && std::string(strings[1]) ==
"space value");
184 assert(array && array->elements == 3 &&
static_cast<double *
>(array->data)[2] == 5.0);
189void cWriteRowMode(
const std::filesystem::path &path, sdds::DataMode dataMode,
190 sdds::RowCountMode rowCountMode) {
192 auto filename = mutablePath(path);
194 dataMode == sdds::DataMode::Ascii ? SDDS_ASCII : SDDS_BINARY,
195 1,
nullptr,
nullptr, filename.data()));
197 const std::uint32_t cMode = rowCountMode == sdds::RowCountMode::Fixed ?
198 SDDS_FIXEDROWCOUNT : SDDS_NOROWCOUNT;
202 double values[] = {1.0, 2.0};
203 assert(
SDDS_SetColumn(&dataset, SDDS_SET_BY_NAME, values, 2,
"x"));
208void cppReadRows(
const std::filesystem::path &path, sdds::RowCountMode mode) {
209 auto reader = sdds::Reader::open(path);
210 assert(reader.layout().data.rowCountMode == mode);
211 auto page = reader.next();
212 assert(page && page->rowCount() == 2);
213 assert(page->columnAs<
double>(
"x")[1] == 2.0);
217void cppWriteRowMode(
const std::filesystem::path &path, sdds::DataMode dataMode,
218 sdds::RowCountMode rowCountMode) {
219 sdds::DataOptions data;
220 data.mode = dataMode;
221 data.rowCountMode = rowCountMode;
222 sdds::LayoutBuilder builder;
223 builder.setDataOptions(data).addColumn({{
"x", {}, {}, {}, {}, sdds::Type::Double}, 0});
224 const auto layout = builder.build();
225 auto writer = sdds::Writer::create(path, layout);
226 sdds::Page page(std::make_shared<const sdds::Layout>(layout));
227 page.setColumn(
"x", std::vector<double>{1.0, 2.0});
228 writer.write(std::move(page));
232 auto filename = mutablePath(path);
239void rowCountMatrix(
const std::filesystem::path &directory) {
240 for (
const auto dataMode : {sdds::DataMode::Ascii, sdds::DataMode::Binary}) {
241 const std::string modeName = dataMode == sdds::DataMode::Ascii ?
"ascii" :
"binary";
242 const auto cPath = directory / (
"c-fixed-" + modeName +
".sdds");
243 cWriteRowMode(cPath, dataMode, sdds::RowCountMode::Fixed);
244 cppReadRows(cPath, sdds::RowCountMode::Fixed);
245 const auto cppPath = directory / (
"cpp-fixed-" + modeName +
".sdds");
246 cppWriteRowMode(cppPath, dataMode, sdds::RowCountMode::Fixed);
248 const auto cNoCount = directory /
"c-no-row-count.sdds";
249 cWriteRowMode(cNoCount, sdds::DataMode::Ascii, sdds::RowCountMode::None);
250 cppReadRows(cNoCount, sdds::RowCountMode::None);
251 const auto cppNoCount = directory /
"cpp-no-row-count.sdds";
252 cppWriteRowMode(cppNoCount, sdds::DataMode::Ascii, sdds::RowCountMode::None);
255void versionMatrix(
const std::filesystem::path &directory) {
256 sdds::LayoutBuilder builder;
257 builder.addColumn({{
"x", {}, {}, {}, {}, sdds::Type::Double}, 0});
258 const auto layout = builder.build();
259 for (std::int32_t version = 1; version <= 5; ++version) {
260 const auto path = directory / (
"version-" + std::to_string(version) +
".sdds");
261 sdds::WriterOptions options;
262 options.minimumVersion = version;
263 auto writer = sdds::Writer::create(path, layout, options);
264 sdds::Page page(std::make_shared<const sdds::Layout>(layout));
265 page.setColumn(
"x", std::vector<double>{1.0, 2.0});
266 writer.write(std::move(page));
269 auto filename = mutablePath(path);
271 assert(dataset.layout.version == version);
277void includeMatrix(
const std::filesystem::path &directory) {
278 const auto includePath = std::filesystem::absolute(directory /
"included-layout.sdds");
279 const auto rootPath = directory /
"include-root.sdds";
281 std::ofstream included(includePath);
282 included <<
"&column name=included, type=long &end\n";
283 assert(included.good());
286 std::ofstream root(rootPath);
288 <<
"&include filename=\"" << includePath.generic_string() <<
"\" &end\n"
289 <<
"&data mode=ascii &end\n"
294 auto reader = sdds::Reader::open(rootPath);
295 assert(reader.layout().columns.size() == 1);
296 assert(reader.layout().columns[0].name ==
"included");
297 auto page = reader.next();
298 assert(page && page->rowCount() == 0);
302 auto filename = mutablePath(rootPath);
304 assert(dataset.layout.n_columns == 1);
305 assert(std::string(dataset.layout.column_definition[0].name) ==
"included");
312int main(
int argc,
char **argv) {
314 _putenv_s(
"SDDS_LONGDOUBLE_64BITS",
"1");
316 if (argc != 2)
return 2;
317 const std::filesystem::path directory(argv[1]);
318 std::filesystem::create_directories(directory);
319 const auto cOutput = directory /
"c-to-cpp.sdds";
322 for (
const auto mode : {sdds::DataMode::Ascii, sdds::DataMode::Binary}) {
323 for (
const auto major : {sdds::MajorOrder::Row, sdds::MajorOrder::Column}) {
324 if (mode == sdds::DataMode::Ascii && major == sdds::MajorOrder::Column)
continue;
325 for (
const auto order : {sdds::ByteOrder::Little, sdds::ByteOrder::Big}) {
326 const auto path = directory / (std::string(mode == sdds::DataMode::Ascii ?
"ascii" :
"binary") +
327 (major == sdds::MajorOrder::Row ?
"-row" :
"-column") +
328 (order == sdds::ByteOrder::Little ?
"-little.sdds" :
330 cppWrite(path, mode, major, order);
335 for (
const auto compression : {sdds::Compression::Gzip, sdds::Compression::Xz,
336 sdds::Compression::Lzma}) {
337 const char *extension = compression == sdds::Compression::Gzip ?
".sdds.gz" :
338 compression == sdds::Compression::Xz ?
".sdds.xz" :
".sdds.lzma";
339 const auto path = directory / (std::string(
"compressed") + extension);
340 cppWrite(path, sdds::DataMode::Binary, sdds::MajorOrder::Row,
341 sdds::ByteOrder::Little, compression);
344 versionMatrix(directory);
345 rowCountMatrix(directory);
346 includeMatrix(directory);
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_SetArray(SDDS_DATASET *SDDS_dataset, char *array_name, int32_t mode, void *data_pointer, int32_t *dimension)
Sets the values of an array variable in the SDDS dataset using specified dimensions.
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_DefineSimpleParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data parameter within the SDDS dataset.
int32_t SDDS_SetRowCountMode(SDDS_DATASET *SDDS_dataset, uint32_t mode)
Sets the row count mode for the SDDS dataset.
int32_t SDDS_DefineArray(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length, int32_t dimensions, const char *group_name)
Defines a data array within the SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
void SDDS_FreeArray(SDDS_ARRAY *array)
Frees memory allocated for an SDDS array structure.
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
void SDDS_Free(void *mem)
Free memory previously allocated by SDDS_Malloc.
#define SDDS_ULONG
Identifier for the unsigned 32-bit integer data type.
#define SDDS_FLOAT
Identifier for the float data type.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_ULONG64
Identifier for the unsigned 64-bit integer data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_SHORT
Identifier for the signed short integer data type.
#define SDDS_CHARACTER
Identifier for the character data type.
#define SDDS_USHORT
Identifier for the unsigned short integer data type.
#define SDDS_DOUBLE
Identifier for the double data type.
#define SDDS_LONGDOUBLE
Identifier for the long double data type.
#define SDDS_LONG64
Identifier for the signed 64-bit integer data type.