adressing a structure

C

CptDondo

I have a structure that looks like this:

struct parameterSchedule_t {

uint16_t waterFlow,
uint16_t timerBase,
uint16_t safetyDelay,
uint16_t pressureRiseTimer,
uint16_t stallTimer,
uint8_t autoRestartPower,
uint8_t autoRestartTemp,
uint8_t compassOverride,
uint8_t Group,
uint8_t hmiAddress,
uint8_t plcAddress,
char systemDate[32],
char systemTime[32],
};

This represents the layout in an XML file. I also have an array of XML
elements that looks similar:

char *elements[] = {
"waterFlow",
"timerBase",
"safetyDelay",
"pressureRiseTimer",
"stallTimer",
"autoRestartPower",
"autoRestartTemp",
"compassOverride",
"Group",
"hmiAddress",
"plcAddress",
"systemDate",
"systemTime",
};

What I want to do is to recurse through the XML tree, and somehow look
up the appropriate element in the structure to match the XML element I
just pulled out.... (too much time spent with PHP recently....)

I can't quite figure out how to do that without duplicating a lot of
information. The goal is to be easily maintainable so I am looking for
some what that doesn't require a minor change to touch several header
and code files... Ideally something that can either generate the
structure and array from #defines or something that can be used to get
the correct structure member at runtime....

--Yan
 
M

Michael Mair

CptDondo said:
I have a structure that looks like this:

struct parameterSchedule_t {

uint16_t waterFlow,
uint16_t timerBase,
uint16_t safetyDelay,
uint16_t pressureRiseTimer,
uint16_t stallTimer,
uint8_t autoRestartPower,
uint8_t autoRestartTemp,
uint8_t compassOverride,
uint8_t Group,
uint8_t hmiAddress,
uint8_t plcAddress,
char systemDate[32],
char systemTime[32],
};

This represents the layout in an XML file. I also have an array of XML
elements that looks similar:

char *elements[] = {
"waterFlow",
"timerBase",
"safetyDelay",
"pressureRiseTimer",
"stallTimer",
"autoRestartPower",
"autoRestartTemp",
"compassOverride",
"Group",
"hmiAddress",
"plcAddress",
"systemDate",
"systemTime",
};

What I want to do is to recurse through the XML tree, and somehow look
up the appropriate element in the structure to match the XML element I
just pulled out.... (too much time spent with PHP recently....)

I can't quite figure out how to do that without duplicating a lot of
information. The goal is to be easily maintainable so I am looking for
some what that doesn't require a minor change to touch several header
and code files... Ideally something that can either generate the
structure and array from #defines or something that can be used to get
the correct structure member at runtime....

This will not be easy and depends entirely on what you really need.

If there will be only one object of the struct type, then you can
proceed along the lines of
#define stringize(s) #s
#define XSTR(s) stringize(s)

enum eType { eTypeU16, .... };
#define UINT16 eTypeU16, uint16_t
....
struct lookupEntry {
const char *key;
void* data;
size_t elemSize;
size_t numElem;
eType type;
};
#define createEntry(key, etype, type, num) {\
XSTR(key), \
NULL, \
sizeof (type), \
num, \
etype \
}

struct lookupEntry AbstractStruct[] = {
createEntry(waterFlow, UINT16, 1),
createEntry(timerBase, UINT16, 1),
....
createEntry(systemTime, CHAR, 32)
};

.....
for (i = 0; i < sizeof AbstractStruct/sizeof AbstractStruct[0]; i++)
{
AbstractStruct.data = malloc(elemSize * numElem);
if (NULL == data) {
....
}
....
}

After that, you only are stuck with access code depending
on enum eType.


You cannot generate entries in two types/objects at the
same time via #define, so this is as good as it gets.

If you have more than this one object, then it probably
is better to generate the struct and lookup externally.
Then you can create an ideal hash for your key XML elements
such that lookup works easily.
Then you can index your access operations according to the
hash.
In the simplest case, your programme creates something like
that:
typedef void (*pStoreElement)(struct parameterSchedule_t*,
const char *);
pStoreElement[ELEMENTS+1] = {
store_Invalid,
store_waterFlow,
....
};
void storeElement (struct parameterSchedule_t* obj,
const char *key,
const char *value)
{
pStoreElement[lookup(key)](obj, value);
}
where you can start with lookup():
int lookup (const char *key)
{
for (i = 0; i < ELEMENTS; ++i) {
if (!strcmp(keyTable, key))
return i+1;
}
return 0;
}
and where the functions store_* are simple access operations:
void store_waterFlow(struct parameterSchedule_t* obj,
const char *value)
{
unsigned long val = strtoul(value, NULL, 10);
if (val < 17 || val > 53) {
val = 0;
}
obj->waterFlow = val;
}

Depending on your application, there may be a much better
approach -- or maybe a programming language that is much better
suited to the problem.


Cheers
Michael
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top