📄 ndb.c
字号:
/******************************************************************** * Native Database Record Conversion Routines ********************************************************/// memo// The following types were extracted from the Palm OS sample code in the// Palm OS 3.5 SDK.typedef struct { Char note; // null terminated UInt8 reserved;} MemoDBRecordType;typedef MemoDBRecordType * MemoDBRecordPtr;/******************************************************************** * FUNCTION: NDBMemoMemoGetDesc * * DESCRIPTION: This routine returns the first sentence * of a paragraph in a text string * * RETURNED: A pointer to what it believes is the * first sentence.**********************************************************************/static char *NDBMemoGetDesc // (out) pointer to string( const CharPtr t // (in) pointer to string){ static char desc[ NDBMAXDESCLEN ]; int i, howMany; Boolean stopCopy = false; // Validation if ( t == NULL ) return NULL; // Copy over just the first line for the description.// We'll copy up until the first carriage return, period, question mark, or exclamation point,// or until the string buffer is filled. howMany = NDBMAXDESCLEN - 1 < StrLen( t ) ? NDBMAXDESCLEN - 1 : StrLen( t ); for ( i = 0; i < howMany; i++ ) { desc[i] = t[i]; switch ( desc[i] ) { case chrFullStop: case chrQuestionMark: case chrExclamationMark: case chrLineFeed: case chrCarriageReturn: stopCopy = true; break; default: break; } if ( stopCopy ) break; }// Terminate the string desc[ i+1 ] = '\000'; return desc;}/******************************************************************** * FUNCTION: NDBMemoGetProp * * DESCRIPTION: This routine returns the desired property * of the given record. * * RETURNED: A handle to the property as a string * error code at the location specified * by errP.**********************************************************************/static MemHandle NDBMemoGetProp // (out) Handle to string( NDBRecordType *recordP, // (in) record NDBPropertyEnum prop, // (in) property sought Err *errP // (in) where to place error) // (out) error code for error{ MemoDBRecordPtr dataP; MemHandle resultH = NULL; *errP = noErr; dataP = (MemoDBRecordPtr)MemHandleLock( recordP->recordH ); switch ( prop ) {// Return the note contents case ndbPropNameNote: resultH = NDBNewHandleFromString( &dataP->note, errP ); break; case ndbPropNameDesc: resultH = NDBNewHandleFromString( NDBMemoGetDesc( &dataP->note ), errP ); break;// return the category default: break; } if ( dataP ) MemHandleUnlock( recordP->recordH ); return resultH;}/******************************************************************** * FUNCTION: NDBMemoGetText * * DESCRIPTION: This routine returns a text representation * of the given record. * * RETURNED: A handle to the string * error code at the location specified * by errP.**********************************************************************/static MemHandle NDBMemoGetText // (out) Handle to string( NDBRecordType *recordP, // (in) record Err *errP // (in) where to place error) // (out) error code for error{// For notes, the string representation is simply the text return NDBMemoGetProp( recordP, ndbPropNameNote, errP );}// Addtess const int addrLabelLength = 16;const int addrNumFields = 19;typedef union { struct { unsigned reserved :13; unsigned note :1; // set if record contains a note handle unsigned custom4 :1; // set if record contains a custom4 unsigned custom3 :1; // set if record contains a custom3 unsigned custom2 :1; // set if record contains a custom2 unsigned custom1 :1; // set if record contains a custom1 unsigned title :1; // set if record contains a title unsigned country :1; // set if record contains a birthday unsigned zipCode :1; // set if record contains a birthday unsigned state :1; // set if record contains a birthday unsigned city :1; // set if record contains a birthday unsigned address :1; // set if record contains a address unsigned phone5 :1; // set if record contains a phone5 unsigned phone4 :1; // set if record contains a phone4 unsigned phone3 :1; // set if record contains a phone3 unsigned phone2 :1; // set if record contains a phone2 unsigned phone1 :1; // set if record contains a phone1 unsigned company :1; // set if record contains a company unsigned firstName :1; // set if record contains a firstName unsigned name :1; // set if record contains a name (bit 0) } bits; UInt32 allBits;} AddrDBRecordFlagsType;typedef enum { addrFieldName = 0, addrFieldFirstName, addrFieldCompany, addrFieldPhone1, addrFieldPhone2, addrFieldPhone3, addrFieldPhone4, addrFieldPhone5, addrFieldAddress, addrFieldCity, addrFieldState, addrFieldZipCode, addrFieldCountry, addrFieldTitle, addrFieldCustom1, addrFieldCustom2, addrFieldCustom3, addrFieldCustom4, addrFieldNote, // This field is assumed to be < 4K addrFieldAddressFieldsCount} AddressFieldsEnum;typedef enum { addrLabelWork = 0, addrLabelHome, addrLabelFax, addrLabelOther, addrLabelEmail, addrLabelMain, addrLabelPager, addrLabelMobile} AddressPhoneLabelsEnum;#define NORECORD 0xffff#define firstAddressField addrFieldName#define firstPhoneField addrFieldPhone1#define lastPhoneField addrFieldPhone5#define numPhoneLabels 8#define numPhoneFields (lastPhoneField - firstPhoneField + 1)#define numPhoneLabelsStoredFirst numPhoneFields#define numPhoneLabelsStoredSecond (numPhoneLabels - numPhoneLabelsStoredFirst)#define firstRenameableLabel custom1#define lastRenameableLabel custom4#define lastLabel (addrFieldAddressFieldsCount + numPhoneLabelsStoredSecond)#define IsPhoneLookupField(p) (addrLookupWork <= (p) && (p) <= addrLookupMobile)const UInt16 ndbPropToAddrProp[] = { 0, // ndbPropNameInvalid = 0, addrFieldName, // ndbPropNameLastName, addrFieldFirstName, // ndbPropNameFirstName, addrFieldTitle, // ndbPropNameTitle, addrFieldCompany, // ndbPropNameCompany, addrLabelWork, // ndbPropNameWork, addrLabelHome, // ndbPropNameHome, addrLabelFax, // ndbPropNameFax, addrLabelOther, // ndbPropNameOther, addrLabelEmail, // ndbPropNameEmail, addrLabelMain, // ndbPropNameMain, addrLabelPager, // ndbPropNamePager, addrLabelMobile, // ndbPropNameMobile addrFieldAddress, // ndbPropNameAddress, addrFieldCity, // ndbPropNameCity, addrFieldState, // ndbPropNameState, addrFieldZipCode, // ndbPropNameZipCode, addrFieldCountry, // ndbPropNameCountry, addrFieldNote, // ndbPropNameNote,};typedef union { struct { unsigned reserved:8; unsigned displayPhoneForList:4; // The phone displayed for the list view 0 - 4 unsigned phone5:4; // Which phone (home, work, car, ...) unsigned phone4:4; unsigned phone3:4; unsigned phone2:4; unsigned phone1:4; } phones; UInt32 phoneBits;} AddrOptionsType;// AddrDBRecord.//// This is the unpacked record form as used by the app. Pointers are // either NULL or point to strings elsewhere on the card. All strings // are null character terminated.typedef struct { AddrOptionsType options; // Display by company or by name AddrDBRecordFlagsType flags; UInt8 addrFieldCompanyFieldOffset; // Offset from firstField // data follows Char data;} AddrDBRecordType;typedef AddrDBRecordType *AddrDBRecordPtr;typedef char addressLabel[addrLabelLength];/******************************************************************** * FUNCTION: NDBAddrGetNamedPhone * * DESCRIPTION: This routine extracts the named phone * number field from the record. * * RETURNED: Pointer to record's string. * error code at the location specified * by errP.**********************************************************************/static CharPtr NDBAddrGetNamedPhone // (out) Pointer to phone( AddrDBRecordType *dataP, // (in) Record AddressPhoneLabelsEnum label // (in) phone kind to get){ UInt16 i; CharPtr vP, rP = NULL; // For each of the phone strings:// If there's an entry, look at the corresponding phone field.// If the corresponding phone field points to a label,// see if the label is correct.// If the label is correct, return the string.// For each of the phone numbers in the record for ( i = addrFieldPhone1; i < addrFieldPhone5; i++ ) {// Get the data associated with that phone number vP = NDBFetchStringFromPackedMaskRecord( &dataP->data, i, addrFieldAddressFieldsCount, (UInt32)dataP->flags.allBits );// If there's data, check to see if the label matches what's sought. if ( StrLen( vP ) ) {// Check the matching phone option field to see if it matches the label// If we have a match, stash aside the results. switch( i ) { case addrFieldPhone1: if ( dataP->options.phones.phone1 == label ) rP = vP; break; case addrFieldPhone2: if ( dataP->options.phones.phone2 == label ) rP = vP; break; case addrFieldPhone3: if ( dataP->options.phones.phone3 == label ) rP = vP; break; case addrFieldPhone4: if ( dataP->options.phones.phone4 == label ) rP = vP; break; case addrFieldPhone5: if ( dataP->options.phones.phone5 == label ) rP = vP; break; }// If we have a match, we're through. if ( rP != NULL ) break; } }// Don't let the caller receive NULL; it may not grok it correctly. if ( rP == NULL ) rP = ndbEmptyString; return rP;}/******************************************************************** * FUNCTION: NDBAddrGetDesc * * DESCRIPTION: This routine returns the description * of an address, which is a string like: * lastName,FirstName (addrFieldCompany) * * RETURNED: A pointer to what it believes is the * description.**********************************************************************/static MemHandle NDBAddrGetDesc // (out) pointer to string( AddrDBRecordType *dataP // (in) Record){ CharPtr lastP = NDBFetchStringFromPackedMaskRecord( &dataP->data, addrFieldName, addrFieldAddressFieldsCount, dataP->flags.allBits ); CharPtr firstP = NDBFetchStringFromPackedMaskRecord( &dataP->data, addrFieldFirstName, addrFieldAddressFieldsCount, dataP->flags.allBits ); CharPtr addrFieldCompanyP = NDBFetchStringFromPackedMaskRecord( &dataP->data, addrFieldCompany, addrFieldAddressFieldsCount, dataP->flags.allBits ); MemHandle resultH = MemHandleNew( StrLen( lastP ) + StrLen( ndbSepString ) + StrLen ( firstP ) + StrLen( ndbSepStartSubDesc ) + StrLen( addrFieldCompanyP ) + StrLen( ndbSepEndSubDesc ) + 1 ); // don't forget null if ( resultH ) { CharPtr resultP = MemHandleLock( resultH );// Include the name only if there is one. if ( StrLen( lastP ) > 0 || StrLen( firstP ) > 0 ) { StrCopy( resultP, lastP ); StrCat( resultP, ndbSepString ); StrCat( resultP, firstP ); // Only include the addrFieldCompany in parens if there is one. if ( StrLen( addrFieldCompanyP ) > 0 ) { StrCat( resultP, ndbSepStartSubDesc ); StrCat( resultP, addrFieldCompanyP ); StrCat( resultP, ndbSepEndSubDesc ); } } else { StrCopy( resultP, addrFieldCompanyP ); } MemHandleUnlock( resultH ); } else { MemHandleFree( resultH ); resultH = NULL; } return resultH;}/******************************************************************** * FUNCTION: NDBAddrGetProp * * DESCRIPTION: This routine returns the desired property * of the given address record. * * RETURNED: A handle to the property as a string * error code at the location specified * by errP.**********************************************************************/static MemHandle NDBAddrGetProp // (out) Handle to string( NDBRecordType *recordP, // (in) record NDBPropertyEnum prop, // (in) property sought Err *errP // (in) where to place error) // (out) error code for error{ AddrDBRecordType *dataP; MemHandle resultH = NULL; CharPtr fieldP; *errP = noErr;// Get a pointer to the record we're interested in. dataP = (AddrDBRecordType *)MemHandleLock( recordP->recordH ); // Use the property to select the field in native database terms switch ( prop ) { case ndbPropNameLastName: case ndbPropNameFirstName: case ndbPropNameTitle: case ndbPropNameCompany: case ndbPropNameNote: case ndbPropNameAddress: case ndbPropNameCity: case ndbPropNameState: case ndbPropNameZipCode: case ndbPropNameCountry: fieldP = NDBFetchStringFromPackedMaskRecord( &dataP->data, ndbPropToAddrProp[ prop ], addrFieldAddressFieldsCount, dataP->flags.allBits ); resultH = NDBNewHandleFromString( fieldP, errP ); break; case ndbPropNameWork: case ndbPropNameHome: case ndbPropNameFax: case ndbPropNameOther: case ndbPropNameEmail: case ndbPropNameMain: case ndbPropNamePager: case ndbPropNameMobile: resultH = NDBNewHandleFromString( NDBAddrGetNamedPhone( dataP, (AddressPhoneLabelsEnum)ndbPropToAddrProp[ prop ] ), errP ); break; case ndbPropNameDesc: resultH = NDBAddrGetDesc( dataP ); break;// return the category default: break; } if ( dataP ) MemHandleUnlock( recordP->recordH ); return resultH;}/******************************************************************** * FUNCTION: NDBAddrGetText * * DESCRIPTION: This routine returns a text representation * of the given todo item. * * RETURNED: A handle to the string * error code at the location specified * by errP.**********************************************************************/static MemHandle NDBAddrGetText // (out) Handle to string( NDBRecordType *recordP, // (in) record Err *errP // (in) where to place error) // (out) error code for error{// For addresses, the string representation is simply the description return NDBAddrGetProp( recordP, ndbPropNameDesc, errP );}// Todo// ToDoDBRecord.//// All strings are null terminated and appear within the record.//typedef struct { DateType dueDate; UInt8 priority; // high bit is complete flag char description;} ToDoDBRecord;typedef ToDoDBRecord ToDoDBRecordType;typedef ToDoDBRecordType* ToDoDBRecordTypePtr;#define todoDescription (0)#define todoNote (1)#define todoFieldsCount (2)#define toDoNoDueDate ( 0xffff )/******************************************************************** * FUNCTION: NDBTodoGetProp * * DESCRIPTION: This routine returns the desired property * of the given record. * * RETURNED: A handle to the property as a string
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -