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

📄 ndb.c

📁 CD_高级PALM编程
💻 C
📖 第 1 页 / 共 4 页
字号:
/********************************************************************** FILE:				NDB.c** DESCRIPTION:	The Starter project module.** VERSION:		1.0**********************************************************************/#include <PalmOS.h>#include <PalmCompatibility.h>#include "NDB.h"#include "NDBpriv.h"// Macros// Extract the bit at position index from bitfield.  0 is the high bit.#define BitAtPosition(pos)                  ((UInt32)1 << (pos))#define GetBitMacro(bitfield, index)      ((bitfield) & BitAtPosition(index))#define SetBitMacro(bitfield, index)      ((bitfield) |= BitAtPosition(index))#define RemoveBitMacro(bitfield, index)   ((bitfield) &= ~BitAtPosition(index))// member variablesstatic NDBDmOpenDatabaseType ndbOpenDB[ ndbLastDatabase ] = { 0 };// constant definitions -- type & creator codes for opening databasesstatic UInt32 ndbDatabaseType[] = { 0, addrDBType, memoDBType, datebookDBType, toDoDBType };static UInt32 ndbDatabaseCreator[] = { 0, sysFileCAddress, sysFileCMemo, sysFileCDatebook, sysFileCToDo };#define NDBMAXDESCLEN ( 64 )// private functions/******************************************************************** * FUNCTION:    	NDBNewHandleFromString * * DESCRIPTION: 	This routine creates a new handle given *					a string with a copy of the string * * RETURNED:    	MemHandle to copy of string. Caller frees *					error code at the location specified  *					by errP.**********************************************************************/static MemHandle NDBNewHandleFromString	// (out) string copy(	CharPtr string,	Err *errP				// (in) where to place error)							// (out) error code for error{	MemHandle resultH;	CharPtr resultP;	*errP = noErr;// validate input	if ( string == NULL )		*errP = dmErrInvalidParam;		// create result handle	if ( *errP == noErr )		resultH = MemHandleNew( StrLen( string ) + 1 );	if ( resultH == NULL )		*errP = memErrNotEnoughSpace;// lock result handle			if ( *errP == noErr )		resultP = MemHandleLock( resultH );			// Copy the string	if ( *errP == noErr )		StrCopy( resultP, string );			// Unlock the handle	if ( resultP )		MemHandleUnlock( resultH );// Return the copy			return resultH;}/******************************************************************** * FUNCTION:    	NDBFetchStringFromPackedRecord * * DESCRIPTION: 	This routine fetches the indicated string *					from the run of contiguous null-terminated *					strings. * * RETURNED:    	Pointer to string**********************************************************************/static CharPtr NDBFetchStringFromPackedRecord	// (out) string(	CharPtr startP,			// (in) Start of region	UInt16 index,			// (in) which to get	UInt16 count			// (in) how many there are){	CharPtr resultP = startP;	int i;// validate	if ( startP == NULL )		return ndbEmptyString;			if ( index >= count ) 		return ndbEmptyString;// Find the index'th string.	for ( i = 0; i < index; i++ )		resultP += StrLen( resultP ) + sizeof( Char );	// Don't forget the null!		return resultP;}/******************************************************************** * FUNCTION:    	NDBFetchStringFromPackedMaskRecord * * DESCRIPTION: 	This routine fetches the indicated string *					from the run of contiguous null-terminated *					strings. * * RETURNED:    	Pointer to string**********************************************************************/static CharPtr NDBFetchStringFromPackedMaskRecord	// (out) string(	CharPtr startP,			// (in) Start of region	UInt16 index,			// (in) which to get	UInt16 count,			// (in) how many there are	UInt32 flags			// (in) which strings are there){	CharPtr resultP = startP;	int i;// validate	if ( startP == NULL )		return ndbEmptyString;	else if ( index >= count ) 		return ndbEmptyString;// If this string isn't in the packed set, just say so and return an empty string.	else if ( GetBitMacro( flags, index ) == 0 )		return ndbEmptyString;	else// Find the index'th string.		for ( i = 0; i < index; i++ )			if ( GetBitMacro( flags, i ) != 0 )				resultP += StrLen( resultP ) + sizeof( Char );	// Don't forget the null!		return resultP;}/******************************************************************** * FUNCTION:    	NDBOpenDatabase * * DESCRIPTION: 	This routine opens the desired database *					and increments the reference count *					associted with the given database. *					If the database is already open, a *					handle to it is returned and the *					reference count incremented. * SIDE EFFECT:		This routine manipulates entries *					in the ndbOpenDB array. * * RETURNED:    	nothing *					error code at the location specified  *					by errP. One of *					dmErrInvalidDatabaseName - no such database *					dmErrIndexOutOfRange - bad db specified**********************************************************************/static void NDBOpenDatabase // (out) nothing(	NDBDatabaseEnum db,		// (in) database to open	Err *errP				// (in) where to place error)							// (out) error code for error{	DmOpenRef dbRef = NULL;	LocalID dbId;	UInt16 card;	*errP = noErr;	// validate incoming arguments	if ( db <= ndbInvalid || db >= ndbLastDatabase )		*errP = dmErrIndexOutOfRange;		if ( *errP == noErr )	{// If the database is open, increment the reference count.		if ( ndbOpenDB[ db ].refCount > 0 ) 		{			ndbOpenDB[ db ].refCount++;		}		else		{// Try to open the database on each card.// First, find the database's ID.			dbRef = DmOpenDatabaseByTypeCreator( ndbDatabaseType[ db ], 				ndbDatabaseCreator[ db ], dmModeReadOnly );			if ( dbRef == NULL )				*errP = dmErrInvalidDatabaseName;						if ( *errP == noErr )			{// Get the LocalID of the database so we can open it on all cards.				DmOpenDatabaseInfo ( dbRef, &dbId, NULL, NULL, NULL, NULL );// Close the database				DmCloseDatabase( dbRef );				}				if ( *errP == noErr )			{// Now, loop over all cards and get an open database for each.				for ( card = 0; card < ndbMaxCardNum; card++ )				{					if ( DmNumDatabases( card ) > 0 )						ndbOpenDB[ db ].dbRef[ card ] = 							DmOpenDatabase ( (UInt16)card, dbId, (UInt16)(dmModeReadOnly | dmModeShowSecret) );				}		// And set the reference count to 1, because there's one caller.			ndbOpenDB[ db ].refCount = 1;			}		}	}	return;}/******************************************************************** * FUNCTION:    	NDBCloseDatabase * * DESCRIPTION: 	This routine closes the indicated  * 					database on all cards. If the database's *					reference count indicates that it's still *					in use, we simply decrement the reference *					count; otherwise we close the database as *					well. * * RETURNED:    	Nothing *					error code at the location specified  *					by errP. One of *					dmErrIndexOutOfRange - bad db specified**********************************************************************/static void NDBCloseDatabase // (out) nothing(	NDBDatabaseEnum db,		// (in) database to open	Err *errP				// (in) where to place error)							// (out) error code for error{	int card;		*errP = noErr;	// validate incoming arguments	if ( db <= ndbInvalid || db >= ndbLastDatabase )		*errP = dmErrIndexOutOfRange;		if ( *errP == noErr )	{// If the database is open, decrement the reference count.		if ( ndbOpenDB[ db ].refCount > 0 ) 		{			ndbOpenDB[ db ].refCount--;		}		else		{			*errP = dmErrNoOpenDatabase;		}	}	// If the reference count now indicates that there is nobody// else that needs this database, close the database on each card	if ( *errP == noErr )	{		if ( ndbOpenDB[ db ].refCount == 0 ) 		{// Loop over all cards and close the database for each.			for ( card = 0; card < ndbMaxCardNum; card++ )			{// Only try to close those databases that were opened, of course.				if ( ndbOpenDB[ db ].dbRef[ card ] )				{ 					DmCloseDatabase ( ndbOpenDB[ db ].dbRef[ card ] );					ndbOpenDB[ db ].dbRef[ card ] = NULL;				}			}				}		}		return ;}/******************************************************************** * FUNCTION:    	NDBDatabaseRefForDatabase * * DESCRIPTION: 	This routine returns the array o * SIDE EFFECT(S):	This routine  * * RETURNED:    	Pointer to first of ndbMaxCardNum *					open database references *					error code at the location specified  *					by errP.**********************************************************************/static DmOpenRef *NDBDatabaseRefForDatabase	// (out) db ptr(	NDBDatabaseEnum db,		// (in) database sought	Err *errP				// (in) where to place error)							// (out) error code for error{	DmOpenRef *dbP = NULL;		*errP = noErr;// validate incoming arguments	if ( db <= ndbInvalid || db >= ndbLastDatabase )		*errP = dmErrIndexOutOfRange;		if ( *errP == noErr )	{// If the database is open, return it, otherwise return NULL.		if ( ndbOpenDB[ db ].refCount > 0 )		{			dbP = ndbOpenDB[ db ].dbRef;		}	}	return dbP;}/******************************************************************** * FUNCTION:    	NDBMemSearch * * DESCRIPTION: 	This routine searches a block of memory *					for the desired subfield. * * RETURNED:    	pointer to the location of the first *					occurence of the subfield, or NULL**********************************************************************/static BytePtr NDBMemSearch		// (out) pointer to substr(	BytePtr field,				// (in) field to search	BytePtr sub,				// (in) subfield to find	UInt32 szField,				// (in) size of field	UInt32 szSub				// (in) size of subfield){	Boolean found = false;	UInt32 i, j;	BytePtr res = NULL;	// for each byte in the field...	for ( i = 0; i < szField; i++ )	{// if that byte matches the current byte of the subfield		if ( field[i] == sub[j] )		{			j++;// move ahead to check the next byte of the subfield			if ( j == szSub )			{// No more bytes... we've found it!				found = true;				res = &field[i-szSub];				break;			} 		}		else		{// Hmm. It didn't match the current byte of the target, so reset			j = 0;		}	}	return res;}/******************************************************************** * FUNCTION:    	NDBNextSearchByString * * DESCRIPTION: 	This routine looks for the next record *					containing the desired string. * SIDE EFFECT(S):	This routine modifies the fields of  *					recordP. * * RETURNED:    	nothing *					error code at the location specified  *					by errP. One of: *					ndbErrorSearchOver - search complete**********************************************************************/static void NDBNextSearchByString	// (out) nothing(	NDBRecordType *recordP,	// (in) record to search for	Err *errP,				// (in) where to place error	NDBSearchDirEnum dir	// (in) which way to go)							// (out) error code for error{	BytePtr bP;	Boolean found;	*errP = noErr;// validate arguments	if ( recordP != NULL )		*errP = dmErrInvalidParam;// Loop over index to find the next matching record.	do	{// Find the next record		recordP->recordH = NDBGetRecordWithIndex ( recordP->database, 			recordP->recordIdx, errP );		if ( recordP->recordH != NULL )		{			bP = (BytePtr)MemHandleLock( recordP->recordH );// Does this record have the desired substring?			found = (Boolean)( NDBMemSearch ( (BytePtr)bP, (BytePtr)recordP->targetP, 				MemHandleSize ( (MemHandle)recordP->recordH ), (UInt32)StrLen ( recordP->targetP ) ) != NULL );			MemHandleUnlock( recordP->recordH );// Yep.			if ( found ) 				break;// Nope. Are we at the beginning? If so, quit.			if ( dir == ndbSearchPrev && recordP->recordIdx == 0 )								break;				// Nope. Look at the next record.			recordP->recordIdx+= dir;			recordP->recordH = NULL;		}	}	while ( *errP == noErr );// If it's not found, say so.	if ( !found )	{		recordP->recordH = NULL;		if ( dir == ndbSearchNext )			*errP = ndbErrorSearchOver;		else			*errP = ndbErrorNoPreviousRecord;	}		return;}/******************************************************************** * FUNCTION:    	NDBRecordNew * * DESCRIPTION: 	This routine allocates a new NDBRecord. * SIDE EFFECT:		None * * RETURNED:    	Handle to new record *					error code at the location specified  *					by errP. One of *					memErrNotEnoughSpace - not enough memory *					memErrChunkNotLocked - could not lock **********************************************************************/static MemHandle NDBRecordNew // (out) handle to new record(	NDBDatabaseEnum db,		// (in) database to search	CharPtr keyP,			// (in) search key	Err *errP				// (in) where to place error)							// (out) error code for error{	MemHandle resultH;	NDBRecordType *resultP;	CharPtr tempP = NULL;		*errP = noErr;	// Allocate memory	resultH = MemHandleNew( sizeof ( NDBRecordType ) );	if ( !resultH )		*errP = memErrNotEnoughSpace;	if ( *errP == noErr && keyP ) 		tempP = MemPtrNew( StrLen( keyP ) + 1 );	if ( keyP && tempP == NULL )		*errP = memErrNotEnoughSpace;	if ( *errP == noErr )		resultP = MemHandleLock( resultH );// Initialize fields.	if ( *errP == noErr )	{		resultP->database = db;		resultP->targetP = tempP;		if ( keyP )			StrCopy( resultP->targetP, keyP );		resultP->recordIdx = 0;// Unlock		MemHandleUnlock( resultH );	}		return resultH;}/******************************************************************** * FUNCTION:    	NDBGetRecordWithIndex * * DESCRIPTION: 	This routine retrieves the record  *					at the virtual index specified. * * RETURNED:    	The record or NULL. *					error code at the location specified  *					by errP. One of *					dmErrIndexOutOfRange - db invalid *					**********************************************************************/static MemHandle NDBGetRecordWithIndex				(							// (out) handle to data	NDBDatabaseEnum db,		// (in) what database?	UInt16 index,			// (in) which record?	Err *errP				// (in) where to place error)							// (out) error code for error{	MemHandle dataH = NULL;	DmOpenRef *databaseP;	DmOpenRef theDatabase;	UInt16 theCard;	UInt16 theIndex = index;	UInt32 recCountOnCard = 0;	LocalID dbID;	Boolean found = false;	*errP = noErr;// validate arguments	if ( db <= ndbInvalid || db >= ndbLastDatabase )		*errP = dmErrIndexOutOfRange;			databaseP = NDBDatabaseRefForDatabase( db, errP );	if (*errP == noErr )		for ( theCard = 0; theCard < ndbMaxCardNum; theCard++ )		{			theDatabase = databaseP[ theCard ];

⌨️ 快捷键说明

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