📄 ndb.c
字号:
* error code at the location specified * by errP.**********************************************************************/static MemHandle NDBTodoGetProp // (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{ ToDoDBRecordTypePtr dataP; MemHandle resultH = NULL; static char buff[64]; CharPtr fieldP; DateFormatType dateFormat; *errP = noErr; dataP = (ToDoDBRecordTypePtr)MemHandleLock( recordP->recordH ); switch ( prop ) {// Return the note contents case ndbPropNameNote: fieldP = NDBFetchStringFromPackedRecord( &dataP->description, todoNote, todoFieldsCount ); resultH = NDBNewHandleFromString( fieldP, errP ); break; case ndbPropNameDesc: fieldP = NDBFetchStringFromPackedRecord( &dataP->description, todoDescription, todoFieldsCount ); resultH = NDBNewHandleFromString( fieldP, errP ); break; case ndbPropNamePriority: StrPrintF( buff, "%d",dataP->priority ); resultH = NDBNewHandleFromString( buff, errP ); break; case ndbPropNameDueDate: case ndbPropNameDate: case ndbPropNameTime: //if ( (UInt16)( dataP->dueDate.year ) != toDoNoDueDate ) if ( dataP->dueDate.month < 13 ) { dateFormat = (DateFormatType)PrefGetPreference( prefDateFormat ); DateToAscii ( (UInt8)dataP->dueDate.month, (UInt8)dataP->dueDate.day, (UInt16)dataP->dueDate.year + 1904, dateFormat, buff ); resultH = NDBNewHandleFromString( buff, errP ); } break;// return the category default: break; } if ( dataP ) MemHandleUnlock( recordP->recordH ); return resultH;}/******************************************************************** * FUNCTION: NDBTodoGetText * * 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 NDBTodoGetText // (out) Handle to string( NDBRecordType *recordP, // (in) record Err *errP // (in) where to place error) // (out) error code for error{// For to do, the string representation looks like this:// (priority):date description MemHandle resultH; CharPtr resultP, priorityP, dateP, descP; MemHandle priorityH, dateH, descH; UInt32 sz; resultP = priorityP = dateP = descP = NULL; priorityH = NDBTodoGetProp( recordP, ndbPropNamePriority, errP ); dateH = NDBTodoGetProp( recordP, ndbPropNameDueDate, errP ); descH = NDBTodoGetProp( recordP, ndbPropNameDesc, errP ); if ( priorityH ) priorityP = MemHandleLock( priorityH ); if ( dateH ) dateP = MemHandleLock( dateH ); if ( descH ) descP = MemHandleLock( descH );// Find out how big the result handle needs to be. sz = (int)6*sizeof(Char) + // parenthesis, colon, space, and termination ( priorityP ? StrLen( priorityP ) : 0 ) + ( dateP ? StrLen( dateP ) : 0 ) + ( descP ? StrLen( descP ) : 0 );// create the handle resultH = MemHandleNew( sz ); if ( resultH == NULL ) *errP = memErrNotEnoughSpace; else {// create the result resultP = MemHandleLock( resultH ); StrPrintF( resultP, "(%s):%s %s", priorityP ? priorityP : "", dateP ? dateP : "", descP ? descP : "" ); MemHandleUnlock( resultH ); } return resultH;}// Datestypedef struct { TimeType startTime; // Time the appointment starts TimeType endTime; // Time the appointment ends DateType date; // date of appointment} ApptDateTimeType;typedef struct { UInt16 numExceptions; DateType exception;} ExceptionsListType;typedef struct { unsigned when :1; // set if when info changed (ApptChangeRecord) unsigned alarm :1; // set if record contains alarm info unsigned repeat :1; // set if record contains repeat info unsigned note :1; // set if record contains a note unsigned exceptions :1; // set if record contains exceptions list unsigned description :1; } ApptDBRecordFlags;typedef enum alarmTypes {aauMinutes, aauHours, aauDays} AlarmUnitType;typedef struct { Int8 advance; // Alarm advance (-1 = no alarm) AlarmUnitType advanceUnit; // minutes, hours, days} AlarmInfoType;enum repeatTypes { repeatNone, repeatDaily, repeatWeekly, repeatMonthlyByDay, repeatMonthlyByDate, repeatYearly};typedef enum repeatTypes RepeatType;typedef struct { RepeatType repeatType; // daily, weekly, monthlyByDay, etc. UInt8 reserved1; DateType repeatEndDate; // minus one if forever UInt8 repeatFrequency; // i.e. every 2 days if repeatType daily UInt8 repeatOn; // monthlyByDay and repeatWeekly only UInt8 repeatStartOfWeek;// repeatWeekly only UInt8 reserved2;} RepeatInfoType;// The following structure doesn't really exist. The first field// varies depending on the data present. However, it is convient// (and less error prone) to use when accessing the other information.// ApptDateTimeType when;// ApptDBRecordFlags flags; // A flag set for each datum present// AlarmInfoType alarm; // optional// RepeatInfoType repeat; // optional// ExceptionsListType exceptions; // optional// char [] note; // null terminated, optional// char [] description; // null terminated//// All optional data may or may not appear.typedef struct { ApptDateTimeType when; ApptDBRecordFlags flags; // A flag set for each datum present char firstField; UInt8 reserved;} ApptDBRecordType;typedef struct { ApptDateTimeType when; ApptDBRecordFlags flags; AlarmInfoType alarm; RepeatInfoType repeat; ExceptionsListType *listP; CharPtr note; CharPtr desc;} ApptDBUnpackedRecordType; /*********************************************************************** * * Appointment Database constants. * *************************************************************/#define apptMaxPerDay 100 // max appointments displayable on a day.#define apptNoTime -1 // start time of an untimed appt.#define apptNoEndDate 0xffff // end date of appts that repeat forever#define apptNoAlarm -1#define apptMaxEndTime 0x1737 // 11:55 pm, hours in high byte, minutes in low byte#define apptDawnOfTime 0#define apptEndOfTime 0xffffffff#define apptNote (0)#define apptDesc (1)#define apptFieldsCount (2)#define toDoNoDueDate ( 0xffff )/******************************************************************** * FUNCTION: NDBDateNew * * 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 void *NDBDateNew // (out) Handle to string( void *rP, // (in) record Err *errP // (in) where to place error){ BytePtr p = (BytePtr)rP; BytePtr r = NULL; ApptDBUnpackedRecordType *resultP = NULL; int i; ApptDBRecordType *recordP = rP; *errP = noErr;// validate if ( recordP == NULL ) *errP = dmErrInvalidParam; // We take a stream-oriented approach to parsing the date book record,// because it's rather complicated. // First, create a result structure. if ( *errP == noErr ) resultP = (ApptDBUnpackedRecordType *)MemPtrNew( sizeof ( ApptDBUnpackedRecordType ) ); if ( *errP == noErr && resultP == NULL ) { *errP = memErrNotEnoughSpace; } if ( *errP == noErr ) { r = (BytePtr) resultP;// Initialize pointer fields first for safety. resultP->note = resultP->desc = NULL; resultP->listP = NULL;// Extract the when and flags fields. These are pretty easy. MemMove( r, p, sizeof( ApptDateTimeType ) ); r += sizeof( ApptDateTimeType ); p += sizeof( ApptDateTimeType ); MemMove( r, p, sizeof( ApptDBRecordFlags ) ); r += sizeof( ApptDBRecordFlags ); p += sizeof( ApptDBRecordFlags ); // If an alarm was set, copy the alarm information. if ( recordP->flags.alarm == 1 ) { MemMove( r, p, sizeof( AlarmInfoType ) ); r += sizeof( AlarmInfoType ); p += sizeof( AlarmInfoType ); } // there's repeat information, copy it. if ( recordP->flags.repeat == 1 ) { MemMove( r, p, sizeof( RepeatInfoType ) ); r += sizeof( RepeatInfoType ); p += sizeof( RepeatInfoType ); } // if there's a note, make a new holder for the info and copy it. if ( recordP->flags.note ) { resultP->note = MemPtrNew( StrLen( (CharPtr)p ) + sizeof( Char ) ); // null term if ( resultP->note == NULL ) {// Dang. No memory. NDBDateFree( (void*)resultP, errP ); *errP = memErrNotEnoughSpace; resultP = NULL; } else {// We're good -- copy the note. StrCopy( resultP->note, (CharPtr)p ); p += StrLen( (CharPtr)p ) + sizeof( Char ); // null, too! } // is there memory for the note? } // if there's exceptions to the repeat info, make a new holder and copy it. if ( recordP->flags.exceptions ) { ExceptionsListType *eP; BytePtr temp; eP = ( ExceptionsListType * )p; resultP->listP = MemPtrNew( eP->numExceptions * sizeof( DateType ) + sizeof( UInt16 ) ); if ( resultP->listP == NULL ) {// Dang. No memory. NDBDateFree( resultP, errP ); *errP = memErrNotEnoughSpace; resultP = NULL; } else {// We're good -- copy the exceptions. temp = (BytePtr)resultP->listP; resultP->listP->numExceptions = eP->numExceptions; p += sizeof( UInt16 ); temp += sizeof( UInt16 ); for ( i = 0; i < eP->numExceptions; i++ ) { MemMove( temp, p, sizeof( DateType ) ); p += sizeof( DateType ); temp += sizeof( DateType ); } // for each exception } // is there memory for the exception list? }// if there's a description, make a new holder for the and copy it. if ( recordP->flags.description ) { resultP->desc = MemPtrNew( StrLen( (CharPtr)p ) + sizeof( Char ) ); // null term if ( resultP->desc == NULL ) {// Dang. No memory. NDBDateFree( resultP, errP ); *errP = memErrNotEnoughSpace; resultP = NULL; } else {// We're good -- copy the description. StrCopy( resultP->desc, (CharPtr)p ); p += StrLen( (CharPtr)p ) + sizeof( Char ); // null, too! } // is there memory for the description? } // was there a description? } // Was there an error? return (void *)resultP;}/******************************************************************** * FUNCTION: NDBDateFree * * DESCRIPTION: This routine frees the contents of an * unpacked date book record. * * RETURNED: A handle to the property as a string * error code at the location specified * by errP.**********************************************************************/static void NDBDateFree // (out) Handle to string( void *recordP, // (in) record Err */*errP*/ // (in) where to place error){ ApptDBUnpackedRecordType *rP = recordP; if ( recordP != NULL ) { if ( rP->listP ) MemPtrFree( rP->listP ); if ( rP->note ) MemPtrFree( rP->note ); if ( rP->desc ) MemPtrFree( rP->desc ); MemPtrFree( rP ); }}/******************************************************************** * FUNCTION: NDBDateGetProp * * 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 NDBDateGetProp // (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{ ApptDBRecordType *dataP = NULL; MemHandle resultH = NULL; CharPtr fieldP = NULL; DateFormatType dateFormat; TimeFormatType timeFormat; static char buff[64]; ApptDBUnpackedRecordType *uRecordP; *errP = noErr;// Get a pointer to the record we're interested in. dataP = (ApptDBRecordType *)MemHandleLock( recordP->recordH ); uRecordP = (ApptDBUnpackedRecordType*)NDBDateNew( dataP, errP ); if ( *errP == noErr ) {// Use the property to select the field in native database terms switch ( prop ) { case ndbPropNameNote: resultH = NDBNewHandleFromString( uRecordP->note, errP ); break; case ndbPropNameDesc: resultH = NDBNewHandleFromString( uRecordP->desc, errP ); break; case ndbPropNameTime: timeFormat = (TimeFormatType)PrefGetPreference( prefTimeFormat ); TimeToAscii ( (UInt8)uRecordP->when.startTime.hours, (UInt8)uRecordP->when.startTime.minutes, timeFormat, buff ); resultH = NDBNewHandleFromString( buff, errP ); break; case ndbPropNameDate: case ndbPropNameDueDate: dateFormat = (DateFormatType)PrefGetPreference( prefDateFormat ); DateToAscii ( (UInt8)uRecordP->when.date.month, (UInt8)uRecordP->when.date.day, (UInt16)uRecordP->when.date.year + 1904, dateFormat, buff ); resultH = NDBNewHandleFromString( buff, errP ); break; // return the category default: break; } } if ( uRecordP ) NDBDateFree( uRecordP, errP ); if ( dataP ) MemHandleUnlock( recordP->recordH ); return resultH;}/******************************************************************** * FUNCTION: NDBDateGetText * * DESCRIPTION: This routine returns a text representation * of the given datebook item. * * RETURNED: A handle to the string * error code at the location specified * by errP.**********************************************************************/static MemHandle NDBDateGetText // (out) Handle to string( NDBRecordType *recordP, // (in) record Err *errP // (in) where to place error) // (out) error code for error{// For dates, the string representation is a string looking like this:// date time: description MemHandle resultH; CharPtr resultP, timeP, dateP, descP; MemHandle timeH, dateH, descH; UInt32 sz; resultP = timeP = dateP = descP = NULL; timeH = NDBDateGetProp( recordP, ndbPropNameTime, errP ); dateH = NDBDateGetProp( recordP, ndbPropNameDate, errP ); descH = NDBDateGetProp( recordP, ndbPropNameDesc, errP ); if ( timeH ) timeP = MemHandleLock( timeH ); if ( dateH ) dateP = MemHandleLock( dateH ); if ( descH ) descP = MemHandleLock( descH );// Find out how big the result handle needs to be. sz = (int)5*sizeof(Char) + // space, space, colon, null terminator ( timeP ? StrLen( timeP ) : 0 ) + ( dateP ? StrLen( dateP ) : 0 ) + ( descP ? StrLen( descP ) : 0 );// create the handle resultH = MemHandleNew( sz ); if ( resultH == NULL ) *errP = memErrNotEnoughSpace; else {// create the result resultP = MemHandleLock( resultH ); StrPrintF( resultP, "%s %s: %s", dateP ? dateP : "", timeP ? timeP : "", descP ? descP : "" ); MemHandleUnlock( resultH ); } return resultH;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -