📄 addressdb.c
字号:
}
}
//write birthday info
len = sizeof(DateType);
//fill in birthday info only if the birth date is present
if(s->birthdayInfo.birthdayDate.month && s->birthdayInfo.birthdayDate.day)
{
DmWrite(recordP, offset, &(s->birthdayInfo.birthdayDate), len);
offset += len;
SetBitMacro(flags, birthdayDate);
//write other birthday info only if birthdate is valid
//write birthday mask to determine if year is set.
len = sizeof(AddressDBBirthdayFlags);
DmWrite(recordP, offset, &(s->birthdayInfo.birthdayMask), len);
offset += len;
SetBitMacro(flags, birthdayMask);
//set preset and text only if Date Book reminder option is set
if(s->birthdayInfo.birthdayMask.alarm)
{
len = sizeof(UInt8);
DmWrite(recordP, offset, &(s->birthdayInfo.birthdayPreset), len);
offset += len;
SetBitMacro(flags, birthdayPreset);
}
}
//set picture blob information
if(s->pictureInfo.pictureSize && s->pictureInfo.pictureData)
{
UInt32 blobId = addrPictureBlobId;
UInt16 blobSize = 0;
//set 4 byte id
len = sizeof(blobId);
DmWrite(recordP, offset, &blobId, len);
offset += len;
//set 2 bytes len: blob size = 2 bytes picture dirty flag + picture size
len = sizeof(blobSize);
blobSize = s->pictureInfo.pictureSize + sizeof(s->pictureInfo.pictureDirty);
DmWrite(recordP, offset, &blobSize, len);
offset += len;
//set dirty flag and picture
len = sizeof(s->pictureInfo.pictureDirty);
DmWrite(recordP, offset, &(s->pictureInfo.pictureDirty), len);
offset += len;
DmWrite(recordP, offset, (s->pictureInfo.pictureData), s->pictureInfo.pictureSize);
offset += s->pictureInfo.pictureSize;
blobCount++;
}
// Include any other blobs we don't understand.
ErrNonFatalDisplayIf(blobCount + s->numBlobs > apptMaxBlobs, "Too many blobs");
// Include any other blobs we don't understand.
for (index = 0; index < s->numBlobs; index++)
{
size = sizeof(s->blobs[index].creatorID);
DmWrite(recordP, offset, &(s->blobs[index].creatorID), size);
offset += size;
size = sizeof(s->blobs[index].size);
DmWrite(recordP, offset, &(s->blobs[index].size), size);
offset += size;
DmWrite(recordP, offset, s->blobs[index].content, s->blobs[index].size);
offset += s->blobs[index].size;
}
ErrNonFatalDisplayIf(offset > MemHandleSize(MemPtrRecoverHandle(recordP)), "Not enough room for packed record");
// Set the flags indicating which fields are used
DmWrite(recordP, (Int32)&d->flags.allBits, &flags.allBits, sizeof(flags.allBits));
DmWrite(recordP, (Int32)&d->flags.allBits2, &flags.allBits2, sizeof(flags.allBits2));
// 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));
}
void PrvAddrDBUnpack(PrvAddrPackedDBRecord *src, AddrDBRecordPtr dest)
{
Int16 index;
AddrDBRecordFlags flags;
char *p;
UInt16 recordSize = 0;
Char *blobStart;
Char *blobEnd;
UInt32 blobId;
UInt16 blobSize;
MemMove(&(dest->options), &(src->options), sizeof(AddrOptionsType));
MemMove(&flags, &(src->flags), sizeof(AddrDBRecordFlags));
p = &src->firstField;
for (index = firstAddressField; index < addrNumStringFields; 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;
}
// Unpack birthday info
MemSet(&(dest->birthdayInfo), sizeof(BirthdayInfo), 0 );
if(GetBitMacro(flags, birthdayDate))
{
MemMove(&(dest->birthdayInfo.birthdayDate), p, sizeof(DateType));
p += sizeof(DateType);
}
if(GetBitMacro(flags, birthdayMask))
{
MemMove(&(dest->birthdayInfo.birthdayMask), p, sizeof(AddressDBBirthdayFlags));
//dest->birthdayInfo.birthdayMask = *((AddressDBBirthdayFlags*)p);
p += sizeof(AddressDBBirthdayFlags);
}
if(GetBitMacro(flags, birthdayPreset))
{
dest->birthdayInfo.birthdayPreset = *((UInt8*)p);
p += sizeof(UInt8);
}
// Get picture info
dest->pictureInfo.pictureDirty = 0;
dest->pictureInfo.pictureSize = 0;
dest->pictureInfo.pictureData = NULL;
dest->numBlobs = 0;
// Then iterate through the blobs, ignoring any we don't understand.
blobStart = p; // First blob starts where last non-blob data ends.
recordSize = MemPtrSize(src);
while (blobStart < (Char *)src + recordSize)
{
p = blobStart;
ErrNonFatalDisplayIf((Char *)src + recordSize - blobStart <= sizeof (blobId) + sizeof (blobSize),"Invalid blob encountered");
MemMove(&blobId, p, sizeof (blobId));
p += sizeof (blobId);
MemMove(&blobSize, p, sizeof (blobSize));
p += sizeof (blobSize);
blobEnd = p + blobSize; // Blob size excludes space to store ID and size of blob.
switch (blobId)
{
case addrPictureBlobId:
{
UInt16 pictureDirtySize;
pictureDirtySize = sizeof(dest->pictureInfo.pictureDirty);
dest->pictureInfo.pictureSize = blobSize - pictureDirtySize;
MemMove(&(dest->pictureInfo.pictureDirty), p, pictureDirtySize);
p += pictureDirtySize;
if(dest->pictureInfo.pictureSize)
dest->pictureInfo.pictureData = p;
p += dest->pictureInfo.pictureSize;
break;
}
default:
{
ErrNonFatalDisplayIf (dest->numBlobs >= apptMaxBlobs, "Too many blobs");
dest->blobs[dest->numBlobs].creatorID = blobId;
dest->blobs[dest->numBlobs].size = blobSize;
dest->blobs[dest->numBlobs].content = p;
dest->numBlobs++;
p = blobEnd;
break;
}
}
ErrNonFatalDisplayIf(p != blobEnd, "Blob size does not agree with contents");
blobStart = blobEnd; // Next blob starts where last blob ends.
}
ErrNonFatalDisplayIf(blobStart != (Char *)src + recordSize,
"Last blob not aligned with end of record - don't let fields edit records directly!");
}
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;
}
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);
}
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -