darn!  too fast.

those descriptionP = StrLen(p) + 1;  lines should be

descriptionP += StrLen(p)  + 1;

-----Original Message-----
From: Kevin OKeefe 
Sent: Tuesday, July 08, 2003 3:20 PM
To: Palm Developer Forum
Subject: RE: Multiple Text Records per PalmOS Record


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/



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

Reply via email to