AAO DRAMA/DRAMA2 C++ Interface
DRAMA C++11 and later interface
sds.hh
Go to the documentation of this file.
1#ifndef _DRAMA2_SDS_INC
2#define _DRAMA2_SDS_INC
3
15/*
16 * History:
17 07-Jan-2014 - TJF - Original version
18 14-Sep-2016 - TJF - Start of history after development.
19 14-Sep-2016 - TJF - Add Exists() by index.
20 09-Jan-2023 - TJF - std::iterator is depreciated from C++17.
21
22 * The above ID is for Doxygen, this one has the format ACMM is looking for.
23 * "@(#) $Id$"
24 */
25#include "sds.h"
26#include "arg.h"
27#include <string>
28#include <stdio.h>
29#include <vector>
30#include <memory>
31#include <assert.h>
32
33/*
34 * A bit of a flaw in our include file layout means we need to declare this
35 * here. Its real location is drama.hh, but we don't want to include that
36 * in this file.
37 */
38namespace drama {
39 extern void CheckLockTaken(const std::string func,
40 const std::string &file,
41 const int lineNum) ;
42} // namespace drama.
43
44
45#include "drama/exception.hh"
46#include "drama/sdsarray.hh"
47
48#include <tuple>
49
50namespace drama {
54 namespace sds {
55 using std::begin;
56 using std::end;
57
58 /*
59 * The SdsArgPut() template function is used by the Put() method
60 * of sds::Id and is implementing traditional Arg style Put.
61 *
62 * The idea is that we must instantiate a specific version of this
63 * for each primitive SDS type and for strings.
64 *
65 * The Put() method won't link unless there is a specific version for
66 * the type in question. There are all implemented in parsys.cpp.
67 */
68 template <typename T> void SdsArgPut(
69 SdsIdType id, const std::string &name,
71
72 template <> void SdsArgPut<bool>(
73 SdsIdType id, const std::string &name,
74 bool value, StatusType *status);
75 template <> void SdsArgPut<char>(
76 SdsIdType id, const std::string &name,
77 char value, StatusType *status);
78 template <> void SdsArgPut<short>(
79 SdsIdType id, const std::string &name,
80 short value, StatusType *status);
81 template <> void SdsArgPut<unsigned short>(
82 SdsIdType id, const std::string &name,
83 unsigned short value, StatusType *status);
84 template <> void SdsArgPut<INT32>(
85 SdsIdType id, const std::string &name,
87 template <> void SdsArgPut<UINT32>(
88 SdsIdType id, const std::string &name,
90 template <> void SdsArgPut<INT64>(
91 SdsIdType id, const std::string &name,
93 template <> void SdsArgPut<UINT64>(
94 SdsIdType id, const std::string &name,
96 template <> void SdsArgPut<float>(
97 SdsIdType id, const std::string &name,
98 float value, StatusType *status);
99 template <> void SdsArgPut<double>(
100 SdsIdType id, const std::string &name,
101 double value, StatusType *status);
102
103 template <> void SdsArgPut<const char *>(
104 SdsIdType id, const std::string &name,
105 const char *value, StatusType *status);
106
107 /*
108 * The SdsArgGet() template function is used by the Get() method
109 * of sds::Id and is implementing traditional Arg style Get.
110 *
111 * The idea is that we must instantiate a specific version of this
112 * for each primitive SDS type.
113 *
114 * The Get() method won't link unless there is a specific version for
115 * the type in question.
116 */
117 template <typename T> void SdsArgGet(
118 SdsIdType id, const std::string &name,
119 T *value, StatusType *status);
120
121 template <> void SdsArgGet<bool>(
122 SdsIdType id, const std::string &name,
123 bool *value, StatusType *status);
124 template <> void SdsArgGet<char>(
125 SdsIdType id, const std::string &name,
126 char *value, StatusType *status);
127 template <> void SdsArgGet<short>(
128 SdsIdType id, const std::string &name,
129 short *value, StatusType *status);
130 template <> void SdsArgGet<unsigned short>(
131 SdsIdType id, const std::string &name,
132 unsigned short *value, StatusType *status);
133 template <> void SdsArgGet<INT32>(
134 SdsIdType id, const std::string &name,
136 template <> void SdsArgGet<UINT32>(
137 SdsIdType id, const std::string &name,
139 template <> void SdsArgGet<INT64>(
140 SdsIdType id, const std::string &name,
142 template <> void SdsArgGet<UINT64>(
143 SdsIdType id, const std::string &name,
145 template <> void SdsArgGet<float>(
146 SdsIdType id, const std::string &name,
147 float *value, StatusType *status);
148 template <> void SdsArgGet<double>(
149 SdsIdType id, const std::string &name,
150 double *value, StatusType *status);
151 template <> void SdsArgGet<std::string>(
152 SdsIdType id, const std::string &name,
153 std::string *value, StatusType *status);
154
155
156
157
158
159
160 /*
161 * The PutScalar() template function is used by the Put() method
162 * of sds::Id (no name version) and is implementing something like
163 * the traditional Arg style Put, but directly into the current item.
164 *
165 * The idea is that we must instantiate a specific version of this
166 * for each primitive SDS type and for strings.
167 *
168 * The Put() method won't link unless there is a specific version for
169 * the type in question. There are all implemented in parsys.cpp.
170 */
171 template <typename T> void PutScalar(
172 SdsIdType id,
173 T value, StatusType *status);
174
175 template <> void PutScalar<bool>(
176 SdsIdType id,
177 bool value, StatusType *status);
178 template <> void PutScalar<char>(
179 SdsIdType id,
180 char value, StatusType *status);
181 template <> void PutScalar<short>(
182 SdsIdType id,
183 short value, StatusType *status);
184 template <> void PutScalar<unsigned short>(
185 SdsIdType id,
186 unsigned short value, StatusType *status);
187 template <> void PutScalar<INT32>(
188 SdsIdType id,
190 template <> void PutScalar<UINT32>(
191 SdsIdType id,
193 template <> void PutScalar<INT64>(
194 SdsIdType id,
196 template <> void PutScalar<UINT64>(
197 SdsIdType id,
199 template <> void PutScalar<float>(
200 SdsIdType id,
201 float value, StatusType *status);
202 template <> void PutScalar<double>(
203 SdsIdType id,
204 double value, StatusType *status);
205
206 template <> void PutScalar<const char *>(
207 SdsIdType id,
208 const char *value, StatusType *status);
209
210 template <> void PutScalar<const std::string &>(
211 SdsIdType id,
212 const std::string &value, StatusType *status);
213
214 /*
215 * The GetScalar() template function is used by the Get() method
216 * (no name versions) of sds::Id and is implementing something like
217 * the traditional Arg style Get, but from the current item directly,
218 * hence why no name is supplied.
219 *
220 * The idea is that we must instantiate a specific version of this
221 * for each primitive SDS type.
222 *
223 * The Get() method won't link unless there is a specific version for
224 * the type in question.
225 */
226 template <typename T> void GetScalar(
227 SdsIdType id,
228 T *value, StatusType *status);
229
230 template <> void GetScalar<bool>(
231 SdsIdType id,
232 bool *value, StatusType *status);
233 template <> void GetScalar<char>(
234 SdsIdType id,
235 char *value, StatusType *status);
236 template <> void GetScalar<short>(
237 SdsIdType id,
238 short *value, StatusType *status);
239 template <> void GetScalar<unsigned short>(
240 SdsIdType id,
241 unsigned short *value, StatusType *status);
242 template <> void GetScalar<INT32>(
243 SdsIdType id,
245 template <> void GetScalar<UINT32>(
246 SdsIdType id,
248 template <> void GetScalar<INT64>(
249 SdsIdType id,
251 template <> void GetScalar<UINT64>(
252 SdsIdType id,
254 template <> void GetScalar<float>(
255 SdsIdType id,
256 float *value, StatusType *status);
257 template <> void GetScalar<double>(
258 SdsIdType id,
259 double *value, StatusType *status);
260 template <> void GetScalar<std::string>(
261 SdsIdType id,
262 std::string *value, StatusType *status);
263
264
268 class PrintObjectPnt {
269 public:
278 virtual void Print(const std::string &line) = 0;
279 };
283 class PrintObjectCR {
284 public:
293 virtual void Print(const std::string &line) const = 0;
294 };
401 class Id {
402 private:
403 SdsIdType _id; /* Actual Sds id. 0 (zero) is the null ID */
404 struct {
405 bool free : 1;/* Set true to cause destructor to free the OD*/
406 bool del : 1;/* If free is true, destructor will do SdsDelete*/
407 bool readfree : 1;/* if free , destructor will do SdsReadFree */
408 } _flags;
409
410 /*
411 * Private routine to clean up, will be called by destructor and
412 * Shallow copy operations.
413 *
414 * We defer the work to CleanUpWorker(), but need to indicate to
415 * it if SdsFreeIdAndCheck() should be invoked instead of
416 * just SdsFreeId().
417 *
418 * @param from_where Where have we been invoked form, for message
419 * about SDS ID free failures.
420 */
421 /* no exceptions allowed as may be called from move or destructor */
422 void CleanUp(const std::string &from_where) noexcept {
423#if defined(SDS_CHECK_FREE)||defined(SDS_CHECK_FREE_W)
424 bool check_free = true;
425#else
426 bool check_free = false;
427#endif
428 CleanUpWorker(check_free, from_where);
429 }
430
431 /*
432 * Do the actual clean up.
433 */
434 void CleanUpWorker(bool check, const std::string &from_where) noexcept;
435
436
437
438 /* This method is used by the ArrayAccess methods to check the item
439 is appropriate for the SdsArrayAccessHelper being used
440 */
441 template <class ContainerType>
442 void CheckArrayType(
443 const SdsCodeType code, /* Expected code */
444 const long ndims, /* Expected number of dims */
445 ContainerType * const dims) const { /* Actual dims written here */
446
447 /*
448 * This assertion is detecting that the caller has passed a non-container type
449 *
450 * is_stl_container_v is defined in drama/util.hh
451 */
452 static_assert(is_stl_container_v<ContainerType> == true,
453 "ContainerType is NOT an stl container, if a simple index value, maybe you should consider casting to \"unsigned long\"!");
454
455
457 /*
458 * Get details on the object.
459 */
460 GetDims(dims);
461 /*
462 * Check the code and number of dimensions are correct.
463 */
464 if (tcode != code)
465 {
467 "SDS type does not match expected array type");
468 }
469 if (dims->size() == 0)
470 {
472 "Attempt to access an array in an SDS structure which is not an array");
473 }
474 if (dims->size() != static_cast<unsigned>(ndims))
475 {
477 "SDS Array structure has % dimensions instead of the expected %",
478 dims->size(), ndims);
479 }
480
481 }
482 /*
483 * A simplified access to CheckArrayType, for a single
484 * dimensional array.
485 */
486 void CheckArrayTypeSingleDim(
487 const SdsCodeType code,
488 unsigned long * const nitems) const { /* Actual number of items written here*/
489
490 std::vector<unsigned long> dims;
491 CheckArrayType(code, 1, &dims);
492 *nitems = dims[0];
493
494 }
495
496 /*
497 * This is used to set an ArrayAccessHelper item's data
498 * pointer to be the result of SdsPointer() on this item.
499 *
500 */
501 template <class T> void SetArrayHelperDataAddr(
502 T * const data) const {
503
504 unsigned char *dataAddr = 0;
506 data->SetDataToAddr(dataAddr);
507 }
508
509
510 public:
522 /* Whilst we have SdsCloneId() we can't really use it at this
523 * point since we don't know what to do with the flags.
524 */
525 Id& operator=(const Id &rhs) = delete;
537 /* Whilst we have SdsCloneId() we can't really use it at this
538 * point since we don't know what to do with the flags (who
539 * gets to control deletion?)
540 */
541 Id(const Id &source) = delete;
542
543 /*
544 * Note, the "copy elision" rule is an allowed optimization
545 * in C++, implemented in gcc. It means that the following
546 * two methods will not actually be invoked, through they
547 * must exist for the moves to be allowed. In effect, in cases
548 * where a temp would be constructed and its value moved,
549 * the optimization allows the target variable to be constructed
550 * instead of the temp. See
551 *
552 * http://en.cppreference.com/w/cpp/language/copy_elision
553 *
554 */
555
556
564 Id& operator=(Id &&rhs) noexcept {
565 //fprintf(stderr,"drama::sds::Id move assignment triggered\n");
566
567 CleanUp("sds::Id move assignment");
569 _id = rhs._id;
570 _flags = std::move(rhs._flags);
571
572 rhs._id = 0;
573 return *this;
574 }
582 Id(Id &&source) noexcept :
583 _id(source._id), _flags(std::move(source._flags)) {
584 //fprintf(stderr,"drama::sds::Id move constructor triggered\n");
585 source._id = 0;
586 }
587
593 Id() {
594 _id = 0;
595 _flags.free = false;
596 _flags.del = false;
597 _flags.readfree = false;
598 }
599
600 private:
601 /* Construct an sds::Id item from an existing C language SDS id.
602 *
603 * This sds::Id constructor that takes an existing SDS id
604 * (C style) and creates an sds::Id class object which refers
605 * to that SDS id. You must explicitly specify if the item is to be
606 * free-ed and/or deleted when the object's destructor is invoked,
607 * and what you do depends on when what other code may do with
608 * item. The del and readfree are mutually exclusive, through
609 * this is currently not checked in this implementation.
610 *
611 * @param item The SdsIdType of the item. If 0 (the default), the
612 * sds::Id object constructed does not refer to any SDS
613 * item. This is normally only used when we want an
614 * argument to pass (by pointer) to a function which
615 * will use move assignment or sds::Id::ShallowCopy()
616 * to set the ID.
617 *
618 * @param free Set true to invoke DCF(SdsFreeId) on the ID when the
619 * object is destroyed. The default is false.
621 * @param del Set true to invoke DCF(SdsDelete) on the ID when
622 * the object is destroyed. The default is false.
623 *
624 * @param readfree Set true to invoke DCF(SdsReadFree) on the ID
625 * when the object is destroyed. The default is false.
626 *
627 */
628 explicit Id(const SdsIdType item, const bool free=false,
629 const bool del = false, const bool readfree = false) :
630 _id(item) {
631 _flags.free = free;
632 _flags.del = del;
633 _flags.readfree = readfree;
634 }
635 public:
651 static Id CreateNullItem();
652
679 const SdsIdType item, const bool free=false,
680 const bool del = false, const bool readfree = false);
681
693 const SdsIdType item);
694
695
712 static Id CreateFromSdsId(const SdsId &item);
713
731 static Id CreateFromSdsId(SdsId *item);
732
733
761 template <class ContainerType>
763
764 /*
765 * Confirm the container is a container of POD types.
766 * From C++20, std::is_pod<>() is depreciated, we can replace
767 * by std::is_standard_layout<>::value
768 */
769 static_assert(
770 std::is_standard_layout<typename ContainerType::value_type>::value,
771 "The value type in the container must be a standard layout type");
772
773 if (container->empty())
774 {
776 "Attempt to access data in empty container");
777 }
778 Id item(0, true, false, false); /* Must free-ed when done */
780 SdsAccess(&(*container)[0],&item._id,&status);
781 if (status != STATUS__OK)
782 DramaTHROW(status, "Failed to access SDS Item");
783
784 return item;
785 }
809 template <class ContainerType>
811 /*
812 * Confirm the container is a container of POD types.
813 * From C++20, std::is_pod<>() is depreciated, we can replace
814 * by std::is_standard_layout<>::value
815 */
816 static_assert(
817 std::is_standard_layout<typename ContainerType::value_type>::value,
818 "The value type in the container must be a standard layout type");
819
820
821 if (container.empty())
822 {
824 "Attempt to access data in empty container");
825 }
826
827
828 Id item(0, true, true, false); /* Must deleted and free-ed when done */
830 SdsImport(&container[0],&item._id,&status);
831 if (status != STATUS__OK)
832 DramaTHROW(status, "Failed to import SDS Item");
833
834 return item;
835 }
836
852 static Id FromFile(const std::string &filename);
871 virtual Id CreateChildItem(
872 const std::string &name,
873 const SdsCodeType code,
874 const std::string &extra = "") const;
875
889 static Id CreateTopLevel(
890 const std::string &name,
891 const SdsCodeType code,
892 const std::string &extra = "");
893
925 template <class ContainerType>
927 const std::string &name,
928 const SdsCodeType code,
929 const ContainerType& dims,
930 const std::string &extra = "") const {
931
932 /*
933 * This assertion is detecting that the caller has passed a non-container type
934 *
935 * is_stl_container_v is defined in drama/util.hh
936 */
937 static_assert(is_stl_container_v<ContainerType> == true,
938 "ContainerType is NOT an stl container, if a simple index value, maybe you should consider casting to \"unsigned long\"!");
939
940
941 Id item(0,true, false, false);
943
944 /*
945 * "dims" can be any container that
946 * 1. Has a size method.
947 * 2. Can be used to initialize a std::vector of unsigned long.
948 * 3. And it is validated for a 0 < size <= 7.
949 */
950 if ((dims.size() < 1)||(dims.size() > SDS__MAXDIMS))
951 {
953 "Failed to create new SDS array - % dimensions, minimum supported 1, maximum supported is %",
954 dims.size(),
956 }
957 /*
958 * We need to pass an array of unsigned long to SdsNew for
959 * the dimensions. The best approach is to create a vector
960 * of unsigned long and initialize it with the contents of
961 * our passed in container.
962 */
963 std::vector<unsigned long> myDims(dims);
964
965 SdsNew(_id,name.c_str(),extra.size(),extra.data(),code,
966 myDims.size(), myDims.data(),&item._id,&status);
967 if (status != STATUS__OK)
968 DramaTHROW_S(status, "Failed to create new SDS array top-level item %",name);
969 return item;
970 }
971
1001 const std::string &name,
1002 const SdsCodeType code,
1003 const unsigned nElem,
1004 const std::string &extra = "") const {
1005
1006 Id item(0,true, false, false);
1008
1009 /*
1010 * This is a simplification of the above multi-dimensional
1011 * version.
1012 */
1013 unsigned long dims[1];
1014 dims[0] = nElem;
1015 SdsNew(_id,name.c_str(),extra.size(),extra.data(),code,
1016 1, dims, &item._id,&status);
1017 if (status != STATUS__OK)
1018 DramaTHROW_S(status, "Failed to create new SDS array top-level item %",name);
1019 return item;
1020 }
1021
1022
1023
1050 template <class ContainerType>
1051 static Id CreateTopLevelArray(
1052 const std::string & name,
1053 const SdsCodeType code,
1054 const ContainerType& dims,
1055 const std::string &extra = ""){
1056
1057 Id item(0,true, true, false);
1059
1060 /*
1061 * "dims" can be any container that
1062 * 1. Has a size method.
1063 * 2. Can be used to initialize a std::vector of unsigned long.
1064 * 3. And it is validated for a 0 < size <= 7.
1065 */
1066 if ((dims.size() < 1)||(dims.size() > SDS__MAXDIMS))
1067 {
1069 "Failed to create new SDS array - % dimensions, minimum supported 1, maximum supported is %",
1070 dims.size(),
1072 }
1073 /*
1074 * We need to pass an array of unsigned long to SdsNew for
1075 * the dimensions. The best approach is to create a vector
1076 * of unsigned long and initialize it with the contents of
1077 * our passed in container.
1079 std::vector<unsigned long> myDims(dims);
1080
1081
1082 SdsNew(0,name.c_str(),extra.size(),extra.data(),code,
1083 myDims.size(), myDims.data(),&item._id,&status);
1084 if (status != STATUS__OK)
1085 DramaTHROW_S(status, "Failed to create new SDS array top-level item %",name);
1086
1087 return item;
1088 }
1089
1115 static Id CreateTopLevelArray(
1116 const std::string & name,
1117 const SdsCodeType code,
1118 const unsigned nElem,
1119 const std::string &extra = ""){
1120
1121 Id item(0,true, true, false);
1123
1124 /*
1125 * This is a simplification of the above multi-dimensional
1126 * version.
1127 */
1128 unsigned long dims[1];
1129 dims[0] = nElem;
1130
1131
1132 SdsNew(0,name.c_str(),extra.size(),extra.data(),code,
1133 1, dims,&item._id,&status);
1134 if (status != STATUS__OK)
1135 DramaTHROW_S(status, "Failed to create new SDS array top-level item %",name);
1136
1137 return item;
1138 }
1139
1140
1141
1184 template <class ContainerType>
1186 bool throwOnNotFound=true) const {
1187 Id item(0, true, false, false);
1188
1189 /*
1190 * This assertion is detecting that the caller has passed a non-container type
1191 *
1192 * is_stl_container_v is defined in drama/util.hh
1193 */
1194 static_assert(is_stl_container_v<ContainerType> == true,
1195 "ContainerType is NOT an stl container, if a simple index value, maybe you should consider casting to \"unsigned long\"!");
1196
1197
1198 /*
1199 * "dims" can be any container that
1200 * 1. Has a size method.
1201 * 2. Can be used to initialize a std::vector of unsigned long.
1202 * 3. And it is validated for a 0 < size <= 7.
1203 */
1204 if ((indicies.size() < 1)||(indicies.size() > SDS__MAXDIMS))
1205 {
1207 "Failed to access SDS array cell - % dimensions, minimum supported 1, maximum supported is %",
1208 indicies.size(),
1210 }
1211 /*
1212 * We need to pass an array of unsigned long to SdsCell for
1213 * the dimensions. The best approach is to create a vector
1214 * of unsigned long and initialize it with the contents of
1215 * our passed in container.
1216 */
1217 std::vector<unsigned long> myDims(indicies);
1218
1219
1221 SdsCell(_id, myDims.size(), myDims.data(), &item._id, &status);
1222
1223 /* Special case of item not found and don't want to throw, return null id */
1225 {
1226 item._flags.free = false;
1227 return item;
1228 }
1229
1230 if (status != STATUS__OK)
1232 "Failed to access cell of existing SDS array id");
1233 return item;
1234 }
1272 Id Cell(unsigned long index,
1273 bool throwOnNotFound=true) const {
1274 Id item(0, true, false, false);
1275
1276 /*
1277 * We need to pass an array of unsigned long to SdsCell for
1278 * the dimensions.
1279 */
1280 unsigned long dims[1] = {index};
1281
1282
1284 SdsCell(_id, 1, dims, &item._id, &status);
1285
1286 /* Special case of item not found and don't want to throw, return null id */
1288 {
1289 item._flags.free = false;
1290 return item;
1291 }
1292
1293 if (status != STATUS__OK)
1294 {
1295 List();
1297 "Failed to access cell index % of existing SDS array id", index);
1298 }
1299 return item;
1300 }
1301
1317 virtual Id Copy() const;
1318
1340 virtual Id Find(const std::string &name,
1341 bool throwOnNotFound=true) const;
1342
1370 virtual Id Index(const long index, bool throwOnNotFound=true) const;
1371
1388 virtual ~Id() {
1389 /*Just invoke the private cleanup routine */
1390 CleanUp("sds::Id destructor");
1391 }
1392 /* Modify flags */
1393
1399 virtual void SetFree() { _flags.free = true; }
1405 virtual void SetDelete() { _flags.del = true; }
1406
1415 virtual void ClearDelete() { _flags.del = false; }
1416
1426 virtual void Outlive() {
1427 _flags.free = false;
1428 _flags.del = false;
1429 _flags.readfree = false;
1430 }
1431
1433 * General operations, as per similar SDS operations.
1434 * Currently only Delete, Get and Put are virtual.
1435 */
1436
1454 virtual void Delete() {
1456 SdsDelete(_id,&status);
1457 if (status == STATUS__OK)
1458 {
1459 _flags.del = false;
1460 if (_flags.free)
1461 {
1462 SdsFreeId(_id, &status);
1463 if (status == STATUS__OK)
1464 {
1465 _id = 0;
1466 _flags.free = false;
1467 }
1468 }
1469 }
1470 else
1471 DramaTHROW(status, "Failed to delete SDS item");
1472 }
1473
1474
1483 virtual void DeleteIfExists(const std::string &name) {
1484
1485 if (!Exists(name)) return;
1486
1487 auto itemId = Find(name);
1488 itemId.Delete();
1489 }
1490
1518 template <class ContainerType>
1519 void Export(ContainerType *container) const {
1521
1522 /*
1523 * Confirm the container is a container of POD types.
1524 * From C++20, std::is_pod<>() is depreciated, we can replace
1525 * by std::is_standard_layout<>::value
1526 */
1527 static_assert(
1528 std::is_standard_layout<typename ContainerType::value_type>::value,
1529 "The value type in the container must be a standard layout type");
1530
1531
1532 // Must multiple container size() in units by size of each unit.
1533 SdsExport(_id,
1534 (container->size()*sizeof((*container)[0])),
1535 &(*container)[0],&status);
1536 if (status != STATUS__OK)
1537 DramaTHROW(status, "Failed to export SDS item");
1538
1539 }
1564 template <class ContainerType>
1566 /*
1567 * Confirm the container is a container of POD types.
1568 * From C++20, std::is_pod<>() is depreciated, we can replace
1569 * by std::is_standard_layout<>::value
1570 */
1571 static_assert(
1572 std::is_standard_layout<typename ContainerType::value_type>::value ,
1573 "The value type in the container must be a standard layout type");
1574
1576 SdsExportDefined(_id,container->size(),&(*container)[0],&status);
1577 if (status != STATUS__OK)
1578 DramaTHROW(status, "Failed to export defined SDS item");
1579 }
1598 virtual void Extract() {
1600 SdsExtract(_id,&status);
1601 if (status != STATUS__OK)
1602 DramaTHROW(status, "Failed to extract SDS item");
1603
1604 /*
1605 * We need to modify the flags to those appropriate for
1606 * and indepent toplevel item
1607 */
1608 _flags.free = true;
1609 _flags.del = true;
1610 _flags.readfree = false;
1611 }
1624 virtual void Flush() {
1626
1627 //fprintf(stderr,"FLUSH:ID=%d\n", (int)(_id));
1628
1629
1630 SdsFlush(_id,&status);
1631 if (status != STATUS__OK)
1632 DramaTHROW(status, "Failed to flush SDS item");
1633 }
1661 template <typename T>
1662 void Get(const unsigned long length,
1663 T * const data,
1664 unsigned long *actlen = nullptr,
1665 const unsigned long offset=0) const {
1666
1667 /*
1668 * Confirm the data type is a POD type.
1669 * From C++20, std::is_pod<>() is depreciated, we can replace
1670 * by std::is_standard_layout<>::value.
1671 */
1672 static_assert(
1673 std::is_standard_layout<T>::value,
1674 "The type T must be a standard layout type");
1675
1676 unsigned long myactlen;
1677 if (!actlen) actlen = &myactlen;
1679 SdsGet(_id,length,offset,(void *)data,actlen,&status);
1680
1681 if (status != STATUS__OK)
1682 DramaTHROW(status, "Failed to Get data from SDS item");
1683 }
1696 virtual std::string GetExtra() const {
1697
1698 unsigned long length = 0;
1700 SdsGetExtraLen(_id, &length, &status);
1701 if ((status == STATUS__OK)&&(length == 0))
1702 return "";
1703 /*
1704 * Allocate some space to store the extra data in.
1705 */
1706 std::unique_ptr<char[]> extraData(new char[length+1]);
1707
1708 unsigned long actlen;
1709 /*
1710 * Get the data.
1711 */
1713 if (status != STATUS__OK)
1715 "Failed to Get extra data from SDS item");
1716 extraData[length] = 0; // Ensure null termination.
1717 return &extraData[0];
1718 }
1728 virtual std::string GetName() const {
1729
1730 char tName[SDS_C_NAMELEN];
1732 SdsGetName(_id,tName,&status);
1733
1734 if (status != STATUS__OK)
1736 "Failed to Get Name of SDS item");
1737 return tName;
1738
1739
1740 }
1755 virtual SdsCodeType GetCode() const {
1756 SdsCodeType code;
1758 SdsGetCode(_id,&code,&status);
1759 if (status != STATUS__OK)
1760 DramaTHROW(status, "Failed to Get code of SDS item");
1761
1762 return code;
1763
1764 }
1777 virtual void ValidateCode(SdsCodeType requiredCode) const {
1781 if (status != STATUS__OK)
1783 DramaTHROW(status, "Failed to Get code of SDS item");
1784 }
1785
1786 if (actualCode != requiredCode)
1787 {
1789 "SDS Item % has code %, was expected to have code %",
1790 GetName(),
1793 }
1794
1795 }
1796
1818 template <class ContainerType>
1819 void GetDims(ContainerType *dims) const {
1820
1821 /*
1822 * This assertion is detecting that the caller has passed a non-container type
1823 *
1824 * is_stl_container_v is defined in drama/util.hh
1825 */
1826 static_assert(is_stl_container_v<ContainerType> == true,
1827 "ContainerType is NOT an stl container!");
1828
1829
1830 unsigned long tdims[SDS_C_MAXARRAYDIMS];
1831 long ndims;
1834 if (status != STATUS__OK)
1836 "Failed to Get dimensions of SDS item");
1837
1838 /*
1839 * Copy dims to output location.
1840 */
1841 dims->clear();
1842 for (int i = 0; i < (int)(ndims) ; ++i)
1843 {
1844 dims->push_back(tdims[i]);
1845 }
1847 }
1857 unsigned GetNumItems() const {
1858
1859 long numItems = 0;
1861 SdsNumItems(_id, &numItems, &status);
1862 if (status != STATUS__OK)
1864 "Failed to Get number of SDS items");
1865
1866 return numItems;
1867 }
1868
1869
1879 virtual void Insert(Id & to_insert) {
1881 SdsInsert(_id,to_insert._id,&status);
1882 if (status != STATUS__OK)
1883 DramaTHROW(status, "Failed to insert SDS item.");
1885
1886
1887 /*
1888 * If we succeed, the new child should not be deleted when
1889 * it's id is destroyed, so clear the flag. (This is why
1890 * we break Tony's normal rule of not using non-const
1891 * references.
1892 */
1893 to_insert._flags.del = false;
1894 }
1914 template <class ContainerType>
1915 void Insert(Id & to_insert,
1916 const ContainerType& dims) {
1917
1918 /*
1919 * This assertion is detecting that the caller has passed a non-container type
1920 *
1921 * is_stl_container_v is defined in drama/util.hh
1922 */
1923 static_assert(is_stl_container_v<ContainerType> == true,
1924 "ContainerType is NOT an stl container!");
1925
1926
1928 /*
1929 * "dims" can be any container that
1930 * 1. Has a size method.
1931 * 2. Can be used to initialize a std::vector of unsigned long.
1932 * 3. And it is validated for a 0 < size <= 7.
1933 */
1934 if ((dims.size() < 1)||(dims.size() > SDS__MAXDIMS))
1935 {
1937 "Failed to create new SDS array - % dimensions, minimum supported 1, maximum supported is %",
1938 dims.size(),
1940 }
1941
1943 * We need to pass an array of unsigned long to SdsNew for
1944 * the dimensions. The best approach is to create a vector
1945 * of unsigned long and initialize it with the contents of
1946 * our passed in container.
1947 */
1948 std::vector<unsigned long> myDims(dims);
1949
1950
1951 SdsInsertCell(_id,myDims.size(),myDims.data(),to_insert._id,&status);
1952
1953 if (status != STATUS__OK)
1954 DramaTHROW(status, "Failed to insert item into array cell");
1955 /*
1956 * If we succeed, the new child should not be deleted when
1957 * it's id is destroyed, so clear the flag
1958 */
1959 to_insert._flags.del = false;
1960 }
1961
1972 virtual void FillArray(const Id &elem) {
1974 SdsFillArray(_id,elem._id,&status);
1975 if (status != STATUS__OK)
1976 DramaTHROW(status, "Failed to fill structure");
1977 }
1978
2017 template <typename T>
2018 void Pointer(T **data, unsigned long * length=0) const {
2019
2020
2021 /*
2022 * Confirm the data type is a POD type.
2023 * From C++20, std::is_pod<>() is depreciated, we can replace
2024 * by std::is_standard_layout<>::value
2025 */
2026 static_assert(
2027 std::is_standard_layout<T>::value,
2028 "The type T must be a standard layout and type");
2029
2030
2031 unsigned long mylength;
2033
2034 if (!length) length = &mylength;
2035
2036 void *tdata;
2037
2039 if (status != STATUS__OK)
2040 DramaTHROW(status, "Failed to get pointer to data.");
2041
2042 *data = static_cast<T *>(tdata);
2043
2044 /* fprintf(stderr,"Pointer:ID=%d, pointer=%p\n",
2045 (int)(_id), (void *)(tdata));
2046 */
2047 }
2048
2073 template <typename T>
2074 void Put(const unsigned long length,
2075 const T * const data,
2076 const unsigned long offset=0) {
2078 /*
2079 * Confirm the data type is a POD type.
2080 * From C++20, std::is_pod<>() is depreciated, we can replace
2081 * by std::is_standard_layout<>::value
2082 */
2083 static_assert(
2084 std::is_standard_layout<T>::value,
2085 "The type T must be a standard layout type");
2086
2087 const void *tdata = static_cast<const void *>(data);
2088
2090 if (status != STATUS__OK)
2091 DramaTHROW(status, "Failed to put data into SDS.");
2092
2093
2094 }
2095
2107 virtual void PutExtra(const std::string &extra) {
2108
2110 SdsPutExtra(_id,extra.size(),extra.data(),&status);
2111 if (status != STATUS__OK)
2112 DramaTHROW(status, "Failed to put extra data into SDS.");
2113 }
2122 virtual void Rename(const std::string &name) {
2124 SdsRename(_id,name.c_str(),&status);
2125 if (status != STATUS__OK)
2126 DramaTHROW(status, "Failed to rename SDS item..");
2127
2128 }
2155 template <class ContainerType>
2156 void Resize(const ContainerType& dims) {
2157
2158 /*
2159 * This assertion is detecting that the caller has passed a non-container type
2160 *
2161 * is_stl_container_v is defined in drama/util.hh
2162 */
2163 static_assert(is_stl_container_v<ContainerType> == true,
2164 "ContainerType is NOT an stl container!");
2165
2166
2168 /*
2169 * "dims" can be any container that
2170 * 1. Has a size method.
2171 * 2. Can be used to initialize a std::vector of unsigned long.
2172 * 3. And it is validated for a 0 < size <= 7.
2173 */
2174 if ((dims.size() < 1)||(dims.size() > SDS__MAXDIMS))
2175 {
2177 "Failed to create new SDS array - % dimensions, minimum supported 1, maximum supported is %",
2178 dims.size(),
2180 }
2181
2182 /*
2183 * We need to pass an array of unsigned long to SdsResize for
2184 * the dimensions. The best approach is to create a vector
2185 * of unsigned long and initialize it with the contents of
2186 * our passed in container.
2187 */
2188 std::vector<unsigned long> myDims(dims);
2189
2190 SdsResize(_id,myDims.size(),myDims.data(),&status);
2191
2192 if (status != STATUS__OK)
2193 DramaTHROW(status, "Failed to resize SDS array");
2194
2195 }
2203 virtual unsigned long Size() const {
2204 unsigned long bytes;
2206 SdsSize(_id,&bytes,&status);
2207 if (status != STATUS__OK)
2208 DramaTHROW(status, "Failed to return size of SDS structure");
2209 return bytes;
2210
2211 }
2225 virtual unsigned long SizeDefined() const {
2226 unsigned long bytes;
2229 if (status != STATUS__OK)
2230 DramaTHROW(status, "Failed to return size of SDS structure");
2231 return bytes;
2232
2233 }
2234
2239 virtual void List() const {
2241 SdsList(_id,&status);
2242
2243 if (status != STATUS__OK)
2244 DramaTHROW(status, "Failed to list SDS structure");
2245 }
2251 virtual void List(FILE *to) const {
2253 SdsListTo(to, _id,&status);
2254
2255 if (status != STATUS__OK)
2256 DramaTHROW(status,"Failed to list SDS structure");
2257 }
2269 virtual void List(std::ostream &strm,
2270 int lineMaxLen=100) const;
2271
2294 virtual void List(PrintObjectPnt *printer, int lineMaxLen=100) const;
2295
2318 virtual void List(const PrintObjectCR
2319 &printer, int lineMaxLen=100) const;
2320
2331 virtual void Write(const std::string &filename) const {
2333 SdsWrite(_id,filename.c_str(),&status);
2334 if (status != STATUS__OK)
2336 "Failed to write SDS structure to file \"%\"",
2337 filename);
2338
2339 }
2340
2351 virtual bool IsExternal() const {
2353 int external = 0;
2354 SdsIsExternal(_id, &external, &status);
2355 if (status != STATUS__OK)
2356 DramaTHROW(status, "Failed to determine if SDS is external");
2357
2358 return external;
2359 }
2360 /* Return the address of an external item.
2361 *
2362 * This method is used to determine the address of the buffer
2363 * containing an external item, if this item refers to an external
2364 * item. This is the value given the contructor which accessed this
2365 * item.
2366 *
2367 * @returns The address of the external item data buffer.
2368 */
2369#if 0 // SdsGetExternInfo() does not actually exist - not sure what happened
2370 virtual void *GetExternInfo() const {
2371 void *data;
2373 SdsGetExternInfo(_id, &data, &status);
2374 if (status != STATUS__OK)
2376 "Failed to get SDS external structure address");
2377
2379 return data;
2380 }
2381#endif
2382
2383
2397 virtual bool Exists(const std::string &name) const;
2411 virtual bool Exists(unsigned index) const;
2412
2413
2425 explicit operator SdsIdType() const { return _id; }
2426
2432 explicit operator bool() const {
2433 return (_id != 0);
2434 }
2435
2463 virtual SdsIdType COut(const bool outlives, bool * const free = 0,
2464 bool * const del= 0, bool * const readfree = 0) {
2465 if (free)
2466 *free = _flags.free;
2467 if (del)
2468 *del = _flags.del;
2469 if (readfree)
2470 *readfree = _flags.readfree;
2471 if (outlives)
2472 _flags.free = _flags.del = _flags.readfree = false;
2473 return (_id);
2474 }
2494 virtual void ShallowCopy (const Id & source) {
2495 if (this != &source)
2496 {
2497 CleanUp("sds::Id::ShallowCopy 1"); /* Run destructor on old id */
2498 _id = source._id;
2499 _flags.free = _flags.del = _flags.readfree = false;
2500 }
2501 }
2502
2503
2523 virtual void ShallowCopy (Id * source, const bool outlives) {
2524 if (this != source)
2525 {
2526 CleanUp("sds::Id::ShallowCopy 2"); /* Run destructor on old id */
2527 _id = source->_id;
2528 if (outlives)
2529 {
2530 /* If we will outlive the source, then we copy the source's
2531 * flags and set the sources flags to false.
2532 */
2533
2534 _flags.free = source->_flags.free;
2535 _flags.del = source->_flags.del;
2536 _flags.readfree = source->_flags.readfree;
2537
2538 source->_flags.free = source->_flags.del =
2539 source->_flags.readfree = false;
2540 }
2541 else
2542 {
2543 _flags.free = _flags.del = _flags.readfree = false;
2544 }
2545 }
2546 }
2547
2548
2568 virtual void ShallowCopy (const SdsIdType source, const bool free=false,
2569 const bool del = false, const bool readfree = false) {
2570 CleanUp("sds::Id::ShallowCopy 3"); /* Run destructor on old id */
2571 _flags.free = free;
2572 _flags.del = del;
2573 _flags.readfree = readfree;
2574 _id = source;
2575 }
2576
2588 virtual void ToSdsId(::SdsId *target, const bool outlives= false) {
2589 if (outlives)
2590 {
2591 /*
2592 * If the target outlives the source, then copy the
2593 * flags and then clear the close versions.
2594 */
2595 target->ShallowCopy(_id, _flags.free,
2596 _flags.del, _flags.readfree);
2597 _flags.free = false;
2598 _flags.del = false;
2599 _flags.readfree = false;
2600 }
2601 else
2602 {
2603 /*
2604 * Otherwise the defaults will do.
2605 */
2606 target->ShallowCopy(_id);
2607 }
2608 }
2609
2646 template <typename T> void ArrayAccess(
2647 ArrayAccessHelper<T> * const data) const {
2648
2649 unsigned long dims[SDS_C_MAXARRAYDIMS];
2650 CheckArrayTypeSingleDim(data->Code(), dims);
2651 data->SetNumElements(dims[0]);
2652 SetArrayHelperDataAddr(data);
2653 }
2690 template <typename T> void ArrayAccess(
2691 const unsigned long nitems,
2692 sds::ArrayAccessHelper<T> * const data) const {
2693
2694 unsigned long dims[SDS_C_MAXARRAYDIMS];
2695 CheckArrayTypeSingleDim(data->Code(), dims);
2696 if (dims[0] != nitems)
2697 {
2699 "ArrayAccess expected % items, found %",
2700 nitems, dims[0]);
2701 }
2702 data->SetNumElements(dims[0]);
2703 SetArrayHelperDataAddr(data);
2704 }
2749 template <typename T, class ContainerType> void ArrayAccess(
2750 ArrayAccessHelper<T> * const data,
2751 long ndims,
2752 ContainerType *dims) const {
2753
2754
2755
2756 if ((ndims < 1)||(ndims > SDS_C_MAXARRAYDIMS))
2757 {
2759 "Failed to access SDS array. Numbers of dimensions % invalid, must be in range 1 to %",
2761
2762 }
2763 CheckArrayType(data->Code(), ndims, dims);
2764
2765 /*
2766 * work out the number of elements
2767 */
2768 unsigned long elements = (*dims)[0];
2769 for (unsigned long i = 1; i < dims->size() ; ++i)
2770 {
2771 elements *= (long)((*dims)[i]);
2772 }
2773 data->SetNumElements(elements);
2774 /*
2775 * Access the data.
2777 SetArrayHelperDataAddr(data);
2778 }
2779
2780
2826 template <typename T, class ContainerType> void ArrayAccess(
2827 ArrayAccessHelper<T> * const data,
2828 ContainerType *dims ) const {
2829
2830 /*
2831 * A bit of a pain, we need to call Dims to get the number
2832 * of dimensions.
2833 */
2834 GetDims(dims);
2835 /*
2836 * The use the above version where we know the number of dimensions
2837 */
2838 ArrayAccess(data, dims->size(), dims);
2839 }
2840 /*** Array creation and access in one operation */
2841
2884 template <typename T> Id ArrayCreateAndAccess(
2885 const std::string &name,
2886 const unsigned nitems,
2887 sds::ArrayWriteHelper<T> * const data,
2888 const std::string & extra = "") {
2889
2890 auto arrayId = CreateChildArray(name, data->Code(), nitems, extra);
2891
2892 data->SetNumElements(nitems);
2893 arrayId.SetArrayHelperDataAddr(data);
2894 return arrayId;
2895 }
2949 template <typename T, class ContainerType> Id ArrayCreateAndAccess(
2950 const std::string &name,
2951 const ContainerType &dims,
2952 sds::ArrayWriteHelper<T> * const data,
2953 const std::string & extra = "") {
2954
2955 auto arrayId = CreateChildArray(name, data->Code(), dims, extra);
2956
2957 /* We need the number of elements (items) in the SDS
2958 * array we have just created
2959 */
2960 unsigned long elements = dims[0];
2961 for (unsigned long i = 1; i < dims.size() ; ++i)
2962 {
2963 elements *= (long)(dims[i]);
2964 }
2965 /* now we can set things up */
2966 data->SetNumElements(elements);
2967 arrayId.SetArrayHelperDataAddr(data);
2968 return arrayId;
2969 }
2970
2971 /*** ARG style methods ***/
2972
2987 static Id CreateArgStruct(const std::string &name = "ArgStructure");
2988
3021 template <typename ContainerType>
3022 static Id CreateArgCmdStruct(
3023 const ContainerType &values,
3024 const std::string &name="ArgStructure") {
3025
3026
3027 Id item(CreateArgStruct(name));
3028
3029 std::string itemName = "Argument";
3030
3031 unsigned argNum = 1;
3032 for (auto s: values) {
3033
3034 std::string thisName = itemName + std::to_string(argNum);
3035
3036 item.Put(thisName,s);
3037
3038 ++argNum;
3039
3040 }
3041
3042 return item;
3043
3044 }
3077 template <typename T>
3078 static Id CreateArgCmdStruct(
3079 const std::initializer_list<T> &values,
3080 const std::string &name="ArgStructure") {
3081
3082 return CreateArgCmdStruct(std::vector<T>(values), name);
3083 }
3113 template <typename T>
3115 const T value,
3116 const std::string &name="ArgStructure") {
3117
3118
3119 Id item(CreateArgStruct(name));
3120 item.Put("Argument1",value);
3121 return item;
3122 }
3123
3124
3153 template <typename ContainerType>
3154 void AddToArgCmdStruct(
3155 const ContainerType &values,
3156 const unsigned firstArg = 1) {
3157
3158 std::string itemName = "Argument";
3159
3160 unsigned argNum = firstArg;
3161 if (argNum == 0) argNum = 1;
3162 for (auto s: values) {
3163
3164 std::string thisName = itemName + std::to_string(argNum);
3165
3166 Put(thisName,s);
3167
3168 ++argNum;
3169
3170 }
3171 }
3172
3173
3174
3186 virtual std::string toString(int maxlen = 200) {
3187
3188 /*
3189 * Allocate some space to store the string in.
3190 */
3191 //std::unique_ptr<char[]> string(new char[maxlen]);
3192 char *string = new char[maxlen];
3193 int length=0;
3195 /*
3196 * ArgToString() does the job for us.
3197 */
3198 ArgToString((SdsIdType)(*this),maxlen,&length,&string[0],&status);
3199 if (status != STATUS__OK)
3200 {
3201 delete[] string;
3202 DramaTHROW(status, "Failed to convert SDS to string");
3203 }
3204
3205 std::string result=&string[0];
3206
3207 return result;
3208 }
3236 template <typename T>
3237 void Put (const std::string &name, T value, const std::string &extraData="") {
3238
3239
3241 /* There must be a specialization of SdsArgPut() which
3242 supports type T. Note that conversion of DRAMA status
3243 to DRAMA 2 exceptions is done here so it need only be
3244 done once.
3245 */
3246 SdsArgPut(_id, name, value, &status);
3247 if (status != STATUS__OK)
3249 "ArgPut failed of item \"%\" failed",
3250 name);
3251 if (extraData != "")
3252 {
3253 auto itemId = Find(name);
3254 itemId.PutExtra(extraData);
3255 }
3256
3257 }
3258
3270 void Put (const std::string &name, const std::string &value,
3271 const std::string &extraData="") {
3272
3273
3275 ArgPutString(_id, name.c_str(), value.c_str(), &status);
3276 if (status != STATUS__OK)
3278 "ArgPut failed of item \"%\" failed",
3279 name);
3280 if (extraData != "")
3281 {
3282 auto itemId = Find(name);
3283 itemId.PutExtra(extraData);
3284 }
3285
3286 }
3306 template <typename T>
3307 void Get (const std::string &name, T *value) const {
3308
3309
3311 /* There must be a specialization of SdsArgGet() which
3312 supports type T. Note that conversion of DRAMA status
3313 to DRAMA 2 exceptions is done here so it need only be
3314 done once.
3315 */
3316 SdsArgGet(_id, name, value, &status);
3317 if (status != STATUS__OK)
3319 "ArgGet failed of item \"%\" failed",
3320 name);
3321
3322 }
3323
3324
3342 template <typename T>
3343 void Put (T value) {
3344
3345
3347 /* There must be a specialization of PutScalar() which
3348 supports type T. Note that conversion of DRAMA status
3349 to DRAMA 2 exceptions is done here so it need only be
3350 done once.
3351 */
3352 PutScalar(_id, value, &status);
3353 if (status != STATUS__OK)
3354 DramaTHROW(status, "PutScalar failed of item failed");
3355
3356 }
3357
3365 void Put (const std::string &value) {
3366
3367
3369 ArgCvt(value.c_str(),ARG_STRING,ARG_SDS,&_id,0,&status);
3371 if (status != STATUS__OK)
3372 DramaTHROW(status, "ArgCvt failed of item failed");
3373
3374 }
3386 template <typename T>
3387 void Get (T *value) const {
3388
3389
3391 /* There must be a specialization of GetScalar() which
3392 supports type T. Note that conversion of DRAMA status
3393 to DRAMA 2 exceptions is done here so it need only be
3394 done once.
3395 */
3396 GetScalar(_id, value, &status);
3397 if (status != STATUS__OK)
3398 DramaTHROW(status, "GetScalar failed of item failed");
3399
3400 }
3401
3402
3424 template <class ContainerType>
3425 void CheckItem(SdsCodeType code,
3426 const ContainerType& dims) const {
3427
3428
3430 /*
3431 * "dims" can be any container that
3432 * 1. Has a size method.
3433 * 2. Can be used to initialize a std::vector of unsigned long.
3434 * 3. And it is validated for a 0 <= size <= 7.
3435 * (Note - dims.size() is unsigned)
3436 */
3437 if (dims.size() > SDS__MAXDIMS)
3438 {
3440 "Failed to check SDS array - % dimensions, minimum supported 0, maximum supported is %",
3441 dims.size(),
3443 }
3444
3445 /*
3446 * We need to pass an array of unsigned long to ArgCheckItem for
3447 * the dimensions. The best approach is to create a vector
3448 * of unsigned long and initialize it with the contents of
3449 * our passed in container.
3450 */
3451 std::vector<long> myDims(dims);
3453 ArgCheckItem(_id,code, myDims.size(),myDims.data(),&status);
3454
3455 if (status != STATUS__OK)
3456 DramaTHROW(status, "Check of SDS item failed");
3457
3458 }
3464 virtual int GetInt() const;
3470 virtual unsigned int GetUInt() const;
3476 virtual long GetLong() const;
3477
3483 virtual unsigned long GetULong() const;
3489 virtual double GetDouble() const;
3490
3496 std::string GetString() const;
3498
3499
3500 /* Enable watching of this SDS id.
3501 *
3502 * Output will go to stderr and any older watch details
3503 * are lost
3504 */
3505 void SetWatch() {
3507 SdsSetWatch(_id, nullptr, nullptr,
3508 nullptr, nullptr, nullptr, &status);
3509 if (status != STATUS__OK)
3510 DramaTHROW(status, "SdsSetWatch failed");
3511 }
3512
3513 }; /* class Id */
3514
3524 private:
3525 SdsCheckType _chkData;
3526 int _line;
3527 std::string _file;
3528 std::string _function;
3529 public:
3550 IdChecker(int line, const char *file, const char *function)
3551 : _line(line), _file(file), _function(function) {
3553 SdsCheckInit(&_chkData, &ignore);
3554 }
3561 virtual ~IdChecker() {
3563 SdsCheck(0, &_chkData, &status);
3564 if (status == SDS__CHK_LEAK)
3565 fprintf(stderr,"Warning:sds::IdChecker:Function leaked SDS id's - function %s, file %s, check object at line %d\n", _function.c_str(), _file.c_str(), _line);
3566 else if (status == SDS__CHK_RELEASED)
3567 fprintf(stderr,"Warning:sds::IdChecker:Function released SDS id's - function %s, file %s, check object at line %d\n", _function.c_str(), _file.c_str(), _line);
3568 }
3569 };
3581#define SDS_CHECK_IDS2(function_) drama::sds:IdChecker _sds_id_checker(__LINE__, __FILE__, (function_))
3582
3583
3586 typedef std::shared_ptr<Id> IdPtr;
3587
3589
3590 /*
3591 * This structure is used to specify a deleter to unique_ptr in
3592 * the DataPointer class. It provides a null deleter operation as
3593 * SDS will handle tidying this up.
3594 */
3595 struct _nodel
3596 {
3597 void operator()(void *) const { }
3598 };
3599
3618 template <typename T>
3619 class DataPointer : public std::unique_ptr<T,_nodel> {
3620
3621 private:
3622 unsigned long _lengthBytes; // Length of item in bytes.
3623 drama::sds::Id _refId; // SDS Id.
3624 public:
3633
3634 /*
3635 * Confirm the data type is a POD type.
3636 * From C++20, std::is_pod<>() is depreciated, we can replace
3637 * by std::is_standard_layout<>::value
3638 */
3639 static_assert(
3640 std::is_standard_layout<T>::value,
3641 "The type T must be a standard layout and type");
3642
3643 T *dataPnt = 0;
3644 theId.Pointer(&dataPnt, &_lengthBytes);
3645
3646 if (_lengthBytes != sizeof(T))
3647 {
3649 "SDS Pointer error - expected % bytes, got %",
3650 sizeof(T), _lengthBytes);
3651
3652 }
3653
3654
3655 std::unique_ptr<T, _nodel> p(dataPnt, _nodel());
3656
3657 *((std::unique_ptr<T,_nodel>*)(this)) = std::move(p);
3658
3660
3661 }
3671
3672
3673 /*
3674 * Confirm the data type is a POD type.
3675 * From C++20, std::is_pod<>() is depreciated, we can replace
3676 * by std::is_standard_layout<>::value
3677 */
3678 static_assert(
3679 std::is_standard_layout<T>::value,
3680 "The type T must be a standard layout type");
3681
3682 T *dataPnt = 0;
3683 theId->Pointer(&dataPnt, &_lengthBytes);
3684
3685 if (_lengthBytes != sizeof(T))
3686 {
3688 "SDS Pointer error - expected % bytes, got %",
3689 sizeof(T), _lengthBytes);
3690
3691 }
3692
3693
3694 std::unique_ptr<T, _nodel> p(dataPnt, _nodel());
3695
3696 *((std::unique_ptr<T,_nodel>*)(this)) = std::move(p);
3698 _refId.ShallowCopy(theId, outlives);
3699
3700 }
3701
3702
3707 ~DataPointer() {
3708 try
3709 {
3710 _refId.Flush();
3711 }
3712 catch (...)
3713 {
3714 }
3715 }
3720 unsigned long NumBytes() const {
3721 return _lengthBytes;
3722 }
3723 }; // class DataPointer
3724
3744 template <typename T>
3745 class DataPointer<T[]> : public std::unique_ptr<T[], _nodel> {
3746
3747 private:
3748 unsigned long _numItems;
3749 unsigned long _lengthBytes;
3750 drama::sds::Id _refId;
3751 public:
3753 typedef T * iterator;
3755 typedef const T * const_iterator;
3757 typedef T value_type;
3758
3769
3770
3771 /*
3772 * Confirm the data type is a POD type.
3773 * From C++20, std::is_pod<>() is depreciated, we can replace
3774 * by std::is_standard_layout<>::value
3775 */
3776 static_assert(
3777 std::is_standard_layout<T>::value,
3778 "The type T must be a standard layout type");
3779
3780 T *dataPnt = 0;
3781 theId.Pointer(&dataPnt, &_lengthBytes);
3783 if (_lengthBytes < sizeof(T))
3786 "SDS Array Pointer error - expected at least % bytes, got %",
3787 sizeof(T), _lengthBytes);
3788
3789 }
3790
3791
3792 _numItems = _lengthBytes/sizeof(dataPnt[0]);
3793
3794
3795 std::unique_ptr<T[], _nodel> p(dataPnt, _nodel());
3796
3797 *((std::unique_ptr<T[],_nodel>*)(this)) = std::move(p);
3798
3799 _refId.ShallowCopy(theId);
3800
3801 }
3812
3813
3814 /*
3815 * Confirm the data type is a POD type.
3816 * From C++20, std::is_pod<>() is depreciated, we can replace
3817 * by std::is_standard_layout<>::value
3818 */
3819 static_assert(
3820 std::is_standard_layout<T>::value,
3821 "The type T must be a standard layout type");
3822
3823 T *dataPnt = 0;
3824 theId->Pointer(&dataPnt, &_lengthBytes);
3825
3826 if (_lengthBytes < sizeof(T))
3827 {
3829 "SDS Array Pointer error - expected at least % bytes, got %",
3830 sizeof(T), _lengthBytes);
3831
3832 }
3833
3834
3835 _numItems = _lengthBytes/sizeof(dataPnt[0]);
3836
3837
3838 std::unique_ptr<T[], _nodel> p(dataPnt, _nodel());
3839
3840 *((std::unique_ptr<T[],_nodel>*)(this)) = std::move(p);
3841
3842 _refId.ShallowCopy(theId, outlives);
3843
3844 }
3845
3850 ~DataPointer() {
3851 try
3852 {
3853 _refId.Flush();
3854 }
3855 catch (...)
3856 {
3857 }
3858 }
3863 unsigned long size() const {
3864 return _numItems;
3865 }
3870 unsigned long NumBytes() const {
3871 return _lengthBytes;
3872 }
3877 iterator begin() {
3878 return & (*this)[0];
3879 }
3884 iterator end() {
3885 return (&(*this)[0])+_numItems;
3886 }
3891 const_iterator begin() const {
3892 return & (*this)[0];
3893 }
3898 const_iterator end() const {
3899 return (&(*this)[0])+_numItems;
3900 }
3908 const_iterator cbegin() const {
3909 return & (*this)[0];
3910 }
3918 const_iterator cend() const {
3919 return (&(*this)[0])+_numItems;
3920 }
3932 bool empty() const {
3933 return false;
3934 }
3936 }; // class DataPointer - Array Partial specialization
3937
3965 /*
3966 * We need to implement the std::iterator template to ensure we pick
3967 * up various iterator types etc.
3968 *
3969 * It is unclear if we need to define the third argument to this
3970 * template, if we do, I'm not sure what it should be.
3971 *
3972 * std::iterator was depreciated from C++17, we are supposed
3973 * to now provide each of the relevant types explicitly.
3974 * See https://www.fluentcpp.com/2018/05/08/std-iterator-deprecated/ and
3975 * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0174r2.html#2.1
3976 */
3977 class IdIterator /*: public std::iterator<std::forward_iterator_tag, Id> */ {
3978 public: /* std::iterator equivalents */
3979 using iterator_category = std::forward_iterator_tag;
3980 using value_type = Id;
3981 using difference_type =std::ptrdiff_t;
3982 using pointer = Id*;
3983 using reference = Id&;
3984
3985 private:
3986 /* The item we are iterating through */
3987 const Id &_top;
3988 /* Is the item an array of structures. If false, presumed to
3989 * be a structure (validated by constructor)
3990 */
3991 bool _isArray = false;
3992 /* Index to Current component */
3993 unsigned long _curCell = ULONG_MAX;
3994 /* Index to last component + 1 */
3995 unsigned long _endCell = ULONG_MAX;
3996 public:
4008 explicit IdIterator(const Id & id, const bool setEnd=false) :
4009 _top(id) {
4010 /*
4011 * id must be a structure.
4012 */
4013 if (_top.GetCode() != SDS_STRUCT)
4014 {
4016 "Attempt to construct IdIterator on non-structured SDS item (code %)", _top.GetCode());
4017
4018 }
4019 /*
4020 * Grab the dimensions - can only work with a value of 0 or 1.
4021 */
4022 std::vector<unsigned> dims;
4023 _top.GetDims(&dims);
4024 if (dims.size() > 0)
4025 {
4026 /*
4027 * Array item.
4028 */
4029 _isArray = true;
4030 /*
4031 * Code does not yet handle dimensions greater then 1, as
4032 * that requires determining the order we index the
4033 * array etc.
4034 */
4035 if (dims.size() > 1)
4036 {
4038 "Attempt to construct IdIterator on an array of structures with more then 1 dimension - can't yet do that. ");
4039 }
4040 /*
4041 * Index of arrays starts at 1. dims[0] is one
4042 * past the last element.
4043 */
4044 _endCell = dims[0]+1;
4045 _curCell = 1;
4046 }
4047 else
4048 {
4049 /*
4050 * Indexing of structures starts at 1. GetNumItems() is
4051 * the maximum value.
4052 */
4053 _endCell = id.GetNumItems()+1;
4054 _curCell = 1;
4055 }
4056 /*
4057 * IF we are constructing the end item, set _curCell to _endCell.
4058 */
4059 if (setEnd)
4060 _curCell = _endCell;
4061 }
4062
4070 bool operator!= (const IdIterator& other) const {
4071 /* First ensure we are referring to the same SDS structure */
4072 if (&_top != &other._top)
4073 return false;
4074 return _curCell != other._curCell;
4075 }
4076
4082 Id operator* () const {
4083 if (_curCell >= _endCell)
4084 {
4086 "Attempt to dereference IdIterator past end of structure");
4087
4088
4089 }
4090 if (_isArray) {
4091 std::vector<unsigned long> indicies(1);
4092 indicies[0] = _curCell;
4093 return _top.Cell(indicies);
4094 } else {
4095 return _top.Index(_curCell);
4096 }
4104 const IdIterator & operator++ () {
4105 /*
4106 * Only increment if less then _endCell. This should ensure
4107 * we never advance past _endCell, ensuring that the comparison
4108 * against end() works correctly
4110 if (_curCell < _endCell)
4111 ++_curCell;
4112
4113 // although not strictly necessary for a range-based for loop
4114 // following the normal convention of returning a value from
4115 // operator++ is a good idea.
4116 return *this;
4117 }
4118
4119
4120 private:
4121 }; // class IdIterator
4122
4123
4124
4139 template <typename T>
4140 class ArrayContainer {
4141 public:
4143 typedef T value_type;
4145 typedef value_type& reference;
4147 typedef std::size_t size_type;
4148 private:
4149 T *_address = nullptr;
4150 size_type _size = 0;
4151 public:
4158 ArrayContainer(T *address, size_type size) :
4159 _address(address), _size(size){
4160 static_assert(
4161 std::is_standard_layout<T>::value,
4162 "The type T must be a standard layout and type");
4163 }
4168 bool empty() const {
4169 return (_size <= 0);
4175 size_type size() const {
4176 return _size;
4177 }
4184 return _address[n];
4188 ~ArrayContainer() {}
4189 }; // Class ArrayContainer
4190
4191
4192 inline drama::sds::IdIterator begin(const drama::sds::Id &id) {
4193 return drama::sds::IdIterator(id);
4194 }
4196 return drama::sds::IdIterator(id, true);
4197 }
4198
4199 } // namespace sds
4200
4201} // namespace drama
4203#endif
SdsCodeType Code() const
Return the SDS type code of the item being accessed.
Definition sdsarray.hh:262
Helper class for access to an SDS Scalar Arrays.
Definition sdsarray.hh:180
size_type size() const
Returns the size of the container in items.
Definition sds.hh:4202
reference operator[](size_type n)
Returns an item at a particular address.
Definition sds.hh:4210
bool empty() const
Returns true if the container is empty.
Definition sds.hh:4195
value_type & reference
The type for a reference to the value.
Definition sds.hh:4172
T value_type
The value type.
Definition sds.hh:4170
ArrayContainer(T *address, size_type size)
Create a container to access the array.
Definition sds.hh:4185
std::size_t size_type
The type used for sizes.
Definition sds.hh:4174
~ArrayContainer()
Destroy the container, not the underlying array item.
Definition sds.hh:4215
A container for simple arrays for use with SDS templates.
Definition sds.hh:4167
Helper class for writing data to SDS Scalar Arrays.
Definition sdsarray.hh:303
const_iterator cend() const
Returns a const iterator pointing to the past-the-end element in the array.
Definition sds.hh:3945
iterator begin()
Returns an iterator pointing to the first element in the array.
Definition sds.hh:3904
const_iterator cbegin() const
Returns a const iterator pointing to the first element in the array.
Definition sds.hh:3935
bool empty() const
Returns true if container is empty.
Definition sds.hh:3959
const T * const_iterator
const iterator for this item
Definition sds.hh:3782
iterator end()
Returns an iterator pointing to the past-the-end element in the array.
Definition sds.hh:3911
unsigned long size() const
Return the number of elements in the array.
Definition sds.hh:3890
DataPointer(const drama::sds::Id &theId)
DataPointer Constructor.
Definition sds.hh:3795
const_iterator begin() const
Returns a const iterator pointing to the first element in the array.
Definition sds.hh:3918
unsigned long NumBytes() const
Return the size of the item in bytes.
Definition sds.hh:3897
~DataPointer()
DataPointer destructor.
Definition sds.hh:3877
T * iterator
iterator for this item
Definition sds.hh:3780
T value_type
Returns the type of T
Definition sds.hh:3784
DataPointer(drama::sds::Id *theId, bool outlives=false)
DataPointer Constructor.
Definition sds.hh:3838
const_iterator end() const
Returns a const iterator pointing to the past-the-end element in the array.
Definition sds.hh:3925
unsigned long NumBytes() const
Return the size of the item in bytes.
Definition sds.hh:3747
DataPointer(drama::sds::Id *theId, bool outlives)
DataPointer Constructor.
Definition sds.hh:3697
~DataPointer()
DataPointer destructor.
Definition sds.hh:3734
DataPointer(const drama::sds::Id &theId)
DataPointer Constructor.
Definition sds.hh:3659
A class that provides direct access to the data of an SDS item, via a sub-class of std::unique_ptr<>.
Definition sds.hh:3646
IdChecker(int line, const char *file, const char *function)
Construct an SdsChecker object.
Definition sds.hh:3577
virtual ~IdChecker()
SdsCheck destructor.
Definition sds.hh:3588
A class to check for SDS leaks.
Definition sds.hh:3550
IdIterator(const Id &id, const bool setEnd=false)
Construct a forward iterator for working through an SDS structure or array of structures.
Definition sds.hh:4035
bool operator!=(const IdIterator &other) const
Inequality operator.
Definition sds.hh:4097
Id operator*() const
Dereference operator - return the sds::Id item the iterator is pointing to.
Definition sds.hh:4109
const IdIterator & operator++()
Increment operator (prefix version).
Definition sds.hh:4131
An iterator for working through SDS Structures and SDS arrays of structures.
Definition sds.hh:4004
virtual void SetFree()
Indicate the underlying SDS item should be free-ed when the sds::Id object is destroyed.
Definition sds.hh:1426
virtual unsigned long GetULong() const
If the SDS item refers to a scalar value, convert it to an unsigned long integer.
Id CreateChildArray(const std::string &name, const SdsCodeType code, const unsigned nElem, const std::string &extra="") const
Factory constructor method Constructor which creates a new child item which is a one-dimensional arra...
Definition sds.hh:1027
Id & operator=(Id &&rhs) noexcept
Move assignment operator.
Definition sds.hh:591
virtual std::string GetName() const
Return the name of the SDS item.
Definition sds.hh:1755
virtual std::string GetExtra() const
Get extra data from an SDS item.
Definition sds.hh:1723
virtual Id CreateChildItem(const std::string &name, const SdsCodeType code, const std::string &extra="") const
Factory constructor method which creates a new (non-array) child item.
void Resize(const ContainerType &dims)
Change the dimensions of an SDS array.
Definition sds.hh:2183
static Id FromFile(const std::string &filename)
Factory constructor method that reads an SDS structure from a file.
Id ArrayCreateAndAccess(const std::string &name, const unsigned nitems, sds::ArrayWriteHelper< T > *const data, const std::string &extra="")
Create a new child of primitive items and access that array, one dimensional.
Definition sds.hh:2911
void Get(const std::string &name, T *value) const
Fetch primitive value from a named component of the structure.
Definition sds.hh:3334
virtual void ClearDelete()
Indicate the underlying SDS structure should NOT be deleted when the sds::Id object is destroyed.
Definition sds.hh:1442
virtual bool Exists(unsigned index) const
Determine if a item of a given index exists in a structure.
void CheckItem(SdsCodeType code, const ContainerType &dims) const
Check an item has a required structure.
Definition sds.hh:3452
unsigned GetNumItems() const
Return the number of components in an SDS structure.
Definition sds.hh:1884
virtual long GetLong() const
If the SDS item refers to a scalar value, convert it to long integer.
virtual void Outlive()
Force the actual SDS ID to outlive the sds::Id variable.
Definition sds.hh:1453
void ArrayAccess(const unsigned long nitems, sds::ArrayAccessHelper< T > *const data) const
Access the data of a single dimensional SDS primitive item array of a specified number of elements.
Definition sds.hh:2717
void ArrayAccess(ArrayAccessHelper< T > *const data) const
Access the data of a single dimensional SDS primitive array item of a specified number of elements.
Definition sds.hh:2673
static Id CreateArgCmdStruct(const ContainerType &values, const std::string &name="ArgStructure")
Factory constructor which creates a new "Arg" style SDS structure in the DRAMA Command style.
Definition sds.hh:3049
virtual void List(const PrintObjectCR &printer, int lineMaxLen=100) const
List the contents of the structure via a PrintObjectCR.
virtual void SetDelete()
Indicate the underlying SDS structure should be deleted when the sds::Id object is destroyed.
Definition sds.hh:1432
virtual Id Find(const std::string &name, bool throwOnNotFound=true) const
Factory constructor method Constructor which returns a reference to a named item.
static Id CreateByAccess(ContainerType *container)
Factory constructor method that accesses an exported SDS structure found in a byte stream.
Definition sds.hh:789
virtual unsigned long SizeDefined() const
Return the size of an SDS structure, as required for exporting when fully defined.
Definition sds.hh:2252
virtual void Write(const std::string &filename) const
Write the contents of the structure to a file.
Definition sds.hh:2358
virtual void Rename(const std::string &name)
Rename the SDS item.
Definition sds.hh:2149
virtual void List() const
List the contents of the structure to standard output.
Definition sds.hh:2266
void Put(const std::string &name, const std::string &value, const std::string &extraData="")
Insert a string value into a named component of the structure.
Definition sds.hh:3297
static Id CreateFromSdsId(SdsId *item)
Factory constructor method that constructs an sds::Id item from an existing old C++ interface SdsId i...
virtual void DeleteIfExists(const std::string &name)
Delete the named SDS item within the current structured item.
Definition sds.hh:1510
virtual unsigned int GetUInt() const
If the SDS item refers to a scalar value, convert it to an unsigned integer.
Id ArrayCreateAndAccess(const std::string &name, const ContainerType &dims, sds::ArrayWriteHelper< T > *const data, const std::string &extra="")
Create a new child of primitive items and access that array, multi-dimensional.
Definition sds.hh:2976
void Put(T value)
Insert a primitive value into the item.
Definition sds.hh:3370
Id & operator=(const Id &rhs)=delete
Assignment operator - deleted.
virtual double GetDouble() const
If the SDS item refers to a scalar value, convert it to a double item.
void Insert(Id &to_insert, const ContainerType &dims)
Insert an SDS object into this object, which is a structured array.
Definition sds.hh:1942
Id Cell(const ContainerType &indicies, bool throwOnNotFound=true) const
Factory constructor method Constructor that returns a cell of a SDS structure which must be an array ...
Definition sds.hh:1212
Id Cell(unsigned long index, bool throwOnNotFound=true) const
Factory constructor method Constructor that returns a cell of a SDS structure which must be a single ...
Definition sds.hh:1299
virtual void ToSdsId(::SdsId *target, const bool outlives=false)
Shallow copy to an SdsId type.
Definition sds.hh:2615
static Id CreateByImport(const ContainerType &container)
Factory constructor method that imports an exported SDS structure found in a byte stream.
Definition sds.hh:837
virtual void List(FILE *to) const
List the contents of the structure to a C file.
Definition sds.hh:2278
virtual void ValidateCode(SdsCodeType requiredCode) const
Validate the code of the SDS item.
Definition sds.hh:1804
void ExportDefined(ContainerType *container) const
Export the SDS structure into a buffer, defining any undefined data.
Definition sds.hh:1592
void Export(ContainerType *container) const
Export the SDS structure into a buffer.
Definition sds.hh:1546
void Pointer(T **data, unsigned long *length=0) const
Obtain a pointer to the data area of a primitive SDS item.
Definition sds.hh:2045
virtual SdsCodeType GetCode() const
Return the code of the SDS item.
Definition sds.hh:1782
void ArrayAccess(ArrayAccessHelper< T > *const data, ContainerType *dims) const
Access the data of an SDS primitive item array.
Definition sds.hh:2853
static Id CreateTopLevelArray(const std::string &name, const SdsCodeType code, const unsigned nElem, const std::string &extra="")
Factory constructor method Constructor which creates a new one-dimensional array top-level item.
Definition sds.hh:1142
virtual void List(std::ostream &strm, int lineMaxLen=100) const
List the contents of the structure to an output stream.
Id(const Id &source)=delete
Copy constructor - deleted.
virtual void ShallowCopy(const SdsIdType source, const bool free=false, const bool del=false, const bool readfree=false)
Shallow copy from SdsIdType.
Definition sds.hh:2595
virtual void Delete()
Delete the SDS item.
Definition sds.hh:1481
static Id CreateFromSdsId(const SdsId &item)
Factory constructor method that constructs an sds::Id item from an existing old C++ interface SdsId i...
void GetDims(ContainerType *dims) const
Return the dimensions of the SDS item.
Definition sds.hh:1846
virtual ~Id()
sds::Id Destructor.
Definition sds.hh:1415
virtual void FillArray(const Id &elem)
Fill out the contents of this object, which is a structured array.
Definition sds.hh:1999
virtual SdsIdType COut(const bool outlives, bool *const free=0, bool *const del=0, bool *const readfree=0)
Return this item as an SdsIdType for return to C code.
Definition sds.hh:2490
void ArrayAccess(ArrayAccessHelper< T > *const data, long ndims, ContainerType *dims) const
Access the data of an SDS primitive item array.
Definition sds.hh:2776
virtual void Insert(Id &to_insert)
Insert an SDS object into this object.
Definition sds.hh:1906
virtual Id Index(const long index, bool throwOnNotFound=true) const
Factory constructor method Constructor which returns an id to a structured item indexed by position...
virtual unsigned long Size() const
Return the size of an SDS structure, as required for exporting.
Definition sds.hh:2230
void Get(const unsigned long length, T *const data, unsigned long *actlen=nullptr, const unsigned long offset=0) const
Get data from an SDS item.
Definition sds.hh:1689
static Id CreateArgCmdStructSingle(const T value, const std::string &name="ArgStructure")
Factory constructor which creates a new "Arg" style SDS structure in the DRAMA Command style.
Definition sds.hh:3141
void Put(const std::string &value)
Insert a string value into the component.
Definition sds.hh:3392
virtual void Extract()
Extract the SDS structure from its parent.
Definition sds.hh:1625
virtual void PutExtra(const std::string &extra)
Put extra data into an SDS item.
Definition sds.hh:2134
virtual void List(PrintObjectPnt *printer, int lineMaxLen=100) const
List the contents of the structure via a PrintObjectPnt object.
static Id CreateTopLevel(const std::string &name, const SdsCodeType code, const std::string &extra="")
Constructor which creates a new (non-array) top-level item.
virtual Id Copy() const
Factory constructor method Id Copy constructor.
void AddToArgCmdStruct(const ContainerType &values, const unsigned firstArg=1)
Insert a set of values from a container into an SDS structure in in the DRAMA Command style.
Definition sds.hh:3181
static Id CreateFromSdsIdType(const SdsIdType item, const bool free=false, const bool del=false, const bool readfree=false)
Factory constructor method that constructs an sds::Id item from an existing C language SDS id.
virtual void ShallowCopy(Id *source, const bool outlives)
Shallow copy from sds::Id.
Definition sds.hh:2550
void Put(const unsigned long length, const T *const data, const unsigned long offset=0)
Put data into an SDS item.
Definition sds.hh:2101
virtual void Flush()
Flush data modified by pointer.
Definition sds.hh:1651
static Id CreateArgStruct(const std::string &name="ArgStructure")
Factory constructor which creates a new "Arg" style SDS structure.
void Get(T *value) const
Fetch primitive value from the component.
Definition sds.hh:3414
static Id CreateArgCmdStruct(const std::initializer_list< T > &values, const std::string &name="ArgStructure")
Factory constructor which creates a new "Arg" style SDS structure in the DRAMA Command style.
Definition sds.hh:3105
virtual int GetInt() const
If the SDS item refers to a scalar value, convert it to an integer.
Id()
Default constructor.
Definition sds.hh:620
Id(Id &&source) noexcept
Move copy constructor.
Definition sds.hh:609
Id CreateChildArray(const std::string &name, const SdsCodeType code, const ContainerType &dims, const std::string &extra="") const
Factory constructor method Constructor which creates a new child item which is an multi-dimensional a...
Definition sds.hh:953
std::string GetString() const
If the SDS item refers to a scalar value or a character string, convert it to a string item.
virtual void ShallowCopy(const Id &source)
Shallow copy from a const sds::Id which will outlive this object.
Definition sds.hh:2521
static Id CreateTopLevelArray(const std::string &name, const SdsCodeType code, const ContainerType &dims, const std::string &extra="")
Factory constructor method Constructor which creates a new array top-level item.
Definition sds.hh:1078
void Put(const std::string &name, T value, const std::string &extraData="")
Insert a primitive value into a named component of the structure.
Definition sds.hh:3264
static Id CreateFromSdsIdTypeCopy(const SdsIdType item)
Factory constructor method that constructs an sds::Id item by coping an existing C language SDS id.
static Id CreateNullItem()
Factory constructor method that constructs an null sds::Id item .
virtual bool IsExternal() const
Determine if the SDS structure is external.
Definition sds.hh:2378
virtual std::string toString(int maxlen=200)
Convert the structure to a string.
Definition sds.hh:3213
virtual bool Exists(const std::string &name) const
Determine if a named item exists in a structure.
A C++ Interface to the handling SDS structures.
Definition sds.hh:428
virtual void Print(const std::string &line) const =0
Method invoked to print one line of an SDS listing.
Abstract class which is sub-classed to print SDS item listings.
Definition sds.hh:310
virtual void Print(const std::string &line)=0
Method invoked to print one line of an SDS listing.
Abstract class which is sub-classed to print SDS item listings.
Definition sds.hh:295
#define DramaTHROW_S(status_, format_,...)
Throw a Drama exception with safe string formatting.
Definition exception.hh:108
#define DramaTHROW(status_, message_)
Throw a Drama exception.
Definition exception.hh:87
DRAMA 2 Exception classes.
std::shared_ptr< Id > IdPtr
A shared pointer for sds::Id items.
Definition sds.hh:3613
void CreateRunDramaTask()
Create and run a DRAMA task, with standard exception handling.
Definition task.hh:1327
void CheckLockTaken(const std::string func, const std::string &file, const int lineNum)
Ensure the current thread has taken the DRAMA task lock.
The drama namespace contains all the classes, types etc of the DRAMA 2 implementation.
Definition drama.hh:93
DRAMA 2 include file - drama::sds::ArrayAccessHelper Sds class definitions.