By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
431,943 Members | 1,890 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 431,943 IT Pros & Developers. It's quick & easy.

adressing a structure

P: n/a
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
Sep 21 '06 #1
Share this Question
Share on Google+
1 Reply


P: n/a
CptDondo schrieb:
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[i].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[i], 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
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Sep 22 '06 #2

This discussion thread is closed

Replies have been disabled for this discussion.