home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <iostream.h>
- #include "pi-source.h"
- #include "pi-file.h"
- #include "pi-todo.h"
- #include "pi-memo.h"
- #include "pi-datebook.h"
- #include "pi-address.h"
-
- #define bool int
- #define false 0
- #define true 1
-
- static char *days[] = {
- "Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday"
- };
-
- static char *months[] = {
- "January", "February", "March", "April", "May", "June", "July",
- "August", "September", "October", "November", "December"
- };
-
- // All app info classes subclass from appInfo_t. You could pass any of
- // them to this function to print out the category names. Mainly it's here
- // to show the inheritance, as this has an appInfo_t as it's arguement, but
- // can take any of the default app info classes.
- void printCategoryNames(appInfo_t &ai)
- {
- char *ptr;
-
- for (short int i = 0; i < 16; i++) {
- // This is sort of dangerous. You are getting a pointer back to
- // the real data. That means if you modify what ptr points to, you
- // are changing the value in the class itself. Don't do that!
- // I can't find a way to keep this from happening. Even if I do
- // something anal like return a const char *const all you
- // have to do is cast it to char * and then it's modifiable.
- ptr = ai.category(i);
-
- // The first character will be non-null for an existing category
- if (*ptr)
- cout << "Category " << (i + 1) << " is " << ptr << endl;
- }
- }
-
- void memos(pi_file *pf)
- {
- void *app_info;
- int app_info_size;
-
- if (pi_file_get_app_info(pf, &app_info, &app_info_size) < 0) {
- cerr << "Unable to get app info" << endl;
- return;
- }
-
- // Create mai as an unpacked structure with the memo app info
- memoAppInfo_t mai(app_info);
-
- // packed is now a pointer to an area of memory thta is MEMO_APP_INFO_SIZE
- // bytes long. You are responsible for release this memory via delete
- void *packed = mai.pack();
- delete packed;
-
- int nentries;
- pi_file_get_entries(pf, &nentries);
-
- unsigned char *buf, packedBuf[0xffff];
- int size, attrs, cat;
- recordid_t uid;
-
- memo_t memo;
-
- for (int entnum = 0; entnum < nentries; entnum++) {
- if (pi_file_read_record(pf, entnum, (void **) &buf, &size,
- &attrs, &cat, &uid) < 0) {
- cout << "Error reading record number " << entnum << endl;
- return;
- }
-
- /* Skip deleted records */
- if ((attrs & dlpRecAttrDeleted) || (attrs & dlpRecAttrArchived))
- continue;
-
- memo.unpack(buf);
-
- cout << "Memo number " << (entnum + 1) << endl;
- cout << memo.text() << endl << endl;
-
- // Option 1 for getting a packed memo. Just give an int to be
- // filled in with the size of the memo. You must free the space
- // returned via delete
- packed = memo.pack(&size);
- delete packed;
-
- // Option 2 for getting a packed memo. Give a buffer, and an int
- // telling how big it is. If the buffer is too small to hold the
- // packed data, NULL is returned. Otherwise, the buffer is filled
- // in with the packed data, a pointer to it is returned, and the
- // integer passed in is reset to be the size of the packed data
- if (memo.pack(packedBuf, &size) == NULL)
- cerr << "Record number " << (entnum + 1) << " too big for "
- << "the buffer you passed in." << endl;
- }
- }
-
-
- void todos(pi_file *pf)
- {
- void *app_info;
- int app_info_size;
-
- if (pi_file_get_app_info(pf, &app_info, &app_info_size) < 0) {
- cerr << "Unable to get app info" << endl;
- return;
- }
-
- todoAppInfo_t tai(app_info);
-
- // packed is now a pointer to an area of memory that is TODO_APP_INFO_SIZE
- // bytes long. You are responsible for release this memory via delete
- void *packed = tai.pack();
- delete packed;
-
- int nentries;
- pi_file_get_entries(pf, &nentries);
-
- unsigned char *buf, packedBuf[0xffff];
- int size, attrs, cat;
- recordid_t uid;
- tm *due;
- todo_t todo;
-
- for (int entnum = 0; entnum < nentries; entnum++) {
- if (pi_file_read_record(pf, entnum, (void **) &buf, &size,
- &attrs, &cat, &uid) < 0) {
- cout << "Error reading record number " << entnum << endl;
- return;
- }
-
- /* Skip deleted records */
- if ((attrs & dlpRecAttrDeleted) || (attrs & dlpRecAttrArchived))
- continue;
-
- todo.unpack(buf);
-
- cout << "Category: " << tai.category(cat) << endl;
- if (todo.description())
- cout << "Description: " << todo.description() << endl;
- cout << "Priority: " << todo.priority() << endl;
- cout << "Completed: " << (todo.complete() ? "Yes" : "No") << endl;
- if ((due = todo.due()))
- cout << "Due: " << asctime(due);
- else
- cout << "Due: No Date" << endl;
- if(todo.note())
- cout << "Note: " << todo.note() << endl;
- cout << endl;
-
- // Just like the memo app, you can pack it like this...
- packed = todo.pack(&size);
- delete packed;
-
- // ... or like this
- size = sizeof(packedBuf);
- if (todo.pack(packedBuf, &size) == NULL)
- cerr << "Record number " << (entnum + 1) << " too big for "
- << "the buffer you passed in." << endl;
- }
- }
-
- // Only works for up to i == 31. Beyond that, results are undefined
- char *freqToStr(const int i)
- {
- static char buf[7];
-
- if (i == 1)
- buf[0] = '\0';
- else if (i == 3 || i == 23)
- (void) sprintf(buf, "%drd ", i);
- else if ((i > 3 && i < 21) || (i > 23 && i < 31))
- (void) sprintf(buf, "%dth ", i);
- else if (i == 21 || i == 31)
- (void) sprintf(buf, "%dst ", i);
- else if (i == 2 || i == 22)
- (void) sprintf(buf, "%dnd ", i);
-
- return buf;
- }
-
-
- void prettyPrintRepeat(appointment_t *appt)
- {
- tm *timePtr;
-
- if ((timePtr = appt->repeatEnd()))
- cout << "This event repeats until " << asctime(timePtr);
- else
- cout << "This event repeats forever" << endl;
-
- int freq = appt->repeatFreq();
- int on = appt->repeatOn();
-
- bool found = false;
-
- switch (appt->repeatType()) {
- case appointment_t::daily:
- cout << "It repeats every " << freqToStr(freq) << "day";
- break;
- case appointment_t::weekly:
- {
- cout << "It repeats every " << freqToStr(freq) << "week on ";
-
- for (int i = 0; i < 7; i++) {
- if (on & (1 << i)) {
- if (found)
- cout << " and ";
- else
- found = true;
- cout << days[i];
- }
- }
- cout << endl;
- break;
- }
- case appointment_t::monthlyByDay:
- cout << "It repeats on the ";
-
- switch (on / 7) {
- case 0:
- cout << "first ";
- break;
- case 1:
- cout << "second ";
- break;
- case 2:
- cout << "third ";
- break;
- case 3:
- cout << "fourth ";
- break;
- default:
- cout << "last ";
- }
-
- cout << days[on % 7] << " of every month";
- break;
- case appointment_t::monthlyByDate:
- cout << "It repeats every " << freqToStr(freq);
- timePtr = appt->beginTime();
- cout << "month on the " << freqToStr(timePtr->tm_mday) << endl;
- cout << endl;
- break;
- case appointment_t::yearly:
- cout << "It repeats every " << freqToStr(freq) << "year on ";
- timePtr = appt->beginTime();
- cout << months[timePtr->tm_mon] << " " << timePtr->tm_mday;
- cout << endl;
- break;
- default:
- cerr << "Internal error" << endl;
- }
- }
-
- void datebook(pi_file *pf)
- {
- void *app_info;
- int app_info_size;
-
- if (pi_file_get_app_info(pf, &app_info, &app_info_size) < 0) {
- cerr << "Unable to get app info" << endl;
- return;
- }
-
- appointmentAppInfo_t aai(app_info);
-
- // packed is now a pointer to an area of memory that is
- // APPOINTMENT_APP_INFO_SIZE bytes long. You are responsible for
- // release this memory via delete
- void *packed = aai.pack();
- delete packed;
-
- int nentries;
- pi_file_get_entries(pf, &nentries);
-
- unsigned char *buf;
- int size, attrs, cat;
- recordid_t uid;
- tm *timePtr;
- appointment_t appt;
-
- for (int entnum = 0; entnum < nentries; entnum++) {
- if (pi_file_read_record(pf, entnum, (void **) &buf, &size,
- &attrs, &cat, &uid) < 0) {
- cout << "Error reading record number " << entnum << endl;
- return;
- }
-
- /* Skip deleted records */
- if ((attrs & dlpRecAttrDeleted) || (attrs & dlpRecAttrArchived))
- continue;
-
- appt.unpack(buf);
-
- if (appt.untimed() == false) {
- cout << "Begin Time: " << asctime(appt.beginTime());
- cout << "End Time: " << asctime(appt.endTime());
- } else
- cout << "Untimed event" << endl;
-
- if (appt.hasAlarm()) {
- cout << "The alarm is set to go off " << appt.advance() << " ";
-
- switch (appt.advanceUnits()) {
- case appointment_t::minutes:
- cout << "minutes";
- break;
- case appointment_t::hours:
- cout << "hours";
- break;
- case appointment_t::days:
- cout << "days";
- default:
- cout << "(internal error)";
- }
-
- cout << " before the event" << endl;
- } else
- cout << "There is not an alarm set for this event" << endl;
-
- if (appt.repeatType() != appointment_t::none)
- prettyPrintRepeat(&appt);
- else
- cout << "Event does not repeat" << endl;
-
- if ((timePtr = appt.exceptions())) {
- size = appt.numExceptions();
- cout << "I seem to have " << size << " exceptions:" << endl;
- for (int i = 0; i < size; i++)
- cout << "\t" << asctime(&timePtr[i]);
- }
-
- cout << "Description: " << appt.description() << endl;
-
- if (appt.note())
- cout << "Note: " << appt.note() << endl;
-
- cout << endl;
- }
- }
-
-
- void addresses(pi_file *pf)
- {
-
- void *app_info;
- int app_info_size;
-
- if (pi_file_get_app_info(pf, &app_info, &app_info_size) < 0) {
- cerr << "Unable to get app info" << endl;
- return;
- }
-
- addressAppInfo_t aai(app_info);
-
- printCategoryNames(aai);
-
- // packed is now a pointer to an area of memory that is
- // ADDRESS_APP_INFO_SIZE bytes long. You are responsible for release this
- // memory via delete
- void *packed = aai.pack();
- delete packed;
-
- int nentries;
- pi_file_get_entries(pf, &nentries);
-
- unsigned char *buf, packedBuf[0xffff];
- int size, attrs, cat;
- recordid_t uid;
- address_t address;
- char *phonePtr;
-
- for (int entnum = 0; entnum < nentries; entnum++) {
- if (pi_file_read_record(pf, entnum, (void **) &buf, &size,
- &attrs, &cat, &uid) < 0) {
- cout << "Error reading record number " << entnum << endl;
- return;
- }
-
- /* Skip deleted records */
- if ((attrs & dlpRecAttrDeleted) || (attrs & dlpRecAttrArchived))
- continue;
-
- address.unpack(buf);
-
- cout << "Category: " << aai.category(cat) << endl;
- phonePtr = address.entry(address_t::lastName);
- if (phonePtr)
- cout << "Last Name: " << phonePtr << endl;
- for (cat = address_t::phone1; cat <= address_t::phone5; cat++)
- if ((phonePtr = address.entry((address_t::labelTypes_t) cat)))
- cout << "Phone: " << phonePtr << endl;
-
- // Just like the memo app, you can pack it like this...
- packed = address.pack(&size);
- delete packed;
-
- // ... or like this
- size = sizeof(packedBuf);
- if (address.pack(packedBuf, &size) == NULL)
- cerr << "Record number " << (entnum + 1) << " too big for "
- << "the buffer you passed in." << endl;
- }
- }
-
- int main(int argc, char **argv)
- {
- if (argc != 2) {
- cerr << "Usage: " << *argv << " [.pdb file]" << endl;
- return 1;
- }
-
- pi_file *pf;
- if ((pf = pi_file_open(*(argv + 1))) == NULL) {
- perror("pi_file_open");
- return 1;
- }
-
- char *slash = strrchr(*(argv + 1), '/');
- if (slash)
- slash++;
- else
- slash = *(argv + 1);
-
- if (!strcmp(slash, "ToDoDB.pdb"))
- todos(pf);
- else if (!strcmp(slash, "DatebookDB.pdb"))
- datebook(pf);
- else if (!strcmp(slash, "AddressDB.pdb"))
- addresses(pf);
- else if (!strcmp(slash, "MemoDB.pdb"))
- memos(pf);
- else
- cerr << "Unknown database: " << slash << endl;
-
- pi_file_close(pf);
-
- return 0;
- }
-
-