⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 addressdb.c

📁 我的Palm OS 5 SDK zhCN_PIMApps代码。 使用codewarrior 开发环境
💻 C
📖 第 1 页 / 共 4 页
字号:
	MemHandleFree(oldH);
	return 0;
}


/************************************************************
 *
 *  FUNCTION: AddrDBGetRecord
 *
 *  DESCRIPTION: Get a record from the Address Database
 *
 *  PARAMETERS: database pointer - open db pointer
 *            database index - index of record to lock
 *            address record pointer - pointer address structure
 *            address record - MemHandle to unlock when done
 *
 *  RETURNS: ##0 if successful, errorcode if not
 *    The record's MemHandle is locked so that the pointer to
 *  strings within the record remain pointing to valid chunk
 *  versus the record randomly moving.  Unlock the MemHandle when
 *  AddrDBRecord is destroyed.
 *
 *  CREATED: 1/14/95
 *
 *  BY: Roger Flores
 *
 *************************************************************/
Err AddrDBGetRecord(DmOpenRef dbP, UInt16 index, AddrDBRecordPtr recordP,
				  MemHandle *recordH)
{
	PrvAddrPackedDBRecord *src;

	*recordH = DmQueryRecord(dbP, index);
	if (*recordH == NULL)
		return dmErrMemError;
	
	src = (PrvAddrPackedDBRecord *) MemHandleLock(*recordH);
	if (src == NULL)
		return dmErrIndexOutOfRange;

	PrvAddrDBUnpack(src, recordP);

	return 0;
}


/***********************************************************************
 *
 * FUNCTION:    AddrDBRecordContainsData
 *
 * DESCRIPTION: Checks the record returns true if it contains any data.
 *
 * PARAMETERS:  recordP  - a pointer to an address record
 *
 * RETURNED:    true if one of the fields has data
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         rsf   12/3/97   Initial Revision
 *
 ***********************************************************************/
Boolean AddrDBRecordContainsData (AddrDBRecordPtr recordP)
{
	UInt16 i;


	// Look for a field which isn't empty
	for (i = firstAddressField; i < addressFieldsCount; i++)
	{
		if (recordP->fields[i] != NULL)
			return true;
	}

	return false;
}


/************************************************************
 *
 *  FUNCTION: AddrDBChangeSortOrder
 *
 *  DESCRIPTION: Change the Address Database's sort order
 *
 *  PARAMETERS: dbP - open database pointer
 *            TRUE if sort by company
 *
 *  RETURNS: nothing
 *
 *  CREATED: 1/17/95
 *
 *  BY: Roger Flores
 *
 *************************************************************/
Err AddrDBChangeSortOrder(DmOpenRef dbP, Boolean sortByCompany)
{
	AddrAppInfoPtr appInfoPtr;
	AddrAppInfoPtr   nilP=0;
	AddrDBMisc      misc;

	UInt32 paceVersion;
	UInt16 addrSortLibRefNum;

	appInfoPtr = (AddrAppInfoPtr) AddrDBAppInfoGetPtr(dbP);
	misc = appInfoPtr->misc;
	misc.sortByCompany = sortByCompany;
	DmWrite(appInfoPtr, (Int32) &nilP->misc, &misc, sizeof(misc));
	MemPtrUnlock(appInfoPtr);

	// Use ARM sort if possible. If we're running PACE... it's ARM :-)
	if (FtrGet('pace', 0, &paceVersion ) == ftrErrNoSuchFeature) {
	
		// This is the original code
		DmQuickSort(dbP, (DmComparF *) PrvAddrDBComparePackedRecords, (Int16) sortByCompany);
	}
	else {

#ifndef MAC_SIMULATOR_APP
		// Try to load the lib. If it fails, default to the original code
		if (SysLibLoad('libr', 'adbs', &addrSortLibRefNum) == errNone) {
		
			// This is the ARM lib code
			AddrDBSort(addrSortLibRefNum, dbP, (Int16) sortByCompany);
	
			SysLibRemove(addrSortLibRefNum);
		
		}
		else 
#endif
		{

			DmQuickSort(dbP, (DmComparF *) PrvAddrDBComparePackedRecords, (Int16) sortByCompany);
		
		}
	}
	
	return 0;
}


/***********************************************************************
 *
 * FUNCTION:    AddrDBLookupSeekRecord
 *
 * DESCRIPTION: Given the index of a record, scan
 *              forewards or backwards for displayable records.
 *
 * PARAMETERS:  indexP  - pointer to the index of a record to start from;
 *                        the index of the record sought is returned in
 *                        this parameter.
 *
 *              offset  - number of records to skip:
 *                           0 - mean seek from the current record to the
 *                             next display record, if the current record is
 *                             a display record, its index is retuned.
 *                         1 - mean seek foreward, skipping one displayable
 *                             record
 *                        -1 - means seek backwards, skipping one
 *                             displayable record
 *
 *
 * RETURNED:    true if a displayable record was found.
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         Roger   7/9/96   Initial Revision
 *
 ***********************************************************************/
Boolean AddrDBLookupSeekRecord (DmOpenRef dbP, UInt16 * indexP, Int16 * phoneP, Int16 offset, Int16 direction, AddressLookupFields field1, AddressLookupFields field2, AddressFields lookupFieldMap[])
{
	UInt16 index;
	UInt16 oldIndex;
	UInt16 count;
	UInt16 numRecords;
	MemHandle recordH;
	Boolean match;
	Int16 phone;
	Boolean searchPhones;
	PrvAddrPackedDBRecord *packedRecordP;


	ErrFatalDisplayIf ( (direction != dmSeekForward) && (direction != dmSeekBackward),
						"Bad Param");

	ErrFatalDisplayIf ( (offset < 0), "Bad param");


	index = *indexP;
	phone = *phoneP;

	searchPhones = IsPhoneLookupField(field1) || IsPhoneLookupField(field2);

	numRecords = DmNumRecords(dbP);

	if (index >= numRecords)
	{
		if (direction == dmSeekForward)
			return false;
		else
			index = numRecords - 1;
	}


	// Moving forward?
	if (direction == dmSeekForward )
		count = numRecords - index;
	else
		count = index + 1;

	// Loop through the records
	while (count--) {

		// Make sure the current record isn't hidden.  If so skip it and find the
		// next non hidden record.  Decrease the record count to search by the number
		// of records skipped.
		oldIndex = index;
		if (DmSeekRecordInCategory (dbP, &index, 0, direction, dmAllCategories))
		{
			// There are no more records.
			break;
		}
		if (index != oldIndex)
		{
			if (direction == dmSeekForward)
				count -= index - oldIndex;
			else
				count -= oldIndex - index;
		}

		recordH = DmQueryRecord(dbP, index);

		// If we have found a deleted record stop the search.
		if (!recordH)
			break;

		packedRecordP = MemHandleLock(recordH);
		if (!packedRecordP)
			goto Exit;

		match = PrvAddrDBRecordContainsField(packedRecordP, field1, &phone, direction, lookupFieldMap) &&
			PrvAddrDBRecordContainsField(packedRecordP, field2, &phone, direction, lookupFieldMap);

		MemHandleUnlock(recordH);

		if (match)
		{
			*indexP = index;
			*phoneP = phone;
			if (offset == 0) return true;
			offset--;
		}

		// Look for another phone in this record if one was found or
		// else look at the next record.
		if (searchPhones && match)
		{
			phone += direction;
			// We their are no more phones to search so advance to next record
			if (phone == -1 || numPhoneFields <= phone)
			{
				if (direction == dmSeekForward)
					phone = 0;
				else
					phone = numPhoneFields - 1;

				index += direction;
			}
			else
			{
				// Since we are going to search this record again bump the count up
				// by one.  This loop is supposed to loop once per record to search.
				count++;
			}
		}
		else
			index += direction;

	}

	return false;

Exit:
	ErrDisplay("Err seeking rec");

	return false;
}

/************************************************************
 *
 *  FUNCTION: AddrDBLookupString
 *
 *  DESCRIPTION: Return which record contains the most of
 *      the string passed.  If no string is passed or there
 *  aren't any records then false is returned.
 *
 *  PARAMETERS: address record
 *                key - string to lookup record with
 *                sortByCompany - how the db is sorted
 *                category -  the category to search in
 *                recordP - to contain the record found
 *                completeMatch -  true if a record contains all
 *                                 of the key
 *
 *  RETURNS: the record in recordP or false
 *             completeMatch -  true if a record contains all
 *                              of the key
 *
 *  CREATED: 6/15/95
 *
 *  BY: Roger Flores
 *
 *************************************************************/
Boolean AddrDBLookupString(DmOpenRef dbP, Char * key, Boolean sortByCompany, UInt16 category, UInt16 * recordP, Boolean *completeMatch, Boolean masked)
{
	Int16                   numOfRecords;
	MemHandle                rH;
	PrvAddrPackedDBRecord*   r;
	UInt16                  kmin, probe, probe2, i;      // all positions in the database.
	Int16                   result;                     // result of comparing two records
	UInt16                   whichKey;
	char*                  recordKey;
	UInt16                   matches1, matches2;


	// If there isn't a key to search with stop the with the first record.
	if (key == NULL || *key == '\0')
	{
		*completeMatch = true;
		return false;
	}

	numOfRecords = DmNumRecords(dbP);
	if (numOfRecords == 0)
		return false;

	result = 0;
	kmin = probe = 0;
	rH = 0;


	while (numOfRecords > 0)
	{
		i = numOfRecords / 2;
		probe = kmin + i;


		// Compare the two records.  Treat deleted records as greater.
		// If the records are equal look at the following position.
		if (rH)
			MemHandleUnlock(rH);
		rH = DmQueryRecord(dbP, probe);
		if (rH == 0)
		{
			result = -1;      // Delete record is greater
		}
		else
		{
			r = (PrvAddrPackedDBRecord *) MemHandleLock(rH);
			ErrFatalDisplayIf(r == 0, "Addr bsearch: data somehow missing");


			// Compare the string to the first sort key only
			whichKey = 1;
			PrvAddrDBFindKey(r, &recordKey, &whichKey, sortByCompany);

			if (recordKey == NULL)
				result = 1;
			else
				result = StrCaselessCompare(key, recordKey);


			// If equal stop here!  We don't want the position after.
			if (result == 0)
				goto findRecordInCategory;
		}


		ErrFatalDisplayIf(result == 0, "Impossible bsearch state");

		// More likely than < 0 because of deleted records
		if (result < 0)
			numOfRecords = i;
		else
		{
			kmin = probe + 1;
			numOfRecords = numOfRecords - i - 1;
		}
	}

	if (result >= 0)
		probe++;

findRecordInCategory:
	if (rH)
		MemHandleUnlock(rH);

	// At this point probe is the position where the string could be
	// inserted.  It is in between two entries.  Neither the record
	// before or after may have ANY letters in common, especially after
	// those records in other catergories are skipped.  Go with the
	// record that has the most letters in common.


	// Make sure the record returned is of the same category.
	// If not return the first prior record of the same category.
	probe2 = probe;
	if (!PrvAddrDBSeekVisibleRecordInCategory (dbP, &probe, 0, dmSeekForward, category, masked))
	{
		// Now count the number of matching characters in probe
		rH = DmQueryRecord(dbP, probe);      // No deleted record possible
		r = (PrvAddrPackedDBRecord *) MemHandleLock(rH);
		ErrFatalDisplayIf(r == 0, "Addr bsearch: data somehow missing");
		whichKey = 1;
		PrvAddrDBFindKey(r, &recordKey, &whichKey, sortByCompany);
		if (recordKey == NULL)
			matches1 = 0;
		else
			matches1 = PrvAddrDBStrCmpMatches(key, recordKey);

		MemHandleUnlock(rH);
	}
	else
	{
		// No record in this category was found or probe is past all
		// records in this category.  Either way there aren't any matching
		// letters.
		matches1 = 0;
	}



	// Sometimes the record before has more matching letters. Check it.
	// Passing DmSeekRecordInCategory an offset of 1 doesn't work
	// when probe is at the end of the database and there isn't at least
	// one record to skip.
	probe2 = probe - 1;
	if (probe == 0 ||
		PrvAddrDBSeekVisibleRecordInCategory (dbP, &probe2, 0, dmSeekBackward, category, masked))
	{
		if (matches1 > 0)
		{
			// Go with probe because they have at least some letters in common.
			*recordP = probe;   //
			*completeMatch = (matches1 == StrLen(key));
			return true;
		}
		else
		{
			// probe has no letters in common and nothing earlier in this category
			// was found so this is a failed lookup.
			*completeMatch = false;
			return false;
		}
	}


	// Now count the number of matching characters in probe2
	rH = DmQueryRecord(dbP, probe2);      // No deleted record possible
	r = (PrvAddrPackedDBRecord *) MemHandleLock(rH);
	ErrFatalDisplayIf(r == 0, "Addr bsearch: data somehow missing");
	whichKey = 1;
	PrvAddrDBFindKey(r, &recordKey, &whichKey, sortByCompany);
	if (recordKey == NULL)
		matches2 = 0;
	else
		matches2 = PrvAddrDBStrCmpMatches(key, recordKey);
	MemHandleUnlock(rH);


	// Now, return the probe which has the most letters in common.
	if (matches1 > matches2)
	{
		*completeMatch = (matches1 == StrLen(key));
		*recordP = probe;
	}
	else
		if (matches1 == 0 && matches2 == 0)
		{
			*completeMatch = false;
			return false;            // no item with same first letter found
		}
		else
		{
			// The first item matches as much or more as the second item
			*recordP = probe2;

			// If the prior item in the category has the same number of
			// matching letters use it instead.  Repeat to find the
			// earliest such match.
			while (!PrvAddrDBSeekVisibleRecordInCategory (dbP, &probe2, 1, dmSeekBackward, category, masked))
			{
				rH = DmQueryRecord(dbP, probe2);
				r = (PrvAddrPackedDBRecord *) MemHandleLock(rH);
				ErrFatalDisplayIf(r == 0, "Addr bsearch: data somehow missing");

				// Compare the string to the first sort key only
				whichKey = 1;
				PrvAddrDBFindKey(r, &recordKey, &whichKey, sortByCompany);

				if (recordKey == NULL)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -