I agree the pack and unpack method might be inefficient with a 60,000 element array,
but the second method I showed you is pretty efficient - no copies, just compares.
I used StrStr because I wasn't sure if you were looking for exact matches of the key
in the
strings or just looking for the occurrence of the key in one of the strings.
It's probably better to use nulls to delimit strings, then you can use normal Str
functions and
also don't have to worry about '|' appearing within a string. You could put two nulls
at the end
of your last string so you know when you've hit your last string.
If you need to jump around and skip several items to find the key for each product,
you could do something like this:
// in your search loop
Char* p = (Char*)MemHandleLock(recH);
descriptionP = p;
// if we are at the last one, then descriptionP will point at a null.
while(descriptionP)
{
descriptionP = StrLen(p) + 1; // skip prodno
if(0 == StrCompare(descriptionP, key))
{
found = true;
}
else
{
descriptionP = StrLen(p) + 1; // skip description
descriptionP = StrLen(p) + 1; // skip cost
descriptionP = StrLen(p) + 1; // skip retail
descriptionP = StrLen(p) + 1; // skip unitofmeasure
}
}
Something like that anyway. I'm spewing this out without really thinking too hard
(because I'm really supposed to be doing
other things right now... ;^) )
Kevin
-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Sent: Tuesday, July 08, 2003 3:04 PM
To: Palm Developer Forum
Subject: RE: Multiple Text Records per PalmOS Record
Okay, suppose I'm storing them using "|" as a delimeter.
Also, when I pull the 'string' out from the PalmRecord, it's a 60,000
element character array
essentially. This just doesn't seem efficient to me.
If I use that pointer method, won't that mean that I'm search through every
single string?
Because I'll only want to to a String comparison on the key field.
Or am I missing something alltogether. Your response Kevin btw is greatly
appreciated.
Nole
"Kevin OKeefe"
<[EMAIL PROTECTED]> To: "Palm Developer Forum"
<[EMAIL PROTECTED]>
Sent by: cc: (bcc: Nole
Mailey/pmc)
[EMAIL PROTECTED] Subject: RE: Multiple Text Records
per PalmOS Record
palmos.com
07/08/2003 04:27 PM
Please respond to "Palm Developer
Forum"
Or, after more closely reading your request...
In your searching loop:
// assuming that the strings packed in p are null-terminated...
foundStrPtr = StrStr(stringToFind, p);
if(foundStrPtr)
found = true;
else
p += StrLen(p) + 1; // advance to next
string in packed array.
-----Original Message-----
From: Kevin OKeefe
Sent: Tuesday, July 08, 2003 2:18 PM
To: Palm Developer Forum
Subject: RE: Multiple Text Records per PalmOS Record
// your "packed" record
struct
{
// This just allocates one character.
// you will just use this to start pointing at the null
terminated strings starting at &firstString[0]
Char firstString[1];
}PackedRec;
// your "unpacked" record
// Could also be composed of Char str1[30];...
struct
{
Char* str1;
Char* str2;
Char* str3;
...
}UnpackedRec;
// the packer function
void PackRec(PackedRec* packed, UnpackedRec* unpacked)
{
UInt16 newRecSize = StrLen(unpacked->str1) + 1 +
StrLen(unpacked->str2) + 1 +... // add one for each null for each string.
MemHandle h = DmNewRecord(db, newRecSize);
Char* p = MemHandleLock(h);
UInt32 offset = 0;
DmStrCopy(p, offset, unpacked->str1);
offset += StrLen(unpacked->str1) + 1;
DmStrCopy(p, offset, unpacked->str2);
offset += StrLen(unpacked->str2) + 1;
... etc.
}
// The unpacker function
// Note packed is probably from MemHandle = DmQueryRecord(db, index);
PackedRec* p = MemHandleLock(h);
// Also note that if you do this, you must keep packed locked while using
the pointers in unpacked.
// You could also make unpacked a structure of Char
string1[MAX_CHARS]; and then not have to worry
// about keeping the packed structure locked during use.
void UnpackRec(UnpackedRec* unpacked, PackedRec* packed)
{
Char* packedPtr = (Char*)packed;
unpacked->str1 = packedPtr;
packedPtr += StrLen(packedPtr) + 1; //
advance past null of this string to first char of next string
unpacked->str2 = packedPtr;
packedPtr += StrLen(packedPtr) + 1;
...etc.
}
Hope this hastily typed and completely unchecked code helps give you an
idea...
Kevin
-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Sent: Tuesday, July 08, 2003 1:51 PM
To: Palm Developer Forum
Subject: Re: Multiple Text Records per PalmOS Record
My apologies, here's the FULL function I've been working on:
********************************************************************************************************
static Err DisplayFirstRecord(DmOpenRef testDB, Char *searchKey)
{
Err err = 0;
Int32 len = 0;
Char fieldCount = 9;
Char fieldCounter = 0;
Char i = 0;
Int32 startCoord = 0;
Int16 palmRecIndex = 0;
MemHandle myRecord;
Char data[64];
Char someString[31];
for(i=0;myRecord = DmQueryRecord(testDB, i);i++)
{
Char *s = (Char *) MemHandleLock(myRecord);
Char number[64];
Int16 start=0;
Int16 end=0;
Int16 field=0;
Char key[12];
for(i=0;s[i];i++)
{
if(s[i]=='|')
{
field++;
if(field == 1)
{
end = i;
StrNCopy(key,&s[start],end);
key[end]='\0';
if(!StrCompare(key,searchKey))
{
FrmCustomAlert(MyAlert,"FOUND!
->",key,NULL);
return(true);
}
}
else
{
StrIToA(number,field);
FrmCustomAlert(MyAlert,"FIELD:
",number,NULL);
start = i+1;
}
if(field == 9)
{
field = 0;
}
}
}
palmRecIndex++;
}
if(!myRecord)
{
err = DmGetLastErr();
FrmCustomAlert(MyAlert,"No record found!",NULL,NULL);
}
return 0;
}
********************************************************************************************************
********************************************************************************************************
********************************************************************************************************
********************************************************************************************************
********************************************************************************************************
Here's what I've got so far... (still working out the kinks)
I've got it finding the first record, but anything thereafter is choking.
If anyone can suggest a better way, I'm all ears....
for(i=0;s[i];i++)
{
if(s[i]=='\0')
{
field++;
if(field == 1)
{
end = i;
StrNCopy(key,&s[start],end);
key[end]='\0';
if(!StrCompare(key,searchKey))
{
FrmCustomAlert(MyAlert,"FOUND! ->",key,NULL);
return(true);
}
}
else
{
start = i+1;
}
if(field == 9)
{
field = 0;
}
}
}
Nole Mailey
[EMAIL PROTECTED]
Sent by: To: "Palm
Developer Forum" <[EMAIL PROTECTED]>
[EMAIL PROTECTED] cc: (bcc:
Nole Mailey/pmc)
palmos.com Subject:
Re: Multiple Text Records per PalmOS Record
07/08/2003 09:07 AM
Please respond to "Palm Developer
Forum"
Thanks Nick. I'm actually looking to store in excess of 60,000+ records not
to mention an indexing database along with another large database with it's
own indexing that works interdependantly with the first. I'm also using C
straight
up for this and can't afford the time to learn C++ and become comfortable
with OO programming.
To save space, I'm currently storing all values as variable length strings
as follows:
prodno\0description\0cost\0retail\0unitofmeasure\0prodno\0description\0cost\0retail\0unitofmeasure\0.......up
to 64k limit (including header info)
I'm a relatively new programmer, so I'm having difficulty figuring out an
efficient method
for accessing this information.
Any and all suggestions would be greatly, greatly appreciated.
"Nick"
<[EMAIL PROTECTED] To: "Palm
Developer Forum" <[EMAIL PROTECTED]>
com> cc:
Sent by: Subject:
Re: Multiple Text Records per PalmOS Record
[EMAIL PROTECTED]
palmos.com
07/08/2003 08:31 AM
Please respond to "Palm Developer
Forum"
Nole,
For me, I used POL and its associated CDatabase, CDBStream, etc. classes to
efficently search every record based on any value in the record. This is
very fast and I can search 5000 records (DB is 580KB) in very little time.
In my example, when a record is found that matches the required criteria, I
either return the record index or fill in a tree (or other) control with
some of the record content. Which method I use depends on why I am
searching the database.
For example, each record contains a struct similar to this. This struct
holds automobile make, model, color, stock number, mileage, VIN, etc. Each
record is constructed such that the fixed data is first, followed by any
variable (length) data.
struct x {
int16 year
int16 color
int16 offsetstring4
int16 offsetstring5
int16
int16
int16
int16
int16
int32
int32
...
int32
string1
string2
string3
string4
string5
}
Sample code that searches for all vehicles of a certain color and year.
// note that m_pCarDatabase is a pointer to a an instance of a
// CDatabase object declared in the main application. See
// the POL documentation for more information.
UInt16 numRecords = m_pCarDatabase->NumRecords();
for(int i = 0; i < numRecords; )
{
CDBStream dbs(m_pCarDatabase->QueryRecord(i), 0);
dbs >> year;
dbs >> color;
// collect the offsets to the other strings.
dbs >> off4;
dbs >> off5;
// if the year and color for this record match the selected year
// and color, then add this record to the tree control.
if((year == m_currentYear) && (color == m_currentColor))
{
// the offset to the manufacturer string is always at offset 80. The
// binary data at the start of the record is a fixed length.
// extract the information from the strings.
dbs.Seek(80, fileOriginBeginning);
// mfg, make, model, vin, and stock are CStrings
dbs >> mfg >> make >> model >> vin >> stock;
// add items to a UI control or return the index or return one of the
// strings...
...
}
...
}
Nick.
<[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED]
>
>
> Does anyone have any good resources that show an efficient
> method of searching and retrieving multiple records from a single
> packed, PalmOS record? Books? Website? Suggestions? Anything?
>
> All I've seen so far is searching single packed records per
> PalmOS record (PalmOS Programming Bible) which isn't quite what
> I need.
>
> Thanks.
> Nole
>
>
>
--
For information on using the Palm Developer Forums, or to unsubscribe,
please see http://www.palmos.com/dev/support/forums/
--
For information on using the Palm Developer Forums, or to unsubscribe,
please see http://www.palmos.com/dev/support/forums/
--
For information on using the Palm Developer Forums, or to unsubscribe,
please see http://www.palmos.com/dev/support/forums/
------------------------------------------
The information in this transmittal and any attachments are confidential
and intended only for the recipient(s) listed above. You are hereby
notified that any unauthorized distribution or copying of this transmittal
or its attachments is prohibited. If you have received this transmittal in
error, please notify invivodata immediately at (831) 438-9550.
------------------------------------------
--
For information on using the Palm Developer Forums, or to unsubscribe,
please see http://www.palmos.com/dev/support/forums/
--
For information on using the Palm Developer Forums, or to unsubscribe,
please see http://www.palmos.com/dev/support/forums/
--
For information on using the Palm Developer Forums, or to unsubscribe, please see
http://www.palmos.com/dev/support/forums/
--
For information on using the Palm Developer Forums, or to unsubscribe, please see
http://www.palmos.com/dev/support/forums/