35#ifndef _OPENLCB_CDIUTILS_HXX_
36#define _OPENLCB_CDIUTILS_HXX_
69 free(
const_cast<SXML_CHAR *
>(data));
74 typedef std::unique_ptr<const SXML_CHAR, SXmlStringDeleter>
xmlstring_t;
83 auto count = XMLNode_get_children_count(parent);
84 for (
int i = 0; i < count; ++i)
86 auto *c = XMLNode_get_child(parent, i);
87 if (strcmp(tag, c->tag) == 0)
103 if (n ==
nullptr || n->text ==
nullptr)
116 if (n ==
nullptr || n->text ==
nullptr)
125 static int find_numeric_element(
126 const XMLNode *parent,
const char *tag,
bool *found)
130 if (n ==
nullptr || n->text ==
nullptr){
136 return atoi(n->text);
147 return find_numeric_element(node,
"min", found);
158 return find_numeric_element(node,
"max", found);
169 return find_numeric_element(node,
"default", found);
178 auto *node = XMLDoc_root(doc);
181 node->user =
nullptr;
182 node = XMLNode_next(node);
190 auto *node = XMLDoc_root(doc);
194 node->user =
nullptr;
195 node = XMLNode_next(node);
206 template <
class T,
typename... Args>
209 HASSERT(node->user ==
nullptr);
210 static_assert(std::is_trivially_destructible<T>::value ==
true,
211 "Userdata attached to nodes must be trivially destructible");
212 *info =
static_cast<T *
>(malloc(
sizeof(T)));
213 new (*info) T(std::forward<Args>(args)...);
223 template <
class T>
static void get_userinfo(T **info,
const XMLNode *node)
226 *info =
static_cast<T *
>(node->user);
251 const XMLNode *node,
const char *attr_name,
int def = 0)
253 const SXML_CHAR *attr_value;
254 XMLNode_get_attribute_with_default(
255 const_cast<XMLNode *
>(node), attr_name, &attr_value,
nullptr);
257 if ((!attr_value) || (attr_value[0] == 0))
261 return atoi(attr_value);
279 if (strcmp(child->tag,
"group") == 0)
281 return DataType::GROUP;
283 if (strcmp(child->tag,
"int") == 0)
285 return DataType::INT;
287 if (strcmp(child->tag,
"eventid") == 0)
289 return DataType::EVENTID;
291 if (strcmp(child->tag,
"string") == 0)
293 return DataType::STRING;
295 if (strcmp(child->tag,
"float") == 0)
297 return DataType::FLOAT;
299 return DataType::UNKNOWN;
307 HASSERT(strcmp(segment->tag,
"segment") == 0);
312 if (XMLNode_get_children_count(segment) == 0)
314 XMLNode *current_parent = segment;
315 XMLNode *current_child = XMLNode_get_child(segment, 0);
319 if (strcmp(current_child->tag,
"name") == 0 ||
320 strcmp(current_child->tag,
"description") == 0 ||
321 strcmp(current_child->tag,
"repname") == 0)
334 case DataType::UNKNOWN:
337 case DataType::EVENTID:
340 case DataType::STRING:
342 case DataType::FLOAT:
346 case DataType::GROUP:
347 if (XMLNode_get_children_count(current_child) > 0)
349 current_parent = current_child;
351 XMLNode_get_child(current_parent, 0);
363 while ((current_child = XMLNode_next_sibling(current_child)) ==
367 if (current_parent == segment)
372 current_child = current_parent;
373 current_parent = current_child->father;
378 info->
size *= repcount;
381 if (current_parent == segment && current_child ==
nullptr)
394 HASSERT(strcmp(group->tag,
"group") == 0);
446 if (strcmp(child->tag,
"group") == 0)
470 unsigned stride = info->
size / replication;
471 address_ = base_address + stride * replica;
476 template <
typename... Args>
void reset(Args &&... args)
478 new (
this)
CDINodeRep(std::forward<Args>(args)...);
DataType
Used to classify elements.
static int find_node_default(const XMLNode *node, bool *found)
Finds the default value of the xml integer, if there isn't one it returns a null pointer.
static void layout_segment(XMLNode *segment)
Allocates all userinfo structures within a segment and performs the offset layout algorithm.
static void get_userinfo(T **info, const XMLNode *node)
Retrieve the userinfo structure from an XML node.
static string find_node_name(const XMLNode *node, const char *def)
Finds the name of a CDI element.
CDIUtils()
Static class; never instantiated.
static int get_numeric_attribute(const XMLNode *node, const char *attr_name, int def=0)
Helper function to find and convert an attribute to a number.
static void cleanup_doc(XMLDoc *doc)
Deletes all userinfo structures allocated in a doc.
static void new_userinfo(T **info, XMLNode *node, Args &&... args)
Allocates a new object of type T for the node as userinfo; calls T's constructor with args....
static int get_replication(const XMLNode *group)
static int find_node_max(const XMLNode *node, bool *found)
Finds the max value of the xml integer, if there isn't one it returns a null pointer.
std::unique_ptr< const SXML_CHAR, SXmlStringDeleter > xmlstring_t
Smart pointer class for holding C strings from sxml.
static int find_node_min(const XMLNode *node, bool *found)
Finds the min value of the xml integer, if there isn't one it returns a null pointer.
static string find_node_description(const XMLNode *node)
Find the description of a CDI element.
static void prepare_doc(XMLDoc *doc)
Clears out all user info structure pointers.
static DataType get_type_from_node(XMLNode *child)
Classifies XML elements to node types.
std::unique_ptr< XMLDoc, XMLDocDeleter > xmldoc_ptr_t
Smart pointer class for holding XML documents.
static XMLNode * find_child_or_null(const XMLNode *parent, const char *tag)
Searches the list of children for the first child with a specific tag.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
CDINodeRep(const CDINodeRep *parent, const XMLNode *group, unsigned replica)
Initializes a group rep for a given replica.
unsigned get_child_size(const XMLNode *child) const
Gets the size of a child (number of bytes occupied).
CDINodeRep(const XMLNode *segment)
Initializes a group rep from a segment root.
unsigned address_
address in the current space of the beginning of the current node.
CDINodeRep(const XMLNode *node, std::nullptr_t)
Initializes a group rep from an arbitrary XML element (e.g.
const XMLNode * node_
Element in the XML where we are. This is a segment or a group node.
CDINodeRep()
Default constructor.
unsigned get_child_address(const XMLNode *child) const
Gets the absolute address of a given child in the current segment.
void reset(Args &&... args)
Resets the current representation.
CDINodeRep(const CDINodeRep *parent, const XMLNode *child)
Initializes a group rep which has no replication or an entry rep.
Allocation data we hold about a Data Element in its userinfo structure.
int size
Total number of bytes that this element occupies.
int offset_from_parent
Offset of the address of this element from the address of the parent group element.
Helper class for deleting sxml strings.
void operator()(const SXML_CHAR *data)
Deletion operator.
Helper class for unique_ptr to delete an XML document correctly.
void operator()(XMLDoc *doc)
Deletion operator.