Steve K wrote:
The way I am currently using the palm database does not seem correct.
Yes I have gotten it to work, and it is doing what I ask it to do, however,
It seems WAY too complex and there has to be a better way.

Currently I keep my information in a struct Rec

For example:

Struct Rec {
    char* data;

    int foo;
    char* bar;
.... constructor destructor etc...
};

When I write to the record I am writing Rec.data, which is a char star with
each field seperated by "~"'s.
For example if foo is 5 and bar is "asdf" then data would be "5~asdf"

When I pull the data out of the DB I put it into a new rec's data field.

I then have two functions, CombineDataIntoFields and ExpandData.  This fills
the appropriate fields, foo and bar, with the data out of data, or vice
versa, creates data by concating all the fields with the "~" spacer.

Like I said, WAY too complex.

Yep... I'd say so too!


I have tried just writing a pointer to a record this way:
Struct Rec {
    int foo;
    char* bar;
};
// rec is a *Rec
newRec = DmResizeRecord(db, index, sizeof(rec));
errDb = DmWrite(MemHandleLock(newRec), index, rec, sizeof(rec));
Keep in mind, that you should NEVER store pointers in a database!!!!
The value of a pointer is a highly volatile thing and the next time you read a record from the database it is pretty much sure, that his pointer then points to a memory location that contains something fundamentally different from what it was when you wrote the record! Also the second parameter to DmWrite is the OFFSET into the memory pointed to by the first parameter defining where the writing starts. Using index here doesn't make any sense but I presume you know that and it was just a typo...


Having said that, it is clear (isn't it?) that you have to make sure, you actually write the string to the record and not the pointer to it (or even worse a pointer to the record). Just think in terms of bytes in memory! You have 3 pieces of information here:

1. the value of foo
2. the pointer to a string (bar)
3. the string itself

1. and 2. are stored together in memory in the way that is defined by your struct Rec. It will take 2 bytes for the (16bit) integer and 4 bytes for the pointer to the string.
3. may be anywhere in memory and can only be referenced through the pointer to it stored in bar. It would take as much bytes as the string is long and possibly one more (for the null terminator)


To make this really clear lets say foo=5 and your string pointed to by bar is "asdf" like in your above example and it is stored at the address 0x066666 then your record (let's say it is at address 0x044444) would look like this:

0x044444: 00 05 00 06 66 66 (the equivalent of foo=5, bar=0x066666)

and at 0x066666 you'd see

0x066666: 61 73 64 66 00 (the equivalent of "adsf" with null terminator)

Now doing DmWrite(MemHandleLock(newRec), 0, rec, sizeof(Rec)) would write the bytes 00 05 00 06 66 66 to the record and the next time you read this record the address of bar (0x066666) will most certainly point to something very different than your string "adsf"!!!

What you actually want to write to the record in the DB is the byte sequence 00 05 61 73 64 66 00 representing your value of foo (5) and the data of the string ("asdf" plus null terminator).

You can pretty easily acomplish that by doing the following:

// making the record big enough to store foo and the string:
newRec = DmResizeRecord(db,index,sizeof(Rec.foo)+strlen(rec->bar)+1)
// getting a pointer to the resized record's memory
newRecPtr = MemHandleLock(newRec);
// writing the value of foo to the record
DmWrite(newRecPtr,0,&(rec->foo),sizeof(Rec.foo));
// writing the string to the record
DmWrite(newRecPtr,sizeof(Rec.foo),rec->bar,strlen(rec->bar)+1);

I hope that clarifies it for you good enough to finally realize the difference between a pointer to a string and the string itself.
C is very confusing in that area since dealing with strings in C always means dealing with pointers to strings and you have to take special care if you want to actually do something with the string's memory itself!



I know there has to be a way to do something like this but it isn't quite working yet.

Any suggestions?

tia,

Steve K


--
For information on using the Palm Developer Forums, or to unsubscribe, please see 
http://www.palmos.com/dev/support/forums/

Reply via email to