📄 addressdb.c
字号:
* if sortByCompany:
* companyKey, nameKey, firstNameKey, uniq ID
*
* if !sortByCompany:
* nameKey, firstNameKey, companyKey (if no name or first name), uniq ID
*
*
*************************************************************/
void PrvAddrDBFindKey(PrvAddrPackedDBRecord *r, char **key, UInt16 *whichKey, Int16 sortByCompany)
{
AddrDBRecordFlags fieldFlags;
fieldFlags.allBits = r->flags.allBits;
ErrFatalDisplayIf(*whichKey == 0 || *whichKey == 5, "Bad addr key");
if (sortByCompany)
{
if (*whichKey == 1 && fieldFlags.bits.company)
{
*whichKey = 2;
goto returnCompanyKey;
}
if (*whichKey <= 2 && fieldFlags.bits.name)
{
*whichKey = 3;
goto returnNameKey;
}
if (*whichKey <= 3 && fieldFlags.bits.firstName)
{
*whichKey = 4;
goto returnFirstNameKey;
}
}
else
{
if (*whichKey == 1 && fieldFlags.bits.name)
{
*whichKey = 2;
goto returnNameKey;
}
if (*whichKey <= 2 && fieldFlags.bits.firstName)
{
*whichKey = 3;
goto returnFirstNameKey;
}
// For now don't consider company name when sorting by person name
// unless there isn't a name or firstName
if (*whichKey <= 3 && fieldFlags.bits.company &&
!(fieldFlags.bits.name || fieldFlags.bits.firstName))
{
*whichKey = 4;
goto returnCompanyKey;
}
}
// All possible fields have been tried so return NULL so that
// the uniq ID is compared.
*whichKey = 5;
*key = NULL;
return;
returnCompanyKey:
*key = (char *) &r->companyFieldOffset + r->companyFieldOffset;
return;
returnNameKey:
*key = &r->firstField;
return;
returnFirstNameKey:
*key = &r->firstField;
if (r->flags.bits.name)
{
*key += StrLen(*key) + 1;
}
return;
}
/************************************************************
*
* FUNCTION: PrvAddrDBComparePackedRecords
*
* DESCRIPTION: Compare two packed records key by key until
* there is a difference. Return -1 if r1 is less or 1 if r2
* is less. A zero may be returned if two records seem
* identical. NULL fields are considered less than others.
*
* PARAMETERS: address record 1
* address record 2
*
* RETURNS: -1 if record one is less
* 1 if record two is less
*
* HISTORY:
* 01/14/95 rsf Created by Roger Flores.
* 11/30/00 kwk Only call StrCompare, not StrCaselessCompare
* first and then StrCompare. Also use TxtCompare
* instead of StrCompare, to skip a trap call.
*
*************************************************************/
Int16 PrvAddrDBComparePackedRecords(PrvAddrPackedDBRecord *r1,
PrvAddrPackedDBRecord *r2,
Int16 sortByCompany,
SortRecordInfoPtr UNUSED_PARAM(info1),
SortRecordInfoPtr UNUSED_PARAM(info2),
MemHandle UNUSED_PARAM(appInfoH))
{
UInt16 whichKey1, whichKey2;
char *key1, *key2;
Int16 result;
whichKey1 = 1;
whichKey2 = 1;
do {
PrvAddrDBFindKey(r1, &key1, &whichKey1, sortByCompany);
PrvAddrDBFindKey(r2, &key2, &whichKey2, sortByCompany);
// A key with NULL loses the StrCompare.
if (key1 == NULL)
{
// If both are NULL then return them as equal
if (key2 == NULL)
{
result = 0;
return result;
}
else
result = -1;
}
else
if (key2 == NULL)
result = 1;
else
{
// With Palm OS 4.0, StrCompare will try a caseless
// comparison first, then a case-sensitive, so we
// only need to call StrCompare. Also, we can call
// TxtCompare to avoid one extra trap dispatch.
// result = StrCaselessCompare(key1, key2);
// if (result == 0)
// result = StrCompare(key1, key2);
result = TxtCompare( key1, // const Char *s1,
0xFFFF, // UInt16 s1Len,
NULL, // UInt16 *s1MatchLen,
key2, // const Char *s2,
0xFFFF, // UInt16 s2Len,
NULL); // UInt16 *s2MatchLen
}
} while (!result);
return result;
}
/************************************************************
*
* FUNCTION: PrvAddrDBUnpackedSize
*
* DESCRIPTION: Return the size of an AddrDBRecordType
*
* PARAMETERS: address record
*
* RETURNS: the size in bytes
*
* CREATED: 1/10/95
*
* BY: Roger Flores
*
*************************************************************/
Int16 PrvAddrDBUnpackedSize(AddrDBRecordPtr r)
{
Int16 size;
Int16 index;
size = sizeof (PrvAddrPackedDBRecord) - sizeof (char); // correct
for (index = firstAddressField; index < addressFieldsCount; index++)
{
if (r->fields[index] != NULL)
size += StrLen(r->fields[index]) + 1;
}
return size;
}
/************************************************************
*
* FUNCTION: PrvAddrDBPack
*
* DESCRIPTION: Pack an AddrDBRecordType. Doesn't pack empty strings.
*
* PARAMETERS: address record to pack
* address record to pack into
*
* RETURNS: the PrvAddrPackedDBRecord is packed
*
* CREATED: 1/10/95
*
* BY: Roger Flores
*
*************************************************************/
void PrvAddrDBPack(AddrDBRecordPtr s, void * recordP)
{
Int32 offset;
AddrDBRecordFlags flags;
Int16 index;
PrvAddrPackedDBRecord* d=0;
Int16 len;
void * srcP;
UInt8 companyFieldOffset;
flags.allBits = 0;
DmWrite(recordP, (Int32)&d->options, &s->options, sizeof(s->options));
offset = (Int32)&d->firstField;
for (index = firstAddressField; index < addressFieldsCount; index++) {
if (s->fields[index] != NULL)
/* if (s->fields[index][0] == '\0')
{
// so set the companyFieldOffset or clear it code doesn't fail
s->fields[index] = NULL;
}
else
*/
{
ErrFatalDisplayIf(s->fields[index][0] == '\0' && index != note,
"Empty field being added");
srcP = s->fields[index];
len = StrLen(srcP) + 1;
DmWrite(recordP, offset, srcP, len);
offset += len;
SetBitMacro(flags.allBits, index);
}
}
// Set the flags indicating which fields are used
DmWrite(recordP, (Int32)&d->flags.allBits, &flags.allBits, sizeof(flags.allBits));
// Set the companyFieldOffset or clear it
if (s->fields[company] == NULL)
companyFieldOffset = 0;
else {
index = 1;
if (s->fields[name] != NULL)
index += StrLen(s->fields[name]) + 1;
if (s->fields[firstName] != NULL)
index += StrLen(s->fields[firstName]) + 1;
companyFieldOffset = (UInt8) index;
}
DmWrite(recordP, (Int32)(&d->companyFieldOffset), &companyFieldOffset, sizeof(companyFieldOffset));
}
/************************************************************
*
* FUNCTION: PrvAddrDBUnpack
*
* DESCRIPTION: Fills in the AddrDBRecord structure
*
* PARAMETERS: address record to unpack
* the address record to unpack into
*
* RETURNS: the record unpacked
*
* CREATED: 1/14/95
*
* BY: Roger Flores
*
*************************************************************/
void PrvAddrDBUnpack(PrvAddrPackedDBRecord *src, AddrDBRecordPtr dest)
{
Int16 index;
UInt32 flags;
char *p;
dest->options = src->options;
flags = src->flags.allBits;
p = &src->firstField;
for (index = firstAddressField; index < addressFieldsCount; index++)
{
// If the flag is set point to the string else NULL
if (GetBitMacro(flags, index) != 0)
{
dest->fields[index] = p;
p += StrLen(p) + 1;
}
else
dest->fields[index] = NULL;
}
}
/************************************************************
*
* FUNCTION: PrvAddrDBFindSortPosition
*
* DESCRIPTION: Return where a record is or should be
* Useful to find or find where to insert a record.
*
* PARAMETERS: address record
*
* RETURNS: the size in bytes
*
* CREATED: 1/11/95
*
* BY: Roger Flores
*
*************************************************************/
UInt16 PrvAddrDBFindSortPosition(DmOpenRef dbP, PrvAddrPackedDBRecord *newRecord)
{
Int16 sortByCompany;
AddrAppInfoPtr appInfoPtr;
appInfoPtr = (AddrAppInfoPtr) AddrDBAppInfoGetPtr(dbP);
sortByCompany = appInfoPtr->misc.sortByCompany;
MemPtrUnlock(appInfoPtr);
return DmFindSortPosition(dbP, (void *) newRecord, NULL, (DmComparF *)
PrvAddrDBComparePackedRecords, (Int16) sortByCompany);
}
/************************************************************
*
* FUNCTION: PrvAddrDBStrCmpMatches
*
* DESCRIPTION: Compares two strings and reports the number
* of matching bytes from the start of <s1>.
*
* PARAMETERS: 2 string pointers
*
* RETURNS: number of matching bytes from <s1>.
*
* CREATED: 6/15/95
*
* BY: Roger Flores
*
* HISTORY:
* 06/15/95 rsf Created by Roger Flores.
* 05/16/99 kwk Use TxtCaselessCompare routine.
* 11/30/00 kwk Speed things up by not calling StrLen().
*
*************************************************************/
UInt16 PrvAddrDBStrCmpMatches(const Char* s1, const Char* s2)
{
UInt16 matches;
ErrFatalDisplayIf ( s1 == NULL, "Error NULL string parameter");
ErrFatalDisplayIf ( s2 == NULL, "Error NULL string parameter");
// In Palm OS 4.0, TxtCaselessCompare now handles null-terminated
// strings, so the actual string lengths don't need to be passed in.
// Instead we'll pass kMaxUInt16 (doesn't exist, use 0xFFFF).
// On pre-4.0 ROMs, calls to StrLen(s1) & StrLen(s2) would still
// be necessary.
TxtCaselessCompare(s1, 0xFFFF, &matches, s2, 0xFFFF, NULL);
return (matches);
}
/***********************************************************************
*
* FUNCTION: PrvAddrDBRecordContainsField
*
* DESCRIPTION: Check if a packed record contains a desired field.
*
* PARAMETERS: recordP - pointer to the record to search
* field - type of field to find.
*
* RETURNED: true if the record contains the field.
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* Roger 7/9/96 Initial Revision
*
***********************************************************************/
Boolean PrvAddrDBRecordContainsField(PrvAddrPackedDBRecord *packedRecordP, AddressLookupFields field, Int16 * phoneP, Int16 direction, AddressFields lookupFieldMap[])
{
int index;
int stopIndex;
int phoneType;
switch (field)
{
case addrLookupSortField:
return packedRecordP->flags.allBits & sortKeyFieldBits;
case addrLookupListPhone:
return GetBitMacro(packedRecordP->flags.allBits, firstPhoneField +
packedRecordP->options.phones.displayPhoneForList);
case addrLookupNoField:
return true;
default:
if (!IsPhoneLookupField(field))
return GetBitMacro(packedRecordP->flags.allBits, lookupFieldMap[field]) != 0;
phoneType = field - addrLookupWork;
index = firstPhoneField + *phoneP;
if (direction == dmSeekForward)
stopIndex = lastPhoneField + direction;
else
stopIndex = firstPhoneField + direction;
while (index != stopIndex)
{
// If the phone field is the type requested and it's not empty
// return it.
if (GetPhoneLabel(packedRecordP, index) == phoneType &&
GetBitMacro(packedRecordP->flags.allBits, index))
{
*phoneP = index - firstPhoneField;
return true;
}
index += direction;
}
// The phone type wasn't used.
if (direction == dmSeekForward)
*phoneP = 0; // Reset for the next record
else
*phoneP = numPhoneFields - 1; // Reset for the next record
return false;
}
}
/************************************************************
*
* FUNCTION: PrvAddrDBSeekVisibleRecordInCategory
*
* DESCRIPTION: Like DmSeekRecordInCategory, but if masked is true
* also explicitly skips past private records
*
* PARAMETERS: masked - indicates that database is opened in show secret mode
* but should be hide secret.
*
* RETURNS: as DmSeekRecordInCategory
*
* CREATED: 6/15/99
*
* BY: Jameson Quinn
*
*************************************************************/
Boolean PrvAddrDBSeekVisibleRecordInCategory (DmOpenRef dbR, UInt16 * indexP, UInt16 offset, Int16 direction, UInt16 category, Boolean masked)
{
UInt16 attr;
Boolean result;
result = DmSeekRecordInCategory(dbR,indexP,offset,direction,category);
if (result != errNone)
{
goto Exit;
}
DmRecordInfo (dbR, *indexP, &attr, NULL, NULL);
while (masked && (attr & dmRecAttrSecret))
{
result = DmSeekRecordInCategory(dbR,indexP,1,direction,category);
if (result != errNone)
{
goto Exit;
}
DmRecordInfo (dbR, *indexP, &attr, NULL, NULL);
}
Exit:
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -