Michael wrote:
Yes, that is exactly the file struct. Now i try to access with Data Manager
functions. here is the coding
typedef struct {
DmOpenRef openRef;
UInt16 recordCount;
UInt16 recordIndex;
UInt16 offsetInCurrentRecord;
} sTempDB ;
static Err MyReadDBProc(void *dataP, UInt32 *sizeP, void *userDataP)
{
Err err = errNone;
sTempDB *pDB = (sTempDB *) userDataP;
MemHandle rechdl ;
MemPtr recptr;
if (pDB->recordIndex < pDB->recordCount)
{
rechdl = DmQueryRecord(pDB->openRef, pDB->recordIndex);
pDB->recordIndex ++;
if (rechdl==NULL)
{
err = DmGetLastErr();
ErrAlert(err);
}
else;
{
dataP = MemHandleLock(rechdl);
*sizeP = MemHandleSize(rechdl);
err = MemHandleUnlock(rechdl);
err = DmReleaseRecord(pDB->openRef, pDB->recordIndex, true);
}
}
return err;
}
beamthisapp
(
char *file_name, // File name to beam
)
{
UInt16 ret;
Err err = 0;
LocalID id;
UInt16 cardNumber = 0; // better not to hardcode this
sTempDB db;
// file. = file_name;
db.recordCount = 0; // set the start pos
Why would you set the recordCount to 0? Since you are comparing the
current record index to it, your comparison inside MyReadDBProc() will
always return false. This means MyReadDBProc() will always return
errNone() but never writes data into the buffer! And worse, it
never modifies sizeP, so the caller thinks that it wrote *sizeP
bytes of data into the buffer!
I would do something like this after you open the database:
db.recordCount = DmNumRecords (db.openRef);
Also, inside of MyReadDBProc(), you have three big problems (that I
noticed):
(1) You are changing the dataP pointer argument to something else.
But since all values are always passed by value (not by reference)
in C, this change will have no effect. You cannot change the
pointer that is passed as an argument. You must use the value
of the pointer as a destination to copy the data to. (I would
use MemMove() to do the copy.)
(2) You are setting *sizeP to the size of the record. But *sizeP is
the size of the buffer that dataP points to. So, you need to
set it to some number that is NO LARGER than the original *sizeP.
When MyReadDBProc() is called, ExDBRead() is telling you, "I want
you to write some data into the buffer I supplied. The first
argument tells you where the buffer is located. The second tells
you how big the buffer is. The second also tells you how to tell
me how much of the buffer you used."
(3) You are using MemHandleLock() to get a pointer to some data,
and then you are unlocking it with MemHandleUnlock(), and then
you are expecting that the pointer is still good after you've
unlocked the memory. You should never EVER do that. It will
maybe work some of the time, but it is wrong, and it will
eventually cause a crash, because after you do MemHandleUnlock()
(or at least after you do it enough times to bring the lock count
down to zero), the pointer that it returned is totally invalid.
That's the whole point of locking -- when you unlock, the system
is supposed to be able to rearrange memory in order to compact
things.
Hope that helps.
- Logan
--
For information on using the Palm Developer Forums, or to unsubscribe, please
see http://www.palmos.com/dev/support/forums/